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
swiotlb_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
{
void *addr;
unsigned long pci_addr;
int i;
if (direction == PCI_DMA_NONE)
BUG();
for (i = 0; i < nelems; i++, sg++) {
sg->orig_address = SG_ENT_VIRT_ADDRESS(sg);
if ((SG_ENT_PHYS_ADDRESS(sg) & ~hwdev->dma_mask) != 0) {
addr = map_single(hwdev, sg->orig_address, sg->length, direction);
sg->page = virt_to_page(addr);
sg->offset = (u64) addr & ~PAGE_MASK;
}
addr = SG_ENT_VIRT_ADDRESS(sg);
pci_addr = virt_to_phys(addr);
if ((pci_addr & ~hwdev->dma_mask) != 0)
sg->dma_address = map_single(hwdev, addr, sg->length, direction);
else
sg->dma_address = pci_addr;
sg->dma_length = sg->length;
}
return nelems;
}
......@@ -444,12 +446,10 @@ swiotlb_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int
BUG();
for (i = 0; i < nelems; i++, sg++)
if (sg->orig_address != SG_ENT_VIRT_ADDRESS(sg)) {
unmap_single(hwdev, SG_ENT_VIRT_ADDRESS(sg), sg->length, direction);
sg->page = virt_to_page(sg->orig_address);
sg->offset = (u64) sg->orig_address & ~PAGE_MASK;
} else if (direction == PCI_DMA_FROMDEVICE)
mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->length);
if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
unmap_single(hwdev, sg->dma_address, sg->dma_length, direction);
else if (direction == PCI_DMA_FROMDEVICE)
mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length);
}
/*
......@@ -468,14 +468,14 @@ swiotlb_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int
BUG();
for (i = 0; i < nelems; i++, sg++)
if (sg->orig_address != SG_ENT_VIRT_ADDRESS(sg))
sync_single(hwdev, SG_ENT_VIRT_ADDRESS(sg), sg->length, direction);
if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
sync_single(hwdev, sg->dma_address, sg->dma_length, direction);
}
unsigned long
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)
/* Return the index of the PCI controller for device PDEV. */
#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
extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
......
......@@ -7,12 +7,12 @@
*/
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;
unsigned int offset;
unsigned int length; /* buffer length */
dma_addr_t dma_address;
unsigned int dma_length;
};
#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