That's hack as well, isn't it?
The right solution IMHO is what David Miller introduced on sbus:
instead of using virt_to_bus & co. drivers acquire a DMA handler before
doing DMA using
handle = pci_map_single(pci_dev *dev, void *addr, long len, int flags)
or
handle = pci_map_sg(pci_dev *dev, struct scatterlist *sg, int flags)
and after it is done with the DMA it does pci_unmap_{single,sg}.
On sane architectures these routines will set up IO translation tables for
DMA, with the advantage that it can squeeze multiple sg entries into one
single DMA sg entry and on i386 it will be inlined to virt_to_bus or a loop
over the sg list doing virt_to_bus.
unmap will then free the translation tables on Sparc, Alpha and as SCT said
on some AGP chipsets as well.
In the flags, you can code all the flags for buggy devices, like this one
handles only 24bit, this one handles 30bit, this one 31bit DMA and
the pci_map routines can attempt to fulfill broken device's requests.
Plus this scheme is necessary if we want to actually support more than 4GB
of physical memory on 64bit platforms (e.g. on sparc64 if you want 20GB of
memory supported by Linux, you have to make sure you don't have any PCI in
the box, just SBUS).
Cheers,
Jakub
___________________________________________________________________
Jakub Jelinek | jakub@redhat.com | http://sunsite.mff.cuni.cz/~jj
Linux version 2.3.26 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/