int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, int count, bool read, int timeout) { struct completion trans_done; struct scatterlist *sg; dma_addr_t addr; long timeleft; unsigned long flags; unsigned int len; int i, err = 0; u32 val; u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE; if (pcr->remove_pci) return -ENODEV; if ((sglist == NULL) || (count < 1)) return -EINVAL; val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; pcr->sgi = 0; for_each_sg(sglist, sg, count, i) { addr = sg_dma_address(sg); len = sg_dma_len(sg); rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1); }
int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, int num_sg, bool read, int timeout) { struct completion trans_done; u8 dir; int err = 0, i, count; long timeleft; unsigned long flags; struct scatterlist *sg; enum dma_data_direction dma_dir; u32 val; dma_addr_t addr; unsigned int len; dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); /* don't transfer data during abort processing */ if (pcr->remove_pci) return -EINVAL; if ((sglist == NULL) || (num_sg <= 0)) return -EINVAL; if (read) { dir = DEVICE_TO_HOST; dma_dir = DMA_FROM_DEVICE; } else { dir = HOST_TO_DEVICE; dma_dir = DMA_TO_DEVICE; } count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); if (count < 1) { dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); return -EINVAL; } dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; pcr->sgi = 0; for_each_sg(sglist, sg, count, i) { addr = sg_dma_address(sg); len = sg_dma_len(sg); rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1); }