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
17 static int DRM(alloc_queue
) (drm_device_t
* dev
, int is_2d_only
) {
18 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) dev
->dev_private
;
21 for (i
= 0; i
< FFB_MAX_CTXS
; i
++) {
22 if (fpriv
->hw_state
[i
] == NULL
)
25 if (i
== FFB_MAX_CTXS
)
28 fpriv
->hw_state
[i
] = kmalloc(sizeof(struct ffb_hw_context
), GFP_KERNEL
);
29 if (fpriv
->hw_state
[i
] == NULL
)
32 fpriv
->hw_state
[i
]->is_2d_only
= is_2d_only
;
34 /* Plus one because 0 is the special DRM_KERNEL_CONTEXT. */
38 static void ffb_save_context(ffb_dev_priv_t
* fpriv
, int idx
)
40 ffb_fbcPtr ffb
= fpriv
->regs
;
41 struct ffb_hw_context
*ctx
;
44 ctx
= fpriv
->hw_state
[idx
- 1];
45 if (idx
== 0 || ctx
== NULL
)
48 if (ctx
->is_2d_only
) {
49 /* 2D applications only care about certain pieces
52 ctx
->drawop
= upa_readl(&ffb
->drawop
);
53 ctx
->ppc
= upa_readl(&ffb
->ppc
);
54 ctx
->wid
= upa_readl(&ffb
->wid
);
55 ctx
->fg
= upa_readl(&ffb
->fg
);
56 ctx
->bg
= upa_readl(&ffb
->bg
);
57 ctx
->xclip
= upa_readl(&ffb
->xclip
);
58 ctx
->fbc
= upa_readl(&ffb
->fbc
);
59 ctx
->rop
= upa_readl(&ffb
->rop
);
60 ctx
->cmp
= upa_readl(&ffb
->cmp
);
61 ctx
->matchab
= upa_readl(&ffb
->matchab
);
62 ctx
->magnab
= upa_readl(&ffb
->magnab
);
63 ctx
->pmask
= upa_readl(&ffb
->pmask
);
64 ctx
->xpmask
= upa_readl(&ffb
->xpmask
);
65 ctx
->lpat
= upa_readl(&ffb
->lpat
);
66 ctx
->fontxy
= upa_readl(&ffb
->fontxy
);
67 ctx
->fontw
= upa_readl(&ffb
->fontw
);
68 ctx
->fontinc
= upa_readl(&ffb
->fontinc
);
70 /* stencil/stencilctl only exists on FFB2+ and later
71 * due to the introduction of 3DRAM-III.
73 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
74 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
75 ctx
->stencil
= upa_readl(&ffb
->stencil
);
76 ctx
->stencilctl
= upa_readl(&ffb
->stencilctl
);
79 for (i
= 0; i
< 32; i
++)
80 ctx
->area_pattern
[i
] = upa_readl(&ffb
->pattern
[i
]);
81 ctx
->ucsr
= upa_readl(&ffb
->ucsr
);
86 ctx
->drawop
= upa_readl(&ffb
->drawop
);
88 /* If we were saving the vertex registers, this is where
89 * we would do it. We would save 32 32-bit words starting
93 /* Capture rendering attributes. */
95 ctx
->ppc
= upa_readl(&ffb
->ppc
); /* Pixel Processor Control */
96 ctx
->wid
= upa_readl(&ffb
->wid
); /* Current WID */
97 ctx
->fg
= upa_readl(&ffb
->fg
); /* Constant FG color */
98 ctx
->bg
= upa_readl(&ffb
->bg
); /* Constant BG color */
99 ctx
->consty
= upa_readl(&ffb
->consty
); /* Constant Y */
100 ctx
->constz
= upa_readl(&ffb
->constz
); /* Constant Z */
101 ctx
->xclip
= upa_readl(&ffb
->xclip
); /* X plane clip */
102 ctx
->dcss
= upa_readl(&ffb
->dcss
); /* Depth Cue Scale Slope */
103 ctx
->vclipmin
= upa_readl(&ffb
->vclipmin
); /* Primary XY clip, minimum */
104 ctx
->vclipmax
= upa_readl(&ffb
->vclipmax
); /* Primary XY clip, maximum */
105 ctx
->vclipzmin
= upa_readl(&ffb
->vclipzmin
); /* Primary Z clip, minimum */
106 ctx
->vclipzmax
= upa_readl(&ffb
->vclipzmax
); /* Primary Z clip, maximum */
107 ctx
->dcsf
= upa_readl(&ffb
->dcsf
); /* Depth Cue Scale Front Bound */
108 ctx
->dcsb
= upa_readl(&ffb
->dcsb
); /* Depth Cue Scale Back Bound */
109 ctx
->dczf
= upa_readl(&ffb
->dczf
); /* Depth Cue Scale Z Front */
110 ctx
->dczb
= upa_readl(&ffb
->dczb
); /* Depth Cue Scale Z Back */
111 ctx
->blendc
= upa_readl(&ffb
->blendc
); /* Alpha Blend Control */
112 ctx
->blendc1
= upa_readl(&ffb
->blendc1
); /* Alpha Blend Color 1 */
113 ctx
->blendc2
= upa_readl(&ffb
->blendc2
); /* Alpha Blend Color 2 */
114 ctx
->fbc
= upa_readl(&ffb
->fbc
); /* Frame Buffer Control */
115 ctx
->rop
= upa_readl(&ffb
->rop
); /* Raster Operation */
116 ctx
->cmp
= upa_readl(&ffb
->cmp
); /* Compare Controls */
117 ctx
->matchab
= upa_readl(&ffb
->matchab
); /* Buffer A/B Match Ops */
118 ctx
->matchc
= upa_readl(&ffb
->matchc
); /* Buffer C Match Ops */
119 ctx
->magnab
= upa_readl(&ffb
->magnab
); /* Buffer A/B Magnitude Ops */
120 ctx
->magnc
= upa_readl(&ffb
->magnc
); /* Buffer C Magnitude Ops */
121 ctx
->pmask
= upa_readl(&ffb
->pmask
); /* RGB Plane Mask */
122 ctx
->xpmask
= upa_readl(&ffb
->xpmask
); /* X Plane Mask */
123 ctx
->ypmask
= upa_readl(&ffb
->ypmask
); /* Y Plane Mask */
124 ctx
->zpmask
= upa_readl(&ffb
->zpmask
); /* Z Plane Mask */
126 /* Auxiliary Clips. */
127 ctx
->auxclip0min
= upa_readl(&ffb
->auxclip
[0].min
);
128 ctx
->auxclip0max
= upa_readl(&ffb
->auxclip
[0].max
);
129 ctx
->auxclip1min
= upa_readl(&ffb
->auxclip
[1].min
);
130 ctx
->auxclip1max
= upa_readl(&ffb
->auxclip
[1].max
);
131 ctx
->auxclip2min
= upa_readl(&ffb
->auxclip
[2].min
);
132 ctx
->auxclip2max
= upa_readl(&ffb
->auxclip
[2].max
);
133 ctx
->auxclip3min
= upa_readl(&ffb
->auxclip
[3].min
);
134 ctx
->auxclip3max
= upa_readl(&ffb
->auxclip
[3].max
);
136 ctx
->lpat
= upa_readl(&ffb
->lpat
); /* Line Pattern */
137 ctx
->fontxy
= upa_readl(&ffb
->fontxy
); /* XY Font Coordinate */
138 ctx
->fontw
= upa_readl(&ffb
->fontw
); /* Font Width */
139 ctx
->fontinc
= upa_readl(&ffb
->fontinc
); /* Font X/Y Increment */
141 /* These registers/features only exist on FFB2 and later chips. */
142 if (fpriv
->ffb_type
>= ffb2_prototype
) {
143 ctx
->dcss1
= upa_readl(&ffb
->dcss1
); /* Depth Cue Scale Slope 1 */
144 ctx
->dcss2
= upa_readl(&ffb
->dcss2
); /* Depth Cue Scale Slope 2 */
145 ctx
->dcss2
= upa_readl(&ffb
->dcss3
); /* Depth Cue Scale Slope 3 */
146 ctx
->dcs2
= upa_readl(&ffb
->dcs2
); /* Depth Cue Scale 2 */
147 ctx
->dcs3
= upa_readl(&ffb
->dcs3
); /* Depth Cue Scale 3 */
148 ctx
->dcs4
= upa_readl(&ffb
->dcs4
); /* Depth Cue Scale 4 */
149 ctx
->dcd2
= upa_readl(&ffb
->dcd2
); /* Depth Cue Depth 2 */
150 ctx
->dcd3
= upa_readl(&ffb
->dcd3
); /* Depth Cue Depth 3 */
151 ctx
->dcd4
= upa_readl(&ffb
->dcd4
); /* Depth Cue Depth 4 */
153 /* And stencil/stencilctl only exists on FFB2+ and later
154 * due to the introduction of 3DRAM-III.
156 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
157 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
158 ctx
->stencil
= upa_readl(&ffb
->stencil
);
159 ctx
->stencilctl
= upa_readl(&ffb
->stencilctl
);
163 /* Save the 32x32 area pattern. */
164 for (i
= 0; i
< 32; i
++)
165 ctx
->area_pattern
[i
] = upa_readl(&ffb
->pattern
[i
]);
167 /* Finally, stash away the User Constol/Status Register. */
168 ctx
->ucsr
= upa_readl(&ffb
->ucsr
);
171 static void ffb_restore_context(ffb_dev_priv_t
* fpriv
, int old
, int idx
)
173 ffb_fbcPtr ffb
= fpriv
->regs
;
174 struct ffb_hw_context
*ctx
;
177 ctx
= fpriv
->hw_state
[idx
- 1];
178 if (idx
== 0 || ctx
== NULL
)
181 if (ctx
->is_2d_only
) {
182 /* 2D applications only care about certain pieces
185 upa_writel(ctx
->drawop
, &ffb
->drawop
);
187 /* If we were restoring the vertex registers, this is where
188 * we would do it. We would restore 32 32-bit words starting
192 upa_writel(ctx
->ppc
, &ffb
->ppc
);
193 upa_writel(ctx
->wid
, &ffb
->wid
);
194 upa_writel(ctx
->fg
, &ffb
->fg
);
195 upa_writel(ctx
->bg
, &ffb
->bg
);
196 upa_writel(ctx
->xclip
, &ffb
->xclip
);
197 upa_writel(ctx
->fbc
, &ffb
->fbc
);
198 upa_writel(ctx
->rop
, &ffb
->rop
);
199 upa_writel(ctx
->cmp
, &ffb
->cmp
);
200 upa_writel(ctx
->matchab
, &ffb
->matchab
);
201 upa_writel(ctx
->magnab
, &ffb
->magnab
);
202 upa_writel(ctx
->pmask
, &ffb
->pmask
);
203 upa_writel(ctx
->xpmask
, &ffb
->xpmask
);
204 upa_writel(ctx
->lpat
, &ffb
->lpat
);
205 upa_writel(ctx
->fontxy
, &ffb
->fontxy
);
206 upa_writel(ctx
->fontw
, &ffb
->fontw
);
207 upa_writel(ctx
->fontinc
, &ffb
->fontinc
);
209 /* stencil/stencilctl only exists on FFB2+ and later
210 * due to the introduction of 3DRAM-III.
212 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
213 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
214 upa_writel(ctx
->stencil
, &ffb
->stencil
);
215 upa_writel(ctx
->stencilctl
, &ffb
->stencilctl
);
216 upa_writel(0x80000000, &ffb
->fbc
);
217 upa_writel((ctx
->stencilctl
| 0x80000),
218 &ffb
->rawstencilctl
);
219 upa_writel(ctx
->fbc
, &ffb
->fbc
);
222 for (i
= 0; i
< 32; i
++)
223 upa_writel(ctx
->area_pattern
[i
], &ffb
->pattern
[i
]);
224 upa_writel((ctx
->ucsr
& 0xf0000), &ffb
->ucsr
);
228 /* Restore drawop. */
229 upa_writel(ctx
->drawop
, &ffb
->drawop
);
231 /* If we were restoring the vertex registers, this is where
232 * we would do it. We would restore 32 32-bit words starting
236 /* Restore rendering attributes. */
238 upa_writel(ctx
->ppc
, &ffb
->ppc
); /* Pixel Processor Control */
239 upa_writel(ctx
->wid
, &ffb
->wid
); /* Current WID */
240 upa_writel(ctx
->fg
, &ffb
->fg
); /* Constant FG color */
241 upa_writel(ctx
->bg
, &ffb
->bg
); /* Constant BG color */
242 upa_writel(ctx
->consty
, &ffb
->consty
); /* Constant Y */
243 upa_writel(ctx
->constz
, &ffb
->constz
); /* Constant Z */
244 upa_writel(ctx
->xclip
, &ffb
->xclip
); /* X plane clip */
245 upa_writel(ctx
->dcss
, &ffb
->dcss
); /* Depth Cue Scale Slope */
246 upa_writel(ctx
->vclipmin
, &ffb
->vclipmin
); /* Primary XY clip, minimum */
247 upa_writel(ctx
->vclipmax
, &ffb
->vclipmax
); /* Primary XY clip, maximum */
248 upa_writel(ctx
->vclipzmin
, &ffb
->vclipzmin
); /* Primary Z clip, minimum */
249 upa_writel(ctx
->vclipzmax
, &ffb
->vclipzmax
); /* Primary Z clip, maximum */
250 upa_writel(ctx
->dcsf
, &ffb
->dcsf
); /* Depth Cue Scale Front Bound */
251 upa_writel(ctx
->dcsb
, &ffb
->dcsb
); /* Depth Cue Scale Back Bound */
252 upa_writel(ctx
->dczf
, &ffb
->dczf
); /* Depth Cue Scale Z Front */
253 upa_writel(ctx
->dczb
, &ffb
->dczb
); /* Depth Cue Scale Z Back */
254 upa_writel(ctx
->blendc
, &ffb
->blendc
); /* Alpha Blend Control */
255 upa_writel(ctx
->blendc1
, &ffb
->blendc1
); /* Alpha Blend Color 1 */
256 upa_writel(ctx
->blendc2
, &ffb
->blendc2
); /* Alpha Blend Color 2 */
257 upa_writel(ctx
->fbc
, &ffb
->fbc
); /* Frame Buffer Control */
258 upa_writel(ctx
->rop
, &ffb
->rop
); /* Raster Operation */
259 upa_writel(ctx
->cmp
, &ffb
->cmp
); /* Compare Controls */
260 upa_writel(ctx
->matchab
, &ffb
->matchab
); /* Buffer A/B Match Ops */
261 upa_writel(ctx
->matchc
, &ffb
->matchc
); /* Buffer C Match Ops */
262 upa_writel(ctx
->magnab
, &ffb
->magnab
); /* Buffer A/B Magnitude Ops */
263 upa_writel(ctx
->magnc
, &ffb
->magnc
); /* Buffer C Magnitude Ops */
264 upa_writel(ctx
->pmask
, &ffb
->pmask
); /* RGB Plane Mask */
265 upa_writel(ctx
->xpmask
, &ffb
->xpmask
); /* X Plane Mask */
266 upa_writel(ctx
->ypmask
, &ffb
->ypmask
); /* Y Plane Mask */
267 upa_writel(ctx
->zpmask
, &ffb
->zpmask
); /* Z Plane Mask */
269 /* Auxiliary Clips. */
270 upa_writel(ctx
->auxclip0min
, &ffb
->auxclip
[0].min
);
271 upa_writel(ctx
->auxclip0max
, &ffb
->auxclip
[0].max
);
272 upa_writel(ctx
->auxclip1min
, &ffb
->auxclip
[1].min
);
273 upa_writel(ctx
->auxclip1max
, &ffb
->auxclip
[1].max
);
274 upa_writel(ctx
->auxclip2min
, &ffb
->auxclip
[2].min
);
275 upa_writel(ctx
->auxclip2max
, &ffb
->auxclip
[2].max
);
276 upa_writel(ctx
->auxclip3min
, &ffb
->auxclip
[3].min
);
277 upa_writel(ctx
->auxclip3max
, &ffb
->auxclip
[3].max
);
279 upa_writel(ctx
->lpat
, &ffb
->lpat
); /* Line Pattern */
280 upa_writel(ctx
->fontxy
, &ffb
->fontxy
); /* XY Font Coordinate */
281 upa_writel(ctx
->fontw
, &ffb
->fontw
); /* Font Width */
282 upa_writel(ctx
->fontinc
, &ffb
->fontinc
); /* Font X/Y Increment */
284 /* These registers/features only exist on FFB2 and later chips. */
285 if (fpriv
->ffb_type
>= ffb2_prototype
) {
286 upa_writel(ctx
->dcss1
, &ffb
->dcss1
); /* Depth Cue Scale Slope 1 */
287 upa_writel(ctx
->dcss2
, &ffb
->dcss2
); /* Depth Cue Scale Slope 2 */
288 upa_writel(ctx
->dcss3
, &ffb
->dcss2
); /* Depth Cue Scale Slope 3 */
289 upa_writel(ctx
->dcs2
, &ffb
->dcs2
); /* Depth Cue Scale 2 */
290 upa_writel(ctx
->dcs3
, &ffb
->dcs3
); /* Depth Cue Scale 3 */
291 upa_writel(ctx
->dcs4
, &ffb
->dcs4
); /* Depth Cue Scale 4 */
292 upa_writel(ctx
->dcd2
, &ffb
->dcd2
); /* Depth Cue Depth 2 */
293 upa_writel(ctx
->dcd3
, &ffb
->dcd3
); /* Depth Cue Depth 3 */
294 upa_writel(ctx
->dcd4
, &ffb
->dcd4
); /* Depth Cue Depth 4 */
296 /* And stencil/stencilctl only exists on FFB2+ and later
297 * due to the introduction of 3DRAM-III.
299 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
300 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
301 /* Unfortunately, there is a hardware bug on
302 * the FFB2+ chips which prevents a normal write
303 * to the stencil control register from working
306 * The state controlled by the FFB stencilctl register
307 * really gets transferred to the per-buffer instances
308 * of the stencilctl register in the 3DRAM chips.
310 * The bug is that FFB does not update buffer C correctly,
311 * so we have to do it by hand for them.
314 /* This will update buffers A and B. */
315 upa_writel(ctx
->stencil
, &ffb
->stencil
);
316 upa_writel(ctx
->stencilctl
, &ffb
->stencilctl
);
318 /* Force FFB to use buffer C 3dram regs. */
319 upa_writel(0x80000000, &ffb
->fbc
);
320 upa_writel((ctx
->stencilctl
| 0x80000),
321 &ffb
->rawstencilctl
);
323 /* Now restore the correct FBC controls. */
324 upa_writel(ctx
->fbc
, &ffb
->fbc
);
328 /* Restore the 32x32 area pattern. */
329 for (i
= 0; i
< 32; i
++)
330 upa_writel(ctx
->area_pattern
[i
], &ffb
->pattern
[i
]);
332 /* Finally, stash away the User Constol/Status Register.
333 * The only state we really preserve here is the picking
336 upa_writel((ctx
->ucsr
& 0xf0000), &ffb
->ucsr
);
339 #define FFB_UCSR_FB_BUSY 0x01000000
340 #define FFB_UCSR_RP_BUSY 0x02000000
341 #define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
343 static void FFBWait(ffb_fbcPtr ffb
)
348 u32 regval
= upa_readl(&ffb
->ucsr
);
350 if ((regval
& FFB_UCSR_ALL_BUSY
) == 0)
355 int ffb_driver_context_switch(drm_device_t
* dev
, int old
, int new)
357 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) dev
->dev_private
;
359 #ifdef DRM_DMA_HISTOGRAM
360 dev
->ctx_start
= get_cycles();
363 DRM_DEBUG("Context switch from %d to %d\n", old
, new);
365 if (new == dev
->last_context
|| dev
->last_context
== 0) {
366 dev
->last_context
= new;
370 FFBWait(fpriv
->regs
);
371 ffb_save_context(fpriv
, old
);
372 ffb_restore_context(fpriv
, old
, new);
373 FFBWait(fpriv
->regs
);
375 dev
->last_context
= new;
380 int ffb_driver_resctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
387 DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS
);
388 if (copy_from_user(&res
, (drm_ctx_res_t __user
*) arg
, sizeof(res
)))
390 if (res
.count
>= DRM_RESERVED_CONTEXTS
) {
391 memset(&ctx
, 0, sizeof(ctx
));
392 for (i
= 0; i
< DRM_RESERVED_CONTEXTS
; i
++) {
394 if (copy_to_user(&res
.contexts
[i
], &i
, sizeof(i
)))
398 res
.count
= DRM_RESERVED_CONTEXTS
;
399 if (copy_to_user((drm_ctx_res_t __user
*) arg
, &res
, sizeof(res
)))
404 int ffb_driver_addctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
407 drm_file_t
*priv
= filp
->private_data
;
408 drm_device_t
*dev
= priv
->dev
;
412 if (copy_from_user(&ctx
, (drm_ctx_t __user
*) arg
, sizeof(ctx
)))
414 idx
= DRM(alloc_queue
) (dev
, (ctx
.flags
& _DRM_CONTEXT_2DONLY
));
418 DRM_DEBUG("%d\n", ctx
.handle
);
420 if (copy_to_user((drm_ctx_t __user
*) arg
, &ctx
, sizeof(ctx
)))
425 int ffb_driver_modctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
428 drm_file_t
*priv
= filp
->private_data
;
429 drm_device_t
*dev
= priv
->dev
;
430 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) dev
->dev_private
;
431 struct ffb_hw_context
*hwctx
;
435 if (copy_from_user(&ctx
, (drm_ctx_t __user
*) arg
, sizeof(ctx
)))
439 if (idx
<= 0 || idx
>= FFB_MAX_CTXS
)
442 hwctx
= fpriv
->hw_state
[idx
- 1];
446 if ((ctx
.flags
& _DRM_CONTEXT_2DONLY
) == 0)
447 hwctx
->is_2d_only
= 0;
449 hwctx
->is_2d_only
= 1;
454 int ffb_driver_getctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
457 drm_file_t
*priv
= filp
->private_data
;
458 drm_device_t
*dev
= priv
->dev
;
459 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) dev
->dev_private
;
460 struct ffb_hw_context
*hwctx
;
464 if (copy_from_user(&ctx
, (drm_ctx_t __user
*) arg
, sizeof(ctx
)))
468 if (idx
<= 0 || idx
>= FFB_MAX_CTXS
)
471 hwctx
= fpriv
->hw_state
[idx
- 1];
475 if (hwctx
->is_2d_only
!= 0)
476 ctx
.flags
= _DRM_CONTEXT_2DONLY
;
480 if (copy_to_user((drm_ctx_t __user
*) arg
, &ctx
, sizeof(ctx
)))
486 int ffb_driver_switchctx(struct inode
*inode
, struct file
*filp
,
487 unsigned int cmd
, unsigned long arg
)
489 drm_file_t
*priv
= filp
->private_data
;
490 drm_device_t
*dev
= priv
->dev
;
493 if (copy_from_user(&ctx
, (drm_ctx_t __user
*) arg
, sizeof(ctx
)))
495 DRM_DEBUG("%d\n", ctx
.handle
);
496 return ffb_driver_context_switch(dev
, dev
->last_context
, ctx
.handle
);
499 int ffb_driver_newctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
504 if (copy_from_user(&ctx
, (drm_ctx_t __user
*) arg
, sizeof(ctx
)))
506 DRM_DEBUG("%d\n", ctx
.handle
);
511 int ffb_driver_rmctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
515 drm_file_t
*priv
= filp
->private_data
;
516 drm_device_t
*dev
= priv
->dev
;
517 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) dev
->dev_private
;
520 if (copy_from_user(&ctx
, (drm_ctx_t __user
*) arg
, sizeof(ctx
)))
522 DRM_DEBUG("%d\n", ctx
.handle
);
524 idx
= ctx
.handle
- 1;
525 if (idx
< 0 || idx
>= FFB_MAX_CTXS
)
528 kfree(fpriv
->hw_state
[idx
]);
529 fpriv
->hw_state
[idx
] = NULL
;
533 void ffb_set_context_ioctls(void)
535 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX
)].func
= ffb_driver_addctx
;
536 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX
)].func
= ffb_driver_rmctx
;
537 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX
)].func
= ffb_driver_modctx
;
538 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX
)].func
= ffb_driver_getctx
;
539 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX
)].func
=
540 ffb_driver_switchctx
;
541 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX
)].func
= ffb_driver_newctx
;
542 DRM(ioctls
)[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX
)].func
= ffb_driver_resctx
;