static int msm_buspm_dev_alloc(struct file *filp, struct buspm_alloc_params data) { unsigned long paddr; void *vaddr; struct msm_buspm_map_dev *dev = filp->private_data; if (dev->vaddr) msm_buspm_dev_free(filp); vaddr = allocate_contiguous_ebi(data.size, PAGE_SIZE, 0); paddr = (vaddr) ? memory_pool_node_paddr(vaddr) : 0L; if (vaddr == NULL) { pr_err("allocation of 0x%x bytes failed", data.size); return -ENOMEM; } dev->vaddr = vaddr; dev->paddr = paddr; dev->buflen = data.size; filp->f_pos = 0; pr_debug("virt addr = 0x%p\n", dev->vaddr); pr_debug("phys addr = 0x%lx\n", dev->paddr); return 0; }
static int msm_buspm_dev_alloc(struct file *filp, struct buspm_alloc_params data) { dma_addr_t paddr; void *vaddr; struct msm_buspm_map_dev *dev = filp->private_data; /* If buffer already allocated, then free it */ if (dev->vaddr) msm_buspm_dev_free(filp); /* Allocate uncached memory */ vaddr = dma_alloc_coherent(msm_buspm_misc.this_device, data.size, &paddr, GFP_KERNEL); if (vaddr == NULL) { pr_err("allocation of 0x%zu bytes failed", data.size); return -ENOMEM; } dev->vaddr = vaddr; dev->paddr = paddr; dev->buflen = data.size; filp->f_pos = 0; pr_debug("virt addr = 0x%p\n", dev->vaddr); pr_debug("phys addr = 0x%lx\n", dev->paddr); return 0; }
static int msm_buspm_dev_release(struct inode *inode, struct file *filp) { struct msm_buspm_map_dev *dev = filp->private_data; msm_buspm_dev_free(filp); kfree(dev); filp->private_data = NULL; return 0; }
static long msm_buspm_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct buspm_xfer_req xfer; struct buspm_alloc_params alloc_data; unsigned long paddr; int retval = 0; void *buf = msm_buspm_dev_get_vaddr(filp); unsigned char *dbgbuf = buf; switch (cmd) { case MSM_BUSPM_IOC_FREE: pr_debug("cmd = 0x%x (FREE)\n", cmd); msm_buspm_dev_free(filp); break; case MSM_BUSPM_IOC_ALLOC: pr_debug("cmd = 0x%x (ALLOC)\n", cmd); retval = __get_user(alloc_data.size, (size_t __user *)arg); if (retval == 0) retval = msm_buspm_dev_alloc(filp, alloc_data); break; case MSM_BUSPM_IOC_RD_PHYS_ADDR: pr_debug("Read Physical Address\n"); paddr = msm_buspm_dev_get_paddr(filp); if (paddr == 0L) { retval = -EINVAL; } else { pr_debug("phys addr = 0x%lx\n", paddr); retval = __put_user(paddr, (unsigned long __user *)arg); } break; case MSM_BUSPM_IOC_RDBUF: pr_debug("Read Buffer: 0x%x%x%x%x\n", dbgbuf[0], dbgbuf[1], dbgbuf[2], dbgbuf[3]); if (!buf) { retval = -EINVAL; break; } if (copy_from_user(&xfer, (void __user *)arg, sizeof(xfer))) { retval = -EFAULT; break; } if ((xfer.size <= sizeof(buf)) && (copy_to_user((void __user *)xfer.data, buf, xfer.size))) { retval = -EFAULT; break; } break; case MSM_BUSPM_IOC_WRBUF: pr_debug("Write Buffer\n"); if (!buf) { retval = -EINVAL; break; } if (copy_from_user(&xfer, (void __user *)arg, sizeof(xfer))) { retval = -EFAULT; break; } if ((sizeof(buf) <= xfer.size) && (copy_from_user(buf, (void __user *)xfer.data, xfer.size))) { retval = -EFAULT; break; } break; default: pr_debug("Unknown command 0x%x\n", cmd); retval = -EINVAL; break; } return retval; }