From 3d5d41fa9823cf44138c8f4bc954bca80539d74e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 15 Jun 2007 17:13:11 +0200 Subject: i915: Fix handling of breadcrumb counter wraparounds. --- shared-core/i915_dma.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index ebb184cc..dbc5f959 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -445,10 +445,12 @@ void i915_emit_breadcrumb(drm_device_t *dev) drm_i915_private_t *dev_priv = dev->dev_private; RING_LOCALS; - dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; + if (++dev_priv->counter > BREADCRUMB_MASK) { + dev_priv->counter = 1; + DRM_DEBUG("Breadcrumb counter wrapped around\n"); + } - if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; + dev_priv->sarea_priv->last_enqueue = dev_priv->counter; BEGIN_LP_RING(4); OUT_RING(CMD_STORE_DWORD_IDX); -- cgit v1.2.3 From b95ac8b7b313ad3eadc9e8bb0ead155303b7fa92 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 16 Jul 2007 11:22:15 +1000 Subject: drm: detypedef drm.h and fixup all problems --- shared-core/i915_dma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index dbc5f959..f7d3fab4 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -398,11 +398,11 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) } static int i915_emit_box(drm_device_t * dev, - drm_clip_rect_t __user * boxes, + struct drm_clip_rect __user * boxes, int i, int DR1, int DR4) { drm_i915_private_t *dev_priv = dev->dev_private; - drm_clip_rect_t box; + struct drm_clip_rect box; RING_LOCALS; if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { @@ -524,7 +524,7 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev, drm_i915_batchbuffer_t * batch) { drm_i915_private_t *dev_priv = dev->dev_private; - drm_clip_rect_t __user *boxes = batch->cliprects; + struct drm_clip_rect __user *boxes = batch->cliprects; int nbox = batch->num_cliprects; int i = 0, count; RING_LOCALS; @@ -683,7 +683,7 @@ static int i915_batchbuffer(DRM_IOCTL_ARGS) if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects, batch.num_cliprects * - sizeof(drm_clip_rect_t))) + sizeof(struct drm_clip_rect))) return DRM_ERR(EFAULT); ret = i915_dispatch_batchbuffer(dev, &batch); @@ -712,7 +712,7 @@ static int i915_cmdbuffer(DRM_IOCTL_ARGS) if (cmdbuf.num_cliprects && DRM_VERIFYAREA_READ(cmdbuf.cliprects, cmdbuf.num_cliprects * - sizeof(drm_clip_rect_t))) { + sizeof(struct drm_clip_rect))) { DRM_ERROR("Fault accessing cliprects\n"); return DRM_ERR(EFAULT); } -- cgit v1.2.3 From 21ee6fbfb8f2219a454458204afc9c5fcd89f9a8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 16 Jul 2007 12:32:51 +1000 Subject: drm: remove drmP.h internal typedefs --- shared-core/i915_dma.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index f7d3fab4..fbad27c0 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -47,7 +47,7 @@ * the head pointer changes, so that EBUSY only happens if the ring * actually stalls for (eg) 3 seconds. */ -int i915_wait_ring(drm_device_t * dev, int n, const char *caller) +int i915_wait_ring(struct drm_device * dev, int n, const char *caller) { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_ring_buffer_t *ring = &(dev_priv->ring); @@ -74,7 +74,7 @@ int i915_wait_ring(drm_device_t * dev, int n, const char *caller) return DRM_ERR(EBUSY); } -void i915_kernel_lost_context(drm_device_t * dev) +void i915_kernel_lost_context(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_ring_buffer_t *ring = &(dev_priv->ring); @@ -89,7 +89,7 @@ void i915_kernel_lost_context(drm_device_t * dev) dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; } -static int i915_dma_cleanup(drm_device_t * dev) +static int i915_dma_cleanup(struct drm_device * dev) { /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private @@ -125,7 +125,7 @@ static int i915_dma_cleanup(drm_device_t * dev) return 0; } -static int i915_initialize(drm_device_t * dev, +static int i915_initialize(struct drm_device * dev, drm_i915_private_t * dev_priv, drm_i915_init_t * init) { @@ -212,7 +212,7 @@ static int i915_initialize(drm_device_t * dev, return 0; } -static int i915_dma_resume(drm_device_t * dev) +static int i915_dma_resume(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -358,7 +358,7 @@ static int validate_cmd(int cmd) return ret; } -static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) +static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords) { drm_i915_private_t *dev_priv = dev->dev_private; int i; @@ -397,7 +397,7 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) return 0; } -static int i915_emit_box(drm_device_t * dev, +static int i915_emit_box(struct drm_device * dev, struct drm_clip_rect __user * boxes, int i, int DR1, int DR4) { @@ -440,7 +440,7 @@ static int i915_emit_box(drm_device_t * dev, * emit. For now, do it in both places: */ -void i915_emit_breadcrumb(drm_device_t *dev) +void i915_emit_breadcrumb(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -461,7 +461,7 @@ void i915_emit_breadcrumb(drm_device_t *dev) } -int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush) +int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush) { drm_i915_private_t *dev_priv = dev->dev_private; uint32_t flush_cmd = CMD_MI_FLUSH; @@ -482,7 +482,7 @@ int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush) } -static int i915_dispatch_cmdbuffer(drm_device_t * dev, +static int i915_dispatch_cmdbuffer(struct drm_device * dev, drm_i915_cmdbuffer_t * cmd) { #ifdef I915_HAVE_FENCE @@ -520,7 +520,7 @@ static int i915_dispatch_cmdbuffer(drm_device_t * dev, return 0; } -static int i915_dispatch_batchbuffer(drm_device_t * dev, +static int i915_dispatch_batchbuffer(struct drm_device * dev, drm_i915_batchbuffer_t * batch) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -568,7 +568,7 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev, return 0; } -static void i915_do_dispatch_flip(drm_device_t * dev, int pipe, int sync) +static void i915_do_dispatch_flip(struct drm_device * dev, int pipe, int sync) { drm_i915_private_t *dev_priv = dev->dev_private; u32 num_pages, current_page, next_page, dspbase; @@ -620,7 +620,7 @@ static void i915_do_dispatch_flip(drm_device_t * dev, int pipe, int sync) dev_priv->sarea_priv->pf_current_page |= next_page << shift; } -void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync) +void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync) { drm_i915_private_t *dev_priv = dev->dev_private; int i; @@ -642,7 +642,7 @@ void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync) #endif } -static int i915_quiescent(drm_device_t * dev) +static int i915_quiescent(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -727,7 +727,7 @@ static int i915_cmdbuffer(DRM_IOCTL_ARGS) return 0; } -static int i915_do_cleanup_pageflip(drm_device_t * dev) +static int i915_do_cleanup_pageflip(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; int i, pipes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; @@ -939,7 +939,7 @@ static int i915_set_status_page(DRM_IOCTL_ARGS) return 0; } -int i915_driver_load(drm_device_t *dev, unsigned long flags) +int i915_driver_load(struct drm_device *dev, unsigned long flags) { /* i915 has 4 more counters */ dev->counters += 4; @@ -951,7 +951,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) return 0; } -void i915_driver_lastclose(drm_device_t * dev) +void i915_driver_lastclose(struct drm_device * dev) { if (dev->dev_private) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -961,7 +961,7 @@ void i915_driver_lastclose(drm_device_t * dev) i915_dma_cleanup(dev); } -void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) +void i915_driver_preclose(struct drm_device * dev, DRMFILE filp) { if (dev->dev_private) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -969,7 +969,7 @@ void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) } } -drm_ioctl_desc_t i915_ioctls[] = { +struct drm_ioctl_desc i915_ioctls[] = { [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH}, [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, DRM_AUTH}, @@ -1003,7 +1003,7 @@ int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); * \returns * A value of 1 is always retured to indictate every i9x5 is AGP. */ -int i915_driver_device_is_agp(drm_device_t * dev) +int i915_driver_device_is_agp(struct drm_device * dev) { return 1; } -- cgit v1.2.3 From 3f04fe7890fe7728e7df37a6b65ad328a46699bf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 16 Jul 2007 01:53:06 -0700 Subject: Fix FreeBSD build. --- shared-core/i915_dma.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index dbc5f959..535a061a 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -855,12 +855,14 @@ static int mmio_table_size = sizeof(mmio_table)/sizeof(drm_i915_mmio_entry_t); static int i915_mmio(DRM_IOCTL_ARGS) { - char buf[32]; + uint32_t buf[8]; DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_mmio_entry_t *e; drm_i915_mmio_t mmio; void __iomem *base; + int i; + if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); @@ -878,7 +880,8 @@ static int i915_mmio(DRM_IOCTL_ARGS) case I915_MMIO_READ: if (!(e->flag & I915_MMIO_MAY_READ)) return DRM_ERR(EINVAL); - memcpy_fromio(buf, base, e->size); + for (i = 0; i < e->size / 4; i++) + buf[i] = I915_READ(e->offset + i * 4); if (DRM_COPY_TO_USER(mmio.data, buf, e->size)) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); return DRM_ERR(EFAULT); @@ -892,7 +895,8 @@ static int i915_mmio(DRM_IOCTL_ARGS) DRM_ERROR("DRM_COPY_TO_USER failed\n"); return DRM_ERR(EFAULT); } - memcpy_toio(base, buf, e->size); + for (i = 0; i < e->size / 4; i++) + I915_WRITE(e->offset + i * 4, buf[i]); break; } return 0; @@ -910,11 +914,11 @@ static int i915_set_status_page(DRM_IOCTL_ARGS) } DRM_COPY_FROM_USER_IOCTL(hws, (drm_i915_hws_addr_t __user *) data, sizeof(hws)); - printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws.addr); + DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws.addr); dev_priv->status_gfx_addr = hws.addr & (0x1ffff<<12); - dev_priv->hws_map.offset = dev->agp->agp_info.aper_base + hws.addr; + dev_priv->hws_map.offset = dev->agp->base + hws.addr; dev_priv->hws_map.size = 4*1024; dev_priv->hws_map.type = 0; dev_priv->hws_map.flags = 0; -- cgit v1.2.3 From a64b5d8d3763639fbb4098500ad5c86fb8590aa7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 18 Jul 2007 15:49:45 +1000 Subject: fix some missing whitespace/tab --- shared-core/i915_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index fbad27c0..c3a41bd5 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -874,7 +874,7 @@ static int i915_mmio(DRM_IOCTL_ARGS) e = &mmio_table[mmio.reg]; base = (u8 *) dev_priv->mmio_map->handle + e->offset; - switch (mmio.read_write) { + switch (mmio.read_write) { case I915_MMIO_READ: if (!(e->flag & I915_MMIO_MAY_READ)) return DRM_ERR(EINVAL); -- cgit v1.2.3 From e39286eb5eab8846a228863abf8f1b8b07a9e29d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jul 2007 17:00:17 -0700 Subject: Remove DRM_ERR OS macro. This was used to make all ioctl handlers return -errno on linux and errno on *BSD. Instead, just return -errno in shared code, and flip sign on return from shared code to *BSD code. --- shared-core/i915_dma.c | 72 +++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 5fb9fcff..81e6981d 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -71,7 +71,7 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) DRM_UDELAY(1); } - return DRM_ERR(EBUSY); + return -EBUSY; } void i915_kernel_lost_context(struct drm_device * dev) @@ -136,7 +136,7 @@ static int i915_initialize(struct drm_device * dev, DRM_ERROR("can not find sarea!\n"); dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); @@ -144,7 +144,7 @@ static int i915_initialize(struct drm_device * dev, dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("can not find mmio map!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->sarea_priv = (drm_i915_sarea_t *) @@ -168,7 +168,7 @@ static int i915_initialize(struct drm_device * dev, i915_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev_priv->ring.virtual_start = dev_priv->ring.map.handle; @@ -198,7 +198,7 @@ static int i915_initialize(struct drm_device * dev, dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("Can not allocate hardware status page\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; @@ -220,24 +220,24 @@ static int i915_dma_resume(struct drm_device * dev) if (!dev_priv->sarea) { DRM_ERROR("can not find sarea!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (!dev_priv->mmio_map) { DRM_ERROR("can not find mmio map!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (dev_priv->ring.map.handle == NULL) { DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } /* Program Hardware Status Page */ if (!dev_priv->hw_status_page) { DRM_ERROR("Can not find hardware status page\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); @@ -265,7 +265,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS) dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; retcode = i915_initialize(dev, dev_priv, &init); break; case I915_CLEANUP_DMA: @@ -275,7 +275,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS) retcode = i915_dma_resume(dev); break; default: - retcode = DRM_ERR(EINVAL); + retcode = -EINVAL; break; } @@ -365,7 +365,7 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor RING_LOCALS; if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) - return DRM_ERR(EINVAL); + return -EINVAL; BEGIN_LP_RING((dwords+1)&~1); @@ -373,17 +373,17 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor int cmd, sz; if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) - return DRM_ERR(EINVAL); + return -EINVAL; if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) - return DRM_ERR(EINVAL); + return -EINVAL; OUT_RING(cmd); while (++i, --sz) { if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) { - return DRM_ERR(EINVAL); + return -EINVAL; } OUT_RING(cmd); } @@ -406,13 +406,13 @@ static int i915_emit_box(struct drm_device * dev, RING_LOCALS; if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { - return DRM_ERR(EFAULT); + return -EFAULT; } if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { DRM_ERROR("Bad box %d,%d..%d,%d\n", box.x1, box.y1, box.x2, box.y2); - return DRM_ERR(EINVAL); + return -EINVAL; } if (IS_I965G(dev)) { @@ -493,7 +493,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, if (cmd->sz & 0x3) { DRM_ERROR("alignment"); - return DRM_ERR(EINVAL); + return -EINVAL; } i915_kernel_lost_context(dev); @@ -531,7 +531,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, if ((batch->start | batch->used) & 0x7) { DRM_ERROR("alignment"); - return DRM_ERR(EINVAL); + return -EINVAL; } i915_kernel_lost_context(dev); @@ -670,7 +670,7 @@ static int i915_batchbuffer(DRM_IOCTL_ARGS) if (!dev_priv->allow_batchbuffer) { DRM_ERROR("Batchbuffer ioctl disabled\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } DRM_COPY_FROM_USER_IOCTL(batch, (drm_i915_batchbuffer_t __user *) data, @@ -684,7 +684,7 @@ static int i915_batchbuffer(DRM_IOCTL_ARGS) if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects, batch.num_cliprects * sizeof(struct drm_clip_rect))) - return DRM_ERR(EFAULT); + return -EFAULT; ret = i915_dispatch_batchbuffer(dev, &batch); @@ -714,7 +714,7 @@ static int i915_cmdbuffer(DRM_IOCTL_ARGS) cmdbuf.num_cliprects * sizeof(struct drm_clip_rect))) { DRM_ERROR("Fault accessing cliprects\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } ret = i915_dispatch_cmdbuffer(dev, &cmdbuf); @@ -764,7 +764,7 @@ static int i915_flip_bufs(DRM_IOCTL_ARGS) if (param.pipes & ~0x3) { DRM_ERROR("Invalid pipes 0x%x, only <= 0x3 is valid\n", param.pipes); - return DRM_ERR(EINVAL); + return -EINVAL; } i915_dispatch_flip(dev, param.pipes, 0); @@ -782,7 +782,7 @@ static int i915_getparam(DRM_IOCTL_ARGS) if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_getparam_t __user *) data, @@ -800,12 +800,12 @@ static int i915_getparam(DRM_IOCTL_ARGS) break; default: DRM_ERROR("Unknown parameter %d\n", param.param); - return DRM_ERR(EINVAL); + return -EINVAL; } if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; @@ -819,7 +819,7 @@ static int i915_setparam(DRM_IOCTL_ARGS) if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_setparam_t __user *) data, @@ -837,7 +837,7 @@ static int i915_setparam(DRM_IOCTL_ARGS) break; default: DRM_ERROR("unknown parameter %d\n", param.param); - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; @@ -865,13 +865,13 @@ static int i915_mmio(DRM_IOCTL_ARGS) if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } DRM_COPY_FROM_USER_IOCTL(mmio, (drm_i915_mmio_t __user *) data, sizeof(mmio)); if (mmio.reg >= mmio_table_size) - return DRM_ERR(EINVAL); + return -EINVAL; e = &mmio_table[mmio.reg]; base = (u8 *) dev_priv->mmio_map->handle + e->offset; @@ -879,21 +879,21 @@ static int i915_mmio(DRM_IOCTL_ARGS) switch (mmio.read_write) { case I915_MMIO_READ: if (!(e->flag & I915_MMIO_MAY_READ)) - return DRM_ERR(EINVAL); + return -EINVAL; for (i = 0; i < e->size / 4; i++) buf[i] = I915_READ(e->offset + i * 4); if (DRM_COPY_TO_USER(mmio.data, buf, e->size)) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } break; case I915_MMIO_WRITE: if (!(e->flag & I915_MMIO_MAY_WRITE)) - return DRM_ERR(EINVAL); + return -EINVAL; if(DRM_COPY_FROM_USER(buf, mmio.data, e->size)) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } for (i = 0; i < e->size / 4; i++) I915_WRITE(e->offset + i * 4, buf[i]); @@ -910,7 +910,7 @@ static int i915_set_status_page(DRM_IOCTL_ARGS) if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } DRM_COPY_FROM_USER_IOCTL(hws, (drm_i915_hws_addr_t __user *) data, sizeof(hws)); @@ -931,7 +931,7 @@ static int i915_set_status_page(DRM_IOCTL_ARGS) dev_priv->status_gfx_addr = 0; DRM_ERROR("can not ioremap virtual address for" " G33 hw status page\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev_priv->hw_status_page = dev_priv->hws_map.handle; -- cgit v1.2.3 From c1119b1b092527fbb6950d0b5e51e076ddb00f29 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 20 Jul 2007 06:39:25 -0700 Subject: Replace filp in ioctl arguments with drm_file *file_priv. As a fallout, replace filp storage with file_priv storage for "unique identifier of a client" all over the DRM. There is a 1:1 mapping, so this should be a noop. This could be a minor performance improvement, as everything on Linux dereferenced filp to get file_priv anyway, while only the mmap ioctls went the other direction. --- shared-core/i915_dma.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 81e6981d..05336d35 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -654,7 +654,7 @@ static int i915_flush_ioctl(DRM_IOCTL_ARGS) { DRM_DEVICE; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); return i915_quiescent(dev); } @@ -679,7 +679,7 @@ static int i915_batchbuffer(DRM_IOCTL_ARGS) DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", batch.start, batch.used, batch.num_cliprects); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects, batch.num_cliprects * @@ -707,7 +707,7 @@ static int i915_cmdbuffer(DRM_IOCTL_ARGS) DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", cmdbuf.buf, cmdbuf.sz, cmdbuf.num_cliprects); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (cmdbuf.num_cliprects && DRM_VERIFYAREA_READ(cmdbuf.cliprects, @@ -756,7 +756,7 @@ static int i915_flip_bufs(DRM_IOCTL_ARGS) DRM_DEBUG("%s\n", __FUNCTION__); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_flip_t __user *) data, sizeof(param)); @@ -965,11 +965,11 @@ void i915_driver_lastclose(struct drm_device * dev) i915_dma_cleanup(dev); } -void i915_driver_preclose(struct drm_device * dev, DRMFILE filp) +void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) { if (dev->dev_private) { drm_i915_private_t *dev_priv = dev->dev_private; - i915_mem_release(dev, filp, dev_priv->agp_heap); + i915_mem_release(dev, file_priv, dev_priv->agp_heap); } } -- cgit v1.2.3 From 5b38e134163cc375e91424c4688cc9328c6e9082 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jul 2007 17:11:11 -0700 Subject: Replace DRM_IOCTL_ARGS with (dev, data, file_priv) and remove DRM_DEVICE. The data is now in kernel space, copied in/out as appropriate according to the This results in DRM_COPY_{TO,FROM}_USER going away, and error paths to deal with those failures. This also means that XFree86 4.2.0 support for i810 DRM is lost. --- shared-core/i915_dma.c | 174 +++++++++++++++++++++---------------------------- 1 file changed, 76 insertions(+), 98 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 05336d35..5d227d8b 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -250,23 +250,20 @@ static int i915_dma_resume(struct drm_device * dev) return 0; } -static int i915_dma_init(DRM_IOCTL_ARGS) +static int i915_dma_init(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv; - drm_i915_init_t init; + drm_i915_init_t *init = data; int retcode = 0; - DRM_COPY_FROM_USER_IOCTL(init, (drm_i915_init_t __user *) data, - sizeof(init)); - - switch (init.func) { + switch (init->func) { case I915_INIT_DMA: dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) return -ENOMEM; - retcode = i915_initialize(dev, dev_priv, &init); + retcode = i915_initialize(dev, dev_priv, init); break; case I915_CLEANUP_DMA: retcode = i915_dma_cleanup(dev); @@ -358,7 +355,8 @@ static int validate_cmd(int cmd) return ret; } -static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords) +static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, + int dwords) { drm_i915_private_t *dev_priv = dev->dev_private; int i; @@ -650,22 +648,22 @@ static int i915_quiescent(struct drm_device * dev) return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); } -static int i915_flush_ioctl(DRM_IOCTL_ARGS) +static int i915_flush_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; LOCK_TEST_WITH_RETURN(dev, file_priv); return i915_quiescent(dev); } -static int i915_batchbuffer(DRM_IOCTL_ARGS) +static int i915_batchbuffer(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) dev_priv->sarea_priv; - drm_i915_batchbuffer_t batch; + drm_i915_batchbuffer_t *batch = data; int ret; if (!dev_priv->allow_batchbuffer) { @@ -673,51 +671,45 @@ static int i915_batchbuffer(DRM_IOCTL_ARGS) return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(batch, (drm_i915_batchbuffer_t __user *) data, - sizeof(batch)); - DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", - batch.start, batch.used, batch.num_cliprects); + batch->start, batch->used, batch->num_cliprects); LOCK_TEST_WITH_RETURN(dev, file_priv); - if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects, - batch.num_cliprects * - sizeof(struct drm_clip_rect))) + if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, + batch->num_cliprects * + sizeof(struct drm_clip_rect))) return -EFAULT; - ret = i915_dispatch_batchbuffer(dev, &batch); + ret = i915_dispatch_batchbuffer(dev, batch); sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); return ret; } -static int i915_cmdbuffer(DRM_IOCTL_ARGS) +static int i915_cmdbuffer(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) dev_priv->sarea_priv; - drm_i915_cmdbuffer_t cmdbuf; + drm_i915_cmdbuffer_t *cmdbuf = data; int ret; - DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_i915_cmdbuffer_t __user *) data, - sizeof(cmdbuf)); - DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", - cmdbuf.buf, cmdbuf.sz, cmdbuf.num_cliprects); + cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); LOCK_TEST_WITH_RETURN(dev, file_priv); - if (cmdbuf.num_cliprects && - DRM_VERIFYAREA_READ(cmdbuf.cliprects, - cmdbuf.num_cliprects * + if (cmdbuf->num_cliprects && + DRM_VERIFYAREA_READ(cmdbuf->cliprects, + cmdbuf->num_cliprects * sizeof(struct drm_clip_rect))) { DRM_ERROR("Fault accessing cliprects\n"); return -EFAULT; } - ret = i915_dispatch_cmdbuffer(dev, &cmdbuf); + ret = i915_dispatch_cmdbuffer(dev, cmdbuf); if (ret) { DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); return ret; @@ -749,35 +741,31 @@ static int i915_do_cleanup_pageflip(struct drm_device * dev) return 0; } -static int i915_flip_bufs(DRM_IOCTL_ARGS) +static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_i915_flip_t param; + drm_i915_flip_t *param = data; DRM_DEBUG("%s\n", __FUNCTION__); LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_flip_t __user *) data, - sizeof(param)); - - if (param.pipes & ~0x3) { + if (param->pipes & ~0x3) { DRM_ERROR("Invalid pipes 0x%x, only <= 0x3 is valid\n", - param.pipes); + param->pipes); return -EINVAL; } - i915_dispatch_flip(dev, param.pipes, 0); + i915_dispatch_flip(dev, param->pipes, 0); return 0; } -static int i915_getparam(DRM_IOCTL_ARGS) +static int i915_getparam(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_getparam_t param; + drm_i915_getparam_t *param = data; int value; if (!dev_priv) { @@ -785,10 +773,7 @@ static int i915_getparam(DRM_IOCTL_ARGS) return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_getparam_t __user *) data, - sizeof(param)); - - switch (param.param) { + switch (param->param) { case I915_PARAM_IRQ_ACTIVE: value = dev->irq ? 1 : 0; break; @@ -799,11 +784,11 @@ static int i915_getparam(DRM_IOCTL_ARGS) value = READ_BREADCRUMB(dev_priv); break; default: - DRM_ERROR("Unknown parameter %d\n", param.param); + DRM_ERROR("Unknown parameter %d\n", param->param); return -EINVAL; } - if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { + if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); return -EFAULT; } @@ -811,32 +796,29 @@ static int i915_getparam(DRM_IOCTL_ARGS) return 0; } -static int i915_setparam(DRM_IOCTL_ARGS) +static int i915_setparam(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_setparam_t param; + drm_i915_setparam_t *param = data; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_setparam_t __user *) data, - sizeof(param)); - - switch (param.param) { + switch (param->param) { case I915_SETPARAM_USE_MI_BATCHBUFFER_START: - dev_priv->use_mi_batchbuffer_start = param.value; + dev_priv->use_mi_batchbuffer_start = param->value; break; case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: - dev_priv->tex_lru_log_granularity = param.value; + dev_priv->tex_lru_log_granularity = param->value; break; case I915_SETPARAM_ALLOW_BATCHBUFFER: - dev_priv->allow_batchbuffer = param.value; + dev_priv->allow_batchbuffer = param->value; break; default: - DRM_ERROR("unknown parameter %d\n", param.param); + DRM_ERROR("unknown parameter %d\n", param->param); return -EINVAL; } @@ -853,13 +835,13 @@ drm_i915_mmio_entry_t mmio_table[] = { static int mmio_table_size = sizeof(mmio_table)/sizeof(drm_i915_mmio_entry_t); -static int i915_mmio(DRM_IOCTL_ARGS) +static int i915_mmio(struct drm_device *dev, void *data, + struct drm_file *file_priv) { uint32_t buf[8]; - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_mmio_entry_t *e; - drm_i915_mmio_t mmio; + drm_i915_mmio_t *mmio = data; void __iomem *base; int i; @@ -867,22 +849,20 @@ static int i915_mmio(DRM_IOCTL_ARGS) DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(mmio, (drm_i915_mmio_t __user *) data, - sizeof(mmio)); - if (mmio.reg >= mmio_table_size) + if (mmio->reg >= mmio_table_size) return -EINVAL; - e = &mmio_table[mmio.reg]; + e = &mmio_table[mmio->reg]; base = (u8 *) dev_priv->mmio_map->handle + e->offset; - switch (mmio.read_write) { + switch (mmio->read_write) { case I915_MMIO_READ: if (!(e->flag & I915_MMIO_MAY_READ)) return -EINVAL; for (i = 0; i < e->size / 4; i++) buf[i] = I915_READ(e->offset + i * 4); - if (DRM_COPY_TO_USER(mmio.data, buf, e->size)) { + if (DRM_COPY_TO_USER(mmio->data, buf, e->size)) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); return -EFAULT; } @@ -891,7 +871,7 @@ static int i915_mmio(DRM_IOCTL_ARGS) case I915_MMIO_WRITE: if (!(e->flag & I915_MMIO_MAY_WRITE)) return -EINVAL; - if(DRM_COPY_FROM_USER(buf, mmio.data, e->size)) { + if(DRM_COPY_FROM_USER(buf, mmio->data, e->size)) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); return -EFAULT; } @@ -902,23 +882,21 @@ static int i915_mmio(DRM_IOCTL_ARGS) return 0; } -static int i915_set_status_page(DRM_IOCTL_ARGS) +static int i915_set_status_page(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_hws_addr_t hws; + drm_i915_hws_addr_t *hws = data; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(hws, (drm_i915_hws_addr_t __user *) data, - sizeof(hws)); - DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws.addr); + DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); - dev_priv->status_gfx_addr = hws.addr & (0x1ffff<<12); + dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); - dev_priv->hws_map.offset = dev->agp->base + hws.addr; + dev_priv->hws_map.offset = dev->agp->base + hws->addr; dev_priv->hws_map.size = 4*1024; dev_priv->hws_map.type = 0; dev_priv->hws_map.flags = 0; @@ -974,24 +952,24 @@ void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) } struct drm_ioctl_desc i915_ioctls[] = { - [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, - [DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, - [DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH }, - [DRM_IOCTL_NR(DRM_I915_VBLANK_SWAP)] = {i915_vblank_swap, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_MMIO)] = {i915_mmio, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_HWS_ADDR)] = {i915_set_status_page, DRM_AUTH}, + DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), + DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), + DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), + DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_MMIO, i915_mmio, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH), }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); -- cgit v1.2.3 From da279868706cc799bdf25cdd5523d11fda64d4cc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Aug 2007 18:33:29 +1000 Subject: i915: i965 non-secure batchbuffer bit has moved. --- shared-core/i915_dma.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 5d227d8b..9f18feee 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -546,9 +546,15 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, if (dev_priv->use_mi_batchbuffer_start) { BEGIN_LP_RING(2); - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); + if (IS_I965G(dev)) { + OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); + OUT_RING(batch->start); + } else { + OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); + OUT_RING(batch->start | MI_BATCH_NON_SECURE); + } ADVANCE_LP_RING(); + } else { BEGIN_LP_RING(4); OUT_RING(MI_BATCH_BUFFER); -- cgit v1.2.3 From 3cb8acd5abcb410ab2982f55aec94b5a793a47d6 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 11 Sep 2007 03:48:46 -0700 Subject: Disambiguate planes & pipes for swap operations This mod makes the SAREA track plane to pipe mappings and corrects the name of the plane info variables (they were mislabeled as pipe info since until now all code assumed a direct mapping between planes and pipes). It also updates the flip ioctl argument to take a set of planes rather than pipes, since planes are flipped while pipes generate vblank events. --- shared-core/i915_dma.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 9f18feee..daa03df8 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -572,11 +572,11 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, return 0; } -static void i915_do_dispatch_flip(struct drm_device * dev, int pipe, int sync) +static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync) { drm_i915_private_t *dev_priv = dev->dev_private; u32 num_pages, current_page, next_page, dspbase; - int shift = 2 * pipe, x, y; + int shift = 2 * plane, x, y; RING_LOCALS; /* Calculate display base offset */ @@ -597,25 +597,25 @@ static void i915_do_dispatch_flip(struct drm_device * dev, int pipe, int sync) break; } - if (pipe == 0) { - x = dev_priv->sarea_priv->pipeA_x; - y = dev_priv->sarea_priv->pipeA_y; + if (plane == 0) { + x = dev_priv->sarea_priv->planeA_x; + y = dev_priv->sarea_priv->planeA_y; } else { - x = dev_priv->sarea_priv->pipeB_x; - y = dev_priv->sarea_priv->pipeB_y; + x = dev_priv->sarea_priv->planeB_x; + y = dev_priv->sarea_priv->planeB_y; } dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp; - DRM_DEBUG("pipe=%d current_page=%d dspbase=0x%x\n", pipe, current_page, + DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page, dspbase); BEGIN_LP_RING(4); OUT_RING(sync ? 0 : - (MI_WAIT_FOR_EVENT | (pipe ? MI_WAIT_FOR_PLANE_B_FLIP : + (MI_WAIT_FOR_EVENT | (plane ? MI_WAIT_FOR_PLANE_B_FLIP : MI_WAIT_FOR_PLANE_A_FLIP))); OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) | - (pipe ? DISPLAY_PLANE_B : DISPLAY_PLANE_A)); + (plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A)); OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp); OUT_RING(dspbase); ADVANCE_LP_RING(); @@ -624,19 +624,19 @@ static void i915_do_dispatch_flip(struct drm_device * dev, int pipe, int sync) dev_priv->sarea_priv->pf_current_page |= next_page << shift; } -void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync) +void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) { drm_i915_private_t *dev_priv = dev->dev_private; int i; - DRM_DEBUG("%s: pipes=0x%x pfCurrentPage=%d\n", + DRM_DEBUG("%s: planes=0x%x pfCurrentPage=%d\n", __FUNCTION__, - pipes, dev_priv->sarea_priv->pf_current_page); + planes, dev_priv->sarea_priv->pf_current_page); i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH); for (i = 0; i < 2; i++) - if (pipes & (1 << i)) + if (planes & (1 << i)) i915_do_dispatch_flip(dev, i, sync); i915_emit_breadcrumb(dev); @@ -728,21 +728,21 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, static int i915_do_cleanup_pageflip(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; - int i, pipes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; + int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; DRM_DEBUG("%s\n", __FUNCTION__); - for (i = 0, pipes = 0; i < 2; i++) + for (i = 0, planes = 0; i < 2; i++) if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) { dev_priv->sarea_priv->pf_current_page = (dev_priv->sarea_priv->pf_current_page & ~(0x3 << (2 * i))) | (num_pages - 1) << (2 * i); - pipes |= 1 << i; + planes |= 1 << i; } - if (pipes) - i915_dispatch_flip(dev, pipes, 0); + if (planes) + i915_dispatch_flip(dev, planes, 0); return 0; } @@ -755,13 +755,13 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *f LOCK_TEST_WITH_RETURN(dev, file_priv); - if (param->pipes & ~0x3) { - DRM_ERROR("Invalid pipes 0x%x, only <= 0x3 is valid\n", - param->pipes); + if (param->planes & ~0x3) { + DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n", + param->planes); return -EINVAL; } - i915_dispatch_flip(dev, param->pipes, 0); + i915_dispatch_flip(dev, param->planes, 0); return 0; } -- cgit v1.2.3 From 0bb2395a8be0c33cc687dfd6aae7df81a82ed8e5 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 28 Sep 2007 10:10:08 -0700 Subject: Revert drm_i915_flip_t braindamage I should not have renamed this field. I should not have renamed this field. I should not have renamed this field. On the plus side, it was at least binary compatible. --- shared-core/i915_dma.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index daa03df8..3a9ecab2 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -755,13 +755,14 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *f LOCK_TEST_WITH_RETURN(dev, file_priv); - if (param->planes & ~0x3) { + /* This is really planes */ + if (param->pipes & ~0x3) { DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n", - param->planes); + param->pipes); return -EINVAL; } - i915_dispatch_flip(dev, param->planes, 0); + i915_dispatch_flip(dev, param->pipes, 0); return 0; } -- cgit v1.2.3 From 74001c34e5ad768feec8b2fbe9a617bc598a0a4b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 12 Oct 2007 10:54:38 +1000 Subject: i915: add superioctl support to i915 This adds the initial i915 superioctl interface. The interface should be sufficent even if the implementation may needs fixes/optimisations internally in the drm wrt caching etc. --- shared-core/i915_dma.c | 344 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 3a9ecab2..7209a8de 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -147,6 +147,10 @@ static int i915_initialize(struct drm_device * dev, return -EINVAL; } +#ifdef I915_HAVE_BUFFER + dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; +#endif + dev_priv->sarea_priv = (drm_i915_sarea_t *) ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); @@ -725,6 +729,343 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, return 0; } +#ifdef I915_HAVE_BUFFER +struct i915_relocatee_info { + struct drm_buffer_object *buf; + unsigned long offset; + u32 *data_page; + unsigned page_offset; + struct drm_bo_kmap_obj kmap; + int is_iomem; +}; + +static void i915_dereference_buffers_locked(struct drm_buffer_object **buffers, + unsigned num_buffers) +{ + while (num_buffers--) + drm_bo_usage_deref_locked(&buffers[num_buffers]); +} + +int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, + struct drm_buffer_object **buffers, + struct i915_relocatee_info *relocatee, + uint32_t *reloc) +{ + unsigned index; + unsigned long new_cmd_offset; + u32 val; + int ret; + + if (reloc[2] >= num_buffers) { + DRM_ERROR("Illegal relocation buffer %08X\n", reloc[2]); + return -EINVAL; + } + + new_cmd_offset = reloc[0]; + if (!relocatee->data_page || + !drm_bo_same_page(relocatee->offset, new_cmd_offset)) { + drm_bo_kunmap(&relocatee->kmap); + relocatee->offset = new_cmd_offset; + ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT, + 1, &relocatee->kmap); + if (ret) { + DRM_ERROR("Could not map command buffer to apply relocs\n %08lx", new_cmd_offset); + return ret; + } + + relocatee->data_page = drm_bmo_virtual(&relocatee->kmap, + &relocatee->is_iomem); + relocatee->page_offset = (relocatee->offset & PAGE_MASK); + } + + val = buffers[reloc[2]]->offset; + index = (reloc[0] - relocatee->page_offset) >> 2; + + /* add in validate */ + val = val + reloc[1]; + + relocatee->data_page[index] = val; + return 0; +} + +int i915_process_relocs(struct drm_file *file_priv, + uint32_t buf_handle, + uint32_t *reloc_buf_handle, + struct i915_relocatee_info *relocatee, + struct drm_buffer_object **buffers, + uint32_t num_buffers) +{ + struct drm_device *dev = file_priv->head->dev; + struct drm_buffer_object *reloc_list_object; + uint32_t cur_handle = *reloc_buf_handle; + uint32_t *reloc_page; + int ret, reloc_is_iomem, reloc_stride; + uint32_t num_relocs, reloc_offset, reloc_end, reloc_page_offset, next_offset, cur_offset; + struct drm_bo_kmap_obj reloc_kmap; + + memset(&reloc_kmap, 0, sizeof(reloc_kmap)); + + reloc_list_object = drm_lookup_buffer_object(file_priv, cur_handle, 1); + if (!reloc_list_object) + return -EINVAL; + + ret = drm_bo_kmap(reloc_list_object, 0, 1, &reloc_kmap); + if (ret) { + DRM_ERROR("Could not map relocation buffer.\n"); + goto out; + } + + reloc_page = drm_bmo_virtual(&reloc_kmap, &reloc_is_iomem); + num_relocs = reloc_page[0] & 0xffff; + + if ((reloc_page[0] >> 16) & 0xffff) { + DRM_ERROR("Unsupported relocation type requested\n"); + goto out; + } + + /* get next relocate buffer handle */ + *reloc_buf_handle = reloc_page[1]; + reloc_stride = I915_RELOC0_STRIDE * sizeof(uint32_t); /* may be different for other types of relocs */ + + DRM_DEBUG("num relocs is %d, next is %08X\n", num_relocs, reloc_page[1]); + + reloc_page_offset = 0; + reloc_offset = I915_RELOC_HEADER * sizeof(uint32_t); + reloc_end = reloc_offset + (num_relocs * reloc_stride); + + do { + next_offset = drm_bo_offset_end(reloc_offset, reloc_end); + + do { + cur_offset = ((reloc_offset + reloc_page_offset) & ~PAGE_MASK) / sizeof(uint32_t); + ret = i915_apply_reloc(file_priv, num_buffers, + buffers, relocatee, &reloc_page[cur_offset]); + if (ret) + goto out; + + reloc_offset += reloc_stride; + } while (reloc_offset < next_offset); + + drm_bo_kunmap(&reloc_kmap); + + reloc_offset = next_offset; + if (reloc_offset != reloc_end) { + ret = drm_bo_kmap(reloc_list_object, reloc_offset >> PAGE_SHIFT, 1, &reloc_kmap); + if (ret) { + DRM_ERROR("Could not map relocation buffer.\n"); + goto out; + } + + reloc_page = drm_bmo_virtual(&reloc_kmap, &reloc_is_iomem); + reloc_page_offset = reloc_offset & ~PAGE_MASK; + } + + } while (reloc_offset != reloc_end); +out: + drm_bo_kunmap(&reloc_kmap); + + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(&reloc_list_object); + mutex_unlock(&dev->struct_mutex); + + return ret; +} + +/* + * Validate, add fence and relocate a block of bos from a userspace list + */ +int i915_validate_buffer_list(struct drm_file *file_priv, + unsigned int fence_class, uint64_t data, + struct drm_buffer_object **buffers, + uint32_t *num_buffers) +{ + struct drm_i915_op_arg arg; + struct drm_bo_op_req *req = &arg.d.req; + struct drm_bo_arg_rep rep; + unsigned long next = 0; + int ret = 0; + unsigned buf_count = 0; + struct drm_device *dev = file_priv->head->dev; + uint32_t buf_reloc_handle, buf_handle; + struct i915_relocatee_info relocatee; + + do { + if (buf_count >= *num_buffers) { + DRM_ERROR("Buffer count exceeded %d\n.", *num_buffers); + ret = -EINVAL; + goto out_err; + } + + buffers[buf_count] = NULL; + + if (copy_from_user(&arg, (void __user *)(unsigned)data, sizeof(arg))) { + ret = -EFAULT; + goto out_err; + } + + if (arg.handled) { + data = arg.next; + buffers[buf_count] = drm_lookup_buffer_object(file_priv, req->arg_handle, 1); + buf_count++; + continue; + } + + rep.ret = 0; + if (req->op != drm_bo_validate) { + DRM_ERROR + ("Buffer object operation wasn't \"validate\".\n"); + rep.ret = -EINVAL; + goto out_err; + } + + buf_handle = req->bo_req.handle; + buf_reloc_handle = arg.reloc_handle; + + rep.ret = drm_bo_handle_validate(file_priv, req->bo_req.handle, + req->bo_req.fence_class, + req->bo_req.flags, + req->bo_req.mask, + req->bo_req.hint, + &rep.bo_info, + &buffers[buf_count]); + + if (rep.ret) { + DRM_ERROR("error on handle validate %d\n", rep.ret); + goto out_err; + } + + + next = arg.next; + arg.handled = 1; + arg.d.rep = rep; + + if (copy_to_user((void __user *)(unsigned)data, &arg, sizeof(arg))) + return -EFAULT; + + data = next; + buf_count++; + + if (buf_reloc_handle) { + memset(&relocatee, 0, sizeof(relocatee)); + + relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); + if (!relocatee.buf) { + DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle); + ret = -EINVAL; + goto out_err; + } + + while (buf_reloc_handle) { + ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count); + if (ret) { + DRM_ERROR("process relocs failed\n"); + break; + } + } + + drm_bo_kunmap(&relocatee.kmap); + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(&relocatee.buf); + mutex_unlock(&dev->struct_mutex); + + if (ret) + goto out_err; + + } + } while (next != 0); + *num_buffers = buf_count; + return 0; +out_err: + mutex_lock(&dev->struct_mutex); + i915_dereference_buffers_locked(buffers, buf_count); + mutex_unlock(&dev->struct_mutex); + *num_buffers = 0; + return (ret) ? ret : rep.ret; +} + +static int i915_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) + dev_priv->sarea_priv; + struct drm_i915_execbuffer *exec_buf = data; + struct _drm_i915_batchbuffer *batch = &exec_buf->batch; + struct drm_fence_arg *fence_arg = &exec_buf->fence_arg; + int num_buffers; + int ret; + struct drm_buffer_object **buffers; + struct drm_fence_object *fence; + + if (!dev_priv->allow_batchbuffer) { + DRM_ERROR("Batchbuffer ioctl disabled\n"); + return -EINVAL; + } + + + LOCK_TEST_WITH_RETURN(dev, file_priv); + + if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, + batch->num_cliprects * + sizeof(struct drm_clip_rect))) + return -EFAULT; + + if (exec_buf->num_buffers > dev_priv->max_validate_buffers) + return -EINVAL; + + num_buffers = exec_buf->num_buffers; + + buffers = drm_calloc(num_buffers, sizeof(struct drm_buffer_object *), DRM_MEM_DRIVER); + if (!buffers) + return -ENOMEM; + + /* validate buffer list + fixup relocations */ + ret = i915_validate_buffer_list(file_priv, 0, exec_buf->ops_list, + buffers, &num_buffers); + if (ret) + goto out_free; + + /* submit buffer */ + batch->start = buffers[num_buffers-1]->offset; + + DRM_DEBUG("i915 exec batchbuffer, start %x used %d cliprects %d\n", + batch->start, batch->used, batch->num_cliprects); + + ret = i915_dispatch_batchbuffer(dev, batch); + if (ret) + goto out_err0; + + sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + + /* fence */ + ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence); + if (ret) + goto out_err0; + + if (!(fence_arg->flags & DRM_FENCE_FLAG_NO_USER)) { + ret = drm_fence_add_user_object(file_priv, fence, fence_arg->flags & DRM_FENCE_FLAG_SHAREABLE); + if (!ret) { + fence_arg->handle = fence->base.hash.key; + fence_arg->fence_class = fence->fence_class; + fence_arg->type = fence->type; + fence_arg->signaled = fence->signaled; + } + } + drm_fence_usage_deref_unlocked(&fence); +out_err0: + + /* handle errors */ + mutex_lock(&dev->struct_mutex); + i915_dereference_buffers_locked(buffers, num_buffers); + mutex_unlock(&dev->struct_mutex); + +out_free: + drm_free(buffers, (exec_buf->num_buffers * sizeof(struct drm_buffer_object *)), DRM_MEM_DRIVER); + + return ret; +} +#endif + static int i915_do_cleanup_pageflip(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -977,6 +1318,9 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_MMIO, i915_mmio, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH), +#ifdef I915_HAVE_BUFFER + DRM_IOCTL_DEF(DRM_I915_EXECBUFFER, i915_execbuffer, DRM_AUTH), +#endif }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); -- cgit v1.2.3 From ec1162b212248042bf1317abcb3c47bb10db8aa3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 17 Oct 2007 15:36:14 +1000 Subject: i915: lock struct mutex about buffer object lookups --- shared-core/i915_dma.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 7209a8de..5a51f6ef 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -805,7 +805,9 @@ int i915_process_relocs(struct drm_file *file_priv, memset(&reloc_kmap, 0, sizeof(reloc_kmap)); + mutex_lock(&dev->struct_mutex); reloc_list_object = drm_lookup_buffer_object(file_priv, cur_handle, 1); + mutex_unlock(&dev->struct_mutex); if (!reloc_list_object) return -EINVAL; @@ -905,7 +907,9 @@ int i915_validate_buffer_list(struct drm_file *file_priv, if (arg.handled) { data = arg.next; + mutex_lock(&dev->struct_mutex); buffers[buf_count] = drm_lookup_buffer_object(file_priv, req->arg_handle, 1); + mutex_unlock(&dev->struct_mutex); buf_count++; continue; } @@ -948,7 +952,9 @@ int i915_validate_buffer_list(struct drm_file *file_priv, if (buf_reloc_handle) { memset(&relocatee, 0, sizeof(relocatee)); + mutex_lock(&dev->struct_mutex); relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); + mutex_unlock(&dev->struct_mutex); if (!relocatee.buf) { DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle); ret = -EINVAL; -- cgit v1.2.3 From 48b5eaf303b60077faed09db77785d7a544ac335 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Sat, 20 Oct 2007 16:49:43 +0200 Subject: Simple replacement for hardware lock in some cases. Fix i915 since last commit. --- shared-core/i915_dma.c | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 5a51f6ef..99d98cd3 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -930,6 +930,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv, req->bo_req.flags, req->bo_req.mask, req->bo_req.hint, + 0, &rep.bo_info, &buffers[buf_count]); -- cgit v1.2.3 From 9ddff6d15fdff571193aac10ef81e67798fd712d Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Sun, 21 Oct 2007 12:26:26 +0200 Subject: Adapt i915 super-ioctl for lock-free operation. --- shared-core/i915_dma.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 99d98cd3..14a91f36 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1010,8 +1010,6 @@ static int i915_execbuffer(struct drm_device *dev, void *data, } - LOCK_TEST_WITH_RETURN(dev, file_priv); - if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, batch->num_cliprects * sizeof(struct drm_clip_rect))) @@ -1020,11 +1018,18 @@ static int i915_execbuffer(struct drm_device *dev, void *data, if (exec_buf->num_buffers > dev_priv->max_validate_buffers) return -EINVAL; + + ret = drm_bo_read_lock(&dev->bm.bm_lock); + if (ret) + return ret; + num_buffers = exec_buf->num_buffers; buffers = drm_calloc(num_buffers, sizeof(struct drm_buffer_object *), DRM_MEM_DRIVER); - if (!buffers) + if (!buffers) { + drm_bo_read_unlock(&dev->bm.bm_lock); return -ENOMEM; + } /* validate buffer list + fixup relocations */ ret = i915_validate_buffer_list(file_priv, 0, exec_buf->ops_list, @@ -1068,7 +1073,7 @@ out_err0: out_free: drm_free(buffers, (exec_buf->num_buffers * sizeof(struct drm_buffer_object *)), DRM_MEM_DRIVER); - + drm_bo_read_unlock(&dev->bm.bm_lock); return ret; } #endif -- cgit v1.2.3 From 22883ff26b8a45ab2bec60accc4b822cf6b4f214 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 22 Oct 2007 11:54:41 +1100 Subject: i915: split reloc execution into separate function --- shared-core/i915_dma.c | 65 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 26 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 5a51f6ef..d0d65f8c 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -873,6 +873,43 @@ out: return ret; } +static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, + drm_handle_t buf_reloc_handle, + struct drm_buffer_object **buffers, + uint32_t buf_count) +{ + struct drm_device *dev = file_priv->head->dev; + struct i915_relocatee_info relocatee; + int ret = 0; + + memset(&relocatee, 0, sizeof(relocatee)); + + mutex_lock(&dev->struct_mutex); + relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); + mutex_unlock(&dev->struct_mutex); + if (!relocatee.buf) { + DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle); + ret = -EINVAL; + goto out_err; + } + + while (buf_reloc_handle) { + ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count); + if (ret) { + DRM_ERROR("process relocs failed\n"); + break; + } + } + + drm_bo_kunmap(&relocatee.kmap); + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(&relocatee.buf); + mutex_unlock(&dev->struct_mutex); + +out_err: + return ret; +} + /* * Validate, add fence and relocate a block of bos from a userspace list */ @@ -889,7 +926,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv, unsigned buf_count = 0; struct drm_device *dev = file_priv->head->dev; uint32_t buf_reloc_handle, buf_handle; - struct i915_relocatee_info relocatee; + do { if (buf_count >= *num_buffers) { @@ -950,33 +987,9 @@ int i915_validate_buffer_list(struct drm_file *file_priv, buf_count++; if (buf_reloc_handle) { - memset(&relocatee, 0, sizeof(relocatee)); - - mutex_lock(&dev->struct_mutex); - relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); - mutex_unlock(&dev->struct_mutex); - if (!relocatee.buf) { - DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle); - ret = -EINVAL; - goto out_err; - } - - while (buf_reloc_handle) { - ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count); - if (ret) { - DRM_ERROR("process relocs failed\n"); - break; - } - } - - drm_bo_kunmap(&relocatee.kmap); - mutex_lock(&dev->struct_mutex); - drm_bo_usage_deref_locked(&relocatee.buf); - mutex_unlock(&dev->struct_mutex); - + ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count); if (ret) goto out_err; - } } while (next != 0); *num_buffers = buf_count; -- cgit v1.2.3 From 919c886b2b7728768720aac93e0f6fd1acb8b2df Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 22 Oct 2007 18:59:37 +0200 Subject: A cmdbuf mutex to implement validate-submit-fence atomicity in the absence of a hardware lock. --- shared-core/i915_dma.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 14a91f36..d07be6e0 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -213,6 +213,7 @@ static int i915_initialize(struct drm_device * dev, } DRM_DEBUG("Enabled hardware status page\n"); dev->dev_private = (void *)dev_priv; + mutex_init(&dev_priv->cmdbuf_mutex); return 0; } @@ -1023,11 +1024,23 @@ static int i915_execbuffer(struct drm_device *dev, void *data, if (ret) return ret; + /* + * The cmdbuf_mutex makes sure the validate-submit-fence + * operation is atomic. + */ + + ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex); + if (ret) { + drm_bo_read_unlock(&dev->bm.bm_lock); + return -EAGAIN; + } + num_buffers = exec_buf->num_buffers; buffers = drm_calloc(num_buffers, sizeof(struct drm_buffer_object *), DRM_MEM_DRIVER); if (!buffers) { drm_bo_read_unlock(&dev->bm.bm_lock); + mutex_unlock(&dev_priv->cmdbuf_mutex); return -ENOMEM; } @@ -1073,6 +1086,8 @@ out_err0: out_free: drm_free(buffers, (exec_buf->num_buffers * sizeof(struct drm_buffer_object *)), DRM_MEM_DRIVER); + + mutex_unlock(&dev_priv->cmdbuf_mutex); drm_bo_read_unlock(&dev->bm.bm_lock); return ret; } -- cgit v1.2.3 From a294aa724a1e932fb6017383e08532bfcc914df0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Oct 2007 17:54:07 +1000 Subject: i915: require mfence before submitting batchbuffer --- shared-core/i915_dma.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index d0d65f8c..f0fd6037 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1044,6 +1044,9 @@ static int i915_execbuffer(struct drm_device *dev, void *data, if (ret) goto out_free; + /* make sure all previous memory operations have passed */ + asm volatile("mfence":::"memory"); + /* submit buffer */ batch->start = buffers[num_buffers-1]->offset; -- cgit v1.2.3 From fd7c24753c4020a0022aaa183cfe8fc04a307abd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 24 Oct 2007 11:13:15 +1100 Subject: i915: use a drm memory barrier define --- shared-core/i915_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index f0fd6037..9bc7431d 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1045,7 +1045,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data, goto out_free; /* make sure all previous memory operations have passed */ - asm volatile("mfence":::"memory"); + DRM_MEMORYBARRIER(); /* submit buffer */ batch->start = buffers[num_buffers-1]->offset; -- cgit v1.2.3 From 83199c257ea68a7cc0c6928109ff77bf25131819 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 24 Oct 2007 16:27:46 -0700 Subject: Fix missing \n on some DRM_ERROR in i915_dma.c --- shared-core/i915_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 9bc7431d..eb8c9153 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -494,7 +494,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, int i = 0, count, ret; if (cmd->sz & 0x3) { - DRM_ERROR("alignment"); + DRM_ERROR("alignment\n"); return -EINVAL; } @@ -532,7 +532,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, RING_LOCALS; if ((batch->start | batch->used) & 0x7) { - DRM_ERROR("alignment"); + DRM_ERROR("alignment\n"); return -EINVAL; } -- cgit v1.2.3 From c5f158abbe97492f56eb60ac54679945e9d6ddae Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 25 Oct 2007 16:52:33 +1000 Subject: i915: remove relocatee kernel mapping sooner stops mutex taking during sleep --- shared-core/i915_dma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index eb8c9153..acbb41dc 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -864,6 +864,9 @@ int i915_process_relocs(struct drm_file *file_priv, } while (reloc_offset != reloc_end); out: + drm_bo_kunmap(&relocatee->kmap); + relocatee->data_page = NULL; + drm_bo_kunmap(&reloc_kmap); mutex_lock(&dev->struct_mutex); @@ -901,7 +904,6 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, } } - drm_bo_kunmap(&relocatee.kmap); mutex_lock(&dev->struct_mutex); drm_bo_usage_deref_locked(&relocatee.buf); mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3 From a70fe82baf0ca2be98e02680cff489f90b0ea3de Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 25 Oct 2007 16:53:18 +1000 Subject: i915: relocate buffers before validation add memory barrier between two --- shared-core/i915_dma.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index acbb41dc..1e15e7ce 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -964,6 +964,13 @@ int i915_validate_buffer_list(struct drm_file *file_priv, buf_handle = req->bo_req.handle; buf_reloc_handle = arg.reloc_handle; + if (buf_reloc_handle) { + ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count); + if (ret) + goto out_err; + DRM_MEMORYBARRIER(); + } + rep.ret = drm_bo_handle_validate(file_priv, req->bo_req.handle, req->bo_req.fence_class, req->bo_req.flags, @@ -988,11 +995,6 @@ int i915_validate_buffer_list(struct drm_file *file_priv, data = next; buf_count++; - if (buf_reloc_handle) { - ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count); - if (ret) - goto out_err; - } } while (next != 0); *num_buffers = buf_count; return 0; -- cgit v1.2.3 From 1e2a2bababf3fbaa0a665983856761c2284dba30 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 26 Oct 2007 16:10:02 -0700 Subject: i915: suspend/resume support Add suspend/resume support to the i915 driver. Moves some of the initialization into the driver load routine, and fixes up places where we assumed no dev_private existed in some of the cleanup paths. This allows us to suspend/resume properly even if X isn't running. --- shared-core/i915_dma.c | 112 +++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 54 deletions(-) (limited to 'shared-core/i915_dma.c') diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index b1168635..24a4ec4a 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -31,17 +31,6 @@ #include "i915_drm.h" #include "i915_drv.h" -#define IS_I965G(dev) (dev->pci_device == 0x2972 || \ - dev->pci_device == 0x2982 || \ - dev->pci_device == 0x2992 || \ - dev->pci_device == 0x29A2 || \ - dev->pci_device == 0x2A02 || \ - dev->pci_device == 0x2A12) - -#define IS_G33(dev) (dev->pci_device == 0x29C2 || \ - dev->pci_device == 0x29B2 || \ - dev->pci_device == 0x29D2) - /* Really want an OS-independent resettable timer. Would like to have * this loop run for (eg) 3 sec, but have the timer reset every time * the head pointer changes, so that EBUSY only happens if the ring @@ -91,6 +80,7 @@ void i915_kernel_lost_context(struct drm_device * dev) static int i915_dma_cleanup(struct drm_device * dev) { + drm_i915_private_t *dev_priv = dev->dev_private; /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. @@ -98,50 +88,42 @@ static int i915_dma_cleanup(struct drm_device * dev) if (dev->irq) drm_irq_uninstall(dev); - if (dev->dev_private) { - drm_i915_private_t *dev_priv = - (drm_i915_private_t *) dev->dev_private; - - if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); - } + if (dev_priv->ring.virtual_start) { + drm_core_ioremapfree(&dev_priv->ring.map, dev); + dev_priv->ring.virtual_start = 0; + dev_priv->ring.map.handle = 0; + dev_priv->ring.map.size = 0; + } - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - /* Need to rewrite hardware status page */ - I915_WRITE(0x02080, 0x1ffff000); - } - if (dev_priv->status_gfx_addr) { - dev_priv->status_gfx_addr = 0; - drm_core_ioremapfree(&dev_priv->hws_map, dev); - I915_WRITE(0x02080, 0x1ffff000); - } - drm_free(dev->dev_private, sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); + if (dev_priv->status_page_dmah) { + drm_pci_free(dev, dev_priv->status_page_dmah); + dev_priv->status_page_dmah = NULL; + /* Need to rewrite hardware status page */ + I915_WRITE(0x02080, 0x1ffff000); + } - dev->dev_private = NULL; + if (dev_priv->status_gfx_addr) { + dev_priv->status_gfx_addr = 0; + drm_core_ioremapfree(&dev_priv->hws_map, dev); + I915_WRITE(0x02080, 0x1ffff000); } return 0; } -static int i915_initialize(struct drm_device * dev, - drm_i915_private_t * dev_priv, - drm_i915_init_t * init) +static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) { - memset(dev_priv, 0, sizeof(drm_i915_private_t)); + drm_i915_private_t *dev_priv = dev->dev_private; dev_priv->sarea = drm_getsarea(dev); if (!dev_priv->sarea) { DRM_ERROR("can not find sarea!\n"); - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); return -EINVAL; } dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); if (!dev_priv->mmio_map) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("can not find mmio map!\n"); return -EINVAL; @@ -168,7 +150,6 @@ static int i915_initialize(struct drm_device * dev, drm_core_ioremap(&dev_priv->ring.map, dev); if (dev_priv->ring.map.handle == NULL) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); @@ -199,7 +180,6 @@ static int i915_initialize(struct drm_device * dev, drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); if (!dev_priv->status_page_dmah) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; @@ -212,7 +192,6 @@ static int i915_initialize(struct drm_device * dev, I915_WRITE(0x02080, dev_priv->dma_status_page); } DRM_DEBUG("Enabled hardware status page\n"); - dev->dev_private = (void *)dev_priv; mutex_init(&dev_priv->cmdbuf_mutex); return 0; } @@ -258,17 +237,12 @@ static int i915_dma_resume(struct drm_device * dev) static int i915_dma_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_i915_private_t *dev_priv; drm_i915_init_t *init = data; int retcode = 0; switch (init->func) { case I915_INIT_DMA: - dev_priv = drm_alloc(sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); - if (dev_priv == NULL) - return -ENOMEM; - retcode = i915_initialize(dev, dev_priv, init); + retcode = i915_initialize(dev, init); break; case I915_CLEANUP_DMA: retcode = i915_dma_cleanup(dev); @@ -1299,7 +1273,6 @@ static int i915_set_status_page(struct drm_device *dev, void *data, drm_core_ioremap(&dev_priv->hws_map, dev); if (dev_priv->hws_map.handle == NULL) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); dev_priv->status_gfx_addr = 0; DRM_ERROR("can not ioremap virtual address for" @@ -1318,6 +1291,10 @@ static int i915_set_status_page(struct drm_device *dev, void *data, int i915_driver_load(struct drm_device *dev, unsigned long flags) { + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long base, size; + int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; + /* i915 has 4 more counters */ dev->counters += 4; dev->types[6] = _DRM_STAT_IRQ; @@ -1325,25 +1302,52 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev->types[8] = _DRM_STAT_SECONDARY; dev->types[9] = _DRM_STAT_DMA; + dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; + + memset(dev_priv, 0, sizeof(drm_i915_private_t)); + + dev->dev_private = (void *)dev_priv; + + /* Add register map (needed for suspend/resume) */ + base = drm_get_resource_start(dev, mmio_bar); + size = drm_get_resource_len(dev, mmio_bar); + + ret = drm_addmap(dev, base, size, _DRM_REGISTERS, _DRM_KERNEL, + &dev_priv->mmio_map); + + return ret; +} + +int i915_driver_unload(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->mmio_map) + drm_rmmap(dev, dev_priv->mmio_map); + + drm_free(dev->dev_private, sizeof(drm_i915_private_t), + DRM_MEM_DRIVER); return 0; } void i915_driver_lastclose(struct drm_device * dev) { - if (dev->dev_private) { - drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_private_t *dev_priv = dev->dev_private; + + if (drm_getsarea(dev) && dev_priv->sarea_priv) i915_do_cleanup_pageflip(dev); + if (dev_priv->agp_heap) i915_mem_takedown(&(dev_priv->agp_heap)); - } + i915_dma_cleanup(dev); } void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) { - if (dev->dev_private) { - drm_i915_private_t *dev_priv = dev->dev_private; - i915_mem_release(dev, file_priv, dev_priv->agp_heap); - } + drm_i915_private_t *dev_priv = dev->dev_private; + i915_mem_release(dev, file_priv, dev_priv->agp_heap); } struct drm_ioctl_desc i915_ioctls[] = { -- cgit v1.2.3