1 /* $Id: ffb_context.c,v 1.5 2001/08/09 17:47:51 davem Exp $
2 * ffb_context.c: Creator/Creator3D DRI/DRM context switching.
4 * Copyright (C) 2000 David S. Miller (davem@redhat.com)
6 * Almost entirely stolen from tdfx_context.c, see there
10 #include <linux/sched.h>
18 static int DRM(alloc_queue
)(drm_device_t
*dev
, int is_2d_only
)
20 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) dev
->dev_private
;
23 for (i
= 0; i
< FFB_MAX_CTXS
; i
++) {
24 if (fpriv
->hw_state
[i
] == NULL
)
27 if (i
== FFB_MAX_CTXS
)
30 fpriv
->hw_state
[i
] = kmalloc(sizeof(struct ffb_hw_context
), GFP_KERNEL
);
31 if (fpriv
->hw_state
[i
] == NULL
)
34 fpriv
->hw_state
[i
]->is_2d_only
= is_2d_only
;
36 /* Plus one because 0 is the special DRM_KERNEL_CONTEXT. */
40 static void ffb_save_context(ffb_dev_priv_t
*fpriv
, int idx
)
42 ffb_fbcPtr ffb
= fpriv
->regs
;
43 struct ffb_hw_context
*ctx
;
46 ctx
= fpriv
->hw_state
[idx
- 1];
47 if (idx
== 0 || ctx
== NULL
)
50 if (ctx
->is_2d_only
) {
51 /* 2D applications only care about certain pieces
54 ctx
->drawop
= upa_readl(&ffb
->drawop
);
55 ctx
->ppc
= upa_readl(&ffb
->ppc
);
56 ctx
->wid
= upa_readl(&ffb
->wid
);
57 ctx
->fg
= upa_readl(&ffb
->fg
);
58 ctx
->bg
= upa_readl(&ffb
->bg
);
59 ctx
->xclip
= upa_readl(&ffb
->xclip
);
60 ctx
->fbc
= upa_readl(&ffb
->fbc
);
61 ctx
->rop
= upa_readl(&ffb
->rop
);
62 ctx
->cmp
= upa_readl(&ffb
->cmp
);
63 ctx
->matchab
= upa_readl(&ffb
->matchab
);
64 ctx
->magnab
= upa_readl(&ffb
->magnab
);
65 ctx
->pmask
= upa_readl(&ffb
->pmask
);
66 ctx
->xpmask
= upa_readl(&ffb
->xpmask
);
67 ctx
->lpat
= upa_readl(&ffb
->lpat
);
68 ctx
->fontxy
= upa_readl(&ffb
->fontxy
);
69 ctx
->fontw
= upa_readl(&ffb
->fontw
);
70 ctx
->fontinc
= upa_readl(&ffb
->fontinc
);
72 /* stencil/stencilctl only exists on FFB2+ and later
73 * due to the introduction of 3DRAM-III.
75 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
76 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
77 ctx
->stencil
= upa_readl(&ffb
->stencil
);
78 ctx
->stencilctl
= upa_readl(&ffb
->stencilctl
);
81 for (i
= 0; i
< 32; i
++)
82 ctx
->area_pattern
[i
] = upa_readl(&ffb
->pattern
[i
]);
83 ctx
->ucsr
= upa_readl(&ffb
->ucsr
);
88 ctx
->drawop
= upa_readl(&ffb
->drawop
);
90 /* If we were saving the vertex registers, this is where
91 * we would do it. We would save 32 32-bit words starting
95 /* Capture rendering attributes. */
97 ctx
->ppc
= upa_readl(&ffb
->ppc
); /* Pixel Processor Control */
98 ctx
->wid
= upa_readl(&ffb
->wid
); /* Current WID */
99 ctx
->fg
= upa_readl(&ffb
->fg
); /* Constant FG color */
100 ctx
->bg
= upa_readl(&ffb
->bg
); /* Constant BG color */
101 ctx
->consty
= upa_readl(&ffb
->consty
); /* Constant Y */
102 ctx
->constz
= upa_readl(&ffb
->constz
); /* Constant Z */
103 ctx
->xclip
= upa_readl(&ffb
->xclip
); /* X plane clip */
104 ctx
->dcss
= upa_readl(&ffb
->dcss
); /* Depth Cue Scale Slope */
105 ctx
->vclipmin
= upa_readl(&ffb
->vclipmin
); /* Primary XY clip, minimum */
106 ctx
->vclipmax
= upa_readl(&ffb
->vclipmax
); /* Primary XY clip, maximum */
107 ctx
->vclipzmin
= upa_readl(&ffb
->vclipzmin
); /* Primary Z clip, minimum */
108 ctx
->vclipzmax
= upa_readl(&ffb
->vclipzmax
); /* Primary Z clip, maximum */
109 ctx
->dcsf
= upa_readl(&ffb
->dcsf
); /* Depth Cue Scale Front Bound */
110 ctx
->dcsb
= upa_readl(&ffb
->dcsb
); /* Depth Cue Scale Back Bound */
111 ctx
->dczf
= upa_readl(&ffb
->dczf
); /* Depth Cue Scale Z Front */
112 ctx
->dczb
= upa_readl(&ffb
->dczb
); /* Depth Cue Scale Z Back */
113 ctx
->blendc
= upa_readl(&ffb
->blendc
); /* Alpha Blend Control */
114 ctx
->blendc1
= upa_readl(&ffb
->blendc1
); /* Alpha Blend Color 1 */
115 ctx
->blendc2
= upa_readl(&ffb
->blendc2
); /* Alpha Blend Color 2 */
116 ctx
->fbc
= upa_readl(&ffb
->fbc
); /* Frame Buffer Control */
117 ctx
->rop
= upa_readl(&ffb
->rop
); /* Raster Operation */
118 ctx
->cmp
= upa_readl(&ffb
->cmp
); /* Compare Controls */
119 ctx
->matchab
= upa_readl(&ffb
->matchab
); /* Buffer A/B Match Ops */
120 ctx
->matchc
= upa_readl(&ffb
->matchc
); /* Buffer C Match Ops */
121 ctx
->magnab
= upa_readl(&ffb
->magnab
); /* Buffer A/B Magnitude Ops */
122 ctx
->magnc
= upa_readl(&ffb
->magnc
); /* Buffer C Magnitude Ops */
123 ctx
->pmask
= upa_readl(&ffb
->pmask
); /* RGB Plane Mask */
124 ctx
->xpmask
= upa_readl(&ffb
->xpmask
); /* X Plane Mask */
125 ctx
->ypmask
= upa_readl(&ffb
->ypmask
); /* Y Plane Mask */
126 ctx
->zpmask
= upa_readl(&ffb
->zpmask
); /* Z Plane Mask */
128 /* Auxiliary Clips. */
129 ctx
->auxclip0min
= upa_readl(&ffb
->auxclip
[0].min
);
130 ctx
->auxclip0max
= upa_readl(&ffb
->auxclip
[0].max
);
131 ctx
->auxclip1min
= upa_readl(&ffb
->auxclip
[1].min
);
132 ctx
->auxclip1max
= upa_readl(&ffb
->auxclip
[1].max
);
133 ctx
->auxclip2min
= upa_readl(&ffb
->auxclip
[2].min
);
134 ctx
->auxclip2max
= upa_readl(&ffb
->auxclip
[2].max
);
135 ctx
->auxclip3min
= upa_readl(&ffb
->auxclip
[3].min
);
136 ctx
->auxclip3max
= upa_readl(&ffb
->auxclip
[3].max
);
138 ctx
->lpat
= upa_readl(&ffb
->lpat
); /* Line Pattern */
139 ctx
->fontxy
= upa_readl(&ffb
->fontxy
); /* XY Font Coordinate */
140 ctx
->fontw
= upa_readl(&ffb
->fontw
); /* Font Width */
141 ctx
->fontinc
= upa_readl(&ffb
->fontinc
); /* Font X/Y Increment */
143 /* These registers/features only exist on FFB2 and later chips. */
144 if (fpriv
->ffb_type
>= ffb2_prototype
) {
145 ctx
->dcss1
= upa_readl(&ffb
->dcss1
); /* Depth Cue Scale Slope 1 */
146 ctx
->dcss2
= upa_readl(&ffb
->dcss2
); /* Depth Cue Scale Slope 2 */
147 ctx
->dcss2
= upa_readl(&ffb
->dcss3
); /* Depth Cue Scale Slope 3 */
148 ctx
->dcs2
= upa_readl(&ffb
->dcs2
); /* Depth Cue Scale 2 */
149 ctx
->dcs3
= upa_readl(&ffb
->dcs3
); /* Depth Cue Scale 3 */
150 ctx
->dcs4
= upa_readl(&ffb
->dcs4
); /* Depth Cue Scale 4 */
151 ctx
->dcd2
= upa_readl(&ffb
->dcd2
); /* Depth Cue Depth 2 */
152 ctx
->dcd3
= upa_readl(&ffb
->dcd3
); /* Depth Cue Depth 3 */
153 ctx
->dcd4
= upa_readl(&ffb
->dcd4
); /* Depth Cue Depth 4 */
155 /* And stencil/stencilctl only exists on FFB2+ and later
156 * due to the introduction of 3DRAM-III.
158 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
159 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
160 ctx
->stencil
= upa_readl(&ffb
->stencil
);
161 ctx
->stencilctl
= upa_readl(&ffb
->stencilctl
);
165 /* Save the 32x32 area pattern. */
166 for (i
= 0; i
< 32; i
++)
167 ctx
->area_pattern
[i
] = upa_readl(&ffb
->pattern
[i
]);
169 /* Finally, stash away the User Constol/Status Register. */
170 ctx
->ucsr
= upa_readl(&ffb
->ucsr
);
173 static void ffb_restore_context(ffb_dev_priv_t
*fpriv
, int old
, int idx
)
175 ffb_fbcPtr ffb
= fpriv
->regs
;
176 struct ffb_hw_context
*ctx
;
179 ctx
= fpriv
->hw_state
[idx
- 1];
180 if (idx
== 0 || ctx
== NULL
)
183 if (ctx
->is_2d_only
) {
184 /* 2D applications only care about certain pieces
187 upa_writel(ctx
->drawop
, &ffb
->drawop
);
189 /* If we were restoring the vertex registers, this is where
190 * we would do it. We would restore 32 32-bit words starting
194 upa_writel(ctx
->ppc
, &ffb
->ppc
);
195 upa_writel(ctx
->wid
, &ffb
->wid
);
196 upa_writel(ctx
->fg
, &ffb
->fg
);
197 upa_writel(ctx
->bg
, &ffb
->bg
);
198 upa_writel(ctx
->xclip
, &ffb
->xclip
);
199 upa_writel(ctx
->fbc
, &ffb
->fbc
);
200 upa_writel(ctx
->rop
, &ffb
->rop
);
201 upa_writel(ctx
->cmp
, &ffb
->cmp
);
202 upa_writel(ctx
->matchab
, &ffb
->matchab
);
203 upa_writel(ctx
->magnab
, &ffb
->magnab
);
204 upa_writel(ctx
->pmask
, &ffb
->pmask
);
205 upa_writel(ctx
->xpmask
, &ffb
->xpmask
);
206 upa_writel(ctx
->lpat
, &ffb
->lpat
);
207 upa_writel(ctx
->fontxy
, &ffb
->fontxy
);
208 upa_writel(ctx
->fontw
, &ffb
->fontw
);
209 upa_writel(ctx
->fontinc
, &ffb
->fontinc
);
211 /* stencil/stencilctl only exists on FFB2+ and later
212 * due to the introduction of 3DRAM-III.
214 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
215 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
216 upa_writel(ctx
->stencil
, &ffb
->stencil
);
217 upa_writel(ctx
->stencilctl
, &ffb
->stencilctl
);
218 upa_writel(0x80000000, &ffb
->fbc
);
219 upa_writel((ctx
->stencilctl
| 0x80000),
220 &ffb
->rawstencilctl
);
221 upa_writel(ctx
->fbc
, &ffb
->fbc
);
224 for (i
= 0; i
< 32; i
++)
225 upa_writel(ctx
->area_pattern
[i
], &ffb
->pattern
[i
]);
226 upa_writel((ctx
->ucsr
& 0xf0000), &ffb
->ucsr
);
230 /* Restore drawop. */
231 upa_writel(ctx
->drawop
, &ffb
->drawop
);
233 /* If we were restoring the vertex registers, this is where
234 * we would do it. We would restore 32 32-bit words starting
238 /* Restore rendering attributes. */
240 upa_writel(ctx
->ppc
, &ffb
->ppc
); /* Pixel Processor Control */
241 upa_writel(ctx
->wid
, &ffb
->wid
); /* Current WID */
242 upa_writel(ctx
->fg
, &ffb
->fg
); /* Constant FG color */
243 upa_writel(ctx
->bg
, &ffb
->bg
); /* Constant BG color */
244 upa_writel(ctx
->consty
, &ffb
->consty
); /* Constant Y */
245 upa_writel(ctx
->constz
, &ffb
->constz
); /* Constant Z */
246 upa_writel(ctx
->xclip
, &ffb
->xclip
); /* X plane clip */
247 upa_writel(ctx
->dcss
, &ffb
->dcss
); /* Depth Cue Scale Slope */
248 upa_writel(ctx
->vclipmin
, &ffb
->vclipmin
); /* Primary XY clip, minimum */
249 upa_writel(ctx
->vclipmax
, &ffb
->vclipmax
); /* Primary XY clip, maximum */
250 upa_writel(ctx
->vclipzmin
, &ffb
->vclipzmin
); /* Primary Z clip, minimum */
251 upa_writel(ctx
->vclipzmax
, &ffb
->vclipzmax
); /* Primary Z clip, maximum */
252 upa_writel(ctx
->dcsf
, &ffb
->dcsf
); /* Depth Cue Scale Front Bound */
253 upa_writel(ctx
->dcsb
, &ffb
->dcsb
); /* Depth Cue Scale Back Bound */
254 upa_writel(ctx
->dczf
, &ffb
->dczf
); /* Depth Cue Scale Z Front */
255 upa_writel(ctx
->dczb
, &ffb
->dczb
); /* Depth Cue Scale Z Back */
256 upa_writel(ctx
->blendc
, &ffb
->blendc
); /* Alpha Blend Control */
257 upa_writel(ctx
->blendc1
, &ffb
->blendc1
); /* Alpha Blend Color 1 */
258 upa_writel(ctx
->blendc2
, &ffb
->blendc2
); /* Alpha Blend Color 2 */
259 upa_writel(ctx
->fbc
, &ffb
->fbc
); /* Frame Buffer Control */
260 upa_writel(ctx
->rop
, &ffb
->rop
); /* Raster Operation */
261 upa_writel(ctx
->cmp
, &ffb
->cmp
); /* Compare Controls */
262 upa_writel(ctx
->matchab
, &ffb
->matchab
); /* Buffer A/B Match Ops */
263 upa_writel(ctx
->matchc
, &ffb
->matchc
); /* Buffer C Match Ops */
264 upa_writel(ctx
->magnab
, &ffb
->magnab
); /* Buffer A/B Magnitude Ops */
265 upa_writel(ctx
->magnc
, &ffb
->magnc
); /* Buffer C Magnitude Ops */
266 upa_writel(ctx
->pmask
, &ffb
->pmask
); /* RGB Plane Mask */
267 upa_writel(ctx
->xpmask
, &ffb
->xpmask
); /* X Plane Mask */
268 upa_writel(ctx
->ypmask
, &ffb
->ypmask
); /* Y Plane Mask */
269 upa_writel(ctx
->zpmask
, &ffb
->zpmask
); /* Z Plane Mask */
271 /* Auxiliary Clips. */
272 upa_writel(ctx
->auxclip0min
, &ffb
->auxclip
[0].min
);
273 upa_writel(ctx
->auxclip0max
, &ffb
->auxclip
[0].max
);
274 upa_writel(ctx
->auxclip1min
, &ffb
->auxclip
[1].min
);
275 upa_writel(ctx
->auxclip1max
, &ffb
->auxclip
[1].max
);
276 upa_writel(ctx
->auxclip2min
, &ffb
->auxclip
[2].min
);
277 upa_writel(ctx
->auxclip2max
, &ffb
->auxclip
[2].max
);
278 upa_writel(ctx
->auxclip3min
, &ffb
->auxclip
[3].min
);
279 upa_writel(ctx
->auxclip3max
, &ffb
->auxclip
[3].max
);
281 upa_writel(ctx
->lpat
, &ffb
->lpat
); /* Line Pattern */
282 upa_writel(ctx
->fontxy
, &ffb
->fontxy
); /* XY Font Coordinate */
283 upa_writel(ctx
->fontw
, &ffb
->fontw
); /* Font Width */
284 upa_writel(ctx
->fontinc
, &ffb
->fontinc
); /* Font X/Y Increment */
286 /* These registers/features only exist on FFB2 and later chips. */
287 if (fpriv
->ffb_type
>= ffb2_prototype
) {
288 upa_writel(ctx
->dcss1
, &ffb
->dcss1
); /* Depth Cue Scale Slope 1 */
289 upa_writel(ctx
->dcss2
, &ffb
->dcss2
); /* Depth Cue Scale Slope 2 */
290 upa_writel(ctx
->dcss3
, &ffb
->dcss2
); /* Depth Cue Scale Slope 3 */
291 upa_writel(ctx
->dcs2
, &ffb
->dcs2
); /* Depth Cue Scale 2 */
292 upa_writel(ctx
->dcs3
, &ffb
->dcs3
); /* Depth Cue Scale 3 */
293 upa_writel(ctx
->dcs4
, &ffb
->dcs4
); /* Depth Cue Scale 4 */
294 upa_writel(ctx
->dcd2
, &ffb
->dcd2
); /* Depth Cue Depth 2 */
295 upa_writel(ctx
->dcd3
, &ffb
->dcd3
); /* Depth Cue Depth 3 */
296 upa_writel(ctx
->dcd4
, &ffb
->dcd4
); /* Depth Cue Depth 4 */
298 /* And stencil/stencilctl only exists on FFB2+ and later
299 * due to the introduction of 3DRAM-III.
301 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
302 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
303 /* Unfortunately, there is a hardware bug on
304 * the FFB2+ chips which prevents a normal write
305 * to the stencil control register from working
308 * The state controlled by the FFB stencilctl register
309 * really gets transferred to the per-buffer instances
310 * of the stencilctl register in the 3DRAM chips.
312 * The bug is that FFB does not update buffer C correctly,
313 * so we have to do it by hand for them.
316 /* This will update buffers A and B. */
317 upa_writel(ctx
->stencil
, &ffb
->stencil
);
318 upa_writel(ctx
->stencilctl
, &ffb
->stencilctl
);
320 /* Force FFB to use buffer C 3dram regs. */
321 upa_writel(0x80000000, &ffb
->fbc
);
322 upa_writel((ctx
->stencilctl
| 0x80000),
323 &ffb
->rawstencilctl
);
325 /* Now restore the correct FBC controls. */
326 upa_writel(ctx
->fbc
, &ffb
->fbc
);
330 /* Restore the 32x32 area pattern. */
331 for (i
= 0; i
< 32; i
++)
332 upa_writel(ctx
->area_pattern
[i
], &ffb
->pattern
[i
]);
334 /* Finally, stash away the User Constol/Status Register.
335 * The only state we really preserve here is the picking
338 upa_writel((ctx
->ucsr
& 0xf0000), &ffb
->ucsr
);
341 #define FFB_UCSR_FB_BUSY 0x01000000
342 #define FFB_UCSR_RP_BUSY 0x02000000
343 #define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
345 static void FFBWait(ffb_fbcPtr ffb
)
350 u32 regval
= upa_readl(&ffb
->ucsr
);
352 if ((regval
& FFB_UCSR_ALL_BUSY
) == 0)
357 int ffb_driver_context_switch(drm_device_t
*dev
, int old
, int new)
359 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) dev
->dev_private
;
361 #ifdef DRM_DMA_HISTOGRAM
362 dev
->ctx_start
= get_cycles();
365 DRM_DEBUG("Context switch from %d to %d\n", old
, new);
367 if (new == dev
->last_context
||
368 dev
->last_context
== 0) {
369 dev
->last_context
= new;
373 FFBWait(fpriv
->regs
);
374 ffb_save_context(fpriv
, old
);
375 ffb_restore_context(fpriv
, old
, new);
376 FFBWait(fpriv
->regs
);
378 dev
->last_context
= new;
383 int ffb_driver_resctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
390 DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS
);
391 if (copy_from_user(&res
, (drm_ctx_res_t __user
*)arg
, sizeof(res
)))
393 if (res
.count
>= DRM_RESERVED_CONTEXTS
) {
394 memset(&ctx
, 0, sizeof(ctx
));
395 for (i
= 0; i
< DRM_RESERVED_CONTEXTS
; i
++) {
397 if (copy_to_user(&res
.contexts
[i
],
403 res
.count
= DRM_RESERVED_CONTEXTS
;
404 if (copy_to_user((drm_ctx_res_t __user
*)arg
, &res
, sizeof(res
)))
410 int ffb_driver_addctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
413 drm_file_t
*priv
= filp
->private_data
;
414 drm_device_t
*dev
= priv
->dev
;
418 if (copy_from_user(&ctx
, (drm_ctx_t __user
*)arg
, sizeof(ctx
)))
420 idx
= DRM(alloc_queue
)(dev
, (ctx
.flags
& _DRM_CONTEXT_2DONLY
));
424 DRM_DEBUG("%d\n", ctx
.handle
);
426 if (copy_to_user((drm_ctx_t __user
*)arg
, &ctx
, sizeof(ctx
)))
431 int ffb_driver_modctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
434 drm_file_t
*priv
= filp
->private_data
;
435 drm_device_t
*dev
= priv
->dev
;
436 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) dev
->dev_private
;
437 struct ffb_hw_context
*hwctx
;
441 if (copy_from_user(&ctx
, (drm_ctx_t __user
*)arg
, sizeof(ctx
)))
445 if (idx
<= 0 || idx
>= FFB_MAX_CTXS
)
448 hwctx
= fpriv
->hw_state
[idx
- 1];
452 if ((ctx
.flags
& _DRM_CONTEXT_2DONLY
) == 0)
453 hwctx
->is_2d_only
= 0;
455 hwctx
->is_2d_only
= 1;
460 int ffb_driver_getctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
463 drm_file_t
*priv
= filp
->private_data
;
464 drm_device_t
*dev
= priv
->dev
;
465 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) dev
->dev_private
;
466 struct ffb_hw_context
*hwctx
;
470 if (copy_from_user(&ctx
, (drm_ctx_t __user
*)arg
, sizeof(ctx
)))
474 if (idx
<= 0 || idx
>= FFB_MAX_CTXS
)
477 hwctx
= fpriv
->hw_state
[idx
- 1];
481 if (hwctx
->is_2d_only
!= 0)
482 ctx
.flags
= _DRM_CONTEXT_2DONLY
;
486 if (copy_to_user((drm_ctx_t __user
*)arg
, &ctx
, sizeof(ctx
)))
492 int ffb_driver_switchctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
495 drm_file_t
*priv
= filp
->private_data
;
496 drm_device_t
*dev
= priv
->dev
;
499 if (copy_from_user(&ctx
, (drm_ctx_t __user
*)arg
, sizeof(ctx
)))
501 DRM_DEBUG("%d\n", ctx
.handle
);
502 return ffb_driver_context_switch(dev
, dev
->last_context
, ctx
.handle
);
505 int ffb_driver_newctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
510 if (copy_from_user(&ctx
, (drm_ctx_t __user
*)arg
, sizeof(ctx
)))
512 DRM_DEBUG("%d\n", ctx
.handle
);
517 int ffb_driver_rmctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
521 drm_file_t
*priv
= filp
->private_data
;
522 drm_device_t
*dev
= priv
->dev
;
523 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) dev
->dev_private
;
526 if (copy_from_user(&ctx
, (drm_ctx_t __user
*)arg
, sizeof(ctx
)))
528 DRM_DEBUG("%d\n", ctx
.handle
);
530 idx
= ctx
.handle
- 1;
531 if (idx
< 0 || idx
>= FFB_MAX_CTXS
)
534 if (fpriv
->hw_state
[idx
] != NULL
) {
535 kfree(fpriv
->hw_state
[idx
]);
536 fpriv
->hw_state
[idx
] = NULL
;
541 void ffb_set_context_ioctls(void)
543 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX
)].func
= ffb_driver_addctx
;
544 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX
)].func
= ffb_driver_rmctx
;
545 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX
)].func
= ffb_driver_modctx
;
546 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX
)].func
= ffb_driver_getctx
;
547 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX
)].func
= ffb_driver_switchctx
;
548 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX
)].func
= ffb_driver_newctx
;
549 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX
)].func
= ffb_driver_resctx
;