[patch 52/54] SPARC64: Dont be picky about virtual-dma values on sun4v.

From: Chris Wright
Date: Fri Jun 08 2007 - 03:53:26 EST


-stable review patch. If anyone has any objections, please let us know.
---------------------

From: David Miller <davem@xxxxxxxxxxxxx>

Handle arbitrary base and length values as long as they
are multiples of IO_PAGE_SIZE.

Bug found by Arun Kumar Rao.

Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
Signed-off-by: Chris Wright <chrisw@xxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>

---
arch/sparc64/kernel/pci_sun4v.c | 36 ++++++++++--------------------------
1 file changed, 10 insertions(+), 26 deletions(-)

--- linux-2.6.21.4.orig/arch/sparc64/kernel/pci_sun4v.c
+++ linux-2.6.21.4/arch/sparc64/kernel/pci_sun4v.c
@@ -12,6 +12,7 @@
#include <linux/percpu.h>
#include <linux/irq.h>
#include <linux/msi.h>
+#include <linux/log2.h>

#include <asm/pbm.h>
#include <asm/iommu.h>
@@ -996,9 +997,8 @@ static void pci_sun4v_iommu_init(struct
{
struct pci_iommu *iommu = pbm->iommu;
struct property *prop;
- unsigned long num_tsb_entries, sz;
+ unsigned long num_tsb_entries, sz, tsbsize;
u32 vdma[2], dma_mask, dma_offset;
- int tsbsize;

prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
if (prop) {
@@ -1012,31 +1012,15 @@ static void pci_sun4v_iommu_init(struct
vdma[1] = 0x80000000;
}

- dma_mask = vdma[0];
- switch (vdma[1]) {
- case 0x20000000:
- dma_mask |= 0x1fffffff;
- tsbsize = 64;
- break;
-
- case 0x40000000:
- dma_mask |= 0x3fffffff;
- tsbsize = 128;
- break;
-
- case 0x80000000:
- dma_mask |= 0x7fffffff;
- tsbsize = 256;
- break;
-
- default:
- prom_printf("PCI-SUN4V: strange virtual-dma size.\n");
- prom_halt();
+ if ((vdma[0] | vdma[1]) & ~IO_PAGE_MASK) {
+ prom_printf("PCI-SUN4V: strange virtual-dma[%08x:%08x].\n",
+ vdma[0], vdma[1]);
+ prom_halt();
};

- tsbsize *= (8 * 1024);
-
- num_tsb_entries = tsbsize / sizeof(iopte_t);
+ dma_mask = (roundup_pow_of_two(vdma[1]) - 1UL);
+ num_tsb_entries = vdma[1] / IO_PAGE_SIZE;
+ tsbsize = num_tsb_entries * sizeof(iopte_t);

dma_offset = vdma[0];

@@ -1047,7 +1031,7 @@ static void pci_sun4v_iommu_init(struct
iommu->dma_addr_mask = dma_mask;

/* Allocate and initialize the free area map. */
- sz = num_tsb_entries / 8;
+ sz = (num_tsb_entries + 7) / 8;
sz = (sz + 7UL) & ~7UL;
iommu->arena.map = kzalloc(sz, GFP_KERNEL);
if (!iommu->arena.map) {

--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/