Commit 9fe69704 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by David Mosberger

[PATCH] ia64: Here's a patch to make sba_iommu work again.

I added dma_address and dma_length to struct scatterlist and
removed orig_address.  This brings IA64 in line with most other
architectures, but required a few changes to swiotlb.

Grant Grundler did the sba_iommu.c updates.

Note that this isn't *quite* enough to make the generic kernel
work on ZX1 boxes, because the ACPI in 2.5.18 barfs on a
ZX1 _CRS method.

David, I've tested both the swiotlb (on i2000 and ZX1) and
sba_iommu (on ZX1, with a kludge for the ACPI problem),
and they seem to work fine.
parent 791386cb
This diff is collapsed.
...@@ -415,18 +415,20 @@ int ...@@ -415,18 +415,20 @@ int
swiotlb_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) swiotlb_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
{ {
void *addr; void *addr;
unsigned long pci_addr;
int i; int i;
if (direction == PCI_DMA_NONE) if (direction == PCI_DMA_NONE)
BUG(); BUG();
for (i = 0; i < nelems; i++, sg++) { for (i = 0; i < nelems; i++, sg++) {
sg->orig_address = SG_ENT_VIRT_ADDRESS(sg); addr = SG_ENT_VIRT_ADDRESS(sg);
if ((SG_ENT_PHYS_ADDRESS(sg) & ~hwdev->dma_mask) != 0) { pci_addr = virt_to_phys(addr);
addr = map_single(hwdev, sg->orig_address, sg->length, direction); if ((pci_addr & ~hwdev->dma_mask) != 0)
sg->page = virt_to_page(addr); sg->dma_address = map_single(hwdev, addr, sg->length, direction);
sg->offset = (u64) addr & ~PAGE_MASK; else
} sg->dma_address = pci_addr;
sg->dma_length = sg->length;
} }
return nelems; return nelems;
} }
...@@ -444,12 +446,10 @@ swiotlb_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int ...@@ -444,12 +446,10 @@ swiotlb_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int
BUG(); BUG();
for (i = 0; i < nelems; i++, sg++) for (i = 0; i < nelems; i++, sg++)
if (sg->orig_address != SG_ENT_VIRT_ADDRESS(sg)) { if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
unmap_single(hwdev, SG_ENT_VIRT_ADDRESS(sg), sg->length, direction); unmap_single(hwdev, sg->dma_address, sg->dma_length, direction);
sg->page = virt_to_page(sg->orig_address); else if (direction == PCI_DMA_FROMDEVICE)
sg->offset = (u64) sg->orig_address & ~PAGE_MASK; mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length);
} else if (direction == PCI_DMA_FROMDEVICE)
mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->length);
} }
/* /*
...@@ -468,14 +468,14 @@ swiotlb_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int ...@@ -468,14 +468,14 @@ swiotlb_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int
BUG(); BUG();
for (i = 0; i < nelems; i++, sg++) for (i = 0; i < nelems; i++, sg++)
if (sg->orig_address != SG_ENT_VIRT_ADDRESS(sg)) if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
sync_single(hwdev, SG_ENT_VIRT_ADDRESS(sg), sg->length, direction); sync_single(hwdev, sg->dma_address, sg->dma_length, direction);
} }
unsigned long unsigned long
swiotlb_dma_address (struct scatterlist *sg) swiotlb_dma_address (struct scatterlist *sg)
{ {
return SG_ENT_PHYS_ADDRESS(sg); return sg->dma_address;
} }
/* /*
......
...@@ -90,7 +90,7 @@ pcibios_penalize_isa_irq (int irq) ...@@ -90,7 +90,7 @@ pcibios_penalize_isa_irq (int irq)
/* Return the index of the PCI controller for device PDEV. */ /* Return the index of the PCI controller for device PDEV. */
#define pci_controller_num(PDEV) (0) #define pci_controller_num(PDEV) (0)
#define sg_dma_len(sg) ((sg)->length) #define sg_dma_len(sg) ((sg)->dma_length)
#define HAVE_PCI_MMAP #define HAVE_PCI_MMAP
extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
......
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
*/ */
struct scatterlist { struct scatterlist {
char *orig_address; /* for use by swiotlb */
/* These two are only valid if ADDRESS member of this struct is NULL. */
struct page *page; struct page *page;
unsigned int offset; unsigned int offset;
unsigned int length; /* buffer length */ unsigned int length; /* buffer length */
dma_addr_t dma_address;
unsigned int dma_length;
}; };
#define ISA_DMA_THRESHOLD (~0UL) #define ISA_DMA_THRESHOLD (~0UL)
......
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