summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/r128_drv.c4
-rw-r--r--linux/Makefile.linux6
-rw-r--r--linux/bufs.c41
-rw-r--r--linux/r128_bufs.c10
-rw-r--r--linux/r128_cce.c58
-rw-r--r--linux/r128_drv.c4
-rw-r--r--linux/r128_drv.h11
-rw-r--r--linux/r128_pcigart.c73
-rw-r--r--linux/r128_state.c26
-rw-r--r--linux/scatter.c73
-rw-r--r--linux/vm.c33
11 files changed, 136 insertions, 203 deletions
diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c
index 977be8ea..ddc1103f 100644
--- a/linux-core/r128_drv.c
+++ b/linux-core/r128_drv.c
@@ -37,7 +37,7 @@
#define R128_NAME "r128"
#define R128_DESC "ATI Rage 128"
-#define R128_DATE "20010101"
+#define R128_DATE "20010123"
#define R128_MAJOR 2
#define R128_MINOR 1
#define R128_PATCHLEVEL 4
@@ -312,7 +312,7 @@ static int r128_takedown(drm_device_t *dev)
handled in the AGP/GART driver. */
break;
case _DRM_SCATTER_GATHER:
- if(dev->sg) {
+ if (dev->sg) {
drm_sg_cleanup(dev->sg);
dev->sg = NULL;
}
diff --git a/linux/Makefile.linux b/linux/Makefile.linux
index ecbe5aca..c312ba85 100644
--- a/linux/Makefile.linux
+++ b/linux/Makefile.linux
@@ -23,7 +23,7 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
-#
+#
#
# ***** NOTE NOTE NOTE NOTE NOTE *****
# To override the automatic Linux source tree determination, pass the
@@ -47,7 +47,7 @@
# **** End of SMP/MODVERSIONS detection
CC= gcc
-MODS= gamma.o tdfx.o
+MODS= gamma.o tdfx.o r128.o
LIBS= libdrm.a
DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
@@ -129,7 +129,7 @@ endif
ifeq ($(AGP),1)
MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE
DRMOBJS += agpsupport.o
-MODS += mga.o r128.o radeon.o
+MODS += mga.o radeon.o
ifeq ($(MACHINE),i386)
MODS += i810.o
endif
diff --git a/linux/bufs.c b/linux/bufs.c
index 127ef142..3d13d899 100644
--- a/linux/bufs.c
+++ b/linux/bufs.c
@@ -11,11 +11,11 @@
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -23,7 +23,7 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
- *
+ *
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
*
@@ -51,7 +51,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_map_t *map;
-
+
if (!(filp->f_mode & 3)) return -EACCES; /* Require read/write */
map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
@@ -89,7 +89,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
#endif
map->handle = drm_ioremap(map->offset, map->size);
break;
-
+
case _DRM_SHM:
map->handle = (void *)drm_alloc_pages(drm_order(map->size)
@@ -112,7 +112,10 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
break;
#endif
case _DRM_SCATTER_GATHER:
- if(!dev->sg) return -EINVAL;
+ if (!dev->sg) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EINVAL;
+ }
map->offset = map->offset + dev->sg->handle;
break;
default:
@@ -144,7 +147,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
&map->offset,
sizeof(map->offset)))
return -EFAULT;
- }
+ }
return 0;
}
@@ -179,7 +182,7 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
count = request.count;
order = drm_order(request.size);
size = 1 << order;
-
+
DRM_DEBUG("count = %d, size = %d (%d), order = %d, queue_count = %d\n",
request.count, request.size, size, order, dev->queue_count);
@@ -197,7 +200,7 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
}
atomic_inc(&dev->buf_alloc);
spin_unlock(&dev->count_lock);
-
+
down(&dev->struct_sem);
entry = &dma->bufs[order];
if (entry->buf_count) {
@@ -205,7 +208,7 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
atomic_dec(&dev->buf_alloc);
return -ENOMEM; /* May only call once for each order */
}
-
+
entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
DRM_MEM_BUFS);
if (!entry->buflist) {
@@ -289,12 +292,12 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
dma->seg_count += entry->seg_count;
dma->page_count += entry->seg_count << page_order;
dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
-
+
drm_freelist_create(&entry->freelist, entry->buf_count);
for (i = 0; i < entry->buf_count; i++) {
drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
}
-
+
up(&dev->struct_sem);
request.count = entry->buf_count;
@@ -304,7 +307,7 @@ int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
&request,
sizeof(request)))
return -EFAULT;
-
+
atomic_dec(&dev->buf_alloc);
return 0;
}
@@ -337,9 +340,9 @@ int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
if (dma->bufs[i].buf_count) ++count;
}
-
+
DRM_DEBUG("count = %d\n", count);
-
+
if (request.count >= count) {
for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
if (dma->bufs[i].buf_count) {
@@ -379,7 +382,7 @@ int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
&request,
sizeof(request)))
return -EFAULT;
-
+
return 0;
}
@@ -413,7 +416,7 @@ int drm_markbufs(struct inode *inode, struct file *filp, unsigned int cmd,
entry->freelist.low_mark = request.low_mark;
entry->freelist.high_mark = request.high_mark;
-
+
return 0;
}
@@ -454,7 +457,7 @@ int drm_freebufs(struct inode *inode, struct file *filp, unsigned int cmd,
}
drm_free_buffer(dev, buf);
}
-
+
return 0;
}
@@ -472,7 +475,7 @@ int drm_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
int i;
if (!dma) return -EINVAL;
-
+
DRM_DEBUG("\n");
spin_lock(&dev->count_lock);
diff --git a/linux/r128_bufs.c b/linux/r128_bufs.c
index 2730e07b..4d5004fa 100644
--- a/linux/r128_bufs.c
+++ b/linux/r128_bufs.c
@@ -351,16 +351,16 @@ int r128_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
return -EINVAL;
if (!dev_priv->is_pci && (request.flags & _DRM_SG_BUFFER))
return -EINVAL;
- if (request.flags & _DRM_AGP_BUFFER)
+
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+ if (request.flags & _DRM_AGP_BUFFER)
return r128_addbufs_agp(inode, filp, cmd, arg);
-#else
- printk("WARNING: trying to use AGP without kernel support!\n");
#endif
- if (request.flags & _DRM_SG_BUFFER)
+ if (request.flags & _DRM_SG_BUFFER) {
return r128_addbufs_sg(inode, filp, cmd, arg);
- else
+ } else {
return -EINVAL;
+ }
}
int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
diff --git a/linux/r128_cce.c b/linux/r128_cce.c
index 144f2ab9..ca1991f2 100644
--- a/linux/r128_cce.c
+++ b/linux/r128_cce.c
@@ -342,15 +342,13 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev )
/* The manual (p. 2) says this address is in "VM space". This
* means it's an offset from the start of AGP space.
*/
- if ( !dev_priv->is_pci ) {
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+ if ( !dev_priv->is_pci )
ring_start = dev_priv->cce_ring->offset - dev->agp->base;
-#else
- printk("WARNING: Trying to use AGP without kernel support!\n");
+ else
#endif
- } else {
ring_start = dev_priv->cce_ring->offset - dev->sg->handle;
- }
+
R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET );
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
@@ -405,12 +403,8 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
dev_priv->is_pci = init->is_pci;
- /* GH: We don't support PCI cards until PCI GART is implemented.
- * Fail here so we can remove all checks for PCI cards around
- * the CCE ring code.
- */
-
- if ( dev_priv->is_pci && !dev->sg) {
+ if ( dev_priv->is_pci && !dev->sg ) {
+ DRM_ERROR( "PCI GART memory not allocated!\n" );
drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
dev->dev_private = NULL;
return -EINVAL;
@@ -511,21 +505,25 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
(drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
init->sarea_priv_offset);
- if(dev_priv->is_pci) {
- dev_priv->cce_ring->handle =
- (void *)dev_priv->cce_ring->offset;
- dev_priv->ring_rptr->handle =
- (void *)dev_priv->ring_rptr->offset;
- dev_priv->buffers->handle = (void *)dev_priv->buffers->offset;
- } else {
+ if ( !dev_priv->is_pci ) {
DO_IOREMAP( dev_priv->cce_ring );
DO_IOREMAP( dev_priv->ring_rptr );
DO_IOREMAP( dev_priv->buffers );
+ } else {
+ dev_priv->cce_ring->handle =
+ (void *)dev_priv->cce_ring->offset;
+ dev_priv->ring_rptr->handle =
+ (void *)dev_priv->ring_rptr->offset;
+ dev_priv->buffers->handle = (void *)dev_priv->buffers->offset;
}
- if ( !dev_priv->is_pci ) {
- DO_IOREMAP( dev_priv->agp_textures );
- }
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+ if ( !dev_priv->is_pci )
+ dev_priv->cce_buffers_offset = dev->agp->base;
+ else
+#endif
+ dev_priv->cce_buffers_offset = dev->sg->handle;
+
dev_priv->ring.head = ((__volatile__ u32 *)
dev_priv->ring_rptr->handle);
@@ -546,10 +544,9 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
R128_WRITE( R128_LAST_DISPATCH_REG,
dev_priv->sarea_priv->last_dispatch );
- if ( dev_priv->is_pci && r128_pcigart_init( dev ) < 0) {
- DRM_ERROR( "failed to init PCIGART!\n" );
- drm_free( dev_priv, sizeof(*dev_priv),
- DRM_MEM_DRIVER );
+ if ( dev_priv->is_pci && r128_pcigart_init( dev ) < 0 ) {
+ DRM_ERROR( "failed to init PCI GART!\n" );
+ drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
dev->dev_private = NULL;
return -EINVAL;
}
@@ -611,10 +608,10 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
r128_do_wait_for_idle( dev_priv );
r128_do_engine_reset( dev );
- r128_do_wait_for_idle( dev_priv );
+ r128_do_wait_for_idle( dev_priv );
}
#endif
-
+
return 0;
}
@@ -623,15 +620,14 @@ static int r128_do_cleanup_cce( drm_device_t *dev )
if ( dev->dev_private ) {
drm_r128_private_t *dev_priv = dev->dev_private;
- if(!dev_priv->is_pci) {
+ if ( !dev_priv->is_pci ) {
DO_IOREMAPFREE( dev_priv->cce_ring );
DO_IOREMAPFREE( dev_priv->ring_rptr );
DO_IOREMAPFREE( dev_priv->buffers );
- DO_IOREMAPFREE( dev_priv->agp_textures );
+ } else {
+ r128_pcigart_cleanup( dev );
}
- r128_pcigart_cleanup(dev);
-
drm_free( dev->dev_private, sizeof(drm_r128_private_t),
DRM_MEM_DRIVER );
dev->dev_private = NULL;
diff --git a/linux/r128_drv.c b/linux/r128_drv.c
index 977be8ea..ddc1103f 100644
--- a/linux/r128_drv.c
+++ b/linux/r128_drv.c
@@ -37,7 +37,7 @@
#define R128_NAME "r128"
#define R128_DESC "ATI Rage 128"
-#define R128_DATE "20010101"
+#define R128_DATE "20010123"
#define R128_MAJOR 2
#define R128_MINOR 1
#define R128_PATCHLEVEL 4
@@ -312,7 +312,7 @@ static int r128_takedown(drm_device_t *dev)
handled in the AGP/GART driver. */
break;
case _DRM_SCATTER_GATHER:
- if(dev->sg) {
+ if (dev->sg) {
drm_sg_cleanup(dev->sg);
dev->sg = NULL;
}
diff --git a/linux/r128_drv.h b/linux/r128_drv.h
index 6b6a04c2..3c02dbc5 100644
--- a/linux/r128_drv.h
+++ b/linux/r128_drv.h
@@ -62,6 +62,7 @@ typedef struct drm_r128_private {
int cce_fifo_size;
int cce_secure;
int cce_running;
+ u32 cce_buffers_offset;
drm_r128_freelist_t *head;
drm_r128_freelist_t *tail;
@@ -92,8 +93,7 @@ typedef struct drm_r128_private {
u32 depth_pitch_offset_c;
u32 span_pitch_offset_c;
- void *pci_gart_page;
- unsigned long phys_pci_gart_page;
+ unsigned long phys_pci_gart;
drm_map_t *sarea;
drm_map_t *fb;
@@ -404,14 +404,17 @@ extern int r128_pcigart_init(drm_device_t *dev);
#define R128_WATERMARK_N 8
#define R128_WATERMARK_K 128
-#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */
+#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */
#define R128_LAST_FRAME_REG R128_GUI_SCRATCH_REG0
#define R128_LAST_DISPATCH_REG R128_GUI_SCRATCH_REG1
#define R128_MAX_VB_AGE 0x7fffffff
-
#define R128_MAX_VB_VERTS (0xffff)
+#define R128_PCIGART_TABLE_ORDER 3
+#define R128_PCIGART_TABLE_PAGES (1 << 3)
+#define R128_MAX_PCIGART_PAGES 8192 /* 32 MB aperture */
+
#define R128_BASE(reg) ((u32)(dev_priv->mmio->handle))
#define R128_ADDR(reg) (R128_BASE(reg) + reg)
diff --git a/linux/r128_pcigart.c b/linux/r128_pcigart.c
index d0f05cce..ff32f1dc 100644
--- a/linux/r128_pcigart.c
+++ b/linux/r128_pcigart.c
@@ -25,36 +25,28 @@
*
* Authors:
* Gareth Hughes <gareth@valinux.com>
- *
*/
#define __NO_VERSION__
#include "drmP.h"
#include "r128_drv.h"
-#include <linux/interrupt.h> /* For task queue support */
-#include <linux/delay.h>
-
-
-
-static unsigned long r128_alloc_pages( void )
+static unsigned long r128_alloc_pcigart_table( void )
{
unsigned long address;
- unsigned long addr_end;
struct page *page;
-
+ int i;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- address = __get_free_pages( GFP_KERNEL, 3 );
+ address = __get_free_pages( GFP_KERNEL, R128_PCIGART_TABLE_ORDER );
if ( address == 0UL ) {
return 0;
}
- addr_end = address + ((PAGE_SIZE * (1 << 3)) - 1);
- for (page = virt_to_page(address);
- page <= virt_to_page(addr_end);
- page++) {
+ page = virt_to_page( address );
+
+ for ( i = 0 ; i <= R128_PCIGART_TABLE_PAGES ; i++, page++ ) {
atomic_inc( &page->count );
SetPageReserved( page );
}
@@ -63,24 +55,22 @@ static unsigned long r128_alloc_pages( void )
return address;
}
-static void r128_free_pages( unsigned long address )
+static void r128_free_pcigart_table( unsigned long address )
{
- unsigned long addr_end;
struct page *page;
-
+ int i;
DRM_DEBUG( "%s\n", __FUNCTION__ );
+
if ( !address ) return;
- addr_end = address + ((PAGE_SIZE * (1 << 3)) - 1);
+ page = virt_to_page( address );
- for (page = virt_to_page(address);
- page <= virt_to_page(addr_end);
- page++) {
+ for ( i = 0 ; i <= R128_PCIGART_TABLE_PAGES ; i++, page++ ) {
atomic_dec( &page->count );
ClearPageReserved( page );
}
- free_pages( address , 3 );
+ free_pages( address, R128_PCIGART_TABLE_ORDER );
}
int r128_pcigart_init( drm_device_t *dev )
@@ -89,50 +79,36 @@ int r128_pcigart_init( drm_device_t *dev )
drm_sg_mem_t *entry = dev->sg;
unsigned long address;
unsigned long pages;
- unsigned long *pci_gart;
+ u32 *pci_gart;
int i;
DRM_DEBUG( "%s\n", __FUNCTION__ );
-#if 0
- dev_priv->phys_pci_gart_page = 0;
- dev_priv->pci_gart_page = NULL;
-
- return 0;
-#endif
-
if ( !entry ) {
DRM_ERROR( "no scatter/gather memory!\n" );
return -EINVAL;
}
- /* 32 MB aperture is the largest size */
- pages = ( entry->pages <= 8192 )
- ? entry->pages : 8192;
-
- address = r128_alloc_pages();
-
-
+ address = r128_alloc_pcigart_table();
if ( !address ) {
DRM_ERROR( "cannot allocate PCI GART page!\n" );
return -ENOMEM;
}
- dev_priv->phys_pci_gart_page = address;
- dev_priv->pci_gart_page = (unsigned long *)address;
+ dev_priv->phys_pci_gart = address;
- DRM_DEBUG( "%s: phys=0x%08lx virt=%p\n",
- __FUNCTION__, dev_priv->phys_pci_gart_page,
- dev_priv->pci_gart_page );
+ pci_gart = (u32 *)dev_priv->phys_pci_gart;
- pci_gart = (unsigned long *)dev_priv->pci_gart_page;
+ pages = ( entry->pages <= R128_MAX_PCIGART_PAGES )
+ ? entry->pages : R128_MAX_PCIGART_PAGES;
+
+ memset( pci_gart, 0, R128_MAX_PCIGART_PAGES * sizeof(u32) );
- for ( i = 0; i < 8192 ; i++) pci_gart[i] = 0;
for ( i = 0 ; i < pages ; i++ ) {
- pci_gart[i] = virt_to_bus( entry->pagelist[i]->virtual );
+ pci_gart[i] = (u32) virt_to_bus( entry->pagelist[i]->virtual );
}
DRM_DEBUG( "%s: writing PCI_GART_PAGE...\n", __FUNCTION__ );
- R128_WRITE( R128_PCI_GART_PAGE, virt_to_bus((void *)address) );
+ R128_WRITE( R128_PCI_GART_PAGE, virt_to_bus( (void *)address ) );
DRM_DEBUG( "%s: writing PCI_GART_PAGE... done.\n", __FUNCTION__ );
#if __i386__
@@ -149,10 +125,9 @@ int r128_pcigart_cleanup( drm_device_t *dev )
drm_r128_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( dev_priv->phys_pci_gart_page ) {
- r128_free_pages( dev_priv->phys_pci_gart_page );
+ if ( dev_priv->phys_pci_gart ) {
+ r128_free_pcigart_table( dev_priv->phys_pci_gart );
}
return 0;
}
-
diff --git a/linux/r128_state.c b/linux/r128_state.c
index 29750456..f6ff3838 100644
--- a/linux/r128_state.c
+++ b/linux/r128_state.c
@@ -616,9 +616,6 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
int format = sarea_priv->vc_format;
int offset = buf->bus_address;
-/*
- int offset = dev_priv->buffers->offset + buf->offset - dev->agp->base;
- */
int size = buf->used;
int prim = buf_priv->prim;
int i = 0;
@@ -685,9 +682,6 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
sarea_priv->nbox = 0;
}
-
-
-
static void r128_cce_dispatch_indirect( drm_device_t *dev,
drm_buf_t *buf,
int start, int end )
@@ -752,12 +746,11 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
int start, int end,
int count )
{
- drm_device_dma_t *dma = dev->dma;
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_buf_priv_t *buf_priv = buf->dev_private;
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
int format = sarea_priv->vc_format;
- int offset;
+ int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset;
int prim = buf_priv->prim;
u32 *data;
int dwords;
@@ -765,15 +758,6 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
RING_LOCALS;
DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
- if(dma->flags == _DRM_DMA_USE_SG)
- offset = dev_priv->buffers->offset - dev->sg->handle;
- else
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
- offset = dev_priv->buffers->offset - dev->agp->base;
-#else
- printk("WARNING: trying to use AGP without kernel support!\n");
-#endif
-
r128_update_ring_snapshot( dev_priv );
if ( 0 )
@@ -1436,10 +1420,8 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
return -EINVAL;
}
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+ if ( !dev_priv )
return -EINVAL;
- }
if ( copy_from_user( &vertex, (drm_r128_vertex_t *)arg,
sizeof(vertex) ) )
@@ -1501,10 +1483,8 @@ int r128_cce_indices( struct inode *inode, struct file *filp,
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
return -EINVAL;
}
- if ( !dev_priv ) {
- DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+ if ( !dev_priv )
return -EINVAL;
- }
if ( copy_from_user( &elts, (drm_r128_indices_t *)arg,
sizeof(elts) ) )
diff --git a/linux/scatter.c b/linux/scatter.c
index 8bd4bd82..36066e64 100644
--- a/linux/scatter.c
+++ b/linux/scatter.c
@@ -24,24 +24,25 @@
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Gareth Hughes <gareth@valinux.com>
- *
+ * Gareth Hughes <gareth@valinux.com>
*/
#define __NO_VERSION__
#include <linux/config.h>
#include <linux/vmalloc.h>
#include "drmP.h"
-#include <linux/wrapper.h>
#define DEBUG_SCATTER 0
void drm_sg_cleanup( drm_sg_mem_t *entry )
{
+ struct page *page;
int i;
for ( i = 0 ; i < entry->pages ; i++ ) {
- ClearPageReserved( entry->pagelist[i] );
+ page = entry->pagelist[i];
+ if ( page )
+ ClearPageReserved( page );
}
vfree( entry->virtual );
@@ -54,15 +55,6 @@ void drm_sg_cleanup( drm_sg_mem_t *entry )
DRM_MEM_SGLISTS );
}
-static inline long usec( void )
-{
- struct timeval tv;
-
- do_gettimeofday( &tv );
-
- return (tv.tv_sec & 0x7ff) * 1000000 + tv.tv_usec;
-}
-
int drm_sg_alloc( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -77,7 +69,8 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( dev->sg ) return -EINVAL;
+ if ( dev->sg )
+ return -EINVAL;
if ( copy_from_user( &request,
(drm_scatter_gather_t *)arg,
@@ -85,7 +78,8 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
return -EFAULT;
entry = drm_alloc( sizeof(*entry), DRM_MEM_SGLISTS );
- if ( !entry ) return -ENOMEM;
+ if ( !entry )
+ return -ENOMEM;
memset( entry, 0, sizeof(*entry) );
@@ -100,11 +94,7 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
return -ENOMEM;
}
- /* FIXME: We should really have a kernel call for this...
- */
- entry->virtual = __vmalloc( (pages << PAGE_SHIFT),
- GFP_KERNEL,
- PAGE_KERNEL);
+ entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
if ( !entry->virtual ) {
drm_free( entry->pagelist,
entry->pages * sizeof(*entry->pagelist),
@@ -127,30 +117,20 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
pgd = pgd_offset_k( i );
+ if ( !pgd_present( *pgd ) )
+ goto failed;
- if ( pgd_present( *pgd ) && ( pmd = pmd_offset( pgd, i ) )
- && pmd_present( *pmd ) && ( pte = pte_offset( pmd, i ) )
- && pte_present( *pte ) )
- entry->pagelist[j] = pte_page( *pte );
- else
- {
- vfree( entry->virtual );
- drm_free( entry->pagelist,
- entry->pages * sizeof(*entry->pagelist),
- DRM_MEM_PAGES );
- drm_free( entry,
- sizeof(*entry),
- DRM_MEM_SGLISTS );
- return -ENOMEM;
- }
+ pmd = pmd_offset( pgd, i );
+ if ( !pmd_present( *pmd ) )
+ goto failed;
- SetPageReserved( entry->pagelist[j] );
+ pte = pte_offset( pmd, i );
+ if ( !pte_present( *pte ) )
+ goto failed;
- if ( j < 16 ) {
- DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n",
- i, j,
- (unsigned long)entry->pagelist[j]->virtual);
- }
+ entry->pagelist[j] = pte_page( *pte );
+
+ SetPageReserved( entry->pagelist[j] );
}
request.handle = entry->handle;
@@ -165,7 +145,7 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
dev->sg = entry;
#if DEBUG_SCATTER
- /* Verify that each page points to its virtual address, and vice
+ /* Verify that each page points to its virtual address, and vice
* versa.
*/
{
@@ -178,7 +158,7 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
for(j = 0; j < PAGE_SIZE / sizeof(unsigned long); j++, tmp++) {
*tmp = 0xcafebabe;
}
- tmp = (unsigned long *)((u8 *)entry->virtual +
+ tmp = (unsigned long *)((u8 *)entry->virtual +
(PAGE_SIZE * i));
for(j = 0; j < PAGE_SIZE / sizeof(unsigned long); j++, tmp++) {
if(*tmp != 0xcafebabe && error == 0) {
@@ -197,6 +177,10 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
#endif
return 0;
+
+ failed:
+ drm_sg_cleanup( entry );
+ return -ENOMEM;
}
int drm_sg_free( struct inode *inode, struct file *filp,
@@ -215,7 +199,8 @@ int drm_sg_free( struct inode *inode, struct file *filp,
entry = dev->sg;
dev->sg = NULL;
- if ( !entry || entry->handle != request.handle ) return -EINVAL;
+ if ( !entry || entry->handle != request.handle )
+ return -EINVAL;
DRM_DEBUG( "sg free virtual = %p\n", entry->virtual );
diff --git a/linux/vm.c b/linux/vm.c
index 9db8c5a8..b713ba84 100644
--- a/linux/vm.c
+++ b/linux/vm.c
@@ -11,11 +11,11 @@
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -23,7 +23,7 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
- *
+ *
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
*
@@ -213,7 +213,6 @@ struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
page = entry->pagelist[page_offset];
atomic_inc(&page->count); /* Dec. by kernel */
-
#if LINUX_VERSION_CODE < 0x020317
return (unsigned long)virt_to_phys(page->virtual);
#else
@@ -289,7 +288,7 @@ int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
drm_device_t *dev;
drm_device_dma_t *dma;
unsigned long length = vma->vm_end - vma->vm_start;
-
+
lock_kernel();
dev = priv->dev;
dma = dev->dma;
@@ -305,7 +304,7 @@ int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = &drm_vm_dma_ops;
vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
-
+
#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
/* In Linux 2.2.3 and above, this is
handled in do_mmap() in mm/mmap.c. */
@@ -322,7 +321,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
drm_device_t *dev = priv->dev;
drm_map_t *map = NULL;
int i;
-
+
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
@@ -339,14 +338,14 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
map = dev->maplist[i];
if (map->offset == VM_OFFSET(vma)) break;
}
-
+
if (i >= dev->map_count) return -EINVAL;
if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
return -EPERM;
/* Check for valid size. */
if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
-
+
if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
vma->vm_flags &= VM_MAYWRITE;
#if defined(__i386__)
@@ -360,12 +359,6 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
#endif
}
- if (map->type == _DRM_SCATTER_GATHER) {
- DRM_DEBUG("%s: scatter/gather\n", __FUNCTION__);
- DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
- vma->vm_start, vma->vm_end, VM_OFFSET(vma));
- }
-
switch (map->type) {
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
@@ -377,10 +370,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
}
#elif defined(__powerpc__)
- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;
+ pgprot_val(vma->vm_page_prot) |=
+ _PAGE_NO_CACHE | _PAGE_GUARDED;
#elif defined(__ia64__)
if (map->type != _DRM_AGP)
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ vma->vm_page_prot =
+ pgprot_writecombine(vma->vm_page_prot);
#endif
vma->vm_flags |= VM_IO; /* not in core dump */
}
@@ -432,9 +427,5 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
#endif
vma->vm_file = filp; /* Needed for drm_vm_open() */
drm_vm_open(vma);
-
- if(map->type == _DRM_SCATTER_GATHER) {
- DRM_DEBUG("%s: scatter/gather done.\n", __FUNCTION__);
- }
return 0;
}