diff options
Diffstat (limited to 'drivers/gpu/drm/i830/i830_dma.c')
-rw-r--r-- | drivers/gpu/drm/i830/i830_dma.c | 137 |
1 files changed, 72 insertions, 65 deletions
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 65759a9..5168862 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c @@ -36,6 +36,7 @@ #include "i830_drm.h" #include "i830_drv.h" #include <linux/interrupt.h> /* For task queue support */ +#include <linux/smp_lock.h> #include <linux/pagemap.h> #include <linux/delay.h> #include <linux/slab.h> @@ -62,9 +63,8 @@ static struct drm_buf *i830_freelist_get(struct drm_device * dev) /* In use is already a pointer */ used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, I830_BUF_CLIENT); - if (used == I830_BUF_FREE) { + if (used == I830_BUF_FREE) return buf; - } } return NULL; } @@ -73,7 +73,7 @@ static struct drm_buf *i830_freelist_get(struct drm_device * dev) * yet, the hardware updates in use for us once its on the ring buffer. */ -static int i830_freelist_put(struct drm_device * dev, struct drm_buf * buf) +static int i830_freelist_put(struct drm_device *dev, struct drm_buf *buf) { drm_i830_buf_priv_t *buf_priv = buf->dev_private; int used; @@ -123,7 +123,7 @@ static const struct file_operations i830_buffer_fops = { .fasync = drm_fasync, }; -static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) +static int i830_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) { struct drm_device *dev = file_priv->minor->dev; drm_i830_buf_priv_t *buf_priv = buf->dev_private; @@ -156,7 +156,7 @@ static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv) return retcode; } -static int i830_unmap_buffer(struct drm_buf * buf) +static int i830_unmap_buffer(struct drm_buf *buf) { drm_i830_buf_priv_t *buf_priv = buf->dev_private; int retcode = 0; @@ -176,7 +176,7 @@ static int i830_unmap_buffer(struct drm_buf * buf) return retcode; } -static int i830_dma_get_buffer(struct drm_device * dev, drm_i830_dma_t * d, +static int i830_dma_get_buffer(struct drm_device *dev, drm_i830_dma_t *d, struct drm_file *file_priv) { struct drm_buf *buf; @@ -206,7 +206,7 @@ static int i830_dma_get_buffer(struct drm_device * dev, drm_i830_dma_t * d, return retcode; } -static int i830_dma_cleanup(struct drm_device * dev) +static int i830_dma_cleanup(struct drm_device *dev) { struct drm_device_dma *dma = dev->dma; @@ -222,9 +222,8 @@ static int i830_dma_cleanup(struct drm_device * dev) drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private; - if (dev_priv->ring.virtual_start) { + if (dev_priv->ring.virtual_start) drm_core_ioremapfree(&dev_priv->ring.map, dev); - } if (dev_priv->hw_status_page) { pci_free_consistent(dev->pdev, PAGE_SIZE, dev_priv->hw_status_page, @@ -246,7 +245,7 @@ static int i830_dma_cleanup(struct drm_device * dev) return 0; } -int i830_wait_ring(struct drm_device * dev, int n, const char *caller) +int i830_wait_ring(struct drm_device *dev, int n, const char *caller) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_ring_buffer_t *ring = &(dev_priv->ring); @@ -276,11 +275,11 @@ int i830_wait_ring(struct drm_device * dev, int n, const char *caller) dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT; } - out_wait_ring: +out_wait_ring: return iters; } -static void i830_kernel_lost_context(struct drm_device * dev) +static void i830_kernel_lost_context(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_ring_buffer_t *ring = &(dev_priv->ring); @@ -295,7 +294,7 @@ static void i830_kernel_lost_context(struct drm_device * dev) dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY; } -static int i830_freelist_init(struct drm_device * dev, drm_i830_private_t * dev_priv) +static int i830_freelist_init(struct drm_device *dev, drm_i830_private_t *dev_priv) { struct drm_device_dma *dma = dev->dma; int my_idx = 36; @@ -329,9 +328,9 @@ static int i830_freelist_init(struct drm_device * dev, drm_i830_private_t * dev_ return 0; } -static int i830_dma_initialize(struct drm_device * dev, - drm_i830_private_t * dev_priv, - drm_i830_init_t * init) +static int i830_dma_initialize(struct drm_device *dev, + drm_i830_private_t *dev_priv, + drm_i830_init_t *init) { struct drm_map_list *r_list; @@ -482,7 +481,7 @@ static int i830_dma_init(struct drm_device *dev, void *data, /* Most efficient way to verify state for the i830 is as it is * emitted. Non-conformant state is silently dropped. */ -static void i830EmitContextVerified(struct drm_device * dev, unsigned int *code) +static void i830EmitContextVerified(struct drm_device *dev, unsigned int *code) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; @@ -527,7 +526,7 @@ static void i830EmitContextVerified(struct drm_device * dev, unsigned int *code) ADVANCE_LP_RING(); } -static void i830EmitTexVerified(struct drm_device * dev, unsigned int *code) +static void i830EmitTexVerified(struct drm_device *dev, unsigned int *code) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; @@ -561,7 +560,7 @@ static void i830EmitTexVerified(struct drm_device * dev, unsigned int *code) printk("rejected packet %x\n", code[0]); } -static void i830EmitTexBlendVerified(struct drm_device * dev, +static void i830EmitTexBlendVerified(struct drm_device *dev, unsigned int *code, unsigned int num) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -586,7 +585,7 @@ static void i830EmitTexBlendVerified(struct drm_device * dev, ADVANCE_LP_RING(); } -static void i830EmitTexPalette(struct drm_device * dev, +static void i830EmitTexPalette(struct drm_device *dev, unsigned int *palette, int number, int is_shared) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -603,9 +602,8 @@ static void i830EmitTexPalette(struct drm_device * dev, } else { OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number)); } - for (i = 0; i < 256; i++) { + for (i = 0; i < 256; i++) OUT_RING(palette[i]); - } OUT_RING(0); /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! */ @@ -613,7 +611,7 @@ static void i830EmitTexPalette(struct drm_device * dev, /* Need to do some additional checking when setting the dest buffer. */ -static void i830EmitDestVerified(struct drm_device * dev, unsigned int *code) +static void i830EmitDestVerified(struct drm_device *dev, unsigned int *code) { drm_i830_private_t *dev_priv = dev->dev_private; unsigned int tmp; @@ -674,7 +672,7 @@ static void i830EmitDestVerified(struct drm_device * dev, unsigned int *code) ADVANCE_LP_RING(); } -static void i830EmitStippleVerified(struct drm_device * dev, unsigned int *code) +static void i830EmitStippleVerified(struct drm_device *dev, unsigned int *code) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -685,7 +683,7 @@ static void i830EmitStippleVerified(struct drm_device * dev, unsigned int *code) ADVANCE_LP_RING(); } -static void i830EmitState(struct drm_device * dev) +static void i830EmitState(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -788,7 +786,7 @@ static void i830EmitState(struct drm_device * dev) * Performance monitoring functions */ -static void i830_fill_box(struct drm_device * dev, +static void i830_fill_box(struct drm_device *dev, int x, int y, int w, int h, int r, int g, int b) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -816,17 +814,16 @@ static void i830_fill_box(struct drm_device * dev, OUT_RING((y << 16) | x); OUT_RING(((y + h) << 16) | (x + w)); - if (dev_priv->current_page == 1) { + if (dev_priv->current_page == 1) OUT_RING(dev_priv->front_offset); - } else { + else OUT_RING(dev_priv->back_offset); - } OUT_RING(color); ADVANCE_LP_RING(); } -static void i830_cp_performance_boxes(struct drm_device * dev) +static void i830_cp_performance_boxes(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -871,7 +868,7 @@ static void i830_cp_performance_boxes(struct drm_device * dev) dev_priv->sarea_priv->perf_boxes = 0; } -static void i830_dma_dispatch_clear(struct drm_device * dev, int flags, +static void i830_dma_dispatch_clear(struct drm_device *dev, int flags, unsigned int clear_color, unsigned int clear_zval, unsigned int clear_depthmask) @@ -966,7 +963,7 @@ static void i830_dma_dispatch_clear(struct drm_device * dev, int flags, } } -static void i830_dma_dispatch_swap(struct drm_device * dev) +static void i830_dma_dispatch_swap(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -1036,7 +1033,7 @@ static void i830_dma_dispatch_swap(struct drm_device * dev) } } -static void i830_dma_dispatch_flip(struct drm_device * dev) +static void i830_dma_dispatch_flip(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -1079,8 +1076,8 @@ static void i830_dma_dispatch_flip(struct drm_device * dev) dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; } -static void i830_dma_dispatch_vertex(struct drm_device * dev, - struct drm_buf * buf, int discard, int used) +static void i830_dma_dispatch_vertex(struct drm_device *dev, + struct drm_buf *buf, int discard, int used) { drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_buf_priv_t *buf_priv = buf->dev_private; @@ -1100,9 +1097,8 @@ static void i830_dma_dispatch_vertex(struct drm_device * dev, if (discard) { u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_HARDWARE); - if (u != I830_BUF_CLIENT) { + if (u != I830_BUF_CLIENT) DRM_DEBUG("xxxx 2\n"); - } } if (used > 4 * 1023) @@ -1191,7 +1187,7 @@ static void i830_dma_dispatch_vertex(struct drm_device * dev, } } -static void i830_dma_quiescent(struct drm_device * dev) +static void i830_dma_quiescent(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -1208,7 +1204,7 @@ static void i830_dma_quiescent(struct drm_device * dev) i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__); } -static int i830_flush_queue(struct drm_device * dev) +static int i830_flush_queue(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; struct drm_device_dma *dma = dev->dma; @@ -1241,7 +1237,7 @@ static int i830_flush_queue(struct drm_device * dev) } /* Must be called with the lock held */ -static void i830_reclaim_buffers(struct drm_device * dev, struct drm_file *file_priv) +static void i830_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) { struct drm_device_dma *dma = dev->dma; int i; @@ -1316,9 +1312,8 @@ static int i830_clear_bufs(struct drm_device *dev, void *data, LOCK_TEST_WITH_RETURN(dev, file_priv); /* GH: Someone's doing nasty things... */ - if (!dev->dev_private) { + if (!dev->dev_private) return -EINVAL; - } i830_dma_dispatch_clear(dev, clear->flags, clear->clear_color, @@ -1339,7 +1334,7 @@ static int i830_swap_bufs(struct drm_device *dev, void *data, /* Not sure why this isn't set all the time: */ -static void i830_do_init_pageflip(struct drm_device * dev) +static void i830_do_init_pageflip(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -1349,7 +1344,7 @@ static void i830_do_init_pageflip(struct drm_device * dev) dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; } -static int i830_do_cleanup_pageflip(struct drm_device * dev) +static int i830_do_cleanup_pageflip(struct drm_device *dev) { drm_i830_private_t *dev_priv = dev->dev_private; @@ -1490,47 +1485,59 @@ int i830_driver_load(struct drm_device *dev, unsigned long flags) return 0; } -void i830_driver_lastclose(struct drm_device * dev) +void i830_driver_lastclose(struct drm_device *dev) { i830_dma_cleanup(dev); } -void i830_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) +void i830_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) { if (dev->dev_private) { drm_i830_private_t *dev_priv = dev->dev_private; - if (dev_priv->page_flipping) { + if (dev_priv->page_flipping) i830_do_cleanup_pageflip(dev); - } } } -void i830_driver_reclaim_buffers_locked(struct drm_device * dev, struct drm_file *file_priv) +void i830_driver_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv) { i830_reclaim_buffers(dev, file_priv); } -int i830_driver_dma_quiescent(struct drm_device * dev) +int i830_driver_dma_quiescent(struct drm_device *dev) { i830_dma_quiescent(dev); return 0; } +/* + * call the drm_ioctl under the big kernel lock because + * to lock against the i830_mmap_buffers function. + */ +long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + lock_kernel(); + ret = drm_ioctl(file, cmd, arg); + unlock_kernel(); + return ret; +} + struct drm_ioctl_desc i830_ioctls[] = { - DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH) + DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), }; int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); @@ -1546,7 +1553,7 @@ int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); * \returns * A value of 1 is always retured to indictate every i8xx is AGP. */ -int i830_driver_device_is_agp(struct drm_device * dev) +int i830_driver_device_is_agp(struct drm_device *dev) { return 1; } |