aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/drm/drmP.h16
-rw-r--r--drivers/char/drm/drm_bufs.c22
-rw-r--r--drivers/char/drm/drm_drv.c8
-rw-r--r--drivers/char/drm/drm_pci.c45
-rw-r--r--drivers/char/drm/drm_vm.c8
-rw-r--r--drivers/char/drm/i915_dma.c15
-rw-r--r--drivers/char/drm/i915_drv.h3
7 files changed, 78 insertions, 39 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 804e622436a9..7e633a9ce933 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -527,6 +527,12 @@ typedef struct drm_sigdata {
527 drm_hw_lock_t *lock; 527 drm_hw_lock_t *lock;
528} drm_sigdata_t; 528} drm_sigdata_t;
529 529
530typedef struct drm_dma_handle {
531 dma_addr_t busaddr;
532 void *vaddr;
533 size_t size;
534} drm_dma_handle_t;
535
530/** 536/**
531 * Mappings list 537 * Mappings list
532 */ 538 */
@@ -978,12 +984,10 @@ extern int drm_ati_pcigart_cleanup(drm_device_t *dev,
978 unsigned long addr, 984 unsigned long addr,
979 dma_addr_t bus_addr); 985 dma_addr_t bus_addr);
980 986
981extern void *drm_pci_alloc(drm_device_t * dev, size_t size, 987extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size,
982 size_t align, dma_addr_t maxaddr, 988 size_t align, dma_addr_t maxaddr);
983 dma_addr_t * busaddr); 989extern void __drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
984 990extern void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
985extern void drm_pci_free(drm_device_t * dev, size_t size,
986 void *vaddr, dma_addr_t busaddr);
987 991
988 /* sysfs support (drm_sysfs.c) */ 992 /* sysfs support (drm_sysfs.c) */
989struct drm_sysfs_class; 993struct drm_sysfs_class;
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index eb3cf550626d..be54efbefe84 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -90,6 +90,7 @@ int drm_addmap( struct inode *inode, struct file *filp,
90 drm_map_t *map; 90 drm_map_t *map;
91 drm_map_t __user *argp = (void __user *)arg; 91 drm_map_t __user *argp = (void __user *)arg;
92 drm_map_list_t *list; 92 drm_map_list_t *list;
93 drm_dma_handle_t *dmah;
93 94
94 if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */ 95 if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
95 96
@@ -181,21 +182,19 @@ int drm_addmap( struct inode *inode, struct file *filp,
181 map->offset += dev->sg->handle; 182 map->offset += dev->sg->handle;
182 break; 183 break;
183 case _DRM_CONSISTENT: 184 case _DRM_CONSISTENT:
184 {
185 /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G, 185 /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
186 * As we're limit the address to 2^32-1 (or lses), 186 * As we're limiting the address to 2^32-1 (or less),
187 * casting it down to 32 bits is no problem, but we 187 * casting it down to 32 bits is no problem, but we
188 * need to point to a 64bit variable first. */ 188 * need to point to a 64bit variable first. */
189 dma_addr_t bus_addr; 189 dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL);
190 map->handle = drm_pci_alloc(dev, map->size, map->size, 190 if (!dmah) {
191 0xffffffffUL, &bus_addr);
192 map->offset = (unsigned long)bus_addr;
193 if (!map->handle) {
194 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 191 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
195 return -ENOMEM; 192 return -ENOMEM;
196 } 193 }
194 map->handle = dmah->vaddr;
195 map->offset = (unsigned long)dmah->busaddr;
196 kfree(dmah);
197 break; 197 break;
198 }
199 default: 198 default:
200 drm_free( map, sizeof(*map), DRM_MEM_MAPS ); 199 drm_free( map, sizeof(*map), DRM_MEM_MAPS );
201 return -EINVAL; 200 return -EINVAL;
@@ -286,6 +285,8 @@ int drm_rmmap(struct inode *inode, struct file *filp,
286 } 285 }
287 286
288 if(!found_maps) { 287 if(!found_maps) {
288 drm_dma_handle_t dmah;
289
289 switch (map->type) { 290 switch (map->type) {
290 case _DRM_REGISTERS: 291 case _DRM_REGISTERS:
291 case _DRM_FRAME_BUFFER: 292 case _DRM_FRAME_BUFFER:
@@ -307,7 +308,10 @@ int drm_rmmap(struct inode *inode, struct file *filp,
307 case _DRM_SCATTER_GATHER: 308 case _DRM_SCATTER_GATHER:
308 break; 309 break;
309 case _DRM_CONSISTENT: 310 case _DRM_CONSISTENT:
310 drm_pci_free(dev, map->size, map->handle, map->offset); 311 dmah.vaddr = map->handle;
312 dmah.busaddr = map->offset;
313 dmah.size = map->size;
314 __drm_pci_free(dev, &dmah);
311 break; 315 break;
312 } 316 }
313 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 317 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index f4046c8c70b5..ab172ea8e98a 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -198,6 +198,8 @@ int drm_takedown( drm_device_t *dev )
198 r_list = (drm_map_list_t *)list; 198 r_list = (drm_map_list_t *)list;
199 199
200 if ( ( map = r_list->map ) ) { 200 if ( ( map = r_list->map ) ) {
201 drm_dma_handle_t dmah;
202
201 switch ( map->type ) { 203 switch ( map->type ) {
202 case _DRM_REGISTERS: 204 case _DRM_REGISTERS:
203 case _DRM_FRAME_BUFFER: 205 case _DRM_FRAME_BUFFER:
@@ -229,8 +231,10 @@ int drm_takedown( drm_device_t *dev )
229 } 231 }
230 break; 232 break;
231 case _DRM_CONSISTENT: 233 case _DRM_CONSISTENT:
232 drm_pci_free(dev, map->size, 234 dmah.vaddr = map->handle;
233 map->handle, map->offset); 235 dmah.busaddr = map->offset;
236 dmah.size = map->size;
237 __drm_pci_free(dev, &dmah);
234 break; 238 break;
235 } 239 }
236 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 240 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
index 192e8762571c..3e452e8967fa 100644
--- a/drivers/char/drm/drm_pci.c
+++ b/drivers/char/drm/drm_pci.c
@@ -46,10 +46,10 @@
46/** 46/**
47 * \brief Allocate a PCI consistent memory block, for DMA. 47 * \brief Allocate a PCI consistent memory block, for DMA.
48 */ 48 */
49void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, 49drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
50 dma_addr_t maxaddr, dma_addr_t * busaddr) 50 dma_addr_t maxaddr)
51{ 51{
52 void *address; 52 drm_dma_handle_t *dmah;
53#if DRM_DEBUG_MEMORY 53#if DRM_DEBUG_MEMORY
54 int area = DRM_MEM_DMA; 54 int area = DRM_MEM_DMA;
55 55
@@ -74,13 +74,19 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
74 return NULL; 74 return NULL;
75 } 75 }
76 76
77 address = pci_alloc_consistent(dev->pdev, size, busaddr); 77 dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
78 if (!dmah)
79 return NULL;
80
81 dmah->size = size;
82 dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr);
78 83
79#if DRM_DEBUG_MEMORY 84#if DRM_DEBUG_MEMORY
80 if (address == NULL) { 85 if (dmah->vaddr == NULL) {
81 spin_lock(&drm_mem_lock); 86 spin_lock(&drm_mem_lock);
82 ++drm_mem_stats[area].fail_count; 87 ++drm_mem_stats[area].fail_count;
83 spin_unlock(&drm_mem_lock); 88 spin_unlock(&drm_mem_lock);
89 kfree(dmah);
84 return NULL; 90 return NULL;
85 } 91 }
86 92
@@ -90,21 +96,25 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
90 drm_ram_used += size; 96 drm_ram_used += size;
91 spin_unlock(&drm_mem_lock); 97 spin_unlock(&drm_mem_lock);
92#else 98#else
93 if (address == NULL) 99 if (dmah->vaddr == NULL) {
100 kfree(dmah);
94 return NULL; 101 return NULL;
102 }
95#endif 103#endif
96 104
97 memset(address, 0, size); 105 memset(dmah->vaddr, 0, size);
98 106
99 return address; 107 return dmah;
100} 108}
101EXPORT_SYMBOL(drm_pci_alloc); 109EXPORT_SYMBOL(drm_pci_alloc);
102 110
103/** 111/**
104 * \brief Free a PCI consistent memory block. 112 * \brief Free a PCI consistent memory block with freeing its descriptor.
113 *
114 * This function is for internal use in the Linux-specific DRM core code.
105 */ 115 */
106void 116void
107drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr) 117__drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
108{ 118{
109#if DRM_DEBUG_MEMORY 119#if DRM_DEBUG_MEMORY
110 int area = DRM_MEM_DMA; 120 int area = DRM_MEM_DMA;
@@ -112,12 +122,13 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
112 int free_count; 122 int free_count;
113#endif 123#endif
114 124
115 if (!vaddr) { 125 if (!dmah->vaddr) {
116#if DRM_DEBUG_MEMORY 126#if DRM_DEBUG_MEMORY
117 DRM_MEM_ERROR(area, "Attempt to free address 0\n"); 127 DRM_MEM_ERROR(area, "Attempt to free address 0\n");
118#endif 128#endif
119 } else { 129 } else {
120 pci_free_consistent(dev->pdev, size, vaddr, busaddr); 130 pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr,
131 dmah->busaddr);
121 } 132 }
122 133
123#if DRM_DEBUG_MEMORY 134#if DRM_DEBUG_MEMORY
@@ -135,6 +146,16 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
135#endif 146#endif
136 147
137} 148}
149
150/**
151 * \brief Free a PCI consistent memory block
152 */
153void
154drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah)
155{
156 __drm_pci_free(dev, dmah);
157 kfree(dmah);
158}
138EXPORT_SYMBOL(drm_pci_free); 159EXPORT_SYMBOL(drm_pci_free);
139 160
140/*@}*/ 161/*@}*/
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index 644ec9dadc05..675d2397def9 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -210,6 +210,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
210 } 210 }
211 211
212 if(!found_maps) { 212 if(!found_maps) {
213 drm_dma_handle_t dmah;
214
213 switch (map->type) { 215 switch (map->type) {
214 case _DRM_REGISTERS: 216 case _DRM_REGISTERS:
215 case _DRM_FRAME_BUFFER: 217 case _DRM_FRAME_BUFFER:
@@ -229,8 +231,10 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
229 case _DRM_SCATTER_GATHER: 231 case _DRM_SCATTER_GATHER:
230 break; 232 break;
231 case _DRM_CONSISTENT: 233 case _DRM_CONSISTENT:
232 drm_pci_free(dev, map->size, map->handle, 234 dmah.vaddr = map->handle;
233 map->offset); 235 dmah.busaddr = map->offset;
236 dmah.size = map->size;
237 __drm_pci_free(dev, &dmah);
234 break; 238 break;
235 } 239 }
236 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 240 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index acf9e52a9507..759f22943eb1 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -95,9 +95,8 @@ static int i915_dma_cleanup(drm_device_t * dev)
95 drm_core_ioremapfree( &dev_priv->ring.map, dev); 95 drm_core_ioremapfree( &dev_priv->ring.map, dev);
96 } 96 }
97 97
98 if (dev_priv->hw_status_page) { 98 if (dev_priv->status_page_dmah) {
99 drm_pci_free(dev, PAGE_SIZE, dev_priv->hw_status_page, 99 drm_pci_free(dev, dev_priv->status_page_dmah);
100 dev_priv->dma_status_page);
101 /* Need to rewrite hardware status page */ 100 /* Need to rewrite hardware status page */
102 I915_WRITE(0x02080, 0x1ffff000); 101 I915_WRITE(0x02080, 0x1ffff000);
103 } 102 }
@@ -174,16 +173,18 @@ static int i915_initialize(drm_device_t * dev,
174 dev_priv->allow_batchbuffer = 1; 173 dev_priv->allow_batchbuffer = 1;
175 174
176 /* Program Hardware Status Page */ 175 /* Program Hardware Status Page */
177 dev_priv->hw_status_page = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 176 dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
178 0xffffffff, 177 0xffffffff);
179 &dev_priv->dma_status_page);
180 178
181 if (!dev_priv->hw_status_page) { 179 if (!dev_priv->status_page_dmah) {
182 dev->dev_private = (void *)dev_priv; 180 dev->dev_private = (void *)dev_priv;
183 i915_dma_cleanup(dev); 181 i915_dma_cleanup(dev);
184 DRM_ERROR("Can not allocate hardware status page\n"); 182 DRM_ERROR("Can not allocate hardware status page\n");
185 return DRM_ERR(ENOMEM); 183 return DRM_ERR(ENOMEM);
186 } 184 }
185 dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
186 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
187
187 memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 188 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
188 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 189 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
189 190
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 9c37d2367dd5..93080868d18f 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -79,9 +79,10 @@ typedef struct drm_i915_private {
79 drm_i915_sarea_t *sarea_priv; 79 drm_i915_sarea_t *sarea_priv;
80 drm_i915_ring_buffer_t ring; 80 drm_i915_ring_buffer_t ring;
81 81
82 drm_dma_handle_t *status_page_dmah;
82 void *hw_status_page; 83 void *hw_status_page;
83 unsigned long counter;
84 dma_addr_t dma_status_page; 84 dma_addr_t dma_status_page;
85 unsigned long counter;
85 86
86 int back_offset; 87 int back_offset;
87 int front_offset; 88 int front_offset;