at v2.6.14 551 lines 18 kB view raw
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. 3 * 4 * Copyright (C) 2000 David S. Miller (davem@redhat.com) 5 * 6 * Almost entirely stolen from tdfx_context.c, see there 7 * for authors. 8 */ 9 10#include <linux/sched.h> 11#include <asm/upa.h> 12 13#include "ffb.h" 14#include "drmP.h" 15 16#include "ffb_drv.h" 17 18static int DRM(alloc_queue)(drm_device_t *dev, int is_2d_only) 19{ 20 ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; 21 int i; 22 23 for (i = 0; i < FFB_MAX_CTXS; i++) { 24 if (fpriv->hw_state[i] == NULL) 25 break; 26 } 27 if (i == FFB_MAX_CTXS) 28 return -1; 29 30 fpriv->hw_state[i] = kmalloc(sizeof(struct ffb_hw_context), GFP_KERNEL); 31 if (fpriv->hw_state[i] == NULL) 32 return -1; 33 34 fpriv->hw_state[i]->is_2d_only = is_2d_only; 35 36 /* Plus one because 0 is the special DRM_KERNEL_CONTEXT. */ 37 return i + 1; 38} 39 40static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx) 41{ 42 ffb_fbcPtr ffb = fpriv->regs; 43 struct ffb_hw_context *ctx; 44 int i; 45 46 ctx = fpriv->hw_state[idx - 1]; 47 if (idx == 0 || ctx == NULL) 48 return; 49 50 if (ctx->is_2d_only) { 51 /* 2D applications only care about certain pieces 52 * of state. 53 */ 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); 71 72 /* stencil/stencilctl only exists on FFB2+ and later 73 * due to the introduction of 3DRAM-III. 74 */ 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); 79 } 80 81 for (i = 0; i < 32; i++) 82 ctx->area_pattern[i] = upa_readl(&ffb->pattern[i]); 83 ctx->ucsr = upa_readl(&ffb->ucsr); 84 return; 85 } 86 87 /* Fetch drawop. */ 88 ctx->drawop = upa_readl(&ffb->drawop); 89 90 /* If we were saving the vertex registers, this is where 91 * we would do it. We would save 32 32-bit words starting 92 * at ffb->suvtx. 93 */ 94 95 /* Capture rendering attributes. */ 96 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 */ 127 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); 137 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 */ 142 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 */ 154 155 /* And stencil/stencilctl only exists on FFB2+ and later 156 * due to the introduction of 3DRAM-III. 157 */ 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); 162 } 163 } 164 165 /* Save the 32x32 area pattern. */ 166 for (i = 0; i < 32; i++) 167 ctx->area_pattern[i] = upa_readl(&ffb->pattern[i]); 168 169 /* Finally, stash away the User Constol/Status Register. */ 170 ctx->ucsr = upa_readl(&ffb->ucsr); 171} 172 173static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx) 174{ 175 ffb_fbcPtr ffb = fpriv->regs; 176 struct ffb_hw_context *ctx; 177 int i; 178 179 ctx = fpriv->hw_state[idx - 1]; 180 if (idx == 0 || ctx == NULL) 181 return; 182 183 if (ctx->is_2d_only) { 184 /* 2D applications only care about certain pieces 185 * of state. 186 */ 187 upa_writel(ctx->drawop, &ffb->drawop); 188 189 /* If we were restoring the vertex registers, this is where 190 * we would do it. We would restore 32 32-bit words starting 191 * at ffb->suvtx. 192 */ 193 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); 210 211 /* stencil/stencilctl only exists on FFB2+ and later 212 * due to the introduction of 3DRAM-III. 213 */ 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); 222 } 223 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); 227 return; 228 } 229 230 /* Restore drawop. */ 231 upa_writel(ctx->drawop, &ffb->drawop); 232 233 /* If we were restoring the vertex registers, this is where 234 * we would do it. We would restore 32 32-bit words starting 235 * at ffb->suvtx. 236 */ 237 238 /* Restore rendering attributes. */ 239 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 */ 270 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); 280 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 */ 285 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 */ 297 298 /* And stencil/stencilctl only exists on FFB2+ and later 299 * due to the introduction of 3DRAM-III. 300 */ 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 306 * as it should. 307 * 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. 311 * 312 * The bug is that FFB does not update buffer C correctly, 313 * so we have to do it by hand for them. 314 */ 315 316 /* This will update buffers A and B. */ 317 upa_writel(ctx->stencil, &ffb->stencil); 318 upa_writel(ctx->stencilctl, &ffb->stencilctl); 319 320 /* Force FFB to use buffer C 3dram regs. */ 321 upa_writel(0x80000000, &ffb->fbc); 322 upa_writel((ctx->stencilctl | 0x80000), 323 &ffb->rawstencilctl); 324 325 /* Now restore the correct FBC controls. */ 326 upa_writel(ctx->fbc, &ffb->fbc); 327 } 328 } 329 330 /* Restore the 32x32 area pattern. */ 331 for (i = 0; i < 32; i++) 332 upa_writel(ctx->area_pattern[i], &ffb->pattern[i]); 333 334 /* Finally, stash away the User Constol/Status Register. 335 * The only state we really preserve here is the picking 336 * control. 337 */ 338 upa_writel((ctx->ucsr & 0xf0000), &ffb->ucsr); 339} 340 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) 344 345static void FFBWait(ffb_fbcPtr ffb) 346{ 347 int limit = 100000; 348 349 do { 350 u32 regval = upa_readl(&ffb->ucsr); 351 352 if ((regval & FFB_UCSR_ALL_BUSY) == 0) 353 break; 354 } while (--limit); 355} 356 357int ffb_driver_context_switch(drm_device_t *dev, int old, int new) 358{ 359 ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private; 360 361#ifdef DRM_DMA_HISTOGRAM 362 dev->ctx_start = get_cycles(); 363#endif 364 365 DRM_DEBUG("Context switch from %d to %d\n", old, new); 366 367 if (new == dev->last_context || 368 dev->last_context == 0) { 369 dev->last_context = new; 370 return 0; 371 } 372 373 FFBWait(fpriv->regs); 374 ffb_save_context(fpriv, old); 375 ffb_restore_context(fpriv, old, new); 376 FFBWait(fpriv->regs); 377 378 dev->last_context = new; 379 380 return 0; 381} 382 383int ffb_driver_resctx(struct inode *inode, struct file *filp, unsigned int cmd, 384 unsigned long arg) 385{ 386 drm_ctx_res_t res; 387 drm_ctx_t ctx; 388 int i; 389 390 DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); 391 if (copy_from_user(&res, (drm_ctx_res_t __user *)arg, sizeof(res))) 392 return -EFAULT; 393 if (res.count >= DRM_RESERVED_CONTEXTS) { 394 memset(&ctx, 0, sizeof(ctx)); 395 for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { 396 ctx.handle = i; 397 if (copy_to_user(&res.contexts[i], 398 &i, 399 sizeof(i))) 400 return -EFAULT; 401 } 402 } 403 res.count = DRM_RESERVED_CONTEXTS; 404 if (copy_to_user((drm_ctx_res_t __user *)arg, &res, sizeof(res))) 405 return -EFAULT; 406 return 0; 407} 408 409 410int ffb_driver_addctx(struct inode *inode, struct file *filp, unsigned int cmd, 411 unsigned long arg) 412{ 413 drm_file_t *priv = filp->private_data; 414 drm_device_t *dev = priv->dev; 415 drm_ctx_t ctx; 416 int idx; 417 418 if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) 419 return -EFAULT; 420 idx = DRM(alloc_queue)(dev, (ctx.flags & _DRM_CONTEXT_2DONLY)); 421 if (idx < 0) 422 return -ENFILE; 423 424 DRM_DEBUG("%d\n", ctx.handle); 425 ctx.handle = idx; 426 if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx))) 427 return -EFAULT; 428 return 0; 429} 430 431int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd, 432 unsigned long arg) 433{ 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; 438 drm_ctx_t ctx; 439 int idx; 440 441 if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) 442 return -EFAULT; 443 444 idx = ctx.handle; 445 if (idx <= 0 || idx >= FFB_MAX_CTXS) 446 return -EINVAL; 447 448 hwctx = fpriv->hw_state[idx - 1]; 449 if (hwctx == NULL) 450 return -EINVAL; 451 452 if ((ctx.flags & _DRM_CONTEXT_2DONLY) == 0) 453 hwctx->is_2d_only = 0; 454 else 455 hwctx->is_2d_only = 1; 456 457 return 0; 458} 459 460int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd, 461 unsigned long arg) 462{ 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; 467 drm_ctx_t ctx; 468 int idx; 469 470 if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) 471 return -EFAULT; 472 473 idx = ctx.handle; 474 if (idx <= 0 || idx >= FFB_MAX_CTXS) 475 return -EINVAL; 476 477 hwctx = fpriv->hw_state[idx - 1]; 478 if (hwctx == NULL) 479 return -EINVAL; 480 481 if (hwctx->is_2d_only != 0) 482 ctx.flags = _DRM_CONTEXT_2DONLY; 483 else 484 ctx.flags = 0; 485 486 if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx))) 487 return -EFAULT; 488 489 return 0; 490} 491 492int ffb_driver_switchctx(struct inode *inode, struct file *filp, unsigned int cmd, 493 unsigned long arg) 494{ 495 drm_file_t *priv = filp->private_data; 496 drm_device_t *dev = priv->dev; 497 drm_ctx_t ctx; 498 499 if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) 500 return -EFAULT; 501 DRM_DEBUG("%d\n", ctx.handle); 502 return ffb_driver_context_switch(dev, dev->last_context, ctx.handle); 503} 504 505int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd, 506 unsigned long arg) 507{ 508 drm_ctx_t ctx; 509 510 if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) 511 return -EFAULT; 512 DRM_DEBUG("%d\n", ctx.handle); 513 514 return 0; 515} 516 517int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, 518 unsigned long arg) 519{ 520 drm_ctx_t ctx; 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; 524 int idx; 525 526 if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx))) 527 return -EFAULT; 528 DRM_DEBUG("%d\n", ctx.handle); 529 530 idx = ctx.handle - 1; 531 if (idx < 0 || idx >= FFB_MAX_CTXS) 532 return -EINVAL; 533 534 if (fpriv->hw_state[idx] != NULL) { 535 kfree(fpriv->hw_state[idx]); 536 fpriv->hw_state[idx] = NULL; 537 } 538 return 0; 539} 540 541void ffb_set_context_ioctls(void) 542{ 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; 550 551}