diff options
Diffstat (limited to 'drivers')
34 files changed, 667 insertions, 531 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 107df9fdba4e..edc72a6348a7 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 | */ |
@@ -813,8 +813,6 @@ extern void drm_mem_init(void); | |||
813 | extern int drm_mem_info(char *buf, char **start, off_t offset, | 813 | extern int drm_mem_info(char *buf, char **start, off_t offset, |
814 | int request, int *eof, void *data); | 814 | int request, int *eof, void *data); |
815 | extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); | 815 | extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); |
816 | extern unsigned long drm_alloc_pages(int order, int area); | ||
817 | extern void drm_free_pages(unsigned long address, int order, int area); | ||
818 | extern void *drm_ioremap(unsigned long offset, unsigned long size, | 816 | extern void *drm_ioremap(unsigned long offset, unsigned long size, |
819 | drm_device_t * dev); | 817 | drm_device_t * dev); |
820 | extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size, | 818 | extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size, |
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_memory.c b/drivers/char/drm/drm_memory.c index 8074771e348f..dddf8de66143 100644 --- a/drivers/char/drm/drm_memory.c +++ b/drivers/char/drm/drm_memory.c | |||
@@ -79,65 +79,6 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) | |||
79 | return pt; | 79 | return pt; |
80 | } | 80 | } |
81 | 81 | ||
82 | /** | ||
83 | * Allocate pages. | ||
84 | * | ||
85 | * \param order size order. | ||
86 | * \param area memory area. (Not used.) | ||
87 | * \return page address on success, or zero on failure. | ||
88 | * | ||
89 | * Allocate and reserve free pages. | ||
90 | */ | ||
91 | unsigned long drm_alloc_pages(int order, int area) | ||
92 | { | ||
93 | unsigned long address; | ||
94 | unsigned long bytes = PAGE_SIZE << order; | ||
95 | unsigned long addr; | ||
96 | unsigned int sz; | ||
97 | |||
98 | address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); | ||
99 | if (!address) | ||
100 | return 0; | ||
101 | |||
102 | /* Zero */ | ||
103 | memset((void *)address, 0, bytes); | ||
104 | |||
105 | /* Reserve */ | ||
106 | for (addr = address, sz = bytes; | ||
107 | sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { | ||
108 | SetPageReserved(virt_to_page(addr)); | ||
109 | } | ||
110 | |||
111 | return address; | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * Free pages. | ||
116 | * | ||
117 | * \param address address of the pages to free. | ||
118 | * \param order size order. | ||
119 | * \param area memory area. (Not used.) | ||
120 | * | ||
121 | * Unreserve and free pages allocated by alloc_pages(). | ||
122 | */ | ||
123 | void drm_free_pages(unsigned long address, int order, int area) | ||
124 | { | ||
125 | unsigned long bytes = PAGE_SIZE << order; | ||
126 | unsigned long addr; | ||
127 | unsigned int sz; | ||
128 | |||
129 | if (!address) | ||
130 | return; | ||
131 | |||
132 | /* Unreserve */ | ||
133 | for (addr = address, sz = bytes; | ||
134 | sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { | ||
135 | ClearPageReserved(virt_to_page(addr)); | ||
136 | } | ||
137 | |||
138 | free_pages(address, order); | ||
139 | } | ||
140 | |||
141 | #if __OS_HAS_AGP | 82 | #if __OS_HAS_AGP |
142 | /** Wrapper around agp_allocate_memory() */ | 83 | /** Wrapper around agp_allocate_memory() */ |
143 | DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) | 84 | DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) |
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h index e84605fc54af..7868341817da 100644 --- a/drivers/char/drm/drm_memory_debug.h +++ b/drivers/char/drm/drm_memory_debug.h | |||
@@ -206,76 +206,6 @@ void drm_free (void *pt, size_t size, int area) { | |||
206 | } | 206 | } |
207 | } | 207 | } |
208 | 208 | ||
209 | unsigned long drm_alloc_pages (int order, int area) { | ||
210 | unsigned long address; | ||
211 | unsigned long bytes = PAGE_SIZE << order; | ||
212 | unsigned long addr; | ||
213 | unsigned int sz; | ||
214 | |||
215 | spin_lock(&drm_mem_lock); | ||
216 | if ((drm_ram_used >> PAGE_SHIFT) | ||
217 | > (DRM_RAM_PERCENT * drm_ram_available) / 100) { | ||
218 | spin_unlock(&drm_mem_lock); | ||
219 | return 0; | ||
220 | } | ||
221 | spin_unlock(&drm_mem_lock); | ||
222 | |||
223 | address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); | ||
224 | if (!address) { | ||
225 | spin_lock(&drm_mem_lock); | ||
226 | ++drm_mem_stats[area].fail_count; | ||
227 | spin_unlock(&drm_mem_lock); | ||
228 | return 0; | ||
229 | } | ||
230 | spin_lock(&drm_mem_lock); | ||
231 | ++drm_mem_stats[area].succeed_count; | ||
232 | drm_mem_stats[area].bytes_allocated += bytes; | ||
233 | drm_ram_used += bytes; | ||
234 | spin_unlock(&drm_mem_lock); | ||
235 | |||
236 | /* Zero outside the lock */ | ||
237 | memset((void *)address, 0, bytes); | ||
238 | |||
239 | /* Reserve */ | ||
240 | for (addr = address, sz = bytes; | ||
241 | sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { | ||
242 | SetPageReserved(virt_to_page(addr)); | ||
243 | } | ||
244 | |||
245 | return address; | ||
246 | } | ||
247 | |||
248 | void drm_free_pages (unsigned long address, int order, int area) { | ||
249 | unsigned long bytes = PAGE_SIZE << order; | ||
250 | int alloc_count; | ||
251 | int free_count; | ||
252 | unsigned long addr; | ||
253 | unsigned int sz; | ||
254 | |||
255 | if (!address) { | ||
256 | DRM_MEM_ERROR(area, "Attempt to free address 0\n"); | ||
257 | } else { | ||
258 | /* Unreserve */ | ||
259 | for (addr = address, sz = bytes; | ||
260 | sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { | ||
261 | ClearPageReserved(virt_to_page(addr)); | ||
262 | } | ||
263 | free_pages(address, order); | ||
264 | } | ||
265 | |||
266 | spin_lock(&drm_mem_lock); | ||
267 | free_count = ++drm_mem_stats[area].free_count; | ||
268 | alloc_count = drm_mem_stats[area].succeed_count; | ||
269 | drm_mem_stats[area].bytes_freed += bytes; | ||
270 | drm_ram_used -= bytes; | ||
271 | spin_unlock(&drm_mem_lock); | ||
272 | if (free_count > alloc_count) { | ||
273 | DRM_MEM_ERROR(area, | ||
274 | "Excess frees: %d frees, %d allocs\n", | ||
275 | free_count, alloc_count); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | void *drm_ioremap (unsigned long offset, unsigned long size, | 209 | void *drm_ioremap (unsigned long offset, unsigned long size, |
280 | drm_device_t * dev) { | 210 | drm_device_t * dev) { |
281 | void *pt; | 211 | void *pt; |
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 |
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 2c17e88a8847..b1bb3c7b568d 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
@@ -3,49 +3,69 @@ | |||
3 | Please contact dri-devel@lists.sf.net to add new cards to this list | 3 | Please contact dri-devel@lists.sf.net to add new cards to this list |
4 | */ | 4 | */ |
5 | #define radeon_PCI_IDS \ | 5 | #define radeon_PCI_IDS \ |
6 | {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350},\ | 6 | {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ |
7 | {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ | ||
8 | {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ | ||
9 | {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ | ||
10 | {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ | ||
7 | {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \ | 11 | {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \ |
8 | {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ | 12 | {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ |
9 | {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ | 13 | {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
10 | {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ | 14 | {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
11 | {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ | 15 | {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
12 | {0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ | 16 | {0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
17 | {0x1002, 0x4148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | ||
18 | {0x1002, 0x4149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | ||
19 | {0x1002, 0x414A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | ||
20 | {0x1002, 0x414B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | ||
13 | {0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 21 | {0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ |
14 | {0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 22 | {0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ |
15 | {0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 23 | {0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ |
16 | {0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 24 | {0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ |
17 | {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 25 | {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ |
26 | {0x1002, 0x4155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | ||
18 | {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 27 | {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ |
19 | {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP}, \ | 28 | {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ |
20 | {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 29 | {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ |
21 | {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 30 | {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ |
22 | {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ | 31 | {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ |
23 | {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ | 32 | {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ |
24 | {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ | 33 | {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ |
25 | {0x1002, 0x4964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ | 34 | {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \ |
26 | {0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ | 35 | {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \ |
27 | {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ | 36 | {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ |
28 | {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ | 37 | {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ |
29 | {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ | 38 | {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ |
30 | {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ | 39 | {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ |
40 | {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
41 | {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
42 | {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ | ||
43 | {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
44 | {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
45 | {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
46 | {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
47 | {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
48 | {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
49 | {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
31 | {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ | 50 | {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ |
32 | {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ | 51 | {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ |
33 | {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ | 52 | {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ |
34 | {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ | 53 | {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ |
35 | {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ | 54 | {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ |
36 | {0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ | 55 | {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ |
37 | {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ | 56 | {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ |
38 | {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ | ||
39 | {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ | 57 | {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
40 | {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ | 58 | {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
41 | {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 59 | {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
42 | {0x1002, 0x4E47, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ | 60 | {0x1002, 0x4E47, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
43 | {0x1002, 0x4E48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | 61 | {0x1002, 0x4E48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ |
44 | {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | 62 | {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ |
45 | {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 63 | {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ |
46 | {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | 64 | {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ |
47 | {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ | 65 | {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ |
48 | {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ | 66 | {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ |
67 | {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ | ||
68 | {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ | ||
49 | {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ | 69 | {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ |
50 | {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ | 70 | {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ |
51 | {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ | 71 | {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ |
@@ -53,44 +73,66 @@ | |||
53 | {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ | 73 | {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ |
54 | {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ | 74 | {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ |
55 | {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 75 | {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ |
56 | {0x1002, 0x5149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | ||
57 | {0x1002, 0x514A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | ||
58 | {0x1002, 0x514B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | ||
59 | {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 76 | {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ |
60 | {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 77 | {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ |
61 | {0x1002, 0x514E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | ||
62 | {0x1002, 0x514F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | ||
63 | {0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ | 78 | {0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ |
64 | {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ | 79 | {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ |
65 | {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ | 80 | {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ |
66 | {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ | 81 | {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ |
67 | {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ | 82 | {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ |
68 | {0x1002, 0x5168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 83 | {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ |
69 | {0x1002, 0x5169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 84 | {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ |
70 | {0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 85 | {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ |
71 | {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 86 | {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ |
72 | {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ | 87 | {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ |
73 | {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | 88 | {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ |
74 | {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | 89 | {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ |
90 | {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
91 | {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
92 | {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
93 | {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
94 | {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
95 | {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
96 | {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
97 | {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
98 | {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ | ||
99 | {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ | ||
100 | {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ | ||
101 | {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ | ||
102 | {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ | ||
75 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ | 103 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ |
76 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ | 104 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ |
77 | {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ | ||
78 | {0x1002, 0x5837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ | ||
79 | {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 105 | {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
80 | {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 106 | {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
81 | {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 107 | {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
82 | {0x1002, 0x5963, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | ||
83 | {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 108 | {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
84 | {0x1002, 0x5968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 109 | {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
85 | {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ | 110 | {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ |
86 | {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 111 | {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ |
87 | {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 112 | {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ |
113 | {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ | ||
114 | {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ | ||
115 | {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ | ||
88 | {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ | 116 | {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ |
89 | {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | ||
90 | {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ | 117 | {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ |
91 | {0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 118 | {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ |
92 | {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ | 119 | {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ |
93 | {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ | 120 | {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ |
121 | {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
122 | {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
123 | {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
124 | {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
125 | {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
126 | {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
127 | {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ | ||
128 | {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ | ||
129 | {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ | ||
130 | {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ | ||
131 | {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ | ||
132 | {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ | ||
133 | {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ | ||
134 | {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_NEW_MEMMAP}, \ | ||
135 | {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ | ||
94 | {0, 0, 0} | 136 | {0, 0, 0} |
95 | 137 | ||
96 | #define r128_PCI_IDS \ | 138 | #define r128_PCI_IDS \ |
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index 1ff4c7ca0bff..9f4b8ce4c05e 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
@@ -495,8 +495,6 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev, | |||
495 | } | 495 | } |
496 | } | 496 | } |
497 | 497 | ||
498 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; | ||
499 | |||
500 | i915_emit_breadcrumb(dev); | 498 | i915_emit_breadcrumb(dev); |
501 | 499 | ||
502 | return 0; | 500 | return 0; |
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index d3879ac9970f..a752afd86ab8 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c | |||
@@ -53,6 +53,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
53 | 53 | ||
54 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); | 54 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); |
55 | 55 | ||
56 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | ||
57 | |||
56 | if (temp & USER_INT_FLAG) | 58 | if (temp & USER_INT_FLAG) |
57 | DRM_WAKEUP(&dev_priv->irq_queue); | 59 | DRM_WAKEUP(&dev_priv->irq_queue); |
58 | 60 | ||
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index c08fa5076f05..b108c7f913b2 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c | |||
@@ -214,13 +214,13 @@ void r300_init_reg_flags(void) | |||
214 | ADD_RANGE(0x4F54, 1); | 214 | ADD_RANGE(0x4F54, 1); |
215 | 215 | ||
216 | ADD_RANGE(R300_TX_FILTER_0, 16); | 216 | ADD_RANGE(R300_TX_FILTER_0, 16); |
217 | ADD_RANGE(R300_TX_UNK1_0, 16); | 217 | ADD_RANGE(R300_TX_FILTER1_0, 16); |
218 | ADD_RANGE(R300_TX_SIZE_0, 16); | 218 | ADD_RANGE(R300_TX_SIZE_0, 16); |
219 | ADD_RANGE(R300_TX_FORMAT_0, 16); | 219 | ADD_RANGE(R300_TX_FORMAT_0, 16); |
220 | ADD_RANGE(R300_TX_PITCH_0, 16); | 220 | ADD_RANGE(R300_TX_PITCH_0, 16); |
221 | /* Texture offset is dangerous and needs more checking */ | 221 | /* Texture offset is dangerous and needs more checking */ |
222 | ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); | 222 | ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); |
223 | ADD_RANGE(R300_TX_UNK4_0, 16); | 223 | ADD_RANGE(R300_TX_CHROMA_KEY_0, 16); |
224 | ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); | 224 | ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); |
225 | 225 | ||
226 | /* Sporadic registers used as primitives are emitted */ | 226 | /* Sporadic registers used as primitives are emitted */ |
@@ -242,8 +242,10 @@ static __inline__ int r300_check_range(unsigned reg, int count) | |||
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
244 | 244 | ||
245 | /* we expect offsets passed to the framebuffer to be either within video memory or | 245 | /* |
246 | within AGP space */ | 246 | * we expect offsets passed to the framebuffer to be either within video |
247 | * memory or within AGP space | ||
248 | */ | ||
247 | static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, | 249 | static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, |
248 | u32 offset) | 250 | u32 offset) |
249 | { | 251 | { |
@@ -251,11 +253,11 @@ static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, | |||
251 | but this value is not being kept. | 253 | but this value is not being kept. |
252 | This code is correct for now (does the same thing as the | 254 | This code is correct for now (does the same thing as the |
253 | code that sets MC_FB_LOCATION) in radeon_cp.c */ | 255 | code that sets MC_FB_LOCATION) in radeon_cp.c */ |
254 | if ((offset >= dev_priv->fb_location) && | 256 | if (offset >= dev_priv->fb_location && |
255 | (offset < dev_priv->gart_vm_start)) | 257 | offset < (dev_priv->fb_location + dev_priv->fb_size)) |
256 | return 0; | 258 | return 0; |
257 | if ((offset >= dev_priv->gart_vm_start) && | 259 | if (offset >= dev_priv->gart_vm_start && |
258 | (offset < dev_priv->gart_vm_start + dev_priv->gart_size)) | 260 | offset < (dev_priv->gart_vm_start + dev_priv->gart_size)) |
259 | return 0; | 261 | return 0; |
260 | return 1; | 262 | return 1; |
261 | } | 263 | } |
@@ -490,6 +492,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, | |||
490 | 492 | ||
491 | return 0; | 493 | return 0; |
492 | } | 494 | } |
495 | |||
493 | static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, | 496 | static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, |
494 | drm_radeon_kcmd_buffer_t *cmdbuf) | 497 | drm_radeon_kcmd_buffer_t *cmdbuf) |
495 | { | 498 | { |
@@ -701,6 +704,64 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf) | |||
701 | buf->used = 0; | 704 | buf->used = 0; |
702 | } | 705 | } |
703 | 706 | ||
707 | static int r300_scratch(drm_radeon_private_t *dev_priv, | ||
708 | drm_radeon_kcmd_buffer_t *cmdbuf, | ||
709 | drm_r300_cmd_header_t header) | ||
710 | { | ||
711 | u32 *ref_age_base; | ||
712 | u32 i, buf_idx, h_pending; | ||
713 | RING_LOCALS; | ||
714 | |||
715 | if (cmdbuf->bufsz < | ||
716 | (sizeof(u64) + header.scratch.n_bufs * sizeof(buf_idx))) { | ||
717 | return DRM_ERR(EINVAL); | ||
718 | } | ||
719 | |||
720 | if (header.scratch.reg >= 5) { | ||
721 | return DRM_ERR(EINVAL); | ||
722 | } | ||
723 | |||
724 | dev_priv->scratch_ages[header.scratch.reg]++; | ||
725 | |||
726 | ref_age_base = *(u32 **)cmdbuf->buf; | ||
727 | |||
728 | cmdbuf->buf += sizeof(u64); | ||
729 | cmdbuf->bufsz -= sizeof(u64); | ||
730 | |||
731 | for (i=0; i < header.scratch.n_bufs; i++) { | ||
732 | buf_idx = *(u32 *)cmdbuf->buf; | ||
733 | buf_idx *= 2; /* 8 bytes per buf */ | ||
734 | |||
735 | if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) { | ||
736 | return DRM_ERR(EINVAL); | ||
737 | } | ||
738 | |||
739 | if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) { | ||
740 | return DRM_ERR(EINVAL); | ||
741 | } | ||
742 | |||
743 | if (h_pending == 0) { | ||
744 | return DRM_ERR(EINVAL); | ||
745 | } | ||
746 | |||
747 | h_pending--; | ||
748 | |||
749 | if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) { | ||
750 | return DRM_ERR(EINVAL); | ||
751 | } | ||
752 | |||
753 | cmdbuf->buf += sizeof(buf_idx); | ||
754 | cmdbuf->bufsz -= sizeof(buf_idx); | ||
755 | } | ||
756 | |||
757 | BEGIN_RING(2); | ||
758 | OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0)); | ||
759 | OUT_RING(dev_priv->scratch_ages[header.scratch.reg]); | ||
760 | ADVANCE_RING(); | ||
761 | |||
762 | return 0; | ||
763 | } | ||
764 | |||
704 | /** | 765 | /** |
705 | * Parses and validates a user-supplied command buffer and emits appropriate | 766 | * Parses and validates a user-supplied command buffer and emits appropriate |
706 | * commands on the DMA ring buffer. | 767 | * commands on the DMA ring buffer. |
@@ -838,6 +899,15 @@ int r300_do_cp_cmdbuf(drm_device_t *dev, | |||
838 | } | 899 | } |
839 | break; | 900 | break; |
840 | 901 | ||
902 | case R300_CMD_SCRATCH: | ||
903 | DRM_DEBUG("R300_CMD_SCRATCH\n"); | ||
904 | ret = r300_scratch(dev_priv, cmdbuf, header); | ||
905 | if (ret) { | ||
906 | DRM_ERROR("r300_scratch failed\n"); | ||
907 | goto cleanup; | ||
908 | } | ||
909 | break; | ||
910 | |||
841 | default: | 911 | default: |
842 | DRM_ERROR("bad cmd_type %i at %p\n", | 912 | DRM_ERROR("bad cmd_type %i at %p\n", |
843 | header.header.cmd_type, | 913 | header.header.cmd_type, |
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h index d1e19954406b..a881f96c983e 100644 --- a/drivers/char/drm/r300_reg.h +++ b/drivers/char/drm/r300_reg.h | |||
@@ -711,8 +711,22 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
711 | # define R300_TX_MAX_ANISO_16_TO_1 (8 << 21) | 711 | # define R300_TX_MAX_ANISO_16_TO_1 (8 << 21) |
712 | # define R300_TX_MAX_ANISO_MASK (14 << 21) | 712 | # define R300_TX_MAX_ANISO_MASK (14 << 21) |
713 | 713 | ||
714 | #define R300_TX_UNK1_0 0x4440 | 714 | #define R300_TX_FILTER1_0 0x4440 |
715 | # define R300_CHROMA_KEY_MODE_DISABLE 0 | ||
716 | # define R300_CHROMA_KEY_FORCE 1 | ||
717 | # define R300_CHROMA_KEY_BLEND 2 | ||
718 | # define R300_MC_ROUND_NORMAL (0<<2) | ||
719 | # define R300_MC_ROUND_MPEG4 (1<<2) | ||
715 | # define R300_LOD_BIAS_MASK 0x1fff | 720 | # define R300_LOD_BIAS_MASK 0x1fff |
721 | # define R300_EDGE_ANISO_EDGE_DIAG (0<<13) | ||
722 | # define R300_EDGE_ANISO_EDGE_ONLY (1<<13) | ||
723 | # define R300_MC_COORD_TRUNCATE_DISABLE (0<<14) | ||
724 | # define R300_MC_COORD_TRUNCATE_MPEG (1<<14) | ||
725 | # define R300_TX_TRI_PERF_0_8 (0<<15) | ||
726 | # define R300_TX_TRI_PERF_1_8 (1<<15) | ||
727 | # define R300_TX_TRI_PERF_1_4 (2<<15) | ||
728 | # define R300_TX_TRI_PERF_3_8 (3<<15) | ||
729 | # define R300_ANISO_THRESHOLD_MASK (7<<17) | ||
716 | 730 | ||
717 | #define R300_TX_SIZE_0 0x4480 | 731 | #define R300_TX_SIZE_0 0x4480 |
718 | # define R300_TX_WIDTHMASK_SHIFT 0 | 732 | # define R300_TX_WIDTHMASK_SHIFT 0 |
@@ -722,6 +736,8 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
722 | # define R300_TX_UNK23 (1 << 23) | 736 | # define R300_TX_UNK23 (1 << 23) |
723 | # define R300_TX_SIZE_SHIFT 26 /* largest of width, height */ | 737 | # define R300_TX_SIZE_SHIFT 26 /* largest of width, height */ |
724 | # define R300_TX_SIZE_MASK (15 << 26) | 738 | # define R300_TX_SIZE_MASK (15 << 26) |
739 | # define R300_TX_SIZE_PROJECTED (1<<30) | ||
740 | # define R300_TX_SIZE_TXPITCH_EN (1<<31) | ||
725 | #define R300_TX_FORMAT_0 0x44C0 | 741 | #define R300_TX_FORMAT_0 0x44C0 |
726 | /* The interpretation of the format word by Wladimir van der Laan */ | 742 | /* The interpretation of the format word by Wladimir van der Laan */ |
727 | /* The X, Y, Z and W refer to the layout of the components. | 743 | /* The X, Y, Z and W refer to the layout of the components. |
@@ -750,7 +766,8 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
750 | # define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ | 766 | # define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ |
751 | # define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ | 767 | # define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ |
752 | /* 0x16 - some 16 bit green format.. ?? */ | 768 | /* 0x16 - some 16 bit green format.. ?? */ |
753 | # define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ | 769 | # define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ |
770 | # define R300_TX_FORMAT_CUBIC_MAP (1 << 26) | ||
754 | 771 | ||
755 | /* gap */ | 772 | /* gap */ |
756 | /* Floating point formats */ | 773 | /* Floating point formats */ |
@@ -800,18 +817,20 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
800 | 817 | ||
801 | # define R300_TX_FORMAT_YUV_MODE 0x00800000 | 818 | # define R300_TX_FORMAT_YUV_MODE 0x00800000 |
802 | 819 | ||
803 | #define R300_TX_PITCH_0 0x4500 | 820 | #define R300_TX_PITCH_0 0x4500 /* obvious missing in gap */ |
804 | #define R300_TX_OFFSET_0 0x4540 | 821 | #define R300_TX_OFFSET_0 0x4540 |
805 | /* BEGIN: Guess from R200 */ | 822 | /* BEGIN: Guess from R200 */ |
806 | # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) | 823 | # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) |
807 | # define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) | 824 | # define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) |
808 | # define R300_TXO_ENDIAN_WORD_SWAP (2 << 0) | 825 | # define R300_TXO_ENDIAN_WORD_SWAP (2 << 0) |
809 | # define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0) | 826 | # define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0) |
827 | # define R300_TXO_MACRO_TILE (1 << 2) | ||
828 | # define R300_TXO_MICRO_TILE (1 << 3) | ||
810 | # define R300_TXO_OFFSET_MASK 0xffffffe0 | 829 | # define R300_TXO_OFFSET_MASK 0xffffffe0 |
811 | # define R300_TXO_OFFSET_SHIFT 5 | 830 | # define R300_TXO_OFFSET_SHIFT 5 |
812 | /* END */ | 831 | /* END */ |
813 | #define R300_TX_UNK4_0 0x4580 | 832 | #define R300_TX_CHROMA_KEY_0 0x4580 /* 32 bit chroma key */ |
814 | #define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 } | 833 | #define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 } |
815 | 834 | ||
816 | /* END */ | 835 | /* END */ |
817 | 836 | ||
@@ -868,7 +887,9 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
868 | # define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12) | 887 | # define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12) |
869 | # define R300_PFS_NODE_TEX_END_SHIFT 17 | 888 | # define R300_PFS_NODE_TEX_END_SHIFT 17 |
870 | # define R300_PFS_NODE_TEX_END_MASK (31 << 17) | 889 | # define R300_PFS_NODE_TEX_END_MASK (31 << 17) |
871 | # define R300_PFS_NODE_LAST_NODE (1 << 22) | 890 | /*# define R300_PFS_NODE_LAST_NODE (1 << 22) */ |
891 | # define R300_PFS_NODE_OUTPUT_COLOR (1 << 22) | ||
892 | # define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23) | ||
872 | 893 | ||
873 | /* TEX | 894 | /* TEX |
874 | // As far as I can tell, texture instructions cannot write into output | 895 | // As far as I can tell, texture instructions cannot write into output |
@@ -887,6 +908,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
887 | */ | 908 | */ |
888 | # define R300_FPITX_OPCODE_SHIFT 15 | 909 | # define R300_FPITX_OPCODE_SHIFT 15 |
889 | # define R300_FPITX_OP_TEX 1 | 910 | # define R300_FPITX_OP_TEX 1 |
911 | # define R300_FPITX_OP_KIL 2 | ||
890 | # define R300_FPITX_OP_TXP 3 | 912 | # define R300_FPITX_OP_TXP 3 |
891 | # define R300_FPITX_OP_TXB 4 | 913 | # define R300_FPITX_OP_TXB 4 |
892 | 914 | ||
@@ -962,9 +984,11 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
962 | # define R300_FPI1_SRC2C_CONST (1 << 17) | 984 | # define R300_FPI1_SRC2C_CONST (1 << 17) |
963 | # define R300_FPI1_DSTC_SHIFT 18 | 985 | # define R300_FPI1_DSTC_SHIFT 18 |
964 | # define R300_FPI1_DSTC_MASK (31 << 18) | 986 | # define R300_FPI1_DSTC_MASK (31 << 18) |
987 | # define R300_FPI1_DSTC_REG_MASK_SHIFT 23 | ||
965 | # define R300_FPI1_DSTC_REG_X (1 << 23) | 988 | # define R300_FPI1_DSTC_REG_X (1 << 23) |
966 | # define R300_FPI1_DSTC_REG_Y (1 << 24) | 989 | # define R300_FPI1_DSTC_REG_Y (1 << 24) |
967 | # define R300_FPI1_DSTC_REG_Z (1 << 25) | 990 | # define R300_FPI1_DSTC_REG_Z (1 << 25) |
991 | # define R300_FPI1_DSTC_OUTPUT_MASK_SHIFT 26 | ||
968 | # define R300_FPI1_DSTC_OUTPUT_X (1 << 26) | 992 | # define R300_FPI1_DSTC_OUTPUT_X (1 << 26) |
969 | # define R300_FPI1_DSTC_OUTPUT_Y (1 << 27) | 993 | # define R300_FPI1_DSTC_OUTPUT_Y (1 << 27) |
970 | # define R300_FPI1_DSTC_OUTPUT_Z (1 << 28) | 994 | # define R300_FPI1_DSTC_OUTPUT_Z (1 << 28) |
@@ -983,6 +1007,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
983 | # define R300_FPI3_DSTA_MASK (31 << 18) | 1007 | # define R300_FPI3_DSTA_MASK (31 << 18) |
984 | # define R300_FPI3_DSTA_REG (1 << 23) | 1008 | # define R300_FPI3_DSTA_REG (1 << 23) |
985 | # define R300_FPI3_DSTA_OUTPUT (1 << 24) | 1009 | # define R300_FPI3_DSTA_OUTPUT (1 << 24) |
1010 | # define R300_FPI3_DSTA_DEPTH (1 << 27) | ||
986 | 1011 | ||
987 | #define R300_PFS_INSTR0_0 0x48C0 | 1012 | #define R300_PFS_INSTR0_0 0x48C0 |
988 | # define R300_FPI0_ARGC_SRC0C_XYZ 0 | 1013 | # define R300_FPI0_ARGC_SRC0C_XYZ 0 |
@@ -1036,7 +1061,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
1036 | # define R300_FPI0_OUTC_FRC (9 << 23) | 1061 | # define R300_FPI0_OUTC_FRC (9 << 23) |
1037 | # define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) | 1062 | # define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) |
1038 | # define R300_FPI0_OUTC_SAT (1 << 30) | 1063 | # define R300_FPI0_OUTC_SAT (1 << 30) |
1039 | # define R300_FPI0_UNKNOWN_31 (1 << 31) | 1064 | # define R300_FPI0_INSERT_NOP (1 << 31) |
1040 | 1065 | ||
1041 | #define R300_PFS_INSTR2_0 0x49C0 | 1066 | #define R300_PFS_INSTR2_0 0x49C0 |
1042 | # define R300_FPI2_ARGA_SRC0C_X 0 | 1067 | # define R300_FPI2_ARGA_SRC0C_X 0 |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 9bb8ae0c1c27..7f949c9c9691 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -1118,14 +1118,20 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, | |||
1118 | { | 1118 | { |
1119 | u32 ring_start, cur_read_ptr; | 1119 | u32 ring_start, cur_read_ptr; |
1120 | u32 tmp; | 1120 | u32 tmp; |
1121 | 1121 | ||
1122 | /* Initialize the memory controller */ | 1122 | /* Initialize the memory controller. With new memory map, the fb location |
1123 | RADEON_WRITE(RADEON_MC_FB_LOCATION, | 1123 | * is not changed, it should have been properly initialized already. Part |
1124 | ((dev_priv->gart_vm_start - 1) & 0xffff0000) | 1124 | * of the problem is that the code below is bogus, assuming the GART is |
1125 | | (dev_priv->fb_location >> 16)); | 1125 | * always appended to the fb which is not necessarily the case |
1126 | */ | ||
1127 | if (!dev_priv->new_memmap) | ||
1128 | RADEON_WRITE(RADEON_MC_FB_LOCATION, | ||
1129 | ((dev_priv->gart_vm_start - 1) & 0xffff0000) | ||
1130 | | (dev_priv->fb_location >> 16)); | ||
1126 | 1131 | ||
1127 | #if __OS_HAS_AGP | 1132 | #if __OS_HAS_AGP |
1128 | if (dev_priv->flags & CHIP_IS_AGP) { | 1133 | if (dev_priv->flags & CHIP_IS_AGP) { |
1134 | RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); | ||
1129 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, | 1135 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, |
1130 | (((dev_priv->gart_vm_start - 1 + | 1136 | (((dev_priv->gart_vm_start - 1 + |
1131 | dev_priv->gart_size) & 0xffff0000) | | 1137 | dev_priv->gart_size) & 0xffff0000) | |
@@ -1153,8 +1159,6 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, | |||
1153 | 1159 | ||
1154 | #if __OS_HAS_AGP | 1160 | #if __OS_HAS_AGP |
1155 | if (dev_priv->flags & CHIP_IS_AGP) { | 1161 | if (dev_priv->flags & CHIP_IS_AGP) { |
1156 | /* set RADEON_AGP_BASE here instead of relying on X from user space */ | ||
1157 | RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); | ||
1158 | RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, | 1162 | RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, |
1159 | dev_priv->ring_rptr->offset | 1163 | dev_priv->ring_rptr->offset |
1160 | - dev->agp->base + dev_priv->gart_vm_start); | 1164 | - dev->agp->base + dev_priv->gart_vm_start); |
@@ -1174,6 +1178,17 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, | |||
1174 | entry->handle + tmp_ofs); | 1178 | entry->handle + tmp_ofs); |
1175 | } | 1179 | } |
1176 | 1180 | ||
1181 | /* Set ring buffer size */ | ||
1182 | #ifdef __BIG_ENDIAN | ||
1183 | RADEON_WRITE(RADEON_CP_RB_CNTL, | ||
1184 | dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT); | ||
1185 | #else | ||
1186 | RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw); | ||
1187 | #endif | ||
1188 | |||
1189 | /* Start with assuming that writeback doesn't work */ | ||
1190 | dev_priv->writeback_works = 0; | ||
1191 | |||
1177 | /* Initialize the scratch register pointer. This will cause | 1192 | /* Initialize the scratch register pointer. This will cause |
1178 | * the scratch register values to be written out to memory | 1193 | * the scratch register values to be written out to memory |
1179 | * whenever they are updated. | 1194 | * whenever they are updated. |
@@ -1190,28 +1205,9 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, | |||
1190 | 1205 | ||
1191 | RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); | 1206 | RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); |
1192 | 1207 | ||
1193 | /* Writeback doesn't seem to work everywhere, test it first */ | 1208 | /* Turn on bus mastering */ |
1194 | DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); | 1209 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
1195 | RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); | 1210 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); |
1196 | |||
1197 | for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { | ||
1198 | if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == | ||
1199 | 0xdeadbeef) | ||
1200 | break; | ||
1201 | DRM_UDELAY(1); | ||
1202 | } | ||
1203 | |||
1204 | if (tmp < dev_priv->usec_timeout) { | ||
1205 | dev_priv->writeback_works = 1; | ||
1206 | DRM_DEBUG("writeback test succeeded, tmp=%d\n", tmp); | ||
1207 | } else { | ||
1208 | dev_priv->writeback_works = 0; | ||
1209 | DRM_DEBUG("writeback test failed\n"); | ||
1210 | } | ||
1211 | if (radeon_no_wb == 1) { | ||
1212 | dev_priv->writeback_works = 0; | ||
1213 | DRM_DEBUG("writeback forced off\n"); | ||
1214 | } | ||
1215 | 1211 | ||
1216 | dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; | 1212 | dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; |
1217 | RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); | 1213 | RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); |
@@ -1223,26 +1219,45 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, | |||
1223 | dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; | 1219 | dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; |
1224 | RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); | 1220 | RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); |
1225 | 1221 | ||
1226 | /* Set ring buffer size */ | ||
1227 | #ifdef __BIG_ENDIAN | ||
1228 | RADEON_WRITE(RADEON_CP_RB_CNTL, | ||
1229 | dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT); | ||
1230 | #else | ||
1231 | RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw); | ||
1232 | #endif | ||
1233 | |||
1234 | radeon_do_wait_for_idle(dev_priv); | 1222 | radeon_do_wait_for_idle(dev_priv); |
1235 | 1223 | ||
1236 | /* Turn on bus mastering */ | ||
1237 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | ||
1238 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | ||
1239 | |||
1240 | /* Sync everything up */ | 1224 | /* Sync everything up */ |
1241 | RADEON_WRITE(RADEON_ISYNC_CNTL, | 1225 | RADEON_WRITE(RADEON_ISYNC_CNTL, |
1242 | (RADEON_ISYNC_ANY2D_IDLE3D | | 1226 | (RADEON_ISYNC_ANY2D_IDLE3D | |
1243 | RADEON_ISYNC_ANY3D_IDLE2D | | 1227 | RADEON_ISYNC_ANY3D_IDLE2D | |
1244 | RADEON_ISYNC_WAIT_IDLEGUI | | 1228 | RADEON_ISYNC_WAIT_IDLEGUI | |
1245 | RADEON_ISYNC_CPSCRATCH_IDLEGUI)); | 1229 | RADEON_ISYNC_CPSCRATCH_IDLEGUI)); |
1230 | |||
1231 | } | ||
1232 | |||
1233 | static void radeon_test_writeback(drm_radeon_private_t * dev_priv) | ||
1234 | { | ||
1235 | u32 tmp; | ||
1236 | |||
1237 | /* Writeback doesn't seem to work everywhere, test it here and possibly | ||
1238 | * enable it if it appears to work | ||
1239 | */ | ||
1240 | DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); | ||
1241 | RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); | ||
1242 | |||
1243 | for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { | ||
1244 | if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == | ||
1245 | 0xdeadbeef) | ||
1246 | break; | ||
1247 | DRM_UDELAY(1); | ||
1248 | } | ||
1249 | |||
1250 | if (tmp < dev_priv->usec_timeout) { | ||
1251 | dev_priv->writeback_works = 1; | ||
1252 | DRM_INFO("writeback test succeeded in %d usecs\n", tmp); | ||
1253 | } else { | ||
1254 | dev_priv->writeback_works = 0; | ||
1255 | DRM_INFO("writeback test failed\n"); | ||
1256 | } | ||
1257 | if (radeon_no_wb == 1) { | ||
1258 | dev_priv->writeback_works = 0; | ||
1259 | DRM_INFO("writeback forced off\n"); | ||
1260 | } | ||
1246 | } | 1261 | } |
1247 | 1262 | ||
1248 | /* Enable or disable PCI-E GART on the chip */ | 1263 | /* Enable or disable PCI-E GART on the chip */ |
@@ -1317,6 +1332,14 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1317 | 1332 | ||
1318 | DRM_DEBUG("\n"); | 1333 | DRM_DEBUG("\n"); |
1319 | 1334 | ||
1335 | /* if we require new memory map but we don't have it fail */ | ||
1336 | if ((dev_priv->flags & CHIP_NEW_MEMMAP) && !dev_priv->new_memmap) | ||
1337 | { | ||
1338 | DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX\n"); | ||
1339 | radeon_do_cleanup_cp(dev); | ||
1340 | return DRM_ERR(EINVAL); | ||
1341 | } | ||
1342 | |||
1320 | if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) | 1343 | if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) |
1321 | { | 1344 | { |
1322 | DRM_DEBUG("Forcing AGP card to PCI mode\n"); | 1345 | DRM_DEBUG("Forcing AGP card to PCI mode\n"); |
@@ -1496,6 +1519,9 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1496 | 1519 | ||
1497 | dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION) | 1520 | dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION) |
1498 | & 0xffff) << 16; | 1521 | & 0xffff) << 16; |
1522 | dev_priv->fb_size = | ||
1523 | ((RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000u) + 0x10000) | ||
1524 | - dev_priv->fb_location; | ||
1499 | 1525 | ||
1500 | dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | | 1526 | dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | |
1501 | ((dev_priv->front_offset | 1527 | ((dev_priv->front_offset |
@@ -1510,8 +1536,46 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1510 | + dev_priv->fb_location) >> 10)); | 1536 | + dev_priv->fb_location) >> 10)); |
1511 | 1537 | ||
1512 | dev_priv->gart_size = init->gart_size; | 1538 | dev_priv->gart_size = init->gart_size; |
1513 | dev_priv->gart_vm_start = dev_priv->fb_location | 1539 | |
1514 | + RADEON_READ(RADEON_CONFIG_APER_SIZE); | 1540 | /* New let's set the memory map ... */ |
1541 | if (dev_priv->new_memmap) { | ||
1542 | u32 base = 0; | ||
1543 | |||
1544 | DRM_INFO("Setting GART location based on new memory map\n"); | ||
1545 | |||
1546 | /* If using AGP, try to locate the AGP aperture at the same | ||
1547 | * location in the card and on the bus, though we have to | ||
1548 | * align it down. | ||
1549 | */ | ||
1550 | #if __OS_HAS_AGP | ||
1551 | if (dev_priv->flags & CHIP_IS_AGP) { | ||
1552 | base = dev->agp->base; | ||
1553 | /* Check if valid */ | ||
1554 | if ((base + dev_priv->gart_size) > dev_priv->fb_location && | ||
1555 | base < (dev_priv->fb_location + dev_priv->fb_size)) { | ||
1556 | DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", | ||
1557 | dev->agp->base); | ||
1558 | base = 0; | ||
1559 | } | ||
1560 | } | ||
1561 | #endif | ||
1562 | /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ | ||
1563 | if (base == 0) { | ||
1564 | base = dev_priv->fb_location + dev_priv->fb_size; | ||
1565 | if (((base + dev_priv->gart_size) & 0xfffffffful) | ||
1566 | < base) | ||
1567 | base = dev_priv->fb_location | ||
1568 | - dev_priv->gart_size; | ||
1569 | } | ||
1570 | dev_priv->gart_vm_start = base & 0xffc00000u; | ||
1571 | if (dev_priv->gart_vm_start != base) | ||
1572 | DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", | ||
1573 | base, dev_priv->gart_vm_start); | ||
1574 | } else { | ||
1575 | DRM_INFO("Setting GART location based on old memory map\n"); | ||
1576 | dev_priv->gart_vm_start = dev_priv->fb_location + | ||
1577 | RADEON_READ(RADEON_CONFIG_APER_SIZE); | ||
1578 | } | ||
1515 | 1579 | ||
1516 | #if __OS_HAS_AGP | 1580 | #if __OS_HAS_AGP |
1517 | if (dev_priv->flags & CHIP_IS_AGP) | 1581 | if (dev_priv->flags & CHIP_IS_AGP) |
@@ -1596,6 +1660,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1596 | dev_priv->last_buf = 0; | 1660 | dev_priv->last_buf = 0; |
1597 | 1661 | ||
1598 | radeon_do_engine_reset(dev); | 1662 | radeon_do_engine_reset(dev); |
1663 | radeon_test_writeback(dev_priv); | ||
1599 | 1664 | ||
1600 | return 0; | 1665 | return 0; |
1601 | } | 1666 | } |
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h index 9c177a6b2a4c..c8e279e89c2e 100644 --- a/drivers/char/drm/radeon_drm.h +++ b/drivers/char/drm/radeon_drm.h | |||
@@ -222,6 +222,7 @@ typedef union { | |||
222 | # define R300_WAIT_3D 0x2 | 222 | # define R300_WAIT_3D 0x2 |
223 | # define R300_WAIT_2D_CLEAN 0x3 | 223 | # define R300_WAIT_2D_CLEAN 0x3 |
224 | # define R300_WAIT_3D_CLEAN 0x4 | 224 | # define R300_WAIT_3D_CLEAN 0x4 |
225 | #define R300_CMD_SCRATCH 8 | ||
225 | 226 | ||
226 | typedef union { | 227 | typedef union { |
227 | unsigned int u; | 228 | unsigned int u; |
@@ -247,6 +248,9 @@ typedef union { | |||
247 | struct { | 248 | struct { |
248 | unsigned char cmd_type, flags, pad0, pad1; | 249 | unsigned char cmd_type, flags, pad0, pad1; |
249 | } wait; | 250 | } wait; |
251 | struct { | ||
252 | unsigned char cmd_type, reg, n_bufs, flags; | ||
253 | } scratch; | ||
250 | } drm_r300_cmd_header_t; | 254 | } drm_r300_cmd_header_t; |
251 | 255 | ||
252 | #define RADEON_FRONT 0x1 | 256 | #define RADEON_FRONT 0x1 |
@@ -697,6 +701,7 @@ typedef struct drm_radeon_setparam { | |||
697 | #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ | 701 | #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ |
698 | #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ | 702 | #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ |
699 | #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ | 703 | #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ |
704 | #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ | ||
700 | 705 | ||
701 | /* 1.14: Clients can allocate/free a surface | 706 | /* 1.14: Clients can allocate/free a surface |
702 | */ | 707 | */ |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 1f7d2ab8c4fc..78345cee8f8e 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #define DRIVER_NAME "radeon" | 39 | #define DRIVER_NAME "radeon" |
40 | #define DRIVER_DESC "ATI Radeon" | 40 | #define DRIVER_DESC "ATI Radeon" |
41 | #define DRIVER_DATE "20051229" | 41 | #define DRIVER_DATE "20060225" |
42 | 42 | ||
43 | /* Interface history: | 43 | /* Interface history: |
44 | * | 44 | * |
@@ -91,9 +91,11 @@ | |||
91 | * 1.20- Add support for r300 texrect | 91 | * 1.20- Add support for r300 texrect |
92 | * 1.21- Add support for card type getparam | 92 | * 1.21- Add support for card type getparam |
93 | * 1.22- Add support for texture cache flushes (R300_TX_CNTL) | 93 | * 1.22- Add support for texture cache flushes (R300_TX_CNTL) |
94 | * 1.23- Add new radeon memory map work from benh | ||
95 | * 1.24- Add general-purpose packet for manipulating scratch registers (r300) | ||
94 | */ | 96 | */ |
95 | #define DRIVER_MAJOR 1 | 97 | #define DRIVER_MAJOR 1 |
96 | #define DRIVER_MINOR 22 | 98 | #define DRIVER_MINOR 24 |
97 | #define DRIVER_PATCHLEVEL 0 | 99 | #define DRIVER_PATCHLEVEL 0 |
98 | 100 | ||
99 | /* | 101 | /* |
@@ -101,20 +103,21 @@ | |||
101 | */ | 103 | */ |
102 | enum radeon_family { | 104 | enum radeon_family { |
103 | CHIP_R100, | 105 | CHIP_R100, |
104 | CHIP_RS100, | ||
105 | CHIP_RV100, | 106 | CHIP_RV100, |
107 | CHIP_RS100, | ||
106 | CHIP_RV200, | 108 | CHIP_RV200, |
107 | CHIP_R200, | ||
108 | CHIP_RS200, | 109 | CHIP_RS200, |
109 | CHIP_R250, | 110 | CHIP_R200, |
110 | CHIP_RS250, | ||
111 | CHIP_RV250, | 111 | CHIP_RV250, |
112 | CHIP_RS300, | ||
112 | CHIP_RV280, | 113 | CHIP_RV280, |
113 | CHIP_R300, | 114 | CHIP_R300, |
114 | CHIP_RS300, | ||
115 | CHIP_R350, | 115 | CHIP_R350, |
116 | CHIP_RV350, | 116 | CHIP_RV350, |
117 | CHIP_RV380, | ||
117 | CHIP_R420, | 118 | CHIP_R420, |
119 | CHIP_RV410, | ||
120 | CHIP_RS400, | ||
118 | CHIP_LAST, | 121 | CHIP_LAST, |
119 | }; | 122 | }; |
120 | 123 | ||
@@ -136,9 +139,11 @@ enum radeon_chip_flags { | |||
136 | CHIP_IS_AGP = 0x00080000UL, | 139 | CHIP_IS_AGP = 0x00080000UL, |
137 | CHIP_HAS_HIERZ = 0x00100000UL, | 140 | CHIP_HAS_HIERZ = 0x00100000UL, |
138 | CHIP_IS_PCIE = 0x00200000UL, | 141 | CHIP_IS_PCIE = 0x00200000UL, |
142 | CHIP_NEW_MEMMAP = 0x00400000UL, | ||
139 | }; | 143 | }; |
140 | 144 | ||
141 | #define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) | 145 | #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ |
146 | DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR)) | ||
142 | #define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) | 147 | #define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) |
143 | 148 | ||
144 | typedef struct drm_radeon_freelist { | 149 | typedef struct drm_radeon_freelist { |
@@ -199,6 +204,8 @@ typedef struct drm_radeon_private { | |||
199 | drm_radeon_sarea_t *sarea_priv; | 204 | drm_radeon_sarea_t *sarea_priv; |
200 | 205 | ||
201 | u32 fb_location; | 206 | u32 fb_location; |
207 | u32 fb_size; | ||
208 | int new_memmap; | ||
202 | 209 | ||
203 | int gart_size; | 210 | int gart_size; |
204 | u32 gart_vm_start; | 211 | u32 gart_vm_start; |
@@ -272,6 +279,8 @@ typedef struct drm_radeon_private { | |||
272 | unsigned long pcigart_offset; | 279 | unsigned long pcigart_offset; |
273 | drm_ati_pcigart_info gart_info; | 280 | drm_ati_pcigart_info gart_info; |
274 | 281 | ||
282 | u32 scratch_ages[5]; | ||
283 | |||
275 | /* starting from here on, data is preserved accross an open */ | 284 | /* starting from here on, data is preserved accross an open */ |
276 | uint32_t flags; /* see radeon_chip_flags */ | 285 | uint32_t flags; /* see radeon_chip_flags */ |
277 | } drm_radeon_private_t; | 286 | } drm_radeon_private_t; |
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 7bc27516d425..c5b8f774a599 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c | |||
@@ -45,22 +45,53 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * | |||
45 | u32 off = *offset; | 45 | u32 off = *offset; |
46 | struct drm_radeon_driver_file_fields *radeon_priv; | 46 | struct drm_radeon_driver_file_fields *radeon_priv; |
47 | 47 | ||
48 | if (off >= dev_priv->fb_location && | 48 | /* Hrm ... the story of the offset ... So this function converts |
49 | off < (dev_priv->gart_vm_start + dev_priv->gart_size)) | 49 | * the various ideas of what userland clients might have for an |
50 | return 0; | 50 | * offset in the card address space into an offset into the card |
51 | 51 | * address space :) So with a sane client, it should just keep | |
52 | radeon_priv = filp_priv->driver_priv; | 52 | * the value intact and just do some boundary checking. However, |
53 | off += radeon_priv->radeon_fb_delta; | 53 | * not all clients are sane. Some older clients pass us 0 based |
54 | * offsets relative to the start of the framebuffer and some may | ||
55 | * assume the AGP aperture it appended to the framebuffer, so we | ||
56 | * try to detect those cases and fix them up. | ||
57 | * | ||
58 | * Note: It might be a good idea here to make sure the offset lands | ||
59 | * in some "allowed" area to protect things like the PCIE GART... | ||
60 | */ | ||
54 | 61 | ||
55 | DRM_DEBUG("offset fixed up to 0x%x\n", off); | 62 | /* First, the best case, the offset already lands in either the |
63 | * framebuffer or the GART mapped space | ||
64 | */ | ||
65 | if ((off >= dev_priv->fb_location && | ||
66 | off < (dev_priv->fb_location + dev_priv->fb_size)) || | ||
67 | (off >= dev_priv->gart_vm_start && | ||
68 | off < (dev_priv->gart_vm_start + dev_priv->gart_size))) | ||
69 | return 0; | ||
56 | 70 | ||
57 | if (off < dev_priv->fb_location || | 71 | /* Ok, that didn't happen... now check if we have a zero based |
58 | off >= (dev_priv->gart_vm_start + dev_priv->gart_size)) | 72 | * offset that fits in the framebuffer + gart space, apply the |
59 | return DRM_ERR(EINVAL); | 73 | * magic offset we get from SETPARAM or calculated from fb_location |
74 | */ | ||
75 | if (off < (dev_priv->fb_size + dev_priv->gart_size)) { | ||
76 | radeon_priv = filp_priv->driver_priv; | ||
77 | off += radeon_priv->radeon_fb_delta; | ||
78 | } | ||
60 | 79 | ||
61 | *offset = off; | 80 | /* Finally, assume we aimed at a GART offset if beyond the fb */ |
81 | if (off > (dev_priv->fb_location + dev_priv->fb_size)) | ||
82 | off = off - (dev_priv->fb_location + dev_priv->fb_size) + | ||
83 | dev_priv->gart_vm_start; | ||
62 | 84 | ||
63 | return 0; | 85 | /* Now recheck and fail if out of bounds */ |
86 | if ((off >= dev_priv->fb_location && | ||
87 | off < (dev_priv->fb_location + dev_priv->fb_size)) || | ||
88 | (off >= dev_priv->gart_vm_start && | ||
89 | off < (dev_priv->gart_vm_start + dev_priv->gart_size))) { | ||
90 | DRM_DEBUG("offset fixed up to 0x%x\n", off); | ||
91 | *offset = off; | ||
92 | return 0; | ||
93 | } | ||
94 | return DRM_ERR(EINVAL); | ||
64 | } | 95 | } |
65 | 96 | ||
66 | static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * | 97 | static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * |
@@ -1939,11 +1970,6 @@ static int radeon_surface_alloc(DRM_IOCTL_ARGS) | |||
1939 | drm_radeon_private_t *dev_priv = dev->dev_private; | 1970 | drm_radeon_private_t *dev_priv = dev->dev_private; |
1940 | drm_radeon_surface_alloc_t alloc; | 1971 | drm_radeon_surface_alloc_t alloc; |
1941 | 1972 | ||
1942 | if (!dev_priv) { | ||
1943 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
1944 | return DRM_ERR(EINVAL); | ||
1945 | } | ||
1946 | |||
1947 | DRM_COPY_FROM_USER_IOCTL(alloc, | 1973 | DRM_COPY_FROM_USER_IOCTL(alloc, |
1948 | (drm_radeon_surface_alloc_t __user *) data, | 1974 | (drm_radeon_surface_alloc_t __user *) data, |
1949 | sizeof(alloc)); | 1975 | sizeof(alloc)); |
@@ -1960,12 +1986,7 @@ static int radeon_surface_free(DRM_IOCTL_ARGS) | |||
1960 | drm_radeon_private_t *dev_priv = dev->dev_private; | 1986 | drm_radeon_private_t *dev_priv = dev->dev_private; |
1961 | drm_radeon_surface_free_t memfree; | 1987 | drm_radeon_surface_free_t memfree; |
1962 | 1988 | ||
1963 | if (!dev_priv) { | 1989 | DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_surface_free_t __user *) data, |
1964 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
1965 | return DRM_ERR(EINVAL); | ||
1966 | } | ||
1967 | |||
1968 | DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data, | ||
1969 | sizeof(memfree)); | 1990 | sizeof(memfree)); |
1970 | 1991 | ||
1971 | if (free_surface(filp, dev_priv, memfree.address)) | 1992 | if (free_surface(filp, dev_priv, memfree.address)) |
@@ -2100,11 +2121,6 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS) | |||
2100 | 2121 | ||
2101 | LOCK_TEST_WITH_RETURN(dev, filp); | 2122 | LOCK_TEST_WITH_RETURN(dev, filp); |
2102 | 2123 | ||
2103 | if (!dev_priv) { | ||
2104 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2105 | return DRM_ERR(EINVAL); | ||
2106 | } | ||
2107 | |||
2108 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2124 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2109 | 2125 | ||
2110 | DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, | 2126 | DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, |
@@ -2189,11 +2205,6 @@ static int radeon_cp_indices(DRM_IOCTL_ARGS) | |||
2189 | 2205 | ||
2190 | LOCK_TEST_WITH_RETURN(dev, filp); | 2206 | LOCK_TEST_WITH_RETURN(dev, filp); |
2191 | 2207 | ||
2192 | if (!dev_priv) { | ||
2193 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2194 | return DRM_ERR(EINVAL); | ||
2195 | } | ||
2196 | |||
2197 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2208 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2198 | 2209 | ||
2199 | DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data, | 2210 | DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data, |
@@ -2340,11 +2351,6 @@ static int radeon_cp_indirect(DRM_IOCTL_ARGS) | |||
2340 | 2351 | ||
2341 | LOCK_TEST_WITH_RETURN(dev, filp); | 2352 | LOCK_TEST_WITH_RETURN(dev, filp); |
2342 | 2353 | ||
2343 | if (!dev_priv) { | ||
2344 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2345 | return DRM_ERR(EINVAL); | ||
2346 | } | ||
2347 | |||
2348 | DRM_COPY_FROM_USER_IOCTL(indirect, | 2354 | DRM_COPY_FROM_USER_IOCTL(indirect, |
2349 | (drm_radeon_indirect_t __user *) data, | 2355 | (drm_radeon_indirect_t __user *) data, |
2350 | sizeof(indirect)); | 2356 | sizeof(indirect)); |
@@ -2417,11 +2423,6 @@ static int radeon_cp_vertex2(DRM_IOCTL_ARGS) | |||
2417 | 2423 | ||
2418 | LOCK_TEST_WITH_RETURN(dev, filp); | 2424 | LOCK_TEST_WITH_RETURN(dev, filp); |
2419 | 2425 | ||
2420 | if (!dev_priv) { | ||
2421 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2422 | return DRM_ERR(EINVAL); | ||
2423 | } | ||
2424 | |||
2425 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2426 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2426 | 2427 | ||
2427 | DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data, | 2428 | DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data, |
@@ -2738,11 +2739,6 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) | |||
2738 | 2739 | ||
2739 | LOCK_TEST_WITH_RETURN(dev, filp); | 2740 | LOCK_TEST_WITH_RETURN(dev, filp); |
2740 | 2741 | ||
2741 | if (!dev_priv) { | ||
2742 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2743 | return DRM_ERR(EINVAL); | ||
2744 | } | ||
2745 | |||
2746 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2742 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2747 | 2743 | ||
2748 | DRM_COPY_FROM_USER_IOCTL(cmdbuf, | 2744 | DRM_COPY_FROM_USER_IOCTL(cmdbuf, |
@@ -2897,11 +2893,6 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) | |||
2897 | drm_radeon_getparam_t param; | 2893 | drm_radeon_getparam_t param; |
2898 | int value; | 2894 | int value; |
2899 | 2895 | ||
2900 | if (!dev_priv) { | ||
2901 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2902 | return DRM_ERR(EINVAL); | ||
2903 | } | ||
2904 | |||
2905 | DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data, | 2896 | DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data, |
2906 | sizeof(param)); | 2897 | sizeof(param)); |
2907 | 2898 | ||
@@ -2981,11 +2972,6 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) | |||
2981 | drm_radeon_setparam_t sp; | 2972 | drm_radeon_setparam_t sp; |
2982 | struct drm_radeon_driver_file_fields *radeon_priv; | 2973 | struct drm_radeon_driver_file_fields *radeon_priv; |
2983 | 2974 | ||
2984 | if (!dev_priv) { | ||
2985 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2986 | return DRM_ERR(EINVAL); | ||
2987 | } | ||
2988 | |||
2989 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2975 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2990 | 2976 | ||
2991 | DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data, | 2977 | DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data, |
@@ -3012,6 +2998,9 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) | |||
3012 | case RADEON_SETPARAM_PCIGART_LOCATION: | 2998 | case RADEON_SETPARAM_PCIGART_LOCATION: |
3013 | dev_priv->pcigart_offset = sp.value; | 2999 | dev_priv->pcigart_offset = sp.value; |
3014 | break; | 3000 | break; |
3001 | case RADEON_SETPARAM_NEW_MEMMAP: | ||
3002 | dev_priv->new_memmap = sp.value; | ||
3003 | break; | ||
3015 | default: | 3004 | default: |
3016 | DRM_DEBUG("Invalid parameter %d\n", sp.param); | 3005 | DRM_DEBUG("Invalid parameter %d\n", sp.param); |
3017 | return DRM_ERR(EINVAL); | 3006 | return DRM_ERR(EINVAL); |
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c index 6774d2fe3452..5e9936bc307f 100644 --- a/drivers/char/drm/sis_mm.c +++ b/drivers/char/drm/sis_mm.c | |||
@@ -110,7 +110,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS) | |||
110 | 110 | ||
111 | DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); | 111 | DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); |
112 | 112 | ||
113 | DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); | 113 | DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset); |
114 | 114 | ||
115 | return retval; | 115 | return retval; |
116 | } | 116 | } |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index f7854b65fd55..ba54c856b0e5 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -227,6 +227,14 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, | |||
227 | if (!is_vendor_oui(mad_reg_req->oui)) | 227 | if (!is_vendor_oui(mad_reg_req->oui)) |
228 | goto error1; | 228 | goto error1; |
229 | } | 229 | } |
230 | /* Make sure class supplied is consistent with RMPP */ | ||
231 | if (ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) { | ||
232 | if (!rmpp_version) | ||
233 | goto error1; | ||
234 | } else { | ||
235 | if (rmpp_version) | ||
236 | goto error1; | ||
237 | } | ||
230 | /* Make sure class supplied is consistent with QP type */ | 238 | /* Make sure class supplied is consistent with QP type */ |
231 | if (qp_type == IB_QPT_SMI) { | 239 | if (qp_type == IB_QPT_SMI) { |
232 | if ((mad_reg_req->mgmt_class != | 240 | if ((mad_reg_req->mgmt_class != |
@@ -890,6 +898,35 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, | |||
890 | } | 898 | } |
891 | EXPORT_SYMBOL(ib_create_send_mad); | 899 | EXPORT_SYMBOL(ib_create_send_mad); |
892 | 900 | ||
901 | int ib_get_mad_data_offset(u8 mgmt_class) | ||
902 | { | ||
903 | if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM) | ||
904 | return IB_MGMT_SA_HDR; | ||
905 | else if ((mgmt_class == IB_MGMT_CLASS_DEVICE_MGMT) || | ||
906 | (mgmt_class == IB_MGMT_CLASS_DEVICE_ADM) || | ||
907 | (mgmt_class == IB_MGMT_CLASS_BIS)) | ||
908 | return IB_MGMT_DEVICE_HDR; | ||
909 | else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && | ||
910 | (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) | ||
911 | return IB_MGMT_VENDOR_HDR; | ||
912 | else | ||
913 | return IB_MGMT_MAD_HDR; | ||
914 | } | ||
915 | EXPORT_SYMBOL(ib_get_mad_data_offset); | ||
916 | |||
917 | int ib_is_mad_class_rmpp(u8 mgmt_class) | ||
918 | { | ||
919 | if ((mgmt_class == IB_MGMT_CLASS_SUBN_ADM) || | ||
920 | (mgmt_class == IB_MGMT_CLASS_DEVICE_MGMT) || | ||
921 | (mgmt_class == IB_MGMT_CLASS_DEVICE_ADM) || | ||
922 | (mgmt_class == IB_MGMT_CLASS_BIS) || | ||
923 | ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && | ||
924 | (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))) | ||
925 | return 1; | ||
926 | return 0; | ||
927 | } | ||
928 | EXPORT_SYMBOL(ib_is_mad_class_rmpp); | ||
929 | |||
893 | void *ib_get_rmpp_segment(struct ib_mad_send_buf *send_buf, int seg_num) | 930 | void *ib_get_rmpp_segment(struct ib_mad_send_buf *send_buf, int seg_num) |
894 | { | 931 | { |
895 | struct ib_mad_send_wr_private *mad_send_wr; | 932 | struct ib_mad_send_wr_private *mad_send_wr; |
@@ -1022,6 +1059,13 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf, | |||
1022 | goto error; | 1059 | goto error; |
1023 | } | 1060 | } |
1024 | 1061 | ||
1062 | if (!ib_is_mad_class_rmpp(((struct ib_mad_hdr *) send_buf->mad)->mgmt_class)) { | ||
1063 | if (mad_agent_priv->agent.rmpp_version) { | ||
1064 | ret = -EINVAL; | ||
1065 | goto error; | ||
1066 | } | ||
1067 | } | ||
1068 | |||
1025 | /* | 1069 | /* |
1026 | * Save pointer to next work request to post in case the | 1070 | * Save pointer to next work request to post in case the |
1027 | * current one completes, and the user modifies the work | 1071 | * current one completes, and the user modifies the work |
@@ -1618,14 +1662,59 @@ static int is_data_mad(struct ib_mad_agent_private *mad_agent_priv, | |||
1618 | (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA); | 1662 | (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA); |
1619 | } | 1663 | } |
1620 | 1664 | ||
1665 | static inline int rcv_has_same_class(struct ib_mad_send_wr_private *wr, | ||
1666 | struct ib_mad_recv_wc *rwc) | ||
1667 | { | ||
1668 | return ((struct ib_mad *)(wr->send_buf.mad))->mad_hdr.mgmt_class == | ||
1669 | rwc->recv_buf.mad->mad_hdr.mgmt_class; | ||
1670 | } | ||
1671 | |||
1672 | static inline int rcv_has_same_gid(struct ib_mad_send_wr_private *wr, | ||
1673 | struct ib_mad_recv_wc *rwc ) | ||
1674 | { | ||
1675 | struct ib_ah_attr attr; | ||
1676 | u8 send_resp, rcv_resp; | ||
1677 | |||
1678 | send_resp = ((struct ib_mad *)(wr->send_buf.mad))-> | ||
1679 | mad_hdr.method & IB_MGMT_METHOD_RESP; | ||
1680 | rcv_resp = rwc->recv_buf.mad->mad_hdr.method & IB_MGMT_METHOD_RESP; | ||
1681 | |||
1682 | if (!send_resp && rcv_resp) | ||
1683 | /* is request/response. GID/LIDs are both local (same). */ | ||
1684 | return 1; | ||
1685 | |||
1686 | if (send_resp == rcv_resp) | ||
1687 | /* both requests, or both responses. GIDs different */ | ||
1688 | return 0; | ||
1689 | |||
1690 | if (ib_query_ah(wr->send_buf.ah, &attr)) | ||
1691 | /* Assume not equal, to avoid false positives. */ | ||
1692 | return 0; | ||
1693 | |||
1694 | if (!(attr.ah_flags & IB_AH_GRH) && !(rwc->wc->wc_flags & IB_WC_GRH)) | ||
1695 | return attr.dlid == rwc->wc->slid; | ||
1696 | else if ((attr.ah_flags & IB_AH_GRH) && | ||
1697 | (rwc->wc->wc_flags & IB_WC_GRH)) | ||
1698 | return memcmp(attr.grh.dgid.raw, | ||
1699 | rwc->recv_buf.grh->sgid.raw, 16) == 0; | ||
1700 | else | ||
1701 | /* one has GID, other does not. Assume different */ | ||
1702 | return 0; | ||
1703 | } | ||
1621 | struct ib_mad_send_wr_private* | 1704 | struct ib_mad_send_wr_private* |
1622 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid) | 1705 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, |
1706 | struct ib_mad_recv_wc *mad_recv_wc) | ||
1623 | { | 1707 | { |
1624 | struct ib_mad_send_wr_private *mad_send_wr; | 1708 | struct ib_mad_send_wr_private *mad_send_wr; |
1709 | struct ib_mad *mad; | ||
1710 | |||
1711 | mad = (struct ib_mad *)mad_recv_wc->recv_buf.mad; | ||
1625 | 1712 | ||
1626 | list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list, | 1713 | list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list, |
1627 | agent_list) { | 1714 | agent_list) { |
1628 | if (mad_send_wr->tid == tid) | 1715 | if ((mad_send_wr->tid == mad->mad_hdr.tid) && |
1716 | rcv_has_same_class(mad_send_wr, mad_recv_wc) && | ||
1717 | rcv_has_same_gid(mad_send_wr, mad_recv_wc)) | ||
1629 | return mad_send_wr; | 1718 | return mad_send_wr; |
1630 | } | 1719 | } |
1631 | 1720 | ||
@@ -1636,7 +1725,10 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid) | |||
1636 | list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list, | 1725 | list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list, |
1637 | agent_list) { | 1726 | agent_list) { |
1638 | if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) && | 1727 | if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) && |
1639 | mad_send_wr->tid == tid && mad_send_wr->timeout) { | 1728 | mad_send_wr->tid == mad->mad_hdr.tid && |
1729 | mad_send_wr->timeout && | ||
1730 | rcv_has_same_class(mad_send_wr, mad_recv_wc) && | ||
1731 | rcv_has_same_gid(mad_send_wr, mad_recv_wc)) { | ||
1640 | /* Verify request has not been canceled */ | 1732 | /* Verify request has not been canceled */ |
1641 | return (mad_send_wr->status == IB_WC_SUCCESS) ? | 1733 | return (mad_send_wr->status == IB_WC_SUCCESS) ? |
1642 | mad_send_wr : NULL; | 1734 | mad_send_wr : NULL; |
@@ -1661,7 +1753,6 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, | |||
1661 | struct ib_mad_send_wr_private *mad_send_wr; | 1753 | struct ib_mad_send_wr_private *mad_send_wr; |
1662 | struct ib_mad_send_wc mad_send_wc; | 1754 | struct ib_mad_send_wc mad_send_wc; |
1663 | unsigned long flags; | 1755 | unsigned long flags; |
1664 | __be64 tid; | ||
1665 | 1756 | ||
1666 | INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); | 1757 | INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); |
1667 | list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); | 1758 | list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); |
@@ -1677,9 +1768,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, | |||
1677 | 1768 | ||
1678 | /* Complete corresponding request */ | 1769 | /* Complete corresponding request */ |
1679 | if (response_mad(mad_recv_wc->recv_buf.mad)) { | 1770 | if (response_mad(mad_recv_wc->recv_buf.mad)) { |
1680 | tid = mad_recv_wc->recv_buf.mad->mad_hdr.tid; | ||
1681 | spin_lock_irqsave(&mad_agent_priv->lock, flags); | 1771 | spin_lock_irqsave(&mad_agent_priv->lock, flags); |
1682 | mad_send_wr = ib_find_send_mad(mad_agent_priv, tid); | 1772 | mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc); |
1683 | if (!mad_send_wr) { | 1773 | if (!mad_send_wr) { |
1684 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); | 1774 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); |
1685 | ib_free_recv_mad(mad_recv_wc); | 1775 | ib_free_recv_mad(mad_recv_wc); |
@@ -2408,11 +2498,11 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info, | |||
2408 | } | 2498 | } |
2409 | } | 2499 | } |
2410 | sg_list.addr = dma_map_single(qp_info->port_priv-> | 2500 | sg_list.addr = dma_map_single(qp_info->port_priv-> |
2411 | device->dma_device, | 2501 | device->dma_device, |
2412 | &mad_priv->grh, | 2502 | &mad_priv->grh, |
2413 | sizeof *mad_priv - | 2503 | sizeof *mad_priv - |
2414 | sizeof mad_priv->header, | 2504 | sizeof mad_priv->header, |
2415 | DMA_FROM_DEVICE); | 2505 | DMA_FROM_DEVICE); |
2416 | pci_unmap_addr_set(&mad_priv->header, mapping, sg_list.addr); | 2506 | pci_unmap_addr_set(&mad_priv->header, mapping, sg_list.addr); |
2417 | recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list; | 2507 | recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list; |
2418 | mad_priv->header.mad_list.mad_queue = recv_queue; | 2508 | mad_priv->header.mad_list.mad_queue = recv_queue; |
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index a7125d4b5ccf..6c9c133d71ef 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h | |||
@@ -216,7 +216,8 @@ extern kmem_cache_t *ib_mad_cache; | |||
216 | int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr); | 216 | int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr); |
217 | 217 | ||
218 | struct ib_mad_send_wr_private * | 218 | struct ib_mad_send_wr_private * |
219 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid); | 219 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, |
220 | struct ib_mad_recv_wc *mad_recv_wc); | ||
220 | 221 | ||
221 | void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, | 222 | void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, |
222 | struct ib_mad_send_wc *mad_send_wc); | 223 | struct ib_mad_send_wc *mad_send_wc); |
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index bacfdd5bddad..dfd4e588ce03 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005 Intel Inc. All rights reserved. | 2 | * Copyright (c) 2005 Intel Inc. All rights reserved. |
3 | * Copyright (c) 2005 Voltaire, Inc. All rights reserved. | 3 | * Copyright (c) 2005-2006 Voltaire, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
6 | * licenses. You may choose to be licensed under the terms of the GNU | 6 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -100,17 +100,6 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent) | |||
100 | } | 100 | } |
101 | } | 101 | } |
102 | 102 | ||
103 | static int data_offset(u8 mgmt_class) | ||
104 | { | ||
105 | if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM) | ||
106 | return IB_MGMT_SA_HDR; | ||
107 | else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && | ||
108 | (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) | ||
109 | return IB_MGMT_VENDOR_HDR; | ||
110 | else | ||
111 | return IB_MGMT_RMPP_HDR; | ||
112 | } | ||
113 | |||
114 | static void format_ack(struct ib_mad_send_buf *msg, | 103 | static void format_ack(struct ib_mad_send_buf *msg, |
115 | struct ib_rmpp_mad *data, | 104 | struct ib_rmpp_mad *data, |
116 | struct mad_rmpp_recv *rmpp_recv) | 105 | struct mad_rmpp_recv *rmpp_recv) |
@@ -137,7 +126,7 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv, | |||
137 | struct ib_mad_send_buf *msg; | 126 | struct ib_mad_send_buf *msg; |
138 | int ret, hdr_len; | 127 | int ret, hdr_len; |
139 | 128 | ||
140 | hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); | 129 | hdr_len = ib_get_mad_data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); |
141 | msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, | 130 | msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, |
142 | recv_wc->wc->pkey_index, 1, hdr_len, | 131 | recv_wc->wc->pkey_index, 1, hdr_len, |
143 | 0, GFP_KERNEL); | 132 | 0, GFP_KERNEL); |
@@ -163,7 +152,7 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent, | |||
163 | if (IS_ERR(ah)) | 152 | if (IS_ERR(ah)) |
164 | return (void *) ah; | 153 | return (void *) ah; |
165 | 154 | ||
166 | hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); | 155 | hdr_len = ib_get_mad_data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); |
167 | msg = ib_create_send_mad(agent, recv_wc->wc->src_qp, | 156 | msg = ib_create_send_mad(agent, recv_wc->wc->src_qp, |
168 | recv_wc->wc->pkey_index, 1, | 157 | recv_wc->wc->pkey_index, 1, |
169 | hdr_len, 0, GFP_KERNEL); | 158 | hdr_len, 0, GFP_KERNEL); |
@@ -408,7 +397,7 @@ static inline int get_mad_len(struct mad_rmpp_recv *rmpp_recv) | |||
408 | 397 | ||
409 | rmpp_mad = (struct ib_rmpp_mad *)rmpp_recv->cur_seg_buf->mad; | 398 | rmpp_mad = (struct ib_rmpp_mad *)rmpp_recv->cur_seg_buf->mad; |
410 | 399 | ||
411 | hdr_size = data_offset(rmpp_mad->mad_hdr.mgmt_class); | 400 | hdr_size = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); |
412 | data_size = sizeof(struct ib_rmpp_mad) - hdr_size; | 401 | data_size = sizeof(struct ib_rmpp_mad) - hdr_size; |
413 | pad = IB_MGMT_RMPP_DATA - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); | 402 | pad = IB_MGMT_RMPP_DATA - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); |
414 | if (pad > IB_MGMT_RMPP_DATA || pad < 0) | 403 | if (pad > IB_MGMT_RMPP_DATA || pad < 0) |
@@ -562,15 +551,15 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr) | |||
562 | return ib_send_mad(mad_send_wr); | 551 | return ib_send_mad(mad_send_wr); |
563 | } | 552 | } |
564 | 553 | ||
565 | static void abort_send(struct ib_mad_agent_private *agent, __be64 tid, | 554 | static void abort_send(struct ib_mad_agent_private *agent, |
566 | u8 rmpp_status) | 555 | struct ib_mad_recv_wc *mad_recv_wc, u8 rmpp_status) |
567 | { | 556 | { |
568 | struct ib_mad_send_wr_private *mad_send_wr; | 557 | struct ib_mad_send_wr_private *mad_send_wr; |
569 | struct ib_mad_send_wc wc; | 558 | struct ib_mad_send_wc wc; |
570 | unsigned long flags; | 559 | unsigned long flags; |
571 | 560 | ||
572 | spin_lock_irqsave(&agent->lock, flags); | 561 | spin_lock_irqsave(&agent->lock, flags); |
573 | mad_send_wr = ib_find_send_mad(agent, tid); | 562 | mad_send_wr = ib_find_send_mad(agent, mad_recv_wc); |
574 | if (!mad_send_wr) | 563 | if (!mad_send_wr) |
575 | goto out; /* Unmatched send */ | 564 | goto out; /* Unmatched send */ |
576 | 565 | ||
@@ -612,8 +601,7 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, | |||
612 | 601 | ||
613 | rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; | 602 | rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; |
614 | if (rmpp_mad->rmpp_hdr.rmpp_status) { | 603 | if (rmpp_mad->rmpp_hdr.rmpp_status) { |
615 | abort_send(agent, rmpp_mad->mad_hdr.tid, | 604 | abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); |
616 | IB_MGMT_RMPP_STATUS_BAD_STATUS); | ||
617 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); | 605 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); |
618 | return; | 606 | return; |
619 | } | 607 | } |
@@ -621,14 +609,13 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, | |||
621 | seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num); | 609 | seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num); |
622 | newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); | 610 | newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); |
623 | if (newwin < seg_num) { | 611 | if (newwin < seg_num) { |
624 | abort_send(agent, rmpp_mad->mad_hdr.tid, | 612 | abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S); |
625 | IB_MGMT_RMPP_STATUS_W2S); | ||
626 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S); | 613 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S); |
627 | return; | 614 | return; |
628 | } | 615 | } |
629 | 616 | ||
630 | spin_lock_irqsave(&agent->lock, flags); | 617 | spin_lock_irqsave(&agent->lock, flags); |
631 | mad_send_wr = ib_find_send_mad(agent, rmpp_mad->mad_hdr.tid); | 618 | mad_send_wr = ib_find_send_mad(agent, mad_recv_wc); |
632 | if (!mad_send_wr) | 619 | if (!mad_send_wr) |
633 | goto out; /* Unmatched ACK */ | 620 | goto out; /* Unmatched ACK */ |
634 | 621 | ||
@@ -639,8 +626,7 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, | |||
639 | if (seg_num > mad_send_wr->send_buf.seg_count || | 626 | if (seg_num > mad_send_wr->send_buf.seg_count || |
640 | seg_num > mad_send_wr->newwin) { | 627 | seg_num > mad_send_wr->newwin) { |
641 | spin_unlock_irqrestore(&agent->lock, flags); | 628 | spin_unlock_irqrestore(&agent->lock, flags); |
642 | abort_send(agent, rmpp_mad->mad_hdr.tid, | 629 | abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B); |
643 | IB_MGMT_RMPP_STATUS_S2B); | ||
644 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B); | 630 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B); |
645 | return; | 631 | return; |
646 | } | 632 | } |
@@ -728,12 +714,10 @@ static void process_rmpp_stop(struct ib_mad_agent_private *agent, | |||
728 | rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; | 714 | rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; |
729 | 715 | ||
730 | if (rmpp_mad->rmpp_hdr.rmpp_status != IB_MGMT_RMPP_STATUS_RESX) { | 716 | if (rmpp_mad->rmpp_hdr.rmpp_status != IB_MGMT_RMPP_STATUS_RESX) { |
731 | abort_send(agent, rmpp_mad->mad_hdr.tid, | 717 | abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); |
732 | IB_MGMT_RMPP_STATUS_BAD_STATUS); | ||
733 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); | 718 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); |
734 | } else | 719 | } else |
735 | abort_send(agent, rmpp_mad->mad_hdr.tid, | 720 | abort_send(agent, mad_recv_wc, rmpp_mad->rmpp_hdr.rmpp_status); |
736 | rmpp_mad->rmpp_hdr.rmpp_status); | ||
737 | } | 721 | } |
738 | 722 | ||
739 | static void process_rmpp_abort(struct ib_mad_agent_private *agent, | 723 | static void process_rmpp_abort(struct ib_mad_agent_private *agent, |
@@ -745,12 +729,10 @@ static void process_rmpp_abort(struct ib_mad_agent_private *agent, | |||
745 | 729 | ||
746 | if (rmpp_mad->rmpp_hdr.rmpp_status < IB_MGMT_RMPP_STATUS_ABORT_MIN || | 730 | if (rmpp_mad->rmpp_hdr.rmpp_status < IB_MGMT_RMPP_STATUS_ABORT_MIN || |
747 | rmpp_mad->rmpp_hdr.rmpp_status > IB_MGMT_RMPP_STATUS_ABORT_MAX) { | 731 | rmpp_mad->rmpp_hdr.rmpp_status > IB_MGMT_RMPP_STATUS_ABORT_MAX) { |
748 | abort_send(agent, rmpp_mad->mad_hdr.tid, | 732 | abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); |
749 | IB_MGMT_RMPP_STATUS_BAD_STATUS); | ||
750 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); | 733 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); |
751 | } else | 734 | } else |
752 | abort_send(agent, rmpp_mad->mad_hdr.tid, | 735 | abort_send(agent, mad_recv_wc, rmpp_mad->rmpp_hdr.rmpp_status); |
753 | rmpp_mad->rmpp_hdr.rmpp_status); | ||
754 | } | 736 | } |
755 | 737 | ||
756 | struct ib_mad_recv_wc * | 738 | struct ib_mad_recv_wc * |
@@ -764,8 +746,7 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent, | |||
764 | return mad_recv_wc; | 746 | return mad_recv_wc; |
765 | 747 | ||
766 | if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) { | 748 | if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) { |
767 | abort_send(agent, rmpp_mad->mad_hdr.tid, | 749 | abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV); |
768 | IB_MGMT_RMPP_STATUS_UNV); | ||
769 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV); | 750 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV); |
770 | goto out; | 751 | goto out; |
771 | } | 752 | } |
@@ -783,8 +764,7 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent, | |||
783 | process_rmpp_abort(agent, mad_recv_wc); | 764 | process_rmpp_abort(agent, mad_recv_wc); |
784 | break; | 765 | break; |
785 | default: | 766 | default: |
786 | abort_send(agent, rmpp_mad->mad_hdr.tid, | 767 | abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT); |
787 | IB_MGMT_RMPP_STATUS_BADT); | ||
788 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT); | 768 | nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT); |
789 | break; | 769 | break; |
790 | } | 770 | } |
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index fb6cd42601f9..afe70a549c2f 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -177,17 +177,6 @@ static int queue_packet(struct ib_umad_file *file, | |||
177 | return ret; | 177 | return ret; |
178 | } | 178 | } |
179 | 179 | ||
180 | static int data_offset(u8 mgmt_class) | ||
181 | { | ||
182 | if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM) | ||
183 | return IB_MGMT_SA_HDR; | ||
184 | else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && | ||
185 | (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) | ||
186 | return IB_MGMT_VENDOR_HDR; | ||
187 | else | ||
188 | return IB_MGMT_RMPP_HDR; | ||
189 | } | ||
190 | |||
191 | static void send_handler(struct ib_mad_agent *agent, | 180 | static void send_handler(struct ib_mad_agent *agent, |
192 | struct ib_mad_send_wc *send_wc) | 181 | struct ib_mad_send_wc *send_wc) |
193 | { | 182 | { |
@@ -283,7 +272,7 @@ static ssize_t copy_recv_mad(char __user *buf, struct ib_umad_packet *packet, | |||
283 | */ | 272 | */ |
284 | return -ENOSPC; | 273 | return -ENOSPC; |
285 | } | 274 | } |
286 | offset = data_offset(recv_buf->mad->mad_hdr.mgmt_class); | 275 | offset = ib_get_mad_data_offset(recv_buf->mad->mad_hdr.mgmt_class); |
287 | max_seg_payload = sizeof (struct ib_mad) - offset; | 276 | max_seg_payload = sizeof (struct ib_mad) - offset; |
288 | 277 | ||
289 | for (left = packet->length - seg_payload, buf += seg_payload; | 278 | for (left = packet->length - seg_payload, buf += seg_payload; |
@@ -441,21 +430,14 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
441 | } | 430 | } |
442 | 431 | ||
443 | rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; | 432 | rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; |
444 | if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { | 433 | hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); |
445 | hdr_len = IB_MGMT_SA_HDR; | 434 | if (!ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)) { |
446 | copy_offset = IB_MGMT_RMPP_HDR; | 435 | copy_offset = IB_MGMT_MAD_HDR; |
447 | rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & | 436 | rmpp_active = 0; |
448 | IB_MGMT_RMPP_FLAG_ACTIVE; | 437 | } else { |
449 | } else if (rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START && | ||
450 | rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END) { | ||
451 | hdr_len = IB_MGMT_VENDOR_HDR; | ||
452 | copy_offset = IB_MGMT_RMPP_HDR; | 438 | copy_offset = IB_MGMT_RMPP_HDR; |
453 | rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & | 439 | rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & |
454 | IB_MGMT_RMPP_FLAG_ACTIVE; | 440 | IB_MGMT_RMPP_FLAG_ACTIVE; |
455 | } else { | ||
456 | hdr_len = IB_MGMT_MAD_HDR; | ||
457 | copy_offset = IB_MGMT_MAD_HDR; | ||
458 | rmpp_active = 0; | ||
459 | } | 441 | } |
460 | 442 | ||
461 | data_len = count - sizeof (struct ib_user_mad) - hdr_len; | 443 | data_len = count - sizeof (struct ib_user_mad) - hdr_len; |
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c index f023d3936518..bc5bdcbe51b5 100644 --- a/drivers/infiniband/hw/mthca/mthca_av.c +++ b/drivers/infiniband/hw/mthca/mthca_av.c | |||
@@ -265,7 +265,7 @@ int __devinit mthca_init_av_table(struct mthca_dev *dev) | |||
265 | return -ENOMEM; | 265 | return -ENOMEM; |
266 | } | 266 | } |
267 | 267 | ||
268 | void __devexit mthca_cleanup_av_table(struct mthca_dev *dev) | 268 | void mthca_cleanup_av_table(struct mthca_dev *dev) |
269 | { | 269 | { |
270 | if (mthca_is_memfree(dev)) | 270 | if (mthca_is_memfree(dev)) |
271 | return; | 271 | return; |
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index 76aabc5bf371..312cf90731ea 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c | |||
@@ -973,7 +973,7 @@ int __devinit mthca_init_cq_table(struct mthca_dev *dev) | |||
973 | return err; | 973 | return err; |
974 | } | 974 | } |
975 | 975 | ||
976 | void __devexit mthca_cleanup_cq_table(struct mthca_dev *dev) | 976 | void mthca_cleanup_cq_table(struct mthca_dev *dev) |
977 | { | 977 | { |
978 | mthca_array_cleanup(&dev->cq_table.cq, dev->limits.num_cqs); | 978 | mthca_array_cleanup(&dev->cq_table.cq, dev->limits.num_cqs); |
979 | mthca_alloc_cleanup(&dev->cq_table.alloc); | 979 | mthca_alloc_cleanup(&dev->cq_table.alloc); |
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index cbdc348fb689..99f109c3815d 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c | |||
@@ -765,7 +765,7 @@ static int __devinit mthca_map_eq_regs(struct mthca_dev *dev) | |||
765 | 765 | ||
766 | } | 766 | } |
767 | 767 | ||
768 | static void __devexit mthca_unmap_eq_regs(struct mthca_dev *dev) | 768 | static void mthca_unmap_eq_regs(struct mthca_dev *dev) |
769 | { | 769 | { |
770 | if (mthca_is_memfree(dev)) { | 770 | if (mthca_is_memfree(dev)) { |
771 | mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) & | 771 | mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) & |
@@ -821,7 +821,7 @@ int __devinit mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt) | |||
821 | return ret; | 821 | return ret; |
822 | } | 822 | } |
823 | 823 | ||
824 | void __devexit mthca_unmap_eq_icm(struct mthca_dev *dev) | 824 | void mthca_unmap_eq_icm(struct mthca_dev *dev) |
825 | { | 825 | { |
826 | u8 status; | 826 | u8 status; |
827 | 827 | ||
@@ -954,7 +954,7 @@ err_out_free: | |||
954 | return err; | 954 | return err; |
955 | } | 955 | } |
956 | 956 | ||
957 | void __devexit mthca_cleanup_eq_table(struct mthca_dev *dev) | 957 | void mthca_cleanup_eq_table(struct mthca_dev *dev) |
958 | { | 958 | { |
959 | u8 status; | 959 | u8 status; |
960 | int i; | 960 | int i; |
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c index 4ace6a392f41..dfb482eac9a2 100644 --- a/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/drivers/infiniband/hw/mthca/mthca_mad.c | |||
@@ -271,7 +271,7 @@ err: | |||
271 | return PTR_ERR(agent); | 271 | return PTR_ERR(agent); |
272 | } | 272 | } |
273 | 273 | ||
274 | void mthca_free_agents(struct mthca_dev *dev) | 274 | void __devexit mthca_free_agents(struct mthca_dev *dev) |
275 | { | 275 | { |
276 | struct ib_mad_agent *agent; | 276 | struct ib_mad_agent *agent; |
277 | int p, q; | 277 | int p, q; |
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c index 9965bda9afed..47ca8a9b7247 100644 --- a/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/drivers/infiniband/hw/mthca/mthca_mcg.c | |||
@@ -388,7 +388,7 @@ int __devinit mthca_init_mcg_table(struct mthca_dev *dev) | |||
388 | return 0; | 388 | return 0; |
389 | } | 389 | } |
390 | 390 | ||
391 | void __devexit mthca_cleanup_mcg_table(struct mthca_dev *dev) | 391 | void mthca_cleanup_mcg_table(struct mthca_dev *dev) |
392 | { | 392 | { |
393 | mthca_alloc_cleanup(&dev->mcg_table.alloc); | 393 | mthca_alloc_cleanup(&dev->mcg_table.alloc); |
394 | } | 394 | } |
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c index 698b62125765..25e1c1db9a40 100644 --- a/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/drivers/infiniband/hw/mthca/mthca_mr.c | |||
@@ -170,7 +170,7 @@ err_out: | |||
170 | return -ENOMEM; | 170 | return -ENOMEM; |
171 | } | 171 | } |
172 | 172 | ||
173 | static void __devexit mthca_buddy_cleanup(struct mthca_buddy *buddy) | 173 | static void mthca_buddy_cleanup(struct mthca_buddy *buddy) |
174 | { | 174 | { |
175 | int i; | 175 | int i; |
176 | 176 | ||
@@ -866,7 +866,7 @@ err_mtt_buddy: | |||
866 | return err; | 866 | return err; |
867 | } | 867 | } |
868 | 868 | ||
869 | void __devexit mthca_cleanup_mr_table(struct mthca_dev *dev) | 869 | void mthca_cleanup_mr_table(struct mthca_dev *dev) |
870 | { | 870 | { |
871 | /* XXX check if any MRs are still allocated? */ | 871 | /* XXX check if any MRs are still allocated? */ |
872 | if (dev->limits.fmr_reserved_mtts) | 872 | if (dev->limits.fmr_reserved_mtts) |
diff --git a/drivers/infiniband/hw/mthca/mthca_pd.c b/drivers/infiniband/hw/mthca/mthca_pd.c index 105fc5faaddf..59df51614c85 100644 --- a/drivers/infiniband/hw/mthca/mthca_pd.c +++ b/drivers/infiniband/hw/mthca/mthca_pd.c | |||
@@ -77,7 +77,7 @@ int __devinit mthca_init_pd_table(struct mthca_dev *dev) | |||
77 | dev->limits.reserved_pds); | 77 | dev->limits.reserved_pds); |
78 | } | 78 | } |
79 | 79 | ||
80 | void __devexit mthca_cleanup_pd_table(struct mthca_dev *dev) | 80 | void mthca_cleanup_pd_table(struct mthca_dev *dev) |
81 | { | 81 | { |
82 | /* XXX check if any PDs are still allocated? */ | 82 | /* XXX check if any PDs are still allocated? */ |
83 | mthca_alloc_cleanup(&dev->pd_table.alloc); | 83 | mthca_alloc_cleanup(&dev->pd_table.alloc); |
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 1bc2678c2fae..057c8e6af87b 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -2204,7 +2204,7 @@ int __devinit mthca_init_qp_table(struct mthca_dev *dev) | |||
2204 | return err; | 2204 | return err; |
2205 | } | 2205 | } |
2206 | 2206 | ||
2207 | void __devexit mthca_cleanup_qp_table(struct mthca_dev *dev) | 2207 | void mthca_cleanup_qp_table(struct mthca_dev *dev) |
2208 | { | 2208 | { |
2209 | int i; | 2209 | int i; |
2210 | u8 status; | 2210 | u8 status; |
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index 0cfd15802217..2dd3aea05341 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c | |||
@@ -206,7 +206,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, | |||
206 | roundup_pow_of_two(sizeof (struct mthca_next_seg) + | 206 | roundup_pow_of_two(sizeof (struct mthca_next_seg) + |
207 | srq->max_gs * sizeof (struct mthca_data_seg))); | 207 | srq->max_gs * sizeof (struct mthca_data_seg))); |
208 | 208 | ||
209 | if (ds > dev->limits.max_desc_sz) | 209 | if (!mthca_is_memfree(dev) && (ds > dev->limits.max_desc_sz)) |
210 | return -EINVAL; | 210 | return -EINVAL; |
211 | 211 | ||
212 | srq->wqe_shift = long_log2(ds); | 212 | srq->wqe_shift = long_log2(ds); |
@@ -684,7 +684,7 @@ int __devinit mthca_init_srq_table(struct mthca_dev *dev) | |||
684 | return err; | 684 | return err; |
685 | } | 685 | } |
686 | 686 | ||
687 | void __devexit mthca_cleanup_srq_table(struct mthca_dev *dev) | 687 | void mthca_cleanup_srq_table(struct mthca_dev *dev) |
688 | { | 688 | { |
689 | if (!(dev->mthca_flags & MTHCA_FLAG_SRQ)) | 689 | if (!(dev->mthca_flags & MTHCA_FLAG_SRQ)) |
690 | return; | 690 | return; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 53a32f65788d..9b0bd7c746ca 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -723,7 +723,7 @@ static int ipoib_hard_header(struct sk_buff *skb, | |||
723 | * destination address onto the front of the skb so we can | 723 | * destination address onto the front of the skb so we can |
724 | * figure out where to send the packet later. | 724 | * figure out where to send the packet later. |
725 | */ | 725 | */ |
726 | if (!skb->dst || !skb->dst->neighbour) { | 726 | if ((!skb->dst || !skb->dst->neighbour) && daddr) { |
727 | struct ipoib_pseudoheader *phdr = | 727 | struct ipoib_pseudoheader *phdr = |
728 | (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); | 728 | (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); |
729 | memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); | 729 | memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 61924cc30e55..fd8a95a9c5d3 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -607,10 +607,10 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, | |||
607 | */ | 607 | */ |
608 | if (likely(scmnd->use_sg)) { | 608 | if (likely(scmnd->use_sg)) { |
609 | nents = scmnd->use_sg; | 609 | nents = scmnd->use_sg; |
610 | scat = (struct scatterlist *) scmnd->request_buffer; | 610 | scat = scmnd->request_buffer; |
611 | } else { | 611 | } else { |
612 | nents = 1; | 612 | nents = 1; |
613 | scat = (struct scatterlist *) scmnd->request_buffer; | 613 | scat = &req->fake_sg; |
614 | } | 614 | } |
615 | 615 | ||
616 | dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents, | 616 | dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents, |
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c index 95d81d86d8b7..835dff0bafdc 100644 --- a/drivers/scsi/libata-bmdma.c +++ b/drivers/scsi/libata-bmdma.c | |||
@@ -703,6 +703,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int | |||
703 | struct ata_probe_ent *probe_ent = | 703 | struct ata_probe_ent *probe_ent = |
704 | ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); | 704 | ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); |
705 | int p = 0; | 705 | int p = 0; |
706 | unsigned long bmdma; | ||
706 | 707 | ||
707 | if (!probe_ent) | 708 | if (!probe_ent) |
708 | return NULL; | 709 | return NULL; |
@@ -716,7 +717,12 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int | |||
716 | probe_ent->port[p].altstatus_addr = | 717 | probe_ent->port[p].altstatus_addr = |
717 | probe_ent->port[p].ctl_addr = | 718 | probe_ent->port[p].ctl_addr = |
718 | pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; | 719 | pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; |
719 | probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4); | 720 | bmdma = pci_resource_start(pdev, 4); |
721 | if (bmdma) { | ||
722 | if (inb(bmdma + 2) & 0x80) | ||
723 | probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; | ||
724 | probe_ent->port[p].bmdma_addr = bmdma; | ||
725 | } | ||
720 | ata_std_ports(&probe_ent->port[p]); | 726 | ata_std_ports(&probe_ent->port[p]); |
721 | p++; | 727 | p++; |
722 | } | 728 | } |
@@ -726,7 +732,13 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int | |||
726 | probe_ent->port[p].altstatus_addr = | 732 | probe_ent->port[p].altstatus_addr = |
727 | probe_ent->port[p].ctl_addr = | 733 | probe_ent->port[p].ctl_addr = |
728 | pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; | 734 | pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; |
729 | probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8; | 735 | bmdma = pci_resource_start(pdev, 4); |
736 | if (bmdma) { | ||
737 | bmdma += 8; | ||
738 | if(inb(bmdma + 2) & 0x80) | ||
739 | probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; | ||
740 | probe_ent->port[p].bmdma_addr = bmdma; | ||
741 | } | ||
730 | ata_std_ports(&probe_ent->port[p]); | 742 | ata_std_ports(&probe_ent->port[p]); |
731 | p++; | 743 | p++; |
732 | } | 744 | } |
@@ -740,6 +752,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | |||
740 | struct ata_port_info *port, int port_num) | 752 | struct ata_port_info *port, int port_num) |
741 | { | 753 | { |
742 | struct ata_probe_ent *probe_ent; | 754 | struct ata_probe_ent *probe_ent; |
755 | unsigned long bmdma; | ||
743 | 756 | ||
744 | probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); | 757 | probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); |
745 | if (!probe_ent) | 758 | if (!probe_ent) |
@@ -766,8 +779,13 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | |||
766 | break; | 779 | break; |
767 | } | 780 | } |
768 | 781 | ||
769 | probe_ent->port[0].bmdma_addr = | 782 | bmdma = pci_resource_start(pdev, 4); |
770 | pci_resource_start(pdev, 4) + 8 * port_num; | 783 | if (bmdma != 0) { |
784 | bmdma += 8 * port_num; | ||
785 | probe_ent->port[0].bmdma_addr = bmdma; | ||
786 | if (inb(bmdma + 2) & 0x80) | ||
787 | probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; | ||
788 | } | ||
771 | ata_std_ports(&probe_ent->port[0]); | 789 | ata_std_ports(&probe_ent->port[0]); |
772 | 790 | ||
773 | return probe_ent; | 791 | return probe_ent; |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index d279666dcb38..21b0ed583b8a 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -62,7 +62,9 @@ | |||
62 | #include "libata.h" | 62 | #include "libata.h" |
63 | 63 | ||
64 | static unsigned int ata_dev_init_params(struct ata_port *ap, | 64 | static unsigned int ata_dev_init_params(struct ata_port *ap, |
65 | struct ata_device *dev); | 65 | struct ata_device *dev, |
66 | u16 heads, | ||
67 | u16 sectors); | ||
66 | static void ata_set_mode(struct ata_port *ap); | 68 | static void ata_set_mode(struct ata_port *ap); |
67 | static unsigned int ata_dev_set_xfermode(struct ata_port *ap, | 69 | static unsigned int ata_dev_set_xfermode(struct ata_port *ap, |
68 | struct ata_device *dev); | 70 | struct ata_device *dev); |
@@ -1081,9 +1083,8 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) | |||
1081 | * | 1083 | * |
1082 | * Read ID data from the specified device. ATA_CMD_ID_ATA is | 1084 | * Read ID data from the specified device. ATA_CMD_ID_ATA is |
1083 | * performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI | 1085 | * performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI |
1084 | * devices. This function also takes care of EDD signature | 1086 | * devices. This function also issues ATA_CMD_INIT_DEV_PARAMS |
1085 | * misreporting (to be removed once EDD support is gone) and | 1087 | * for pre-ATA4 drives. |
1086 | * issues ATA_CMD_INIT_DEV_PARAMS for pre-ATA4 drives. | ||
1087 | * | 1088 | * |
1088 | * LOCKING: | 1089 | * LOCKING: |
1089 | * Kernel thread context (may sleep) | 1090 | * Kernel thread context (may sleep) |
@@ -1095,7 +1096,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, | |||
1095 | unsigned int *p_class, int post_reset, u16 **p_id) | 1096 | unsigned int *p_class, int post_reset, u16 **p_id) |
1096 | { | 1097 | { |
1097 | unsigned int class = *p_class; | 1098 | unsigned int class = *p_class; |
1098 | unsigned int using_edd; | ||
1099 | struct ata_taskfile tf; | 1099 | struct ata_taskfile tf; |
1100 | unsigned int err_mask = 0; | 1100 | unsigned int err_mask = 0; |
1101 | u16 *id; | 1101 | u16 *id; |
@@ -1104,12 +1104,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, | |||
1104 | 1104 | ||
1105 | DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); | 1105 | DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); |
1106 | 1106 | ||
1107 | if (ap->ops->probe_reset || | ||
1108 | ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET)) | ||
1109 | using_edd = 0; | ||
1110 | else | ||
1111 | using_edd = 1; | ||
1112 | |||
1113 | ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ | 1107 | ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ |
1114 | 1108 | ||
1115 | id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL); | 1109 | id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL); |
@@ -1139,39 +1133,16 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, | |||
1139 | 1133 | ||
1140 | err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE, | 1134 | err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE, |
1141 | id, sizeof(id[0]) * ATA_ID_WORDS); | 1135 | id, sizeof(id[0]) * ATA_ID_WORDS); |
1142 | |||
1143 | if (err_mask) { | 1136 | if (err_mask) { |
1144 | rc = -EIO; | 1137 | rc = -EIO; |
1145 | reason = "I/O error"; | 1138 | reason = "I/O error"; |
1146 | |||
1147 | if (err_mask & ~AC_ERR_DEV) | ||
1148 | goto err_out; | ||
1149 | |||
1150 | /* | ||
1151 | * arg! EDD works for all test cases, but seems to return | ||
1152 | * the ATA signature for some ATAPI devices. Until the | ||
1153 | * reason for this is found and fixed, we fix up the mess | ||
1154 | * here. If IDENTIFY DEVICE returns command aborted | ||
1155 | * (as ATAPI devices do), then we issue an | ||
1156 | * IDENTIFY PACKET DEVICE. | ||
1157 | * | ||
1158 | * ATA software reset (SRST, the default) does not appear | ||
1159 | * to have this problem. | ||
1160 | */ | ||
1161 | if ((using_edd) && (class == ATA_DEV_ATA)) { | ||
1162 | u8 err = tf.feature; | ||
1163 | if (err & ATA_ABORTED) { | ||
1164 | class = ATA_DEV_ATAPI; | ||
1165 | goto retry; | ||
1166 | } | ||
1167 | } | ||
1168 | goto err_out; | 1139 | goto err_out; |
1169 | } | 1140 | } |
1170 | 1141 | ||
1171 | swap_buf_le16(id, ATA_ID_WORDS); | 1142 | swap_buf_le16(id, ATA_ID_WORDS); |
1172 | 1143 | ||
1173 | /* sanity check */ | 1144 | /* sanity check */ |
1174 | if ((class == ATA_DEV_ATA) != ata_id_is_ata(id)) { | 1145 | if ((class == ATA_DEV_ATA) != (ata_id_is_ata(id) | ata_id_is_cfa(id))) { |
1175 | rc = -EINVAL; | 1146 | rc = -EINVAL; |
1176 | reason = "device reports illegal type"; | 1147 | reason = "device reports illegal type"; |
1177 | goto err_out; | 1148 | goto err_out; |
@@ -1187,7 +1158,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, | |||
1187 | * Some drives were very specific about that exact sequence. | 1158 | * Some drives were very specific about that exact sequence. |
1188 | */ | 1159 | */ |
1189 | if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) { | 1160 | if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) { |
1190 | err_mask = ata_dev_init_params(ap, dev); | 1161 | err_mask = ata_dev_init_params(ap, dev, id[3], id[6]); |
1191 | if (err_mask) { | 1162 | if (err_mask) { |
1192 | rc = -EIO; | 1163 | rc = -EIO; |
1193 | reason = "INIT_DEV_PARAMS failed"; | 1164 | reason = "INIT_DEV_PARAMS failed"; |
@@ -1440,7 +1411,11 @@ static int ata_bus_probe(struct ata_port *ap) | |||
1440 | if (!found) | 1411 | if (!found) |
1441 | goto err_out_disable; | 1412 | goto err_out_disable; |
1442 | 1413 | ||
1443 | ata_set_mode(ap); | 1414 | if (ap->ops->set_mode) |
1415 | ap->ops->set_mode(ap); | ||
1416 | else | ||
1417 | ata_set_mode(ap); | ||
1418 | |||
1444 | if (ap->flags & ATA_FLAG_PORT_DISABLED) | 1419 | if (ap->flags & ATA_FLAG_PORT_DISABLED) |
1445 | goto err_out_disable; | 1420 | goto err_out_disable; |
1446 | 1421 | ||
@@ -1845,7 +1820,7 @@ static void ata_host_set_dma(struct ata_port *ap) | |||
1845 | */ | 1820 | */ |
1846 | static void ata_set_mode(struct ata_port *ap) | 1821 | static void ata_set_mode(struct ata_port *ap) |
1847 | { | 1822 | { |
1848 | int i, rc; | 1823 | int i, rc, used_dma = 0; |
1849 | 1824 | ||
1850 | /* step 1: calculate xfer_mask */ | 1825 | /* step 1: calculate xfer_mask */ |
1851 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 1826 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
@@ -1863,6 +1838,9 @@ static void ata_set_mode(struct ata_port *ap) | |||
1863 | dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask); | 1838 | dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask); |
1864 | dev->pio_mode = ata_xfer_mask2mode(pio_mask); | 1839 | dev->pio_mode = ata_xfer_mask2mode(pio_mask); |
1865 | dev->dma_mode = ata_xfer_mask2mode(dma_mask); | 1840 | dev->dma_mode = ata_xfer_mask2mode(dma_mask); |
1841 | |||
1842 | if (dev->dma_mode) | ||
1843 | used_dma = 1; | ||
1866 | } | 1844 | } |
1867 | 1845 | ||
1868 | /* step 2: always set host PIO timings */ | 1846 | /* step 2: always set host PIO timings */ |
@@ -1884,6 +1862,17 @@ static void ata_set_mode(struct ata_port *ap) | |||
1884 | goto err_out; | 1862 | goto err_out; |
1885 | } | 1863 | } |
1886 | 1864 | ||
1865 | /* | ||
1866 | * Record simplex status. If we selected DMA then the other | ||
1867 | * host channels are not permitted to do so. | ||
1868 | */ | ||
1869 | |||
1870 | if (used_dma && (ap->host_set->flags & ATA_HOST_SIMPLEX)) | ||
1871 | ap->host_set->simplex_claimed = 1; | ||
1872 | |||
1873 | /* | ||
1874 | * Chip specific finalisation | ||
1875 | */ | ||
1887 | if (ap->ops->post_set_mode) | 1876 | if (ap->ops->post_set_mode) |
1888 | ap->ops->post_set_mode(ap); | 1877 | ap->ops->post_set_mode(ap); |
1889 | 1878 | ||
@@ -2005,45 +1994,6 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) | |||
2005 | ap->ops->dev_select(ap, 0); | 1994 | ap->ops->dev_select(ap, 0); |
2006 | } | 1995 | } |
2007 | 1996 | ||
2008 | /** | ||
2009 | * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command. | ||
2010 | * @ap: Port to reset and probe | ||
2011 | * | ||
2012 | * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and | ||
2013 | * probe the bus. Not often used these days. | ||
2014 | * | ||
2015 | * LOCKING: | ||
2016 | * PCI/etc. bus probe sem. | ||
2017 | * Obtains host_set lock. | ||
2018 | * | ||
2019 | */ | ||
2020 | |||
2021 | static unsigned int ata_bus_edd(struct ata_port *ap) | ||
2022 | { | ||
2023 | struct ata_taskfile tf; | ||
2024 | unsigned long flags; | ||
2025 | |||
2026 | /* set up execute-device-diag (bus reset) taskfile */ | ||
2027 | /* also, take interrupts to a known state (disabled) */ | ||
2028 | DPRINTK("execute-device-diag\n"); | ||
2029 | ata_tf_init(ap, &tf, 0); | ||
2030 | tf.ctl |= ATA_NIEN; | ||
2031 | tf.command = ATA_CMD_EDD; | ||
2032 | tf.protocol = ATA_PROT_NODATA; | ||
2033 | |||
2034 | /* do bus reset */ | ||
2035 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
2036 | ata_tf_to_host(ap, &tf); | ||
2037 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
2038 | |||
2039 | /* spec says at least 2ms. but who knows with those | ||
2040 | * crazy ATAPI devices... | ||
2041 | */ | ||
2042 | msleep(150); | ||
2043 | |||
2044 | return ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); | ||
2045 | } | ||
2046 | |||
2047 | static unsigned int ata_bus_softreset(struct ata_port *ap, | 1997 | static unsigned int ata_bus_softreset(struct ata_port *ap, |
2048 | unsigned int devmask) | 1998 | unsigned int devmask) |
2049 | { | 1999 | { |
@@ -2078,13 +2028,12 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, | |||
2078 | */ | 2028 | */ |
2079 | msleep(150); | 2029 | msleep(150); |
2080 | 2030 | ||
2081 | |||
2082 | /* Before we perform post reset processing we want to see if | 2031 | /* Before we perform post reset processing we want to see if |
2083 | the bus shows 0xFF because the odd clown forgets the D7 pulldown | 2032 | * the bus shows 0xFF because the odd clown forgets the D7 |
2084 | resistor */ | 2033 | * pulldown resistor. |
2085 | 2034 | */ | |
2086 | if (ata_check_status(ap) == 0xFF) | 2035 | if (ata_check_status(ap) == 0xFF) |
2087 | return 1; /* Positive is failure for some reason */ | 2036 | return AC_ERR_OTHER; |
2088 | 2037 | ||
2089 | ata_bus_post_reset(ap, devmask); | 2038 | ata_bus_post_reset(ap, devmask); |
2090 | 2039 | ||
@@ -2116,7 +2065,7 @@ void ata_bus_reset(struct ata_port *ap) | |||
2116 | struct ata_ioports *ioaddr = &ap->ioaddr; | 2065 | struct ata_ioports *ioaddr = &ap->ioaddr; |
2117 | unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; | 2066 | unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; |
2118 | u8 err; | 2067 | u8 err; |
2119 | unsigned int dev0, dev1 = 0, rc = 0, devmask = 0; | 2068 | unsigned int dev0, dev1 = 0, devmask = 0; |
2120 | 2069 | ||
2121 | DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); | 2070 | DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); |
2122 | 2071 | ||
@@ -2139,18 +2088,8 @@ void ata_bus_reset(struct ata_port *ap) | |||
2139 | 2088 | ||
2140 | /* issue bus reset */ | 2089 | /* issue bus reset */ |
2141 | if (ap->flags & ATA_FLAG_SRST) | 2090 | if (ap->flags & ATA_FLAG_SRST) |
2142 | rc = ata_bus_softreset(ap, devmask); | 2091 | if (ata_bus_softreset(ap, devmask)) |
2143 | else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) { | 2092 | goto err_out; |
2144 | /* set up device control */ | ||
2145 | if (ap->flags & ATA_FLAG_MMIO) | ||
2146 | writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); | ||
2147 | else | ||
2148 | outb(ap->ctl, ioaddr->ctl_addr); | ||
2149 | rc = ata_bus_edd(ap); | ||
2150 | } | ||
2151 | |||
2152 | if (rc) | ||
2153 | goto err_out; | ||
2154 | 2093 | ||
2155 | /* | 2094 | /* |
2156 | * determine by signature whether we have ATA or ATAPI devices | 2095 | * determine by signature whether we have ATA or ATAPI devices |
@@ -2223,9 +2162,9 @@ static int sata_phy_resume(struct ata_port *ap) | |||
2223 | * so makes reset sequence different from the original | 2162 | * so makes reset sequence different from the original |
2224 | * ->phy_reset implementation and Jeff nervous. :-P | 2163 | * ->phy_reset implementation and Jeff nervous. :-P |
2225 | */ | 2164 | */ |
2226 | extern void ata_std_probeinit(struct ata_port *ap) | 2165 | void ata_std_probeinit(struct ata_port *ap) |
2227 | { | 2166 | { |
2228 | if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) { | 2167 | if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) { |
2229 | sata_phy_resume(ap); | 2168 | sata_phy_resume(ap); |
2230 | if (sata_dev_present(ap)) | 2169 | if (sata_dev_present(ap)) |
2231 | ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); | 2170 | ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); |
@@ -2714,18 +2653,23 @@ static int ata_dma_blacklisted(const struct ata_device *dev) | |||
2714 | * known limits including host controller limits, device | 2653 | * known limits including host controller limits, device |
2715 | * blacklist, etc... | 2654 | * blacklist, etc... |
2716 | * | 2655 | * |
2656 | * FIXME: The current implementation limits all transfer modes to | ||
2657 | * the fastest of the lowested device on the port. This is not | ||
2658 | * required on most controllers. | ||
2659 | * | ||
2717 | * LOCKING: | 2660 | * LOCKING: |
2718 | * None. | 2661 | * None. |
2719 | */ | 2662 | */ |
2720 | static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) | 2663 | static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) |
2721 | { | 2664 | { |
2665 | struct ata_host_set *hs = ap->host_set; | ||
2722 | unsigned long xfer_mask; | 2666 | unsigned long xfer_mask; |
2723 | int i; | 2667 | int i; |
2724 | 2668 | ||
2725 | xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, | 2669 | xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, |
2726 | ap->udma_mask); | 2670 | ap->udma_mask); |
2727 | 2671 | ||
2728 | /* use port-wide xfermask for now */ | 2672 | /* FIXME: Use port-wide xfermask for now */ |
2729 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 2673 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
2730 | struct ata_device *d = &ap->device[i]; | 2674 | struct ata_device *d = &ap->device[i]; |
2731 | if (!ata_dev_present(d)) | 2675 | if (!ata_dev_present(d)) |
@@ -2735,12 +2679,23 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) | |||
2735 | xfer_mask &= ata_id_xfermask(d->id); | 2679 | xfer_mask &= ata_id_xfermask(d->id); |
2736 | if (ata_dma_blacklisted(d)) | 2680 | if (ata_dma_blacklisted(d)) |
2737 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | 2681 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); |
2682 | /* Apply cable rule here. Don't apply it early because when | ||
2683 | we handle hot plug the cable type can itself change */ | ||
2684 | if (ap->cbl == ATA_CBL_PATA40) | ||
2685 | xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); | ||
2738 | } | 2686 | } |
2739 | 2687 | ||
2740 | if (ata_dma_blacklisted(dev)) | 2688 | if (ata_dma_blacklisted(dev)) |
2741 | printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, " | 2689 | printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, " |
2742 | "disabling DMA\n", ap->id, dev->devno); | 2690 | "disabling DMA\n", ap->id, dev->devno); |
2743 | 2691 | ||
2692 | if (hs->flags & ATA_HOST_SIMPLEX) { | ||
2693 | if (hs->simplex_claimed) | ||
2694 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | ||
2695 | } | ||
2696 | if (ap->ops->mode_filter) | ||
2697 | xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask); | ||
2698 | |||
2744 | ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, | 2699 | ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, |
2745 | &dev->udma_mask); | 2700 | &dev->udma_mask); |
2746 | } | 2701 | } |
@@ -2795,16 +2750,16 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap, | |||
2795 | */ | 2750 | */ |
2796 | 2751 | ||
2797 | static unsigned int ata_dev_init_params(struct ata_port *ap, | 2752 | static unsigned int ata_dev_init_params(struct ata_port *ap, |
2798 | struct ata_device *dev) | 2753 | struct ata_device *dev, |
2754 | u16 heads, | ||
2755 | u16 sectors) | ||
2799 | { | 2756 | { |
2800 | struct ata_taskfile tf; | 2757 | struct ata_taskfile tf; |
2801 | unsigned int err_mask; | 2758 | unsigned int err_mask; |
2802 | u16 sectors = dev->id[6]; | ||
2803 | u16 heads = dev->id[3]; | ||
2804 | 2759 | ||
2805 | /* Number of sectors per track 1-255. Number of heads 1-16 */ | 2760 | /* Number of sectors per track 1-255. Number of heads 1-16 */ |
2806 | if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) | 2761 | if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) |
2807 | return 0; | 2762 | return AC_ERR_INVALID; |
2808 | 2763 | ||
2809 | /* set up init dev params taskfile */ | 2764 | /* set up init dev params taskfile */ |
2810 | DPRINTK("init dev params \n"); | 2765 | DPRINTK("init dev params \n"); |
@@ -4536,6 +4491,14 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, | |||
4536 | int rc; | 4491 | int rc; |
4537 | 4492 | ||
4538 | DPRINTK("ENTER\n"); | 4493 | DPRINTK("ENTER\n"); |
4494 | |||
4495 | if (!ent->port_ops->probe_reset && | ||
4496 | !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) { | ||
4497 | printk(KERN_ERR "ata%u: no reset mechanism available\n", | ||
4498 | port_no); | ||
4499 | return NULL; | ||
4500 | } | ||
4501 | |||
4539 | host = scsi_host_alloc(ent->sht, sizeof(struct ata_port)); | 4502 | host = scsi_host_alloc(ent->sht, sizeof(struct ata_port)); |
4540 | if (!host) | 4503 | if (!host) |
4541 | return NULL; | 4504 | return NULL; |
@@ -4596,6 +4559,7 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
4596 | host_set->mmio_base = ent->mmio_base; | 4559 | host_set->mmio_base = ent->mmio_base; |
4597 | host_set->private_data = ent->private_data; | 4560 | host_set->private_data = ent->private_data; |
4598 | host_set->ops = ent->port_ops; | 4561 | host_set->ops = ent->port_ops; |
4562 | host_set->flags = ent->host_set_flags; | ||
4599 | 4563 | ||
4600 | /* register each port bound to this device */ | 4564 | /* register each port bound to this device */ |
4601 | for (i = 0; i < ent->n_ports; i++) { | 4565 | for (i = 0; i < ent->n_ports; i++) { |
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 275ed9bd898c..fa901fd65085 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -1010,7 +1010,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) | |||
1010 | 1010 | ||
1011 | pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); | 1011 | pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); |
1012 | pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); | 1012 | pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); |
1013 | pp->sg_tbl[i].flags_size = cpu_to_le32(len); | 1013 | pp->sg_tbl[i].flags_size = cpu_to_le32(len & 0xffff); |
1014 | 1014 | ||
1015 | sg_len -= len; | 1015 | sg_len -= len; |
1016 | addr += len; | 1016 | addr += len; |
@@ -1350,7 +1350,6 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1350 | { | 1350 | { |
1351 | void __iomem *mmio = host_set->mmio_base; | 1351 | void __iomem *mmio = host_set->mmio_base; |
1352 | void __iomem *hc_mmio = mv_hc_base(mmio, hc); | 1352 | void __iomem *hc_mmio = mv_hc_base(mmio, hc); |
1353 | struct ata_port *ap; | ||
1354 | struct ata_queued_cmd *qc; | 1353 | struct ata_queued_cmd *qc; |
1355 | u32 hc_irq_cause; | 1354 | u32 hc_irq_cause; |
1356 | int shift, port, port0, hard_port, handled; | 1355 | int shift, port, port0, hard_port, handled; |
@@ -1373,25 +1372,32 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1373 | 1372 | ||
1374 | for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { | 1373 | for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { |
1375 | u8 ata_status = 0; | 1374 | u8 ata_status = 0; |
1376 | ap = host_set->ports[port]; | 1375 | struct ata_port *ap = host_set->ports[port]; |
1376 | struct mv_port_priv *pp = ap->private_data; | ||
1377 | |||
1377 | hard_port = port & MV_PORT_MASK; /* range 0-3 */ | 1378 | hard_port = port & MV_PORT_MASK; /* range 0-3 */ |
1378 | handled = 0; /* ensure ata_status is set if handled++ */ | 1379 | handled = 0; /* ensure ata_status is set if handled++ */ |
1379 | 1380 | ||
1380 | if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { | 1381 | /* Note that DEV_IRQ might happen spuriously during EDMA, |
1381 | /* new CRPB on the queue; just one at a time until NCQ | 1382 | * and should be ignored in such cases. We could mask it, |
1382 | */ | 1383 | * but it's pretty rare and may not be worth the overhead. |
1383 | ata_status = mv_get_crpb_status(ap); | 1384 | */ |
1384 | handled++; | 1385 | if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { |
1385 | } else if ((DEV_IRQ << hard_port) & hc_irq_cause) { | 1386 | /* EDMA: check for response queue interrupt */ |
1386 | /* received ATA IRQ; read the status reg to clear INTRQ | 1387 | if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { |
1387 | */ | 1388 | ata_status = mv_get_crpb_status(ap); |
1388 | ata_status = readb((void __iomem *) | 1389 | handled = 1; |
1390 | } | ||
1391 | } else { | ||
1392 | /* PIO: check for device (drive) interrupt */ | ||
1393 | if ((DEV_IRQ << hard_port) & hc_irq_cause) { | ||
1394 | ata_status = readb((void __iomem *) | ||
1389 | ap->ioaddr.status_addr); | 1395 | ap->ioaddr.status_addr); |
1390 | handled++; | 1396 | handled = 1; |
1397 | } | ||
1391 | } | 1398 | } |
1392 | 1399 | ||
1393 | if (ap && | 1400 | if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)) |
1394 | (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) | ||
1395 | continue; | 1401 | continue; |
1396 | 1402 | ||
1397 | err_mask = ac_err_mask(ata_status); | 1403 | err_mask = ac_err_mask(ata_status); |
@@ -1403,12 +1409,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1403 | if ((PORT0_ERR << shift) & relevant) { | 1409 | if ((PORT0_ERR << shift) & relevant) { |
1404 | mv_err_intr(ap); | 1410 | mv_err_intr(ap); |
1405 | err_mask |= AC_ERR_OTHER; | 1411 | err_mask |= AC_ERR_OTHER; |
1406 | handled++; | 1412 | handled = 1; |
1407 | } | 1413 | } |
1408 | 1414 | ||
1409 | if (handled && ap) { | 1415 | if (handled) { |
1410 | qc = ata_qc_from_tag(ap, ap->active_tag); | 1416 | qc = ata_qc_from_tag(ap, ap->active_tag); |
1411 | if (NULL != qc) { | 1417 | if (qc && (qc->flags & ATA_QCFLAG_ACTIVE)) { |
1412 | VPRINTK("port %u IRQ found for qc, " | 1418 | VPRINTK("port %u IRQ found for qc, " |
1413 | "ata_status 0x%x\n", port,ata_status); | 1419 | "ata_status 0x%x\n", port,ata_status); |
1414 | /* mark qc status appropriately */ | 1420 | /* mark qc status appropriately */ |