X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Falpha%2Fkernel%2Fpci_iommu.c;h=7cb23f12ecbd03a15cd8a6d52f84d887f96736df;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=b47c35679e870383e93f7a680fdcbe5b3df5c547;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index b47c35679..7cb23f12e 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -930,3 +930,42 @@ pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr) { return (dma_addr & ~PAGE_MASK); } + + +/* Helper for generic DMA-mapping functions. */ + +struct pci_dev * +alpha_gendev_to_pci(struct device *dev) +{ + if (dev && dev->bus == &pci_bus_type) + return to_pci_dev(dev); + + /* Assume that non-PCI devices asking for DMA are either ISA or EISA, + BUG() otherwise. */ + BUG_ON(!isa_bridge); + + /* Assume non-busmaster ISA DMA when dma_mask is not set (the ISA + bridge is bus master then). */ + if (!dev || !dev->dma_mask || !*dev->dma_mask) + return isa_bridge; + + /* For EISA bus masters, return isa_bridge (it might have smaller + dma_mask due to wiring limitations). */ + if (*dev->dma_mask >= isa_bridge->dma_mask) + return isa_bridge; + + /* This assumes ISA bus master with dma_mask 0xffffff. */ + return NULL; +} + +int +dma_set_mask(struct device *dev, u64 mask) +{ + if (!dev->dma_mask || + !pci_dma_supported(alpha_gendev_to_pci(dev), mask)) + return -EIO; + + *dev->dma_mask = mask; + + return 0; +}