/** * vme_dma_ioctl() - ioctl file method for the VME DMA device * @file: Device file descriptor * @cmd: ioctl number * @arg: ioctl argument * * Currently the VME DMA device supports the following ioctl: * * VME_IOCTL_START_DMA */ long vme_dma_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rc = 0; struct vme_dma desc; void __user *argp = (void __user *)arg; switch (cmd) { case VME_IOCTL_START_DMA: /* Get the DMA transfer descriptor */ if (copy_from_user(&desc, (void *)argp, sizeof(struct vme_dma))) return -EFAULT; /* Do the DMA */ rc = vme_do_dma(&desc); if (rc) return rc; /* * Copy back the DMA transfer descriptor containing the DMA * updated status. */ if (copy_to_user((void *)argp, &desc, sizeof(struct vme_dma))) return -EFAULT; break; default: rc = -ENOIOCTLCMD; } return rc; }
static int do_raw_dma(struct vmeio_dma_op *request) { struct vme_dma dma_desc; unsigned int bu, bl; int cc; unsigned int haddr; bl = (unsigned long)request->buffer; bu = 0; memset(&dma_desc, 0, sizeof(dma_desc)); dma_desc.dir = request->direction; dma_desc.novmeinc = 0; dma_desc.length = request->byte_length; dma_desc.ctrl.pci_block_size = VME_DMA_BSIZE_4096; dma_desc.ctrl.pci_backoff_time = VME_DMA_BACKOFF_0; dma_desc.ctrl.vme_block_size = VME_DMA_BSIZE_4096; dma_desc.ctrl.vme_backoff_time = VME_DMA_BACKOFF_0; dma_desc.dst.data_width = request->data_width; dma_desc.dst.am = request->am; dma_desc.src.data_width = request->data_width; dma_desc.src.am = request->am; haddr = request->address; if (request->direction == VME_DMA_TO_DEVICE) { dma_desc.src.addrl = bl; dma_desc.src.addru = bu; dma_desc.dst.addrl = haddr; } else { dma_desc.src.addrl = haddr; dma_desc.dst.addrl = bl; dma_desc.dst.addru = bu; } if ((cc = vme_do_dma(&dma_desc)) < 0) return cc; return 0; }