1 /* $Id: ffb_context.c,v 1.3 2000/06/09 03:46:53 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>
17 static int ffb_alloc_queue(drm_device_t
*dev
, int is_2d_only
)
19 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) (dev
+ 1);
22 for (i
= 0; i
< FFB_MAX_CTXS
; i
++) {
23 if (fpriv
->hw_state
[i
] == NULL
)
26 if (i
== FFB_MAX_CTXS
)
29 fpriv
->hw_state
[i
] = kmalloc(sizeof(struct ffb_hw_context
), GFP_KERNEL
);
30 if (fpriv
->hw_state
[i
] == NULL
)
33 fpriv
->hw_state
[i
]->is_2d_only
= is_2d_only
;
35 /* Plus one because 0 is the special DRM_KERNEL_CONTEXT. */
39 static void ffb_save_context(ffb_dev_priv_t
*fpriv
, int idx
)
41 ffb_fbcPtr ffb
= fpriv
->regs
;
42 struct ffb_hw_context
*ctx
;
45 ctx
= fpriv
->hw_state
[idx
- 1];
46 if (idx
== 0 || ctx
== NULL
)
49 if (ctx
->is_2d_only
) {
50 /* 2D applications only care about certain pieces
53 ctx
->drawop
= upa_readl(&ffb
->drawop
);
54 ctx
->ppc
= upa_readl(&ffb
->ppc
);
55 ctx
->wid
= upa_readl(&ffb
->wid
);
56 ctx
->fg
= upa_readl(&ffb
->fg
);
57 ctx
->bg
= upa_readl(&ffb
->bg
);
58 ctx
->xclip
= upa_readl(&ffb
->xclip
);
59 ctx
->fbc
= upa_readl(&ffb
->fbc
);
60 ctx
->rop
= upa_readl(&ffb
->rop
);
61 ctx
->cmp
= upa_readl(&ffb
->cmp
);
62 ctx
->matchab
= upa_readl(&ffb
->matchab
);
63 ctx
->magnab
= upa_readl(&ffb
->magnab
);
64 ctx
->pmask
= upa_readl(&ffb
->pmask
);
65 ctx
->xpmask
= upa_readl(&ffb
->xpmask
);
66 ctx
->lpat
= upa_readl(&ffb
->lpat
);
67 ctx
->fontxy
= upa_readl(&ffb
->fontxy
);
68 ctx
->fontw
= upa_readl(&ffb
->fontw
);
69 ctx
->fontinc
= upa_readl(&ffb
->fontinc
);
71 /* stencil/stencilctl only exists on FFB2+ and later
72 * due to the introduction of 3DRAM-III.
74 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
75 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
76 ctx
->stencil
= upa_readl(&ffb
->stencil
);
77 ctx
->stencilctl
= upa_readl(&ffb
->stencilctl
);
80 for (i
= 0; i
< 32; i
++)
81 ctx
->area_pattern
[i
] = upa_readl(&ffb
->pattern
[i
]);
82 ctx
->ucsr
= upa_readl(&ffb
->ucsr
);
87 ctx
->drawop
= upa_readl(&ffb
->drawop
);
89 /* If we were saving the vertex registers, this is where
90 * we would do it. We would save 32 32-bit words starting
94 /* Capture rendering attributes. */
96 ctx
->ppc
= upa_readl(&ffb
->ppc
); /* Pixel Processor Control */
97 ctx
->wid
= upa_readl(&ffb
->wid
); /* Current WID */
98 ctx
->fg
= upa_readl(&ffb
->fg
); /* Constant FG color */
99 ctx
->bg
= upa_readl(&ffb
->bg
); /* Constant BG color */
100 ctx
->consty
= upa_readl(&ffb
->consty
); /* Constant Y */
101 ctx
->constz
= upa_readl(&ffb
->constz
); /* Constant Z */
102 ctx
->xclip
= upa_readl(&ffb
->xclip
); /* X plane clip */
103 ctx
->dcss
= upa_readl(&ffb
->dcss
); /* Depth Cue Scale Slope */
104 ctx
->vclipmin
= upa_readl(&ffb
->vclipmin
); /* Primary XY clip, minimum */
105 ctx
->vclipmax
= upa_readl(&ffb
->vclipmax
); /* Primary XY clip, maximum */
106 ctx
->vclipzmin
= upa_readl(&ffb
->vclipzmin
); /* Primary Z clip, minimum */
107 ctx
->vclipzmax
= upa_readl(&ffb
->vclipzmax
); /* Primary Z clip, maximum */
108 ctx
->dcsf
= upa_readl(&ffb
->dcsf
); /* Depth Cue Scale Front Bound */
109 ctx
->dcsb
= upa_readl(&ffb
->dcsb
); /* Depth Cue Scale Back Bound */
110 ctx
->dczf
= upa_readl(&ffb
->dczf
); /* Depth Cue Scale Z Front */
111 ctx
->dczb
= upa_readl(&ffb
->dczb
); /* Depth Cue Scale Z Back */
112 ctx
->blendc
= upa_readl(&ffb
->blendc
); /* Alpha Blend Control */
113 ctx
->blendc1
= upa_readl(&ffb
->blendc1
); /* Alpha Blend Color 1 */
114 ctx
->blendc2
= upa_readl(&ffb
->blendc2
); /* Alpha Blend Color 2 */
115 ctx
->fbc
= upa_readl(&ffb
->fbc
); /* Frame Buffer Control */
116 ctx
->rop
= upa_readl(&ffb
->rop
); /* Raster Operation */
117 ctx
->cmp
= upa_readl(&ffb
->cmp
); /* Compare Controls */
118 ctx
->matchab
= upa_readl(&ffb
->matchab
); /* Buffer A/B Match Ops */
119 ctx
->matchc
= upa_readl(&ffb
->matchc
); /* Buffer C Match Ops */
120 ctx
->magnab
= upa_readl(&ffb
->magnab
); /* Buffer A/B Magnitude Ops */
121 ctx
->magnc
= upa_readl(&ffb
->magnc
); /* Buffer C Magnitude Ops */
122 ctx
->pmask
= upa_readl(&ffb
->pmask
); /* RGB Plane Mask */
123 ctx
->xpmask
= upa_readl(&ffb
->xpmask
); /* X Plane Mask */
124 ctx
->ypmask
= upa_readl(&ffb
->ypmask
); /* Y Plane Mask */
125 ctx
->zpmask
= upa_readl(&ffb
->zpmask
); /* Z Plane Mask */
127 /* Auxiliary Clips. */
128 ctx
->auxclip0min
= upa_readl(&ffb
->auxclip
[0].min
);
129 ctx
->auxclip0max
= upa_readl(&ffb
->auxclip
[0].max
);
130 ctx
->auxclip1min
= upa_readl(&ffb
->auxclip
[1].min
);
131 ctx
->auxclip1max
= upa_readl(&ffb
->auxclip
[1].max
);
132 ctx
->auxclip2min
= upa_readl(&ffb
->auxclip
[2].min
);
133 ctx
->auxclip2max
= upa_readl(&ffb
->auxclip
[2].max
);
134 ctx
->auxclip3min
= upa_readl(&ffb
->auxclip
[3].min
);
135 ctx
->auxclip3max
= upa_readl(&ffb
->auxclip
[3].max
);
137 ctx
->lpat
= upa_readl(&ffb
->lpat
); /* Line Pattern */
138 ctx
->fontxy
= upa_readl(&ffb
->fontxy
); /* XY Font Coordinate */
139 ctx
->fontw
= upa_readl(&ffb
->fontw
); /* Font Width */
140 ctx
->fontinc
= upa_readl(&ffb
->fontinc
); /* Font X/Y Increment */
142 /* These registers/features only exist on FFB2 and later chips. */
143 if (fpriv
->ffb_type
>= ffb2_prototype
) {
144 ctx
->dcss1
= upa_readl(&ffb
->dcss1
); /* Depth Cue Scale Slope 1 */
145 ctx
->dcss2
= upa_readl(&ffb
->dcss2
); /* Depth Cue Scale Slope 2 */
146 ctx
->dcss2
= upa_readl(&ffb
->dcss3
); /* Depth Cue Scale Slope 3 */
147 ctx
->dcs2
= upa_readl(&ffb
->dcs2
); /* Depth Cue Scale 2 */
148 ctx
->dcs3
= upa_readl(&ffb
->dcs3
); /* Depth Cue Scale 3 */
149 ctx
->dcs4
= upa_readl(&ffb
->dcs4
); /* Depth Cue Scale 4 */
150 ctx
->dcd2
= upa_readl(&ffb
->dcd2
); /* Depth Cue Depth 2 */
151 ctx
->dcd3
= upa_readl(&ffb
->dcd3
); /* Depth Cue Depth 3 */
152 ctx
->dcd4
= upa_readl(&ffb
->dcd4
); /* Depth Cue Depth 4 */
154 /* And stencil/stencilctl only exists on FFB2+ and later
155 * due to the introduction of 3DRAM-III.
157 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
158 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
159 ctx
->stencil
= upa_readl(&ffb
->stencil
);
160 ctx
->stencilctl
= upa_readl(&ffb
->stencilctl
);
164 /* Save the 32x32 area pattern. */
165 for (i
= 0; i
< 32; i
++)
166 ctx
->area_pattern
[i
] = upa_readl(&ffb
->pattern
[i
]);
168 /* Finally, stash away the User Constol/Status Register. */
169 ctx
->ucsr
= upa_readl(&ffb
->ucsr
);
172 static void ffb_restore_context(ffb_dev_priv_t
*fpriv
, int old
, int idx
)
174 ffb_fbcPtr ffb
= fpriv
->regs
;
175 struct ffb_hw_context
*ctx
;
178 ctx
= fpriv
->hw_state
[idx
- 1];
179 if (idx
== 0 || ctx
== NULL
)
182 if (ctx
->is_2d_only
) {
183 /* 2D applications only care about certain pieces
186 upa_writel(ctx
->drawop
, &ffb
->drawop
);
188 /* If we were restoring the vertex registers, this is where
189 * we would do it. We would restore 32 32-bit words starting
193 upa_writel(ctx
->ppc
, &ffb
->ppc
);
194 upa_writel(ctx
->wid
, &ffb
->wid
);
195 upa_writel(ctx
->fg
, &ffb
->fg
);
196 upa_writel(ctx
->bg
, &ffb
->bg
);
197 upa_writel(ctx
->xclip
, &ffb
->xclip
);
198 upa_writel(ctx
->fbc
, &ffb
->fbc
);
199 upa_writel(ctx
->rop
, &ffb
->rop
);
200 upa_writel(ctx
->cmp
, &ffb
->cmp
);
201 upa_writel(ctx
->matchab
, &ffb
->matchab
);
202 upa_writel(ctx
->magnab
, &ffb
->magnab
);
203 upa_writel(ctx
->pmask
, &ffb
->pmask
);
204 upa_writel(ctx
->xpmask
, &ffb
->xpmask
);
205 upa_writel(ctx
->lpat
, &ffb
->lpat
);
206 upa_writel(ctx
->fontxy
, &ffb
->fontxy
);
207 upa_writel(ctx
->fontw
, &ffb
->fontw
);
208 upa_writel(ctx
->fontinc
, &ffb
->fontinc
);
210 /* stencil/stencilctl only exists on FFB2+ and later
211 * due to the introduction of 3DRAM-III.
213 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
214 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
215 upa_writel(ctx
->stencil
, &ffb
->stencil
);
216 upa_writel(ctx
->stencilctl
, &ffb
->stencilctl
);
217 upa_writel(0x80000000, &ffb
->fbc
);
218 upa_writel((ctx
->stencilctl
| 0x80000),
219 &ffb
->rawstencilctl
);
220 upa_writel(ctx
->fbc
, &ffb
->fbc
);
223 for (i
= 0; i
< 32; i
++)
224 upa_writel(ctx
->area_pattern
[i
], &ffb
->pattern
[i
]);
225 upa_writel((ctx
->ucsr
& 0xf0000), &ffb
->ucsr
);
229 /* Restore drawop. */
230 upa_writel(ctx
->drawop
, &ffb
->drawop
);
232 /* If we were restoring the vertex registers, this is where
233 * we would do it. We would restore 32 32-bit words starting
237 /* Restore rendering attributes. */
239 upa_writel(ctx
->ppc
, &ffb
->ppc
); /* Pixel Processor Control */
240 upa_writel(ctx
->wid
, &ffb
->wid
); /* Current WID */
241 upa_writel(ctx
->fg
, &ffb
->fg
); /* Constant FG color */
242 upa_writel(ctx
->bg
, &ffb
->bg
); /* Constant BG color */
243 upa_writel(ctx
->consty
, &ffb
->consty
); /* Constant Y */
244 upa_writel(ctx
->constz
, &ffb
->constz
); /* Constant Z */
245 upa_writel(ctx
->xclip
, &ffb
->xclip
); /* X plane clip */
246 upa_writel(ctx
->dcss
, &ffb
->dcss
); /* Depth Cue Scale Slope */
247 upa_writel(ctx
->vclipmin
, &ffb
->vclipmin
); /* Primary XY clip, minimum */
248 upa_writel(ctx
->vclipmax
, &ffb
->vclipmax
); /* Primary XY clip, maximum */
249 upa_writel(ctx
->vclipzmin
, &ffb
->vclipzmin
); /* Primary Z clip, minimum */
250 upa_writel(ctx
->vclipzmax
, &ffb
->vclipzmax
); /* Primary Z clip, maximum */
251 upa_writel(ctx
->dcsf
, &ffb
->dcsf
); /* Depth Cue Scale Front Bound */
252 upa_writel(ctx
->dcsb
, &ffb
->dcsb
); /* Depth Cue Scale Back Bound */
253 upa_writel(ctx
->dczf
, &ffb
->dczf
); /* Depth Cue Scale Z Front */
254 upa_writel(ctx
->dczb
, &ffb
->dczb
); /* Depth Cue Scale Z Back */
255 upa_writel(ctx
->blendc
, &ffb
->blendc
); /* Alpha Blend Control */
256 upa_writel(ctx
->blendc1
, &ffb
->blendc1
); /* Alpha Blend Color 1 */
257 upa_writel(ctx
->blendc2
, &ffb
->blendc2
); /* Alpha Blend Color 2 */
258 upa_writel(ctx
->fbc
, &ffb
->fbc
); /* Frame Buffer Control */
259 upa_writel(ctx
->rop
, &ffb
->rop
); /* Raster Operation */
260 upa_writel(ctx
->cmp
, &ffb
->cmp
); /* Compare Controls */
261 upa_writel(ctx
->matchab
, &ffb
->matchab
); /* Buffer A/B Match Ops */
262 upa_writel(ctx
->matchc
, &ffb
->matchc
); /* Buffer C Match Ops */
263 upa_writel(ctx
->magnab
, &ffb
->magnab
); /* Buffer A/B Magnitude Ops */
264 upa_writel(ctx
->magnc
, &ffb
->magnc
); /* Buffer C Magnitude Ops */
265 upa_writel(ctx
->pmask
, &ffb
->pmask
); /* RGB Plane Mask */
266 upa_writel(ctx
->xpmask
, &ffb
->xpmask
); /* X Plane Mask */
267 upa_writel(ctx
->ypmask
, &ffb
->ypmask
); /* Y Plane Mask */
268 upa_writel(ctx
->zpmask
, &ffb
->zpmask
); /* Z Plane Mask */
270 /* Auxiliary Clips. */
271 upa_writel(ctx
->auxclip0min
, &ffb
->auxclip
[0].min
);
272 upa_writel(ctx
->auxclip0max
, &ffb
->auxclip
[0].max
);
273 upa_writel(ctx
->auxclip1min
, &ffb
->auxclip
[1].min
);
274 upa_writel(ctx
->auxclip1max
, &ffb
->auxclip
[1].max
);
275 upa_writel(ctx
->auxclip2min
, &ffb
->auxclip
[2].min
);
276 upa_writel(ctx
->auxclip2max
, &ffb
->auxclip
[2].max
);
277 upa_writel(ctx
->auxclip3min
, &ffb
->auxclip
[3].min
);
278 upa_writel(ctx
->auxclip3max
, &ffb
->auxclip
[3].max
);
280 upa_writel(ctx
->lpat
, &ffb
->lpat
); /* Line Pattern */
281 upa_writel(ctx
->fontxy
, &ffb
->fontxy
); /* XY Font Coordinate */
282 upa_writel(ctx
->fontw
, &ffb
->fontw
); /* Font Width */
283 upa_writel(ctx
->fontinc
, &ffb
->fontinc
); /* Font X/Y Increment */
285 /* These registers/features only exist on FFB2 and later chips. */
286 if (fpriv
->ffb_type
>= ffb2_prototype
) {
287 upa_writel(ctx
->dcss1
, &ffb
->dcss1
); /* Depth Cue Scale Slope 1 */
288 upa_writel(ctx
->dcss2
, &ffb
->dcss2
); /* Depth Cue Scale Slope 2 */
289 upa_writel(ctx
->dcss3
, &ffb
->dcss2
); /* Depth Cue Scale Slope 3 */
290 upa_writel(ctx
->dcs2
, &ffb
->dcs2
); /* Depth Cue Scale 2 */
291 upa_writel(ctx
->dcs3
, &ffb
->dcs3
); /* Depth Cue Scale 3 */
292 upa_writel(ctx
->dcs4
, &ffb
->dcs4
); /* Depth Cue Scale 4 */
293 upa_writel(ctx
->dcd2
, &ffb
->dcd2
); /* Depth Cue Depth 2 */
294 upa_writel(ctx
->dcd3
, &ffb
->dcd3
); /* Depth Cue Depth 3 */
295 upa_writel(ctx
->dcd4
, &ffb
->dcd4
); /* Depth Cue Depth 4 */
297 /* And stencil/stencilctl only exists on FFB2+ and later
298 * due to the introduction of 3DRAM-III.
300 if (fpriv
->ffb_type
== ffb2_vertical_plus
||
301 fpriv
->ffb_type
== ffb2_horizontal_plus
) {
302 /* Unfortunately, there is a hardware bug on
303 * the FFB2+ chips which prevents a normal write
304 * to the stencil control register from working
307 * The state controlled by the FFB stencilctl register
308 * really gets transferred to the per-buffer instances
309 * of the stencilctl register in the 3DRAM chips.
311 * The bug is that FFB does not update buffer C correctly,
312 * so we have to do it by hand for them.
315 /* This will update buffers A and B. */
316 upa_writel(ctx
->stencil
, &ffb
->stencil
);
317 upa_writel(ctx
->stencilctl
, &ffb
->stencilctl
);
319 /* Force FFB to use buffer C 3dram regs. */
320 upa_writel(0x80000000, &ffb
->fbc
);
321 upa_writel((ctx
->stencilctl
| 0x80000),
322 &ffb
->rawstencilctl
);
324 /* Now restore the correct FBC controls. */
325 upa_writel(ctx
->fbc
, &ffb
->fbc
);
329 /* Restore the 32x32 area pattern. */
330 for (i
= 0; i
< 32; i
++)
331 upa_writel(ctx
->area_pattern
[i
], &ffb
->pattern
[i
]);
333 /* Finally, stash away the User Constol/Status Register.
334 * The only state we really preserve here is the picking
337 upa_writel((ctx
->ucsr
& 0xf0000), &ffb
->ucsr
);
340 #define FFB_UCSR_FB_BUSY 0x01000000
341 #define FFB_UCSR_RP_BUSY 0x02000000
342 #define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
344 static void FFBWait(ffb_fbcPtr ffb
)
349 u32 regval
= upa_readl(&ffb
->ucsr
);
351 if ((regval
& FFB_UCSR_ALL_BUSY
) == 0)
356 int ffb_context_switch(drm_device_t
*dev
, int old
, int new)
358 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) (dev
+ 1);
360 atomic_inc(&dev
->total_ctx
);
362 #if DRM_DMA_HISTOGRAM
363 dev
->ctx_start
= get_cycles();
366 DRM_DEBUG("Context switch from %d to %d\n", old
, new);
368 if (new == dev
->last_context
||
369 dev
->last_context
== 0) {
370 dev
->last_context
= new;
374 FFBWait(fpriv
->regs
);
375 ffb_save_context(fpriv
, old
);
376 ffb_restore_context(fpriv
, old
, new);
377 FFBWait(fpriv
->regs
);
379 dev
->last_context
= new;
384 int ffb_resctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
391 DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS
);
392 copy_from_user_ret(&res
, (drm_ctx_res_t
*)arg
, sizeof(res
), -EFAULT
);
393 if (res
.count
>= DRM_RESERVED_CONTEXTS
) {
394 memset(&ctx
, 0, sizeof(ctx
));
395 for (i
= 0; i
< DRM_RESERVED_CONTEXTS
; i
++) {
397 copy_to_user_ret(&res
.contexts
[i
],
403 res
.count
= DRM_RESERVED_CONTEXTS
;
404 copy_to_user_ret((drm_ctx_res_t
*)arg
, &res
, sizeof(res
), -EFAULT
);
409 int ffb_addctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
412 drm_file_t
*priv
= filp
->private_data
;
413 drm_device_t
*dev
= priv
->dev
;
417 copy_from_user_ret(&ctx
, (drm_ctx_t
*)arg
, sizeof(ctx
), -EFAULT
);
418 idx
= ffb_alloc_queue(dev
, (ctx
.flags
& _DRM_CONTEXT_2DONLY
));
422 DRM_DEBUG("%d\n", ctx
.handle
);
424 copy_to_user_ret((drm_ctx_t
*)arg
, &ctx
, sizeof(ctx
), -EFAULT
);
428 int ffb_modctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
431 drm_file_t
*priv
= filp
->private_data
;
432 drm_device_t
*dev
= priv
->dev
;
433 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) (dev
+ 1);
434 struct ffb_hw_context
*hwctx
;
438 copy_from_user_ret(&ctx
, (drm_ctx_t
*)arg
, sizeof(ctx
), -EFAULT
);
441 if (idx
<= 0 || idx
>= FFB_MAX_CTXS
)
444 hwctx
= fpriv
->hw_state
[idx
- 1];
448 if ((ctx
.flags
& _DRM_CONTEXT_2DONLY
) == 0)
449 hwctx
->is_2d_only
= 0;
451 hwctx
->is_2d_only
= 1;
456 int ffb_getctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
459 drm_file_t
*priv
= filp
->private_data
;
460 drm_device_t
*dev
= priv
->dev
;
461 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) (dev
+ 1);
462 struct ffb_hw_context
*hwctx
;
466 copy_from_user_ret(&ctx
, (drm_ctx_t
*)arg
, sizeof(ctx
), -EFAULT
);
469 if (idx
<= 0 || idx
>= FFB_MAX_CTXS
)
472 hwctx
= fpriv
->hw_state
[idx
- 1];
476 if (hwctx
->is_2d_only
!= 0)
477 ctx
.flags
= _DRM_CONTEXT_2DONLY
;
481 copy_to_user_ret((drm_ctx_t
*)arg
, &ctx
, sizeof(ctx
), -EFAULT
);
486 int ffb_switchctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
489 drm_file_t
*priv
= filp
->private_data
;
490 drm_device_t
*dev
= priv
->dev
;
493 copy_from_user_ret(&ctx
, (drm_ctx_t
*)arg
, sizeof(ctx
), -EFAULT
);
494 DRM_DEBUG("%d\n", ctx
.handle
);
495 return ffb_context_switch(dev
, dev
->last_context
, ctx
.handle
);
498 int ffb_newctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
503 copy_from_user_ret(&ctx
, (drm_ctx_t
*)arg
, sizeof(ctx
), -EFAULT
);
504 DRM_DEBUG("%d\n", ctx
.handle
);
509 int ffb_rmctx(struct inode
*inode
, struct file
*filp
, unsigned int cmd
,
513 drm_file_t
*priv
= filp
->private_data
;
514 drm_device_t
*dev
= priv
->dev
;
515 ffb_dev_priv_t
*fpriv
= (ffb_dev_priv_t
*) (dev
+ 1);
518 copy_from_user_ret(&ctx
, (drm_ctx_t
*)arg
, sizeof(ctx
), -EFAULT
);
519 DRM_DEBUG("%d\n", ctx
.handle
);
521 idx
= ctx
.handle
- 1;
522 if (idx
< 0 || idx
>= FFB_MAX_CTXS
)
525 if (fpriv
->hw_state
[idx
] != NULL
) {
526 kfree(fpriv
->hw_state
[idx
]);
527 fpriv
->hw_state
[idx
] = NULL
;