bus_addr &= IO_PAGE_MASK;
entry = (bus_addr - iommu->tbl.table_map_base) >> IO_PAGE_SHIFT;
dma_4v_iommu_demap(&devhandle, entry, npages);
- iommu_tbl_range_free(&iommu->tbl, bus_addr, npages, DMA_ERROR_CODE);
+ iommu_tbl_range_free(&iommu->tbl, bus_addr, npages, IOMMU_ERROR_CODE);
}
+static int dma_4v_map_sg_bypass(struct device *dev, struct scatterlist *sglist,
+ int nelems, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct pci_pbm_info *pbm;
+ unsigned long devhandle;
+ unsigned long ra;
+ unsigned long prot;
+ unsigned long dma_addr;
+ struct scatterlist *s;
+ int i;
+
+ BUG_ON(!dev);
+ pbm = dev->archdata.host_controller;
+ BUG_ON(!pbm);
+ devhandle = pbm->devhandle;
+
+ if (unlikely(direction == DMA_NONE))
+ goto bad;
+
+ prot = HV_PCI_MAP_ATTR_READ;
+
+ if (direction != DMA_TO_DEVICE)
+ prot |= HV_PCI_MAP_ATTR_WRITE;
+
+ for_each_sg(sglist, s, nelems, i) {
+ ra = (unsigned long) SG_ENT_PHYS_ADDRESS(s);
+ if (pci_sun4v_iommu_getbypass(devhandle, ra, prot, &dma_addr))
+ goto bad;
+ s->dma_address = dma_addr;
+ s->dma_length = s->length;
+ }
+
+ return nelems;
+
+bad:
+ return 0;
+}
+
static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
int nelems, enum dma_data_direction direction,
struct dma_attrs *attrs)