diff options
| -rw-r--r-- | drivers/char/drm/drmP.h | 14 | ||||
| -rw-r--r-- | drivers/char/drm/drm_bufs.c | 20 | ||||
| -rw-r--r-- | drivers/char/drm/drm_dma.c | 4 | ||||
| -rw-r--r-- | drivers/char/drm/drm_pci.c | 29 |
4 files changed, 44 insertions, 23 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 107df9fdba4e..dbe952f899c0 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
| @@ -357,6 +357,12 @@ typedef struct drm_freelist { | |||
| 357 | spinlock_t lock; | 357 | spinlock_t lock; |
| 358 | } drm_freelist_t; | 358 | } drm_freelist_t; |
| 359 | 359 | ||
| 360 | typedef struct drm_dma_handle { | ||
| 361 | dma_addr_t busaddr; | ||
| 362 | void *vaddr; | ||
| 363 | size_t size; | ||
| 364 | } drm_dma_handle_t; | ||
| 365 | |||
| 360 | /** | 366 | /** |
| 361 | * Buffer entry. There is one of this for each buffer size order. | 367 | * Buffer entry. There is one of this for each buffer size order. |
| 362 | */ | 368 | */ |
| @@ -366,7 +372,7 @@ typedef struct drm_buf_entry { | |||
| 366 | drm_buf_t *buflist; /**< buffer list */ | 372 | drm_buf_t *buflist; /**< buffer list */ |
| 367 | int seg_count; | 373 | int seg_count; |
| 368 | int page_order; | 374 | int page_order; |
| 369 | unsigned long *seglist; | 375 | drm_dma_handle_t **seglist; |
| 370 | 376 | ||
| 371 | drm_freelist_t freelist; | 377 | drm_freelist_t freelist; |
| 372 | } drm_buf_entry_t; | 378 | } drm_buf_entry_t; |
| @@ -483,12 +489,6 @@ typedef struct drm_sigdata { | |||
| 483 | drm_hw_lock_t *lock; | 489 | drm_hw_lock_t *lock; |
| 484 | } drm_sigdata_t; | 490 | } drm_sigdata_t; |
| 485 | 491 | ||
| 486 | typedef struct drm_dma_handle { | ||
| 487 | dma_addr_t busaddr; | ||
| 488 | void *vaddr; | ||
| 489 | size_t size; | ||
| 490 | } drm_dma_handle_t; | ||
| 491 | |||
| 492 | /** | 492 | /** |
| 493 | * Mappings list | 493 | * Mappings list |
| 494 | */ | 494 | */ |
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index e2637b4d51de..8a9cf12e6183 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
| @@ -474,8 +474,7 @@ static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry) | |||
| 474 | if (entry->seg_count) { | 474 | if (entry->seg_count) { |
| 475 | for (i = 0; i < entry->seg_count; i++) { | 475 | for (i = 0; i < entry->seg_count; i++) { |
| 476 | if (entry->seglist[i]) { | 476 | if (entry->seglist[i]) { |
| 477 | drm_free_pages(entry->seglist[i], | 477 | drm_pci_free(dev, entry->seglist[i]); |
| 478 | entry->page_order, DRM_MEM_DMA); | ||
| 479 | } | 478 | } |
| 480 | } | 479 | } |
| 481 | drm_free(entry->seglist, | 480 | drm_free(entry->seglist, |
| @@ -678,7 +677,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 678 | int total; | 677 | int total; |
| 679 | int page_order; | 678 | int page_order; |
| 680 | drm_buf_entry_t *entry; | 679 | drm_buf_entry_t *entry; |
| 681 | unsigned long page; | 680 | drm_dma_handle_t *dmah; |
| 682 | drm_buf_t *buf; | 681 | drm_buf_t *buf; |
| 683 | int alignment; | 682 | int alignment; |
| 684 | unsigned long offset; | 683 | unsigned long offset; |
| @@ -781,8 +780,10 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 781 | page_count = 0; | 780 | page_count = 0; |
| 782 | 781 | ||
| 783 | while (entry->buf_count < count) { | 782 | while (entry->buf_count < count) { |
| 784 | page = drm_alloc_pages(page_order, DRM_MEM_DMA); | 783 | |
| 785 | if (!page) { | 784 | dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful); |
| 785 | |||
| 786 | if (!dmah) { | ||
| 786 | /* Set count correctly so we free the proper amount. */ | 787 | /* Set count correctly so we free the proper amount. */ |
| 787 | entry->buf_count = count; | 788 | entry->buf_count = count; |
| 788 | entry->seg_count = count; | 789 | entry->seg_count = count; |
| @@ -794,13 +795,13 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 794 | atomic_dec(&dev->buf_alloc); | 795 | atomic_dec(&dev->buf_alloc); |
| 795 | return -ENOMEM; | 796 | return -ENOMEM; |
| 796 | } | 797 | } |
| 797 | entry->seglist[entry->seg_count++] = page; | 798 | entry->seglist[entry->seg_count++] = dmah; |
| 798 | for (i = 0; i < (1 << page_order); i++) { | 799 | for (i = 0; i < (1 << page_order); i++) { |
| 799 | DRM_DEBUG("page %d @ 0x%08lx\n", | 800 | DRM_DEBUG("page %d @ 0x%08lx\n", |
| 800 | dma->page_count + page_count, | 801 | dma->page_count + page_count, |
| 801 | page + PAGE_SIZE * i); | 802 | (unsigned long)dmah->vaddr + PAGE_SIZE * i); |
| 802 | temp_pagelist[dma->page_count + page_count++] | 803 | temp_pagelist[dma->page_count + page_count++] |
| 803 | = page + PAGE_SIZE * i; | 804 | = (unsigned long)dmah->vaddr + PAGE_SIZE * i; |
| 804 | } | 805 | } |
| 805 | for (offset = 0; | 806 | for (offset = 0; |
| 806 | offset + size <= total && entry->buf_count < count; | 807 | offset + size <= total && entry->buf_count < count; |
| @@ -811,7 +812,8 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 811 | buf->order = order; | 812 | buf->order = order; |
| 812 | buf->used = 0; | 813 | buf->used = 0; |
| 813 | buf->offset = (dma->byte_count + byte_count + offset); | 814 | buf->offset = (dma->byte_count + byte_count + offset); |
| 814 | buf->address = (void *)(page + offset); | 815 | buf->address = (void *)(dmah->vaddr + offset); |
| 816 | buf->bus_address = dmah->busaddr + offset; | ||
| 815 | buf->next = NULL; | 817 | buf->next = NULL; |
| 816 | buf->waiting = 0; | 818 | buf->waiting = 0; |
| 817 | buf->pending = 0; | 819 | buf->pending = 0; |
diff --git a/drivers/char/drm/drm_dma.c b/drivers/char/drm/drm_dma.c index 2afab95ca036..892db7096986 100644 --- a/drivers/char/drm/drm_dma.c +++ b/drivers/char/drm/drm_dma.c | |||
| @@ -85,9 +85,7 @@ void drm_dma_takedown(drm_device_t * dev) | |||
| 85 | dma->bufs[i].seg_count); | 85 | dma->bufs[i].seg_count); |
| 86 | for (j = 0; j < dma->bufs[i].seg_count; j++) { | 86 | for (j = 0; j < dma->bufs[i].seg_count; j++) { |
| 87 | if (dma->bufs[i].seglist[j]) { | 87 | if (dma->bufs[i].seglist[j]) { |
| 88 | drm_free_pages(dma->bufs[i].seglist[j], | 88 | drm_pci_free(dev, dma->bufs[i].seglist[j]); |
| 89 | dma->bufs[i].page_order, | ||
| 90 | DRM_MEM_DMA); | ||
| 91 | } | 89 | } |
| 92 | } | 90 | } |
| 93 | drm_free(dma->bufs[i].seglist, | 91 | drm_free(dma->bufs[i].seglist, |
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c index 1fd7ff164817..b28ca9cea8a2 100644 --- a/drivers/char/drm/drm_pci.c +++ b/drivers/char/drm/drm_pci.c | |||
| @@ -50,6 +50,10 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, | |||
| 50 | dma_addr_t maxaddr) | 50 | dma_addr_t maxaddr) |
| 51 | { | 51 | { |
| 52 | drm_dma_handle_t *dmah; | 52 | drm_dma_handle_t *dmah; |
| 53 | #if 1 | ||
| 54 | unsigned long addr; | ||
| 55 | size_t sz; | ||
| 56 | #endif | ||
| 53 | #ifdef DRM_DEBUG_MEMORY | 57 | #ifdef DRM_DEBUG_MEMORY |
| 54 | int area = DRM_MEM_DMA; | 58 | int area = DRM_MEM_DMA; |
| 55 | 59 | ||
| @@ -79,7 +83,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, | |||
| 79 | return NULL; | 83 | return NULL; |
| 80 | 84 | ||
| 81 | dmah->size = size; | 85 | dmah->size = size; |
| 82 | dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr); | 86 | dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP); |
| 83 | 87 | ||
| 84 | #ifdef DRM_DEBUG_MEMORY | 88 | #ifdef DRM_DEBUG_MEMORY |
| 85 | if (dmah->vaddr == NULL) { | 89 | if (dmah->vaddr == NULL) { |
| @@ -104,18 +108,29 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, | |||
| 104 | 108 | ||
| 105 | memset(dmah->vaddr, 0, size); | 109 | memset(dmah->vaddr, 0, size); |
| 106 | 110 | ||
| 111 | /* XXX - Is virt_to_page() legal for consistent mem? */ | ||
| 112 | /* Reserve */ | ||
| 113 | for (addr = (unsigned long)dmah->vaddr, sz = size; | ||
| 114 | sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { | ||
| 115 | SetPageReserved(virt_to_page(addr)); | ||
| 116 | } | ||
| 117 | |||
| 107 | return dmah; | 118 | return dmah; |
| 108 | } | 119 | } |
| 109 | 120 | ||
| 110 | EXPORT_SYMBOL(drm_pci_alloc); | 121 | EXPORT_SYMBOL(drm_pci_alloc); |
| 111 | 122 | ||
| 112 | /** | 123 | /** |
| 113 | * \brief Free a PCI consistent memory block with freeing its descriptor. | 124 | * \brief Free a PCI consistent memory block without freeing its descriptor. |
| 114 | * | 125 | * |
| 115 | * This function is for internal use in the Linux-specific DRM core code. | 126 | * This function is for internal use in the Linux-specific DRM core code. |
| 116 | */ | 127 | */ |
| 117 | void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah) | 128 | void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah) |
| 118 | { | 129 | { |
| 130 | #if 1 | ||
| 131 | unsigned long addr; | ||
| 132 | size_t sz; | ||
| 133 | #endif | ||
| 119 | #ifdef DRM_DEBUG_MEMORY | 134 | #ifdef DRM_DEBUG_MEMORY |
| 120 | int area = DRM_MEM_DMA; | 135 | int area = DRM_MEM_DMA; |
| 121 | int alloc_count; | 136 | int alloc_count; |
| @@ -127,8 +142,14 @@ void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah) | |||
| 127 | DRM_MEM_ERROR(area, "Attempt to free address 0\n"); | 142 | DRM_MEM_ERROR(area, "Attempt to free address 0\n"); |
| 128 | #endif | 143 | #endif |
| 129 | } else { | 144 | } else { |
| 130 | pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr, | 145 | /* XXX - Is virt_to_page() legal for consistent mem? */ |
| 131 | dmah->busaddr); | 146 | /* Unreserve */ |
| 147 | for (addr = (unsigned long)dmah->vaddr, sz = dmah->size; | ||
| 148 | sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { | ||
| 149 | ClearPageReserved(virt_to_page(addr)); | ||
| 150 | } | ||
| 151 | dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr, | ||
| 152 | dmah->busaddr); | ||
| 132 | } | 153 | } |
| 133 | 154 | ||
| 134 | #ifdef DRM_DEBUG_MEMORY | 155 | #ifdef DRM_DEBUG_MEMORY |
