Commit f49e140b authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: implement pci_dma_error

From: Anton Blanchard <anton@samba.org>

Implement pci_dma_error.  Create PCI_DMA_ERROR_CODE like sparc64, it will
allow us to find and fix out of tree drivers using NO_TCE directly.

ibmveth needs some surgery, fix it temporarily until the guys come up with
a decent fix.
parent b6d83633
...@@ -73,7 +73,7 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl, unsigned long np ...@@ -73,7 +73,7 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl, unsigned long np
if (unlikely(npages) == 0) { if (unlikely(npages) == 0) {
if (printk_ratelimit()) if (printk_ratelimit())
WARN_ON(1); WARN_ON(1);
return NO_TCE; return PCI_DMA_ERROR_CODE;
} }
if (handle && *handle) if (handle && *handle)
...@@ -109,7 +109,7 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl, unsigned long np ...@@ -109,7 +109,7 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl, unsigned long np
goto again; goto again;
} else { } else {
/* Third failure, give up */ /* Third failure, give up */
return NO_TCE; return PCI_DMA_ERROR_CODE;
} }
} }
...@@ -143,15 +143,15 @@ dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page, ...@@ -143,15 +143,15 @@ dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page,
unsigned int npages, int direction) unsigned int npages, int direction)
{ {
unsigned long entry, flags; unsigned long entry, flags;
dma_addr_t ret = NO_TCE; dma_addr_t ret = PCI_DMA_ERROR_CODE;
spin_lock_irqsave(&(tbl->it_lock), flags); spin_lock_irqsave(&(tbl->it_lock), flags);
entry = iommu_range_alloc(tbl, npages, NULL); entry = iommu_range_alloc(tbl, npages, NULL);
if (unlikely(entry == NO_TCE)) { if (unlikely(entry == PCI_DMA_ERROR_CODE)) {
spin_unlock_irqrestore(&(tbl->it_lock), flags); spin_unlock_irqrestore(&(tbl->it_lock), flags);
return NO_TCE; return PCI_DMA_ERROR_CODE;
} }
entry += tbl->it_offset; /* Offset into real TCE table */ entry += tbl->it_offset; /* Offset into real TCE table */
...@@ -262,7 +262,7 @@ int iommu_alloc_sg(struct iommu_table *tbl, struct device *dev, ...@@ -262,7 +262,7 @@ int iommu_alloc_sg(struct iommu_table *tbl, struct device *dev,
DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen);
/* Handle failure */ /* Handle failure */
if (unlikely(entry == NO_TCE)) { if (unlikely(entry == PCI_DMA_ERROR_CODE)) {
if (printk_ratelimit()) if (printk_ratelimit())
printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %lx" printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %lx"
" npages %lx\n", tbl, vaddr, npages); " npages %lx\n", tbl, vaddr, npages);
...@@ -326,7 +326,7 @@ int iommu_alloc_sg(struct iommu_table *tbl, struct device *dev, ...@@ -326,7 +326,7 @@ int iommu_alloc_sg(struct iommu_table *tbl, struct device *dev,
*/ */
if (outcount < nelems) { if (outcount < nelems) {
outs++; outs++;
outs->dma_address = NO_TCE; outs->dma_address = PCI_DMA_ERROR_CODE;
outs->dma_length = 0; outs->dma_length = 0;
} }
return outcount; return outcount;
......
...@@ -82,7 +82,7 @@ void *pci_iommu_alloc_consistent(struct pci_dev *hwdev, size_t size, ...@@ -82,7 +82,7 @@ void *pci_iommu_alloc_consistent(struct pci_dev *hwdev, size_t size,
if (order >= IOMAP_MAX_ORDER) { if (order >= IOMAP_MAX_ORDER) {
printk("PCI_DMA: pci_alloc_consistent size too large: 0x%lx\n", printk("PCI_DMA: pci_alloc_consistent size too large: 0x%lx\n",
size); size);
return (void *)NO_TCE; return (void *)PCI_DMA_ERROR_CODE;
} }
tbl = devnode_table(hwdev); tbl = devnode_table(hwdev);
...@@ -101,7 +101,7 @@ void *pci_iommu_alloc_consistent(struct pci_dev *hwdev, size_t size, ...@@ -101,7 +101,7 @@ void *pci_iommu_alloc_consistent(struct pci_dev *hwdev, size_t size,
/* Set up tces to cover the allocated range */ /* Set up tces to cover the allocated range */
mapping = iommu_alloc(tbl, ret, npages, PCI_DMA_BIDIRECTIONAL); mapping = iommu_alloc(tbl, ret, npages, PCI_DMA_BIDIRECTIONAL);
if (mapping == NO_TCE) { if (mapping == PCI_DMA_ERROR_CODE) {
free_pages((unsigned long)ret, order); free_pages((unsigned long)ret, order);
ret = NULL; ret = NULL;
} else } else
...@@ -139,7 +139,7 @@ dma_addr_t pci_iommu_map_single(struct pci_dev *hwdev, void *vaddr, ...@@ -139,7 +139,7 @@ dma_addr_t pci_iommu_map_single(struct pci_dev *hwdev, void *vaddr,
size_t size, int direction) size_t size, int direction)
{ {
struct iommu_table * tbl; struct iommu_table * tbl;
dma_addr_t dma_handle = NO_TCE; dma_addr_t dma_handle = PCI_DMA_ERROR_CODE;
unsigned long uaddr; unsigned long uaddr;
unsigned int npages; unsigned int npages;
...@@ -153,7 +153,7 @@ dma_addr_t pci_iommu_map_single(struct pci_dev *hwdev, void *vaddr, ...@@ -153,7 +153,7 @@ dma_addr_t pci_iommu_map_single(struct pci_dev *hwdev, void *vaddr,
if (tbl) { if (tbl) {
dma_handle = iommu_alloc(tbl, vaddr, npages, direction); dma_handle = iommu_alloc(tbl, vaddr, npages, direction);
if (dma_handle == NO_TCE) { if (dma_handle == PCI_DMA_ERROR_CODE) {
if (printk_ratelimit()) { if (printk_ratelimit()) {
printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %p npages %d\n", printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %p npages %d\n",
tbl, vaddr, npages); tbl, vaddr, npages);
......
...@@ -419,7 +419,7 @@ dma_addr_t vio_map_single(struct vio_dev *dev, void *vaddr, ...@@ -419,7 +419,7 @@ dma_addr_t vio_map_single(struct vio_dev *dev, void *vaddr,
size_t size, int direction ) size_t size, int direction )
{ {
struct iommu_table *tbl; struct iommu_table *tbl;
dma_addr_t dma_handle = NO_TCE; dma_addr_t dma_handle = PCI_DMA_ERROR_CODE;
unsigned long uaddr; unsigned long uaddr;
unsigned int npages; unsigned int npages;
...@@ -504,7 +504,7 @@ void *vio_alloc_consistent(struct vio_dev *dev, size_t size, ...@@ -504,7 +504,7 @@ void *vio_alloc_consistent(struct vio_dev *dev, size_t size,
/* It is easier to debug here for the drivers than in the tce tables.*/ /* It is easier to debug here for the drivers than in the tce tables.*/
if(order >= IOMAP_MAX_ORDER) { if(order >= IOMAP_MAX_ORDER) {
printk("VIO_DMA: vio_alloc_consistent size to large: 0x%lx \n", size); printk("VIO_DMA: vio_alloc_consistent size to large: 0x%lx \n", size);
return (void *)NO_TCE; return (void *)PCI_DMA_ERROR_CODE;
} }
tbl = dev->iommu_table; tbl = dev->iommu_table;
...@@ -517,7 +517,7 @@ void *vio_alloc_consistent(struct vio_dev *dev, size_t size, ...@@ -517,7 +517,7 @@ void *vio_alloc_consistent(struct vio_dev *dev, size_t size,
memset(ret, 0, npages << PAGE_SHIFT); memset(ret, 0, npages << PAGE_SHIFT);
/* Set up tces to cover the allocated range */ /* Set up tces to cover the allocated range */
tce = iommu_alloc(tbl, ret, npages, PCI_DMA_BIDIRECTIONAL); tce = iommu_alloc(tbl, ret, npages, PCI_DMA_BIDIRECTIONAL);
if (tce == NO_TCE) { if (tce == PCI_DMA_ERROR_CODE) {
PPCDBG(PPCDBG_TCE, "vio_alloc_consistent: iommu_alloc failed\n" ); PPCDBG(PPCDBG_TCE, "vio_alloc_consistent: iommu_alloc failed\n" );
free_pages((unsigned long)ret, order); free_pages((unsigned long)ret, order);
ret = NULL; ret = NULL;
......
...@@ -60,6 +60,9 @@ ...@@ -60,6 +60,9 @@
#include "ibmveth.h" #include "ibmveth.h"
#warning remove NO_TCE usage from ibmveth.c
#define NO_TCE PCI_DMA_ERROR_CODE
#define DEBUG 1 #define DEBUG 1
#define ibmveth_printk(fmt, args...) \ #define ibmveth_printk(fmt, args...) \
......
...@@ -33,8 +33,6 @@ ...@@ -33,8 +33,6 @@
*/ */
#define IOMAP_MAX_ORDER 10 #define IOMAP_MAX_ORDER 10
#define NO_TCE ((dma_addr_t)-1)
/* /*
* Tces come in two formats, one for the virtual bus and a different * Tces come in two formats, one for the virtual bus and a different
* format for PCI * format for PCI
......
...@@ -169,6 +169,12 @@ static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask) ...@@ -169,6 +169,12 @@ static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask)
return 0; return 0;
} }
#define PCI_DMA_ERROR_CODE (~(dma_addr_t)0x0)
static inline int pci_dma_error(dma_addr_t dma_addr)
{
return (dma_addr == PCI_DMA_ERROR_CODE);
}
extern int pci_domain_nr(struct pci_bus *bus); extern int pci_domain_nr(struct pci_bus *bus);
/* Set the name of the bus as it appears in /proc/bus/pci */ /* Set the name of the bus as it appears in /proc/bus/pci */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment