diff options
author | Leif Delgass <ldelgass@users.sourceforge.net> | 2003-02-18 21:47:03 +0000 |
---|---|---|
committer | Leif Delgass <ldelgass@users.sourceforge.net> | 2003-02-18 21:47:03 +0000 |
commit | 3cde41f7cd7f439c11e845fd379e62a45611aa40 (patch) | |
tree | 6f6fb2ee2b91ecf305ed6947e3f3980c2e857426 | |
parent | a44670395a1c74e8de100f1a836d816a5dbcbaf7 (diff) |
More os-independence changes for mach64 DRM, move list_for_each_safe()
definition (for older Linux kernels) to drmP.h, add some additional
checks and enhancements to vertex buffer copy/verify, reduce logging
verbosity.
-rw-r--r-- | linux-core/drmP.h | 6 | ||||
-rw-r--r-- | linux-core/drm_os_linux.h | 42 | ||||
-rw-r--r-- | linux/drmP.h | 6 | ||||
-rw-r--r-- | linux/drm_os_linux.h | 42 | ||||
-rw-r--r-- | shared-core/mach64_dma.c | 100 | ||||
-rw-r--r-- | shared-core/mach64_drv.h | 43 | ||||
-rw-r--r-- | shared-core/mach64_state.c | 144 | ||||
-rw-r--r-- | shared/mach64_dma.c | 100 | ||||
-rw-r--r-- | shared/mach64_drv.h | 43 | ||||
-rw-r--r-- | shared/mach64_state.c | 144 |
10 files changed, 330 insertions, 340 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 01045037..17262609 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -166,6 +166,12 @@ #define pte_unmap(pte) #endif +#ifndef list_for_each_safe +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) static inline struct page * vmalloc_to_page(void * vmalloc_addr) { diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h index e9b24356..a9ad02af 100644 --- a/linux-core/drm_os_linux.h +++ b/linux-core/drm_os_linux.h @@ -60,28 +60,28 @@ do { \ #define DRM_HZ HZ -#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ -do { \ - DECLARE_WAITQUEUE(entry, current); \ - unsigned long end = jiffies + (timeout); \ - add_wait_queue(&(queue), &entry); \ - \ - for (;;) { \ - current->state = TASK_INTERRUPTIBLE; \ - if (condition) \ - break; \ - if((signed)(end - jiffies) <= 0) { \ - ret = -EBUSY; \ - break; \ - } \ +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +do { \ + DECLARE_WAITQUEUE(entry, current); \ + unsigned long end = jiffies + (timeout); \ + add_wait_queue(&(queue), &entry); \ + \ + for (;;) { \ + current->state = TASK_INTERRUPTIBLE; \ + if (condition) \ + break; \ + if((signed)(end - jiffies) <= 0) { \ + ret = -EBUSY; \ + break; \ + } \ schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \ - if (signal_pending(current)) { \ - ret = -EINTR; \ - break; \ - } \ - } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&(queue), &entry); \ + if (signal_pending(current)) { \ + ret = -EINTR; \ + break; \ + } \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&(queue), &entry); \ } while (0) diff --git a/linux/drmP.h b/linux/drmP.h index 01045037..17262609 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -166,6 +166,12 @@ #define pte_unmap(pte) #endif +#ifndef list_for_each_safe +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) static inline struct page * vmalloc_to_page(void * vmalloc_addr) { diff --git a/linux/drm_os_linux.h b/linux/drm_os_linux.h index e9b24356..a9ad02af 100644 --- a/linux/drm_os_linux.h +++ b/linux/drm_os_linux.h @@ -60,28 +60,28 @@ do { \ #define DRM_HZ HZ -#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ -do { \ - DECLARE_WAITQUEUE(entry, current); \ - unsigned long end = jiffies + (timeout); \ - add_wait_queue(&(queue), &entry); \ - \ - for (;;) { \ - current->state = TASK_INTERRUPTIBLE; \ - if (condition) \ - break; \ - if((signed)(end - jiffies) <= 0) { \ - ret = -EBUSY; \ - break; \ - } \ +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +do { \ + DECLARE_WAITQUEUE(entry, current); \ + unsigned long end = jiffies + (timeout); \ + add_wait_queue(&(queue), &entry); \ + \ + for (;;) { \ + current->state = TASK_INTERRUPTIBLE; \ + if (condition) \ + break; \ + if((signed)(end - jiffies) <= 0) { \ + ret = -EBUSY; \ + break; \ + } \ schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \ - if (signal_pending(current)) { \ - ret = -EINTR; \ - break; \ - } \ - } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&(queue), &entry); \ + if (signal_pending(current)) { \ + ret = -EINTR; \ + break; \ + } \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&(queue), &entry); \ } while (0) diff --git a/shared-core/mach64_dma.c b/shared-core/mach64_dma.c index 0d1ffb35..39ac7897 100644 --- a/shared-core/mach64_dma.c +++ b/shared-core/mach64_dma.c @@ -36,7 +36,6 @@ #include "mach64_drm.h" #include "mach64_drv.h" -#include <linux/interrupt.h> /* For task queue support */ #if MACH64_INTERRUPTS @@ -138,11 +137,11 @@ int mach64_do_wait_for_fifo( drm_mach64_private_t *dev_priv, int entries ) slots = (MACH64_READ( MACH64_FIFO_STAT ) & MACH64_FIFO_SLOT_MASK); if ( slots <= (0x8000 >> entries) ) return 0; - udelay( 1 ); + DRM_UDELAY( 1 ); } DRM_INFO( "%s failed! slots=%d entries=%d\n", __FUNCTION__, slots, entries ); - return -EBUSY; + return DRM_ERR(EBUSY); } int mach64_do_wait_for_idle( drm_mach64_private_t *dev_priv ) @@ -156,13 +155,13 @@ int mach64_do_wait_for_idle( drm_mach64_private_t *dev_priv ) if ( !(MACH64_READ( MACH64_GUI_STAT ) & MACH64_GUI_ACTIVE) ) { return 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } DRM_INFO( "%s failed! GUI_STAT=0x%08x\n", __FUNCTION__, MACH64_READ( MACH64_GUI_STAT ) ); mach64_dump_ring_info( dev_priv ); - return -EBUSY; + return DRM_ERR(EBUSY); } int mach64_wait_ring( drm_mach64_private_t *dev_priv, int n ) @@ -178,13 +177,13 @@ int mach64_wait_ring( drm_mach64_private_t *dev_priv, int n ) } return 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } /* FIXME: This is being ignored... */ DRM_ERROR( "failed!\n" ); mach64_dump_ring_info( dev_priv ); - return -EBUSY; + return DRM_ERR(EBUSY); } /* Wait until all DMA requests have been processed... */ @@ -211,13 +210,13 @@ static int mach64_ring_idle( drm_mach64_private_t *dev_priv ) head = ring->head; i = 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } DRM_INFO( "%s failed! GUI_STAT=0x%08x\n", __FUNCTION__, MACH64_READ( MACH64_GUI_STAT ) ); mach64_dump_ring_info( dev_priv ); - return -EBUSY; + return DRM_ERR(EBUSY); } static void mach64_ring_reset( drm_mach64_private_t *dev_priv ) @@ -537,7 +536,7 @@ static int mach64_bm_dma_test( drm_device_t *dev ) cpu_addr_data = pci_alloc_consistent( dev->pdev, 0x1000, &data_handle ); if (!cpu_addr_data || !data_handle) { DRM_INFO( "data-memory allocation failed!\n" ); - return -ENOMEM; + return DRM_ERR(ENOMEM); } else { data = (u32 *) cpu_addr_data; data_addr = (u32) data_handle; @@ -570,8 +569,7 @@ static int mach64_bm_dma_test( drm_device_t *dev ) DRM_INFO( "freeing data buffer memory.\n" ); pci_free_consistent( dev->pdev, 0x1000, cpu_addr_data, data_handle ); - DRM_INFO( "returning ...\n" ); - return -EIO; + return DRM_ERR(EIO); } } @@ -612,7 +610,7 @@ static int mach64_bm_dma_test( drm_device_t *dev ) DRM_DEBUG( " data[%d] = 0x%08x\n", i, data[i] ); } - mach64_flush_write_combine(); + DRM_READMEMORYBARRIER(); DRM_DEBUG( "waiting for idle...\n" ); if ( ( i = mach64_do_wait_for_idle( dev_priv ) ) ) { @@ -625,7 +623,6 @@ static int mach64_bm_dma_test( drm_device_t *dev ) MACH64_WRITE( MACH64_PAT_REG1, pat_reg1 ); DRM_INFO( "freeing data buffer memory.\n" ); pci_free_consistent( dev->pdev, 0x1000, cpu_addr_data, data_handle ); - DRM_INFO( "returning ...\n" ); return i; } DRM_DEBUG( "waiting for idle...done\n" ); @@ -636,7 +633,7 @@ static int mach64_bm_dma_test( drm_device_t *dev ) DRM_DEBUG( "data bus addr = 0x%08x\n", data_addr ); DRM_DEBUG( "table bus addr = 0x%08x\n", dev_priv->ring.start_addr ); - DRM_INFO( "starting DMA transfer...\n" ); + DRM_DEBUG( "starting DMA transfer...\n" ); MACH64_WRITE( MACH64_BM_GUI_TABLE_CMD, dev_priv->ring.start_addr | MACH64_CIRCULAR_BUF_SIZE_16KB ); @@ -649,7 +646,7 @@ static int mach64_bm_dma_test( drm_device_t *dev ) DRM_DEBUG( "starting DMA transfer... done.\n" ); MACH64_WRITE( MACH64_DST_HEIGHT_WIDTH, 0 ); - DRM_INFO( "waiting for idle...\n" ); + DRM_DEBUG( "waiting for idle...\n" ); if ( ( i = mach64_do_wait_for_idle( dev_priv ) ) ) { /* engine locked up, dump register state and reset */ @@ -663,11 +660,10 @@ static int mach64_bm_dma_test( drm_device_t *dev ) MACH64_WRITE( MACH64_PAT_REG1, pat_reg1 ); DRM_INFO( "freeing data buffer memory.\n" ); pci_free_consistent( dev->pdev, 0x1000, cpu_addr_data, data_handle ); - DRM_INFO( "returning ...\n" ); return i; } - DRM_INFO( "waiting for idle...done\n" ); + DRM_DEBUG( "waiting for idle...done\n" ); /* restore SRC_CNTL */ mach64_do_wait_for_fifo( dev_priv, 1 ); @@ -701,7 +697,6 @@ static int mach64_bm_dma_test( drm_device_t *dev ) static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) { drm_mach64_private_t *dev_priv; - struct list_head *list; u32 tmp; int i, ret; @@ -709,7 +704,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) dev_priv = DRM(alloc)( sizeof(drm_mach64_private_t), DRM_MEM_DRIVER ); if ( dev_priv == NULL ) - return -ENOMEM; + return DRM_ERR(ENOMEM); memset( dev_priv, 0, sizeof(drm_mach64_private_t) ); @@ -747,34 +742,27 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) atomic_set(&dev_priv->intr_bm_complete, 0); #endif - list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; - if( r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK ) { - dev_priv->sarea = r_list->map; - break; - } - } + DRM_GETSAREA(); + if (!dev_priv->sarea) { DRM_ERROR("can not find sarea!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); if (!dev_priv->fb) { DRM_ERROR("can not find frame buffer map!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); if (!dev_priv->mmio) { DRM_ERROR("can not find mmio map!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } dev_priv->sarea_priv = (drm_mach64_sarea_t *) @@ -787,7 +775,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) DRM_ERROR( "can not find dma buffer map!\n" ); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_IOREMAP( dev_priv->buffers ); if ( !dev_priv->buffers->handle ) { @@ -795,7 +783,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) " dma buffer\n" ); dev->dev_private = (void *) dev_priv; mach64_do_cleanup_dma( dev ); - return -ENOMEM; + return DRM_ERR(ENOMEM); } DRM_FIND_MAP( dev_priv->agp_textures, init->agp_textures_offset ); @@ -803,7 +791,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) DRM_ERROR("could not find agp texture region!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } } @@ -832,7 +820,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) } /* check DMA addressing limitations */ - DRM_INFO( "Setting 32-bit pci dma mask\n" ); + DRM_DEBUG( "Setting 32-bit pci dma mask\n" ); if ((ret=pci_set_dma_mask( dev->pdev, 0xffffffff ))) { DRM_ERROR( "Setting 32-bit pci dma mask failed\n" ); mach64_do_cleanup_dma( dev ); @@ -840,14 +828,14 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) } /* allocate descriptor memory from pci pool */ - DRM_INFO( "Allocating dma descriptor ring\n" ); + DRM_DEBUG( "Allocating dma descriptor ring\n" ); dev_priv->ring.size = 0x4000; /* 16KB */ dev_priv->ring.start = pci_alloc_consistent( dev->pdev, dev_priv->ring.size, &dev_priv->ring.handle ); if (!dev_priv->ring.start || !dev_priv->ring.handle) { DRM_ERROR( "Allocating dma descriptor ring failed\n"); - return -ENOMEM; + return DRM_ERR(ENOMEM); } else { dev_priv->ring.start_addr = (u32) dev_priv->ring.handle; memset( dev_priv->ring.start, 0x0, 0x4000 ); @@ -865,7 +853,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) & ~MACH64_BUS_MASTER_DIS ) ); /* try a DMA GUI-mastering pass and fall back to MMIO if it fails */ - DRM_INFO( "Starting DMA test...\n"); + DRM_DEBUG( "Starting DMA test...\n"); if ( (ret=mach64_bm_dma_test( dev )) ) { dev_priv->driver_mode = MACH64_MODE_MMIO; } @@ -984,7 +972,7 @@ int mach64_do_dispatch_pseudo_dma( drm_mach64_private_t *dev_priv ) head, ring->tail, buf_addr, (eol ? "eol" : "")); mach64_dump_ring_info( dev_priv ); mach64_do_engine_reset( dev_priv ); - return -EINVAL; + return DRM_ERR(EINVAL); } /* Hand feed the buffer to the card via MMIO, waiting for the fifo @@ -1065,7 +1053,7 @@ int mach64_do_cleanup_dma( drm_device_t *dev ) /* Discard the allocations for the descriptor table... */ if ( (dev->pdev != NULL) && (dev_priv->ring.start != NULL) && dev_priv->ring.handle ) { - DRM_INFO( "freeing dma descriptor ring\n" ); + DRM_DEBUG( "freeing dma descriptor ring\n" ); pci_free_consistent( dev->pdev, dev_priv->ring.size, dev_priv->ring.start, dev_priv->ring.handle ); } @@ -1074,7 +1062,7 @@ int mach64_do_cleanup_dma( drm_device_t *dev ) DRM_IOREMAPFREE( dev_priv->buffers ); } - DRM_INFO( "destroying dma buffer freelist\n" ); + DRM_DEBUG( "destroying dma buffer freelist\n" ); mach64_destroy_freelist( dev ); DRM(free)( dev_priv, sizeof(drm_mach64_private_t), @@ -1106,7 +1094,7 @@ int mach64_dma_init( DRM_IOCTL_ARGS ) return mach64_do_cleanup_dma( dev ); } - return -EINVAL; + return DRM_ERR(EINVAL); } int mach64_dma_idle( DRM_IOCTL_ARGS ) @@ -1164,7 +1152,7 @@ int mach64_init_freelist( drm_device_t *dev ) if ((entry = (drm_mach64_freelist_t *) DRM(alloc)(sizeof(drm_mach64_freelist_t), DRM_MEM_BUFLISTS)) == NULL) - return -ENOMEM; + return DRM_ERR(ENOMEM); memset( entry, 0, sizeof(drm_mach64_freelist_t) ); entry->buf = dma->buflist[i]; ptr = &entry->list; @@ -1311,7 +1299,7 @@ drm_buf_t *mach64_freelist_get( drm_mach64_private_t *dev_priv ) return entry->buf; } } - udelay( 1 ); + DRM_UDELAY( 1 ); } mach64_dump_ring_info( dev_priv ); DRM_ERROR( "timeout waiting for buffers: ring head_addr: 0x%08x head: %d tail: %d\n", ring->head_addr, ring->head, ring->tail ); @@ -1340,19 +1328,19 @@ static int mach64_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) for ( i = d->granted_count ; i < d->request_count ; i++ ) { buf = mach64_freelist_get( dev_priv ); #if MACH64_EXTRA_CHECKING - if ( !buf ) return -EFAULT; + if ( !buf ) return DRM_ERR(EFAULT); #else - if ( !buf ) return -EAGAIN; + if ( !buf ) return DRM_ERR(EAGAIN); #endif - buf->pid = current->pid; + buf->pid = DRM_CURRENTPID; - if ( copy_to_user( &d->request_indices[i], &buf->idx, + if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) - return -EFAULT; - if ( copy_to_user( &d->request_sizes[i], &buf->total, + return DRM_ERR(EFAULT); + if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, sizeof(buf->total) ) ) - return -EFAULT; + return DRM_ERR(EFAULT); d->granted_count++; } @@ -1375,8 +1363,8 @@ int mach64_dma_buffers( DRM_IOCTL_ARGS ) if ( d.send_count != 0 ) { DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", - current->pid, d.send_count ); - return -EINVAL; + DRM_CURRENTPID, d.send_count ); + return DRM_ERR(EINVAL); } /* We'll send you buffers. @@ -1384,8 +1372,8 @@ int mach64_dma_buffers( DRM_IOCTL_ARGS ) if ( d.request_count < 0 || d.request_count > dma->buf_count ) { DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", - current->pid, d.request_count, dma->buf_count ); - ret = -EINVAL; + DRM_CURRENTPID, d.request_count, dma->buf_count ); + ret = DRM_ERR(EINVAL); } d.granted_count = 0; diff --git a/shared-core/mach64_drv.h b/shared-core/mach64_drv.h index 1e52e5c3..9aa55739 100644 --- a/shared-core/mach64_drv.h +++ b/shared-core/mach64_drv.h @@ -33,15 +33,6 @@ #ifndef __MACH64_DRV_H__ #define __MACH64_DRV_H__ -#include <linux/delay.h> -#include <linux/list.h> - -/* Some early 2.4.x kernels need this */ -#ifndef list_for_each_safe -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) -#endif /* FIXME: remove these when not needed */ /* Development driver options */ @@ -586,10 +577,10 @@ mach64_update_ring_snapshot( drm_mach64_private_t *dev_priv ) #define LOCK_TEST_WITH_RETURN( dev ) \ do { \ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != current->pid ) { \ + dev->lock.pid != DRM_CURRENTPID ) { \ DRM_ERROR( "%s called without lock held\n", \ __FUNCTION__ ); \ - return -EINVAL; \ + return DRM_ERR(EINVAL); \ } \ } while (0) @@ -605,12 +596,12 @@ do { \ mach64_update_ring_snapshot( dev_priv ); \ if ( ring->space >= ring->high_mark ) \ goto __ring_space_done; \ - udelay( 1 ); \ + DRM_UDELAY( 1 ); \ } \ DRM_ERROR( "ring space check failed!\n" ); \ DRM_INFO( "ring: head addr: 0x%08x head: %d tail: %d space: %d\n", \ ring->head_addr, ring->head, ring->tail, ring->space ); \ - return -EBUSY; \ + return DRM_ERR(EBUSY); \ } \ __ring_space_done: \ } while (0) @@ -639,8 +630,6 @@ do { \ * DMA descriptor ring macros */ -#define mach64_flush_write_combine() mb() - #define RING_LOCALS \ int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring @@ -729,9 +718,9 @@ do { \ DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ _ring_write, _ring_tail ); \ } \ - mach64_flush_write_combine(); \ + DRM_READMEMORYBARRIER(); \ mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] ); \ - mach64_flush_write_combine(); \ + DRM_READMEMORYBARRIER(); \ dev_priv->ring.tail = _ring_write; \ mach64_ring_tick( dev_priv, &(dev_priv)->ring ); \ } while (0) @@ -766,14 +755,14 @@ static inline int mach64_find_pending_buf_entry ( drm_mach64_private_t *dev_priv #if MACH64_EXTRA_CHECKING if (list_empty(&dev_priv->pending)) { DRM_ERROR("Empty pending list in %s\n", __FUNCTION__); - return -EINVAL; + return DRM_ERR(EINVAL); } #endif ptr = dev_priv->pending.prev; *entry = list_entry(ptr, drm_mach64_freelist_t, list); while ((*entry)->buf != buf) { if (ptr == &dev_priv->pending) { - return -EFAULT; + return DRM_ERR(EFAULT); } ptr = ptr->prev; *entry = list_entry(ptr, drm_mach64_freelist_t, list); @@ -799,14 +788,14 @@ do { \ if (_buf == NULL) { \ DRM_ERROR("%s: couldn't get buffer in DMAGETPTR\n", \ __FUNCTION__ ); \ - return -EAGAIN; \ + return DRM_ERR(EAGAIN); \ } \ if (_buf->pending) { \ DRM_ERROR("%s: pending buf in DMAGETPTR\n", \ __FUNCTION__ ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ - _buf->pid = current->pid; \ + _buf->pid = DRM_CURRENTPID; \ _outcount = 0; \ \ _buf_wptr = GETBUFPTR( _buf ); \ @@ -835,7 +824,7 @@ do { \ if (_buf->used <= 0) { \ DRM_ERROR( "DMAADVANCE() in %s: sending empty buf %d\n", \ __FUNCTION__, _buf->idx ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ if (_buf->pending) { \ /* This is a resued buffer, so we need to find it in the pending list */ \ @@ -848,13 +837,13 @@ do { \ if (_entry->discard) { \ DRM_ERROR( "DMAADVANCE() in %s: sending discarded pending buf %d\n", \ __FUNCTION__, _buf->idx ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ } else { \ if (list_empty(&dev_priv->placeholders)) { \ DRM_ERROR( "DMAADVANCE() in %s: empty placeholder list\n", \ __FUNCTION__ ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ ptr = dev_priv->placeholders.next; \ list_del(ptr); \ @@ -930,12 +919,12 @@ do { \ if (_buf->used <= 0) { \ DRM_ERROR( "DMAADVANCEHOSTDATA() in %s: sending empty buf %d\n", \ __FUNCTION__, _buf->idx ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ if (list_empty(&dev_priv->placeholders)) { \ DRM_ERROR( "%s: empty placeholder list in DMAADVANCEHOSTDATA()\n", \ __FUNCTION__ ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ \ ptr = dev_priv->placeholders.next; \ diff --git a/shared-core/mach64_state.c b/shared-core/mach64_state.c index 5c070dd5..cad08cd8 100644 --- a/shared-core/mach64_state.c +++ b/shared-core/mach64_state.c @@ -34,7 +34,6 @@ #include "drm.h" #include "mach64_drm.h" #include "mach64_drv.h" -#include "drm.h" /* ================================================================ @@ -212,7 +211,7 @@ static int mach64_dma_dispatch_clear( drm_device_t *dev, fb_bpp = MACH64_DATATYPE_ARGB8888; break; default: - return -EINVAL; + return DRM_ERR(EINVAL); } switch ( dev_priv->depth_bpp ) { case 16: @@ -223,7 +222,7 @@ static int mach64_dma_dispatch_clear( drm_device_t *dev, depth_bpp = MACH64_DATATYPE_ARGB8888; break; default: - return -EINVAL; + return DRM_ERR(EINVAL); } if ( !nbox ) @@ -465,48 +464,63 @@ static int mach64_do_get_frames_queued( drm_mach64_private_t *dev_priv ) /* Copy and verify a client submited buffer. * FIXME: Make an assembly optimized version */ -static unsigned long copy_and_verify_from_user( u32 *to, const u32 *from, unsigned long n ) +static inline int copy_and_verify_from_user( u32 *to, const u32 *from, unsigned long bytes ) { - unsigned long copied = 0; + unsigned long n = bytes; /* dwords remaining in buffer */ - if ( access_ok( VERIFY_READ, from, n ) ) { - n >>= 2; - - while ( n ) { - u32 data, reg, count; + if ( DRM_VERIFYAREA_READ( from, n ) ) { + DRM_ERROR( "%s: verify_area\n", __FUNCTION__ ); + return DRM_ERR(EFAULT); + } - if ( __get_user( data, from++ ) ) - break; - n--; - - reg = le32_to_cpu(data); - count = (reg >> 16) + 1; - if( count <= n ) { - n -= count; - reg &= 0xffff; - - /* This is an exact match of Mach64's Setup Engine registers, - * excluding SETUP_CNTL (1_C1). - */ - if( (reg >= 0x0190 && reg < 0x01c1) || (reg >= 0x01ca && reg <= 0x01cf) ) { - *to++ = data; - __copy_from_user( to, from, count << 2 ); - to += count; - copied += 1 + count; - } else { - return 0; - } + n >>= 2; + + while ( n > 1 ) { + u32 data, reg, count; - from += count; + if ( DRM_GET_USER_UNCHECKED( data, from++ ) ) { + DRM_ERROR( "%s: get_user\n", __FUNCTION__ ); + return DRM_ERR(EFAULT); + } + + n--; + + reg = le32_to_cpu(data); + count = (reg >> 16) + 1; + if( count <= n ) { + n -= count; + reg &= 0xffff; + + /* This is an exact match of Mach64's Setup Engine registers, + * excluding SETUP_CNTL (1_C1). + */ + if( (reg >= 0x0190 && reg < 0x01c1) || + (reg >= 0x01ca && reg <= 0x01cf) ) { + *to++ = data; + if ( DRM_COPY_FROM_USER_UNCHECKED( to, from, count << 2 ) ) { + DRM_ERROR( "%s: copy_from_user\n", __FUNCTION__ ); + return DRM_ERR(EFAULT); + } + to += count; } else { - return 0; + DRM_ERROR( "%s: Got bad command: 0x%04x\n", __FUNCTION__, reg ); + return DRM_ERR(EACCES); } - } - copied <<= 2; + from += count; + } else { + DRM_ERROR( "%s: Got bad command count(=%u) dwords remaining=%lu\n", + __FUNCTION__, count, n ); + return DRM_ERR(EINVAL); + } } - return copied; + if (n == 0) + return 0; + else { + DRM_ERROR( "%s: Bad buf->used(=%lu)\n", __FUNCTION__, bytes ); + return DRM_ERR(EINVAL); + } } static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, @@ -516,7 +530,7 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_buf_t *copy_buf; int done = 0; - int verify_failed = 0; + int verify_ret = 0; DMALOCALS; DRM_DEBUG( "%s: buf=%p used=%lu nbox=%d\n", @@ -530,12 +544,13 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, if (copy_buf == NULL) { DRM_ERROR("%s: couldn't get buffer in DMAGETPTR\n", __FUNCTION__ ); - return -EAGAIN; + return DRM_ERR(EAGAIN); } - if ((copy_buf->used = copy_and_verify_from_user( GETBUFPTR( copy_buf ), buf, used )) == 0) { - verify_failed = 1; - } else { + if ( (verify_ret = copy_and_verify_from_user( GETBUFPTR( copy_buf ), buf, used )) == 0 ) { + + copy_buf->used = used; + DMASETPTR( copy_buf ); if ( sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS ) { @@ -578,7 +593,7 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, if (copy_buf == entry->buf) { DRM_ERROR( "%s: Trying to release a pending buf\n", __FUNCTION__ ); - return -EFAULT; + return DRM_ERR(EFAULT); } } #endif @@ -596,12 +611,7 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, sarea_priv->dirty &= ~MACH64_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0; - if (verify_failed) { - DRM_ERROR( "%s: Vertex buffer verification failed\n", __FUNCTION__ ); - return -EINVAL; - } else { - return 0; - } + return verify_ret; } @@ -633,22 +643,22 @@ static int mach64_dma_dispatch_blit( drm_device_t *dev, break; default: DRM_ERROR( "invalid blit format %d\n", blit->format ); - return -EINVAL; + return DRM_ERR(EINVAL); } /* Dispatch the blit buffer. */ buf = dma->buflist[blit->idx]; - if ( buf->pid != current->pid ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } if ( buf->pending ) { DRM_ERROR( "sending pending buffer %d\n", blit->idx ); - return -EINVAL; + return DRM_ERR(EINVAL); } /* Set buf->used to the bytes of blit data based on the blit dimensions @@ -661,7 +671,7 @@ static int mach64_dma_dispatch_blit( drm_device_t *dev, if ( buf->used <= 0 || buf->used > MACH64_BUFFER_SIZE - MACH64_HOSTDATA_BLIT_OFFSET ) { DRM_ERROR( "Invalid blit size: %d bytes\n", buf->used ); - return -EINVAL; + return DRM_ERR(EINVAL); } /* FIXME: Use a last buffer flag and reduce the state emitted for subsequent, @@ -726,7 +736,7 @@ int mach64_dma_clear( DRM_IOCTL_ARGS ) drm_mach64_clear_t clear; int ret; - DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, current->pid ); + DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID ); LOCK_TEST_WITH_RETURN( dev ); @@ -756,7 +766,7 @@ int mach64_dma_swap( DRM_IOCTL_ARGS ) drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; int ret; - DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, current->pid ); + DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID ); LOCK_TEST_WITH_RETURN( dev ); @@ -785,25 +795,25 @@ int mach64_dma_vertex( DRM_IOCTL_ARGS ) if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_COPY_FROM_USER_IOCTL( vertex, (drm_mach64_vertex_t *)data, sizeof(vertex) ); DRM_DEBUG( "%s: pid=%d buf=%p used=%lu discard=%d\n", - __FUNCTION__, current->pid, + __FUNCTION__, DRM_CURRENTPID, vertex.buf, vertex.used, vertex.discard ); if ( vertex.prim < 0 || vertex.prim > MACH64_PRIM_POLYGON ) { DRM_ERROR( "buffer prim %d\n", vertex.prim ); - return -EINVAL; + return DRM_ERR(EINVAL); } - if ( vertex.used > MACH64_BUFFER_SIZE ) { + if ( vertex.used > MACH64_BUFFER_SIZE || (vertex.used & 3) != 0) { DRM_ERROR( "Invalid vertex buffer size: %lu bytes\n", vertex.used ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -830,12 +840,12 @@ int mach64_dma_blit( DRM_IOCTL_ARGS ) sizeof(blit) ); DRM_DEBUG( "%s: pid=%d index=%d\n", - __FUNCTION__, current->pid, blit.idx ); + __FUNCTION__, DRM_CURRENTPID, blit.idx ); if ( blit.idx < 0 || blit.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", blit.idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -870,11 +880,13 @@ int mach64_get_param( DRM_IOCTL_ARGS ) value = mach64_do_get_frames_queued( dev_priv ); break; default: - return -EINVAL; + return DRM_ERR(EINVAL); } - if ( copy_to_user( param.value, &value, sizeof(int) ) ) - return -EFAULT; + if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return DRM_ERR(EFAULT); + } return 0; } diff --git a/shared/mach64_dma.c b/shared/mach64_dma.c index 0d1ffb35..39ac7897 100644 --- a/shared/mach64_dma.c +++ b/shared/mach64_dma.c @@ -36,7 +36,6 @@ #include "mach64_drm.h" #include "mach64_drv.h" -#include <linux/interrupt.h> /* For task queue support */ #if MACH64_INTERRUPTS @@ -138,11 +137,11 @@ int mach64_do_wait_for_fifo( drm_mach64_private_t *dev_priv, int entries ) slots = (MACH64_READ( MACH64_FIFO_STAT ) & MACH64_FIFO_SLOT_MASK); if ( slots <= (0x8000 >> entries) ) return 0; - udelay( 1 ); + DRM_UDELAY( 1 ); } DRM_INFO( "%s failed! slots=%d entries=%d\n", __FUNCTION__, slots, entries ); - return -EBUSY; + return DRM_ERR(EBUSY); } int mach64_do_wait_for_idle( drm_mach64_private_t *dev_priv ) @@ -156,13 +155,13 @@ int mach64_do_wait_for_idle( drm_mach64_private_t *dev_priv ) if ( !(MACH64_READ( MACH64_GUI_STAT ) & MACH64_GUI_ACTIVE) ) { return 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } DRM_INFO( "%s failed! GUI_STAT=0x%08x\n", __FUNCTION__, MACH64_READ( MACH64_GUI_STAT ) ); mach64_dump_ring_info( dev_priv ); - return -EBUSY; + return DRM_ERR(EBUSY); } int mach64_wait_ring( drm_mach64_private_t *dev_priv, int n ) @@ -178,13 +177,13 @@ int mach64_wait_ring( drm_mach64_private_t *dev_priv, int n ) } return 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } /* FIXME: This is being ignored... */ DRM_ERROR( "failed!\n" ); mach64_dump_ring_info( dev_priv ); - return -EBUSY; + return DRM_ERR(EBUSY); } /* Wait until all DMA requests have been processed... */ @@ -211,13 +210,13 @@ static int mach64_ring_idle( drm_mach64_private_t *dev_priv ) head = ring->head; i = 0; } - udelay( 1 ); + DRM_UDELAY( 1 ); } DRM_INFO( "%s failed! GUI_STAT=0x%08x\n", __FUNCTION__, MACH64_READ( MACH64_GUI_STAT ) ); mach64_dump_ring_info( dev_priv ); - return -EBUSY; + return DRM_ERR(EBUSY); } static void mach64_ring_reset( drm_mach64_private_t *dev_priv ) @@ -537,7 +536,7 @@ static int mach64_bm_dma_test( drm_device_t *dev ) cpu_addr_data = pci_alloc_consistent( dev->pdev, 0x1000, &data_handle ); if (!cpu_addr_data || !data_handle) { DRM_INFO( "data-memory allocation failed!\n" ); - return -ENOMEM; + return DRM_ERR(ENOMEM); } else { data = (u32 *) cpu_addr_data; data_addr = (u32) data_handle; @@ -570,8 +569,7 @@ static int mach64_bm_dma_test( drm_device_t *dev ) DRM_INFO( "freeing data buffer memory.\n" ); pci_free_consistent( dev->pdev, 0x1000, cpu_addr_data, data_handle ); - DRM_INFO( "returning ...\n" ); - return -EIO; + return DRM_ERR(EIO); } } @@ -612,7 +610,7 @@ static int mach64_bm_dma_test( drm_device_t *dev ) DRM_DEBUG( " data[%d] = 0x%08x\n", i, data[i] ); } - mach64_flush_write_combine(); + DRM_READMEMORYBARRIER(); DRM_DEBUG( "waiting for idle...\n" ); if ( ( i = mach64_do_wait_for_idle( dev_priv ) ) ) { @@ -625,7 +623,6 @@ static int mach64_bm_dma_test( drm_device_t *dev ) MACH64_WRITE( MACH64_PAT_REG1, pat_reg1 ); DRM_INFO( "freeing data buffer memory.\n" ); pci_free_consistent( dev->pdev, 0x1000, cpu_addr_data, data_handle ); - DRM_INFO( "returning ...\n" ); return i; } DRM_DEBUG( "waiting for idle...done\n" ); @@ -636,7 +633,7 @@ static int mach64_bm_dma_test( drm_device_t *dev ) DRM_DEBUG( "data bus addr = 0x%08x\n", data_addr ); DRM_DEBUG( "table bus addr = 0x%08x\n", dev_priv->ring.start_addr ); - DRM_INFO( "starting DMA transfer...\n" ); + DRM_DEBUG( "starting DMA transfer...\n" ); MACH64_WRITE( MACH64_BM_GUI_TABLE_CMD, dev_priv->ring.start_addr | MACH64_CIRCULAR_BUF_SIZE_16KB ); @@ -649,7 +646,7 @@ static int mach64_bm_dma_test( drm_device_t *dev ) DRM_DEBUG( "starting DMA transfer... done.\n" ); MACH64_WRITE( MACH64_DST_HEIGHT_WIDTH, 0 ); - DRM_INFO( "waiting for idle...\n" ); + DRM_DEBUG( "waiting for idle...\n" ); if ( ( i = mach64_do_wait_for_idle( dev_priv ) ) ) { /* engine locked up, dump register state and reset */ @@ -663,11 +660,10 @@ static int mach64_bm_dma_test( drm_device_t *dev ) MACH64_WRITE( MACH64_PAT_REG1, pat_reg1 ); DRM_INFO( "freeing data buffer memory.\n" ); pci_free_consistent( dev->pdev, 0x1000, cpu_addr_data, data_handle ); - DRM_INFO( "returning ...\n" ); return i; } - DRM_INFO( "waiting for idle...done\n" ); + DRM_DEBUG( "waiting for idle...done\n" ); /* restore SRC_CNTL */ mach64_do_wait_for_fifo( dev_priv, 1 ); @@ -701,7 +697,6 @@ static int mach64_bm_dma_test( drm_device_t *dev ) static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) { drm_mach64_private_t *dev_priv; - struct list_head *list; u32 tmp; int i, ret; @@ -709,7 +704,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) dev_priv = DRM(alloc)( sizeof(drm_mach64_private_t), DRM_MEM_DRIVER ); if ( dev_priv == NULL ) - return -ENOMEM; + return DRM_ERR(ENOMEM); memset( dev_priv, 0, sizeof(drm_mach64_private_t) ); @@ -747,34 +742,27 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) atomic_set(&dev_priv->intr_bm_complete, 0); #endif - list_for_each(list, &dev->maplist->head) { - drm_map_list_t *r_list = (drm_map_list_t *)list; - if( r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK ) { - dev_priv->sarea = r_list->map; - break; - } - } + DRM_GETSAREA(); + if (!dev_priv->sarea) { DRM_ERROR("can not find sarea!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); if (!dev_priv->fb) { DRM_ERROR("can not find frame buffer map!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); if (!dev_priv->mmio) { DRM_ERROR("can not find mmio map!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return -EINVAL; + return DRM_ERR(EINVAL); } dev_priv->sarea_priv = (drm_mach64_sarea_t *) @@ -787,7 +775,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) DRM_ERROR( "can not find dma buffer map!\n" ); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_IOREMAP( dev_priv->buffers ); if ( !dev_priv->buffers->handle ) { @@ -795,7 +783,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) " dma buffer\n" ); dev->dev_private = (void *) dev_priv; mach64_do_cleanup_dma( dev ); - return -ENOMEM; + return DRM_ERR(ENOMEM); } DRM_FIND_MAP( dev_priv->agp_textures, init->agp_textures_offset ); @@ -803,7 +791,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) DRM_ERROR("could not find agp texture region!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma( dev ); - return -EINVAL; + return DRM_ERR(EINVAL); } } @@ -832,7 +820,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) } /* check DMA addressing limitations */ - DRM_INFO( "Setting 32-bit pci dma mask\n" ); + DRM_DEBUG( "Setting 32-bit pci dma mask\n" ); if ((ret=pci_set_dma_mask( dev->pdev, 0xffffffff ))) { DRM_ERROR( "Setting 32-bit pci dma mask failed\n" ); mach64_do_cleanup_dma( dev ); @@ -840,14 +828,14 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) } /* allocate descriptor memory from pci pool */ - DRM_INFO( "Allocating dma descriptor ring\n" ); + DRM_DEBUG( "Allocating dma descriptor ring\n" ); dev_priv->ring.size = 0x4000; /* 16KB */ dev_priv->ring.start = pci_alloc_consistent( dev->pdev, dev_priv->ring.size, &dev_priv->ring.handle ); if (!dev_priv->ring.start || !dev_priv->ring.handle) { DRM_ERROR( "Allocating dma descriptor ring failed\n"); - return -ENOMEM; + return DRM_ERR(ENOMEM); } else { dev_priv->ring.start_addr = (u32) dev_priv->ring.handle; memset( dev_priv->ring.start, 0x0, 0x4000 ); @@ -865,7 +853,7 @@ static int mach64_do_dma_init( drm_device_t *dev, drm_mach64_init_t *init ) & ~MACH64_BUS_MASTER_DIS ) ); /* try a DMA GUI-mastering pass and fall back to MMIO if it fails */ - DRM_INFO( "Starting DMA test...\n"); + DRM_DEBUG( "Starting DMA test...\n"); if ( (ret=mach64_bm_dma_test( dev )) ) { dev_priv->driver_mode = MACH64_MODE_MMIO; } @@ -984,7 +972,7 @@ int mach64_do_dispatch_pseudo_dma( drm_mach64_private_t *dev_priv ) head, ring->tail, buf_addr, (eol ? "eol" : "")); mach64_dump_ring_info( dev_priv ); mach64_do_engine_reset( dev_priv ); - return -EINVAL; + return DRM_ERR(EINVAL); } /* Hand feed the buffer to the card via MMIO, waiting for the fifo @@ -1065,7 +1053,7 @@ int mach64_do_cleanup_dma( drm_device_t *dev ) /* Discard the allocations for the descriptor table... */ if ( (dev->pdev != NULL) && (dev_priv->ring.start != NULL) && dev_priv->ring.handle ) { - DRM_INFO( "freeing dma descriptor ring\n" ); + DRM_DEBUG( "freeing dma descriptor ring\n" ); pci_free_consistent( dev->pdev, dev_priv->ring.size, dev_priv->ring.start, dev_priv->ring.handle ); } @@ -1074,7 +1062,7 @@ int mach64_do_cleanup_dma( drm_device_t *dev ) DRM_IOREMAPFREE( dev_priv->buffers ); } - DRM_INFO( "destroying dma buffer freelist\n" ); + DRM_DEBUG( "destroying dma buffer freelist\n" ); mach64_destroy_freelist( dev ); DRM(free)( dev_priv, sizeof(drm_mach64_private_t), @@ -1106,7 +1094,7 @@ int mach64_dma_init( DRM_IOCTL_ARGS ) return mach64_do_cleanup_dma( dev ); } - return -EINVAL; + return DRM_ERR(EINVAL); } int mach64_dma_idle( DRM_IOCTL_ARGS ) @@ -1164,7 +1152,7 @@ int mach64_init_freelist( drm_device_t *dev ) if ((entry = (drm_mach64_freelist_t *) DRM(alloc)(sizeof(drm_mach64_freelist_t), DRM_MEM_BUFLISTS)) == NULL) - return -ENOMEM; + return DRM_ERR(ENOMEM); memset( entry, 0, sizeof(drm_mach64_freelist_t) ); entry->buf = dma->buflist[i]; ptr = &entry->list; @@ -1311,7 +1299,7 @@ drm_buf_t *mach64_freelist_get( drm_mach64_private_t *dev_priv ) return entry->buf; } } - udelay( 1 ); + DRM_UDELAY( 1 ); } mach64_dump_ring_info( dev_priv ); DRM_ERROR( "timeout waiting for buffers: ring head_addr: 0x%08x head: %d tail: %d\n", ring->head_addr, ring->head, ring->tail ); @@ -1340,19 +1328,19 @@ static int mach64_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) for ( i = d->granted_count ; i < d->request_count ; i++ ) { buf = mach64_freelist_get( dev_priv ); #if MACH64_EXTRA_CHECKING - if ( !buf ) return -EFAULT; + if ( !buf ) return DRM_ERR(EFAULT); #else - if ( !buf ) return -EAGAIN; + if ( !buf ) return DRM_ERR(EAGAIN); #endif - buf->pid = current->pid; + buf->pid = DRM_CURRENTPID; - if ( copy_to_user( &d->request_indices[i], &buf->idx, + if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) - return -EFAULT; - if ( copy_to_user( &d->request_sizes[i], &buf->total, + return DRM_ERR(EFAULT); + if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, sizeof(buf->total) ) ) - return -EFAULT; + return DRM_ERR(EFAULT); d->granted_count++; } @@ -1375,8 +1363,8 @@ int mach64_dma_buffers( DRM_IOCTL_ARGS ) if ( d.send_count != 0 ) { DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", - current->pid, d.send_count ); - return -EINVAL; + DRM_CURRENTPID, d.send_count ); + return DRM_ERR(EINVAL); } /* We'll send you buffers. @@ -1384,8 +1372,8 @@ int mach64_dma_buffers( DRM_IOCTL_ARGS ) if ( d.request_count < 0 || d.request_count > dma->buf_count ) { DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", - current->pid, d.request_count, dma->buf_count ); - ret = -EINVAL; + DRM_CURRENTPID, d.request_count, dma->buf_count ); + ret = DRM_ERR(EINVAL); } d.granted_count = 0; diff --git a/shared/mach64_drv.h b/shared/mach64_drv.h index 1e52e5c3..9aa55739 100644 --- a/shared/mach64_drv.h +++ b/shared/mach64_drv.h @@ -33,15 +33,6 @@ #ifndef __MACH64_DRV_H__ #define __MACH64_DRV_H__ -#include <linux/delay.h> -#include <linux/list.h> - -/* Some early 2.4.x kernels need this */ -#ifndef list_for_each_safe -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) -#endif /* FIXME: remove these when not needed */ /* Development driver options */ @@ -586,10 +577,10 @@ mach64_update_ring_snapshot( drm_mach64_private_t *dev_priv ) #define LOCK_TEST_WITH_RETURN( dev ) \ do { \ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.pid != current->pid ) { \ + dev->lock.pid != DRM_CURRENTPID ) { \ DRM_ERROR( "%s called without lock held\n", \ __FUNCTION__ ); \ - return -EINVAL; \ + return DRM_ERR(EINVAL); \ } \ } while (0) @@ -605,12 +596,12 @@ do { \ mach64_update_ring_snapshot( dev_priv ); \ if ( ring->space >= ring->high_mark ) \ goto __ring_space_done; \ - udelay( 1 ); \ + DRM_UDELAY( 1 ); \ } \ DRM_ERROR( "ring space check failed!\n" ); \ DRM_INFO( "ring: head addr: 0x%08x head: %d tail: %d space: %d\n", \ ring->head_addr, ring->head, ring->tail, ring->space ); \ - return -EBUSY; \ + return DRM_ERR(EBUSY); \ } \ __ring_space_done: \ } while (0) @@ -639,8 +630,6 @@ do { \ * DMA descriptor ring macros */ -#define mach64_flush_write_combine() mb() - #define RING_LOCALS \ int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring @@ -729,9 +718,9 @@ do { \ DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ _ring_write, _ring_tail ); \ } \ - mach64_flush_write_combine(); \ + DRM_READMEMORYBARRIER(); \ mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] ); \ - mach64_flush_write_combine(); \ + DRM_READMEMORYBARRIER(); \ dev_priv->ring.tail = _ring_write; \ mach64_ring_tick( dev_priv, &(dev_priv)->ring ); \ } while (0) @@ -766,14 +755,14 @@ static inline int mach64_find_pending_buf_entry ( drm_mach64_private_t *dev_priv #if MACH64_EXTRA_CHECKING if (list_empty(&dev_priv->pending)) { DRM_ERROR("Empty pending list in %s\n", __FUNCTION__); - return -EINVAL; + return DRM_ERR(EINVAL); } #endif ptr = dev_priv->pending.prev; *entry = list_entry(ptr, drm_mach64_freelist_t, list); while ((*entry)->buf != buf) { if (ptr == &dev_priv->pending) { - return -EFAULT; + return DRM_ERR(EFAULT); } ptr = ptr->prev; *entry = list_entry(ptr, drm_mach64_freelist_t, list); @@ -799,14 +788,14 @@ do { \ if (_buf == NULL) { \ DRM_ERROR("%s: couldn't get buffer in DMAGETPTR\n", \ __FUNCTION__ ); \ - return -EAGAIN; \ + return DRM_ERR(EAGAIN); \ } \ if (_buf->pending) { \ DRM_ERROR("%s: pending buf in DMAGETPTR\n", \ __FUNCTION__ ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ - _buf->pid = current->pid; \ + _buf->pid = DRM_CURRENTPID; \ _outcount = 0; \ \ _buf_wptr = GETBUFPTR( _buf ); \ @@ -835,7 +824,7 @@ do { \ if (_buf->used <= 0) { \ DRM_ERROR( "DMAADVANCE() in %s: sending empty buf %d\n", \ __FUNCTION__, _buf->idx ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ if (_buf->pending) { \ /* This is a resued buffer, so we need to find it in the pending list */ \ @@ -848,13 +837,13 @@ do { \ if (_entry->discard) { \ DRM_ERROR( "DMAADVANCE() in %s: sending discarded pending buf %d\n", \ __FUNCTION__, _buf->idx ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ } else { \ if (list_empty(&dev_priv->placeholders)) { \ DRM_ERROR( "DMAADVANCE() in %s: empty placeholder list\n", \ __FUNCTION__ ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ ptr = dev_priv->placeholders.next; \ list_del(ptr); \ @@ -930,12 +919,12 @@ do { \ if (_buf->used <= 0) { \ DRM_ERROR( "DMAADVANCEHOSTDATA() in %s: sending empty buf %d\n", \ __FUNCTION__, _buf->idx ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ if (list_empty(&dev_priv->placeholders)) { \ DRM_ERROR( "%s: empty placeholder list in DMAADVANCEHOSTDATA()\n", \ __FUNCTION__ ); \ - return -EFAULT; \ + return DRM_ERR(EFAULT); \ } \ \ ptr = dev_priv->placeholders.next; \ diff --git a/shared/mach64_state.c b/shared/mach64_state.c index 5c070dd5..cad08cd8 100644 --- a/shared/mach64_state.c +++ b/shared/mach64_state.c @@ -34,7 +34,6 @@ #include "drm.h" #include "mach64_drm.h" #include "mach64_drv.h" -#include "drm.h" /* ================================================================ @@ -212,7 +211,7 @@ static int mach64_dma_dispatch_clear( drm_device_t *dev, fb_bpp = MACH64_DATATYPE_ARGB8888; break; default: - return -EINVAL; + return DRM_ERR(EINVAL); } switch ( dev_priv->depth_bpp ) { case 16: @@ -223,7 +222,7 @@ static int mach64_dma_dispatch_clear( drm_device_t *dev, depth_bpp = MACH64_DATATYPE_ARGB8888; break; default: - return -EINVAL; + return DRM_ERR(EINVAL); } if ( !nbox ) @@ -465,48 +464,63 @@ static int mach64_do_get_frames_queued( drm_mach64_private_t *dev_priv ) /* Copy and verify a client submited buffer. * FIXME: Make an assembly optimized version */ -static unsigned long copy_and_verify_from_user( u32 *to, const u32 *from, unsigned long n ) +static inline int copy_and_verify_from_user( u32 *to, const u32 *from, unsigned long bytes ) { - unsigned long copied = 0; + unsigned long n = bytes; /* dwords remaining in buffer */ - if ( access_ok( VERIFY_READ, from, n ) ) { - n >>= 2; - - while ( n ) { - u32 data, reg, count; + if ( DRM_VERIFYAREA_READ( from, n ) ) { + DRM_ERROR( "%s: verify_area\n", __FUNCTION__ ); + return DRM_ERR(EFAULT); + } - if ( __get_user( data, from++ ) ) - break; - n--; - - reg = le32_to_cpu(data); - count = (reg >> 16) + 1; - if( count <= n ) { - n -= count; - reg &= 0xffff; - - /* This is an exact match of Mach64's Setup Engine registers, - * excluding SETUP_CNTL (1_C1). - */ - if( (reg >= 0x0190 && reg < 0x01c1) || (reg >= 0x01ca && reg <= 0x01cf) ) { - *to++ = data; - __copy_from_user( to, from, count << 2 ); - to += count; - copied += 1 + count; - } else { - return 0; - } + n >>= 2; + + while ( n > 1 ) { + u32 data, reg, count; - from += count; + if ( DRM_GET_USER_UNCHECKED( data, from++ ) ) { + DRM_ERROR( "%s: get_user\n", __FUNCTION__ ); + return DRM_ERR(EFAULT); + } + + n--; + + reg = le32_to_cpu(data); + count = (reg >> 16) + 1; + if( count <= n ) { + n -= count; + reg &= 0xffff; + + /* This is an exact match of Mach64's Setup Engine registers, + * excluding SETUP_CNTL (1_C1). + */ + if( (reg >= 0x0190 && reg < 0x01c1) || + (reg >= 0x01ca && reg <= 0x01cf) ) { + *to++ = data; + if ( DRM_COPY_FROM_USER_UNCHECKED( to, from, count << 2 ) ) { + DRM_ERROR( "%s: copy_from_user\n", __FUNCTION__ ); + return DRM_ERR(EFAULT); + } + to += count; } else { - return 0; + DRM_ERROR( "%s: Got bad command: 0x%04x\n", __FUNCTION__, reg ); + return DRM_ERR(EACCES); } - } - copied <<= 2; + from += count; + } else { + DRM_ERROR( "%s: Got bad command count(=%u) dwords remaining=%lu\n", + __FUNCTION__, count, n ); + return DRM_ERR(EINVAL); + } } - return copied; + if (n == 0) + return 0; + else { + DRM_ERROR( "%s: Bad buf->used(=%lu)\n", __FUNCTION__, bytes ); + return DRM_ERR(EINVAL); + } } static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, @@ -516,7 +530,7 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_buf_t *copy_buf; int done = 0; - int verify_failed = 0; + int verify_ret = 0; DMALOCALS; DRM_DEBUG( "%s: buf=%p used=%lu nbox=%d\n", @@ -530,12 +544,13 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, if (copy_buf == NULL) { DRM_ERROR("%s: couldn't get buffer in DMAGETPTR\n", __FUNCTION__ ); - return -EAGAIN; + return DRM_ERR(EAGAIN); } - if ((copy_buf->used = copy_and_verify_from_user( GETBUFPTR( copy_buf ), buf, used )) == 0) { - verify_failed = 1; - } else { + if ( (verify_ret = copy_and_verify_from_user( GETBUFPTR( copy_buf ), buf, used )) == 0 ) { + + copy_buf->used = used; + DMASETPTR( copy_buf ); if ( sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS ) { @@ -578,7 +593,7 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, if (copy_buf == entry->buf) { DRM_ERROR( "%s: Trying to release a pending buf\n", __FUNCTION__ ); - return -EFAULT; + return DRM_ERR(EFAULT); } } #endif @@ -596,12 +611,7 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, int prim, void *buf, sarea_priv->dirty &= ~MACH64_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0; - if (verify_failed) { - DRM_ERROR( "%s: Vertex buffer verification failed\n", __FUNCTION__ ); - return -EINVAL; - } else { - return 0; - } + return verify_ret; } @@ -633,22 +643,22 @@ static int mach64_dma_dispatch_blit( drm_device_t *dev, break; default: DRM_ERROR( "invalid blit format %d\n", blit->format ); - return -EINVAL; + return DRM_ERR(EINVAL); } /* Dispatch the blit buffer. */ buf = dma->buflist[blit->idx]; - if ( buf->pid != current->pid ) { + if ( buf->pid != DRM_CURRENTPID ) { DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; + DRM_CURRENTPID, buf->pid ); + return DRM_ERR(EINVAL); } if ( buf->pending ) { DRM_ERROR( "sending pending buffer %d\n", blit->idx ); - return -EINVAL; + return DRM_ERR(EINVAL); } /* Set buf->used to the bytes of blit data based on the blit dimensions @@ -661,7 +671,7 @@ static int mach64_dma_dispatch_blit( drm_device_t *dev, if ( buf->used <= 0 || buf->used > MACH64_BUFFER_SIZE - MACH64_HOSTDATA_BLIT_OFFSET ) { DRM_ERROR( "Invalid blit size: %d bytes\n", buf->used ); - return -EINVAL; + return DRM_ERR(EINVAL); } /* FIXME: Use a last buffer flag and reduce the state emitted for subsequent, @@ -726,7 +736,7 @@ int mach64_dma_clear( DRM_IOCTL_ARGS ) drm_mach64_clear_t clear; int ret; - DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, current->pid ); + DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID ); LOCK_TEST_WITH_RETURN( dev ); @@ -756,7 +766,7 @@ int mach64_dma_swap( DRM_IOCTL_ARGS ) drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; int ret; - DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, current->pid ); + DRM_DEBUG( "%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID ); LOCK_TEST_WITH_RETURN( dev ); @@ -785,25 +795,25 @@ int mach64_dma_vertex( DRM_IOCTL_ARGS ) if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return -EINVAL; + return DRM_ERR(EINVAL); } DRM_COPY_FROM_USER_IOCTL( vertex, (drm_mach64_vertex_t *)data, sizeof(vertex) ); DRM_DEBUG( "%s: pid=%d buf=%p used=%lu discard=%d\n", - __FUNCTION__, current->pid, + __FUNCTION__, DRM_CURRENTPID, vertex.buf, vertex.used, vertex.discard ); if ( vertex.prim < 0 || vertex.prim > MACH64_PRIM_POLYGON ) { DRM_ERROR( "buffer prim %d\n", vertex.prim ); - return -EINVAL; + return DRM_ERR(EINVAL); } - if ( vertex.used > MACH64_BUFFER_SIZE ) { + if ( vertex.used > MACH64_BUFFER_SIZE || (vertex.used & 3) != 0) { DRM_ERROR( "Invalid vertex buffer size: %lu bytes\n", vertex.used ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -830,12 +840,12 @@ int mach64_dma_blit( DRM_IOCTL_ARGS ) sizeof(blit) ); DRM_DEBUG( "%s: pid=%d index=%d\n", - __FUNCTION__, current->pid, blit.idx ); + __FUNCTION__, DRM_CURRENTPID, blit.idx ); if ( blit.idx < 0 || blit.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", blit.idx, dma->buf_count - 1 ); - return -EINVAL; + return DRM_ERR(EINVAL); } RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -870,11 +880,13 @@ int mach64_get_param( DRM_IOCTL_ARGS ) value = mach64_do_get_frames_queued( dev_priv ); break; default: - return -EINVAL; + return DRM_ERR(EINVAL); } - if ( copy_to_user( param.value, &value, sizeof(int) ) ) - return -EFAULT; + if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) { + DRM_ERROR( "copy_to_user\n" ); + return DRM_ERR(EFAULT); + } return 0; } |