int q6usm_us_client_buf_alloc(unsigned int dir, struct us_client *usc, unsigned int bufsz, unsigned int bufcnt) { int rc = 0; struct us_port_data *port = NULL; unsigned int size = bufsz*bufcnt; size_t len; if ((usc == NULL) || ((dir != IN) && (dir != OUT)) || (size == 0) || (usc->session <= 0 || usc->session > USM_SESSION_MAX)) { pr_err("%s: wrong parameters: size=%d; bufcnt=%d\n", __func__, size, bufcnt); return -EINVAL; } mutex_lock(&usc->cmd_lock); port = &usc->port[dir]; /* The size to allocate should be multiple of 4K bytes */ size = PAGE_ALIGN(size); rc = msm_audio_ion_alloc("ultrasound_client", &port->client, &port->handle, size, &port->phys, &len, &port->data); if (rc) { pr_err("%s: US ION allocation failed, rc = %d\n", __func__, rc); mutex_unlock(&usc->cmd_lock); return -ENOMEM; } port->buf_cnt = bufcnt; port->buf_size = bufsz; pr_debug("%s: data[%p]; phys[%llx]; [%p]\n", __func__, (void *)port->data, (u64)port->phys, (void *)&port->phys); rc = q6usm_memory_map(port->phys, dir, size, 1, usc->session, (uint32_t *)port->ext); if (rc < 0) { pr_err("%s: CMD Memory_map failed\n", __func__); mutex_unlock(&usc->cmd_lock); q6usm_us_client_buf_free(dir, usc); q6usm_us_param_buf_free(dir, usc); } else { mutex_unlock(&usc->cmd_lock); rc = 0; } return rc; }
int q6usm_us_param_buf_alloc(unsigned int dir, struct us_client *usc, unsigned int bufsz) { int rc = 0; struct us_port_data *port = NULL; unsigned int size = 0; if ((usc == NULL) || ((dir != IN) && (dir != OUT)) || (usc->session <= 0 || usc->session > SESSION_MAX)) { pr_err("%s: wrong parameters: direction=%d, bufsz=%d\n", __func__, dir, bufsz); return -EINVAL; } mutex_lock(&usc->cmd_lock); port = &usc->port[dir]; if (bufsz == 0) { pr_debug("%s: bufsz=0, get/set param commands are forbidden\n", __func__); port->param_buf = NULL; mutex_unlock(&usc->cmd_lock); return rc; } port->param_buf = dma_alloc_coherent(NULL, bufsz, &(port->param_phys), GFP_KERNEL); if (port->param_buf == NULL) { pr_err("%s: Parameter buffer allocation failed\n", __func__); mutex_unlock(&usc->cmd_lock); return -ENOMEM; } port->param_buf_size = bufsz; pr_debug("%s: param_buf[%p]; param_phys[%p]; [%p]\n", __func__, (void *)port->param_buf, (void *)port->param_phys, (void *)&port->param_phys); size = (bufsz + MEM_4K_OFFSET) & MEM_4K_MASK; rc = q6usm_memory_map(port->param_phys, (IN | OUT), size, 1, usc->session, (uint32_t *)port->param_buf_mem_handle); if (rc < 0) { pr_err("%s: CMD Memory_map failed\n", __func__); mutex_unlock(&usc->cmd_lock); q6usm_us_client_buf_free(dir, usc); q6usm_us_param_buf_free(dir, usc); } else { mutex_unlock(&usc->cmd_lock); rc = 0; } return rc; }
int q6usm_us_client_buf_alloc(unsigned int dir, struct us_client *usc, unsigned int bufsz, unsigned int bufcnt) { int rc = 0; struct us_port_data *port = NULL; unsigned int size = bufsz*bufcnt; if ((usc == NULL) || ((dir != IN) && (dir != OUT)) || (size == 0) || (usc->session <= 0 || usc->session > SESSION_MAX)) { pr_err("%s: wrong parameters: size=%d; bufcnt=%d\n", __func__, size, bufcnt); return -EINVAL; } mutex_lock(&usc->cmd_lock); port = &usc->port[dir]; port->data = dma_alloc_coherent(NULL, size, &(port->phys), GFP_KERNEL); if (port->data == NULL) { pr_err("%s: US region allocation failed\n", __func__); mutex_unlock(&usc->cmd_lock); return -ENOMEM; } port->buf_cnt = bufcnt; port->buf_size = bufsz; pr_debug("%s: data[%p]; phys[%p]; [%p]\n", __func__, (void *)port->data, (void *)port->phys, (void *)&port->phys); size = (size + MEM_4K_OFFSET) & MEM_4K_MASK; rc = q6usm_memory_map(port->phys, dir, size, 1, usc->session, (uint32_t *)port->ext); if (rc < 0) { pr_err("%s: CMD Memory_map failed\n", __func__); mutex_unlock(&usc->cmd_lock); q6usm_us_client_buf_free(dir, usc); q6usm_us_param_buf_free(dir, usc); } else { mutex_unlock(&usc->cmd_lock); rc = 0; } return rc; }
void q6usm_us_client_free(struct us_client *usc) { int loopcnt = 0; struct us_port_data *port; uint32_t *p_mem_handle = NULL; if (usc == NULL) return; if (!(usc->session)) { kfree(usc); return; } for (loopcnt = 0; loopcnt <= OUT; ++loopcnt) { port = &usc->port[loopcnt]; if (port->data == NULL) continue; pr_debug("%s: loopcnt = %d\n", __func__, loopcnt); q6usm_us_client_buf_free(loopcnt, usc); q6usm_us_param_buf_free(loopcnt, usc); } q6usm_session_free(usc); apr_deregister(usc->apr); pr_debug("%s: APR De-Register\n", __func__); if (atomic_read(&this_mmap.ref_cnt) <= 0) { pr_err("%s: APR Common Port Already Closed\n", __func__); goto done; } atomic_dec(&this_mmap.ref_cnt); if (atomic_read(&this_mmap.ref_cnt) == 0) { apr_deregister(this_mmap.apr); pr_debug("%s: APR De-Register common port\n", __func__); } done: p_mem_handle = (uint32_t *)usc->port[IN].ext; kfree(p_mem_handle); kfree(usc); pr_debug("%s:\n", __func__); return; }
int q6usm_us_param_buf_alloc(unsigned int dir, struct us_client *usc, unsigned int bufsz) { int rc = 0; struct us_port_data *port = NULL; unsigned int size = bufsz; size_t len; if ((usc == NULL) || ((dir != IN) && (dir != OUT)) || (usc->session <= 0 || usc->session > USM_SESSION_MAX)) { pr_err("%s: wrong parameters: direction=%d, bufsz=%d\n", __func__, dir, bufsz); return -EINVAL; } mutex_lock(&usc->cmd_lock); port = &usc->port[dir]; if (bufsz == 0) { pr_debug("%s: bufsz=0, get/set param commands are forbidden\n", __func__); port->param_buf = NULL; mutex_unlock(&usc->cmd_lock); return rc; } /* The size to allocate should be multiple of 4K bytes */ size = PAGE_ALIGN(size); rc = msm_audio_ion_alloc("ultrasound_client", &port->param_client, &port->param_handle, size, &port->param_phys, &len, &port->param_buf); if (rc) { pr_err("%s: US ION allocation failed, rc = %d\n", __func__, rc); mutex_unlock(&usc->cmd_lock); return -ENOMEM; } port->param_buf_size = bufsz; pr_debug("%s: param_buf[%p]; param_phys[%llx]; [%p]\n", __func__, (void *)port->param_buf, (u64)port->param_phys, (void *)&port->param_phys); rc = q6usm_memory_map(port->param_phys, (IN | OUT), size, 1, usc->session, (uint32_t *)port->param_buf_mem_handle); if (rc < 0) { pr_err("%s: CMD Memory_map failed\n", __func__); mutex_unlock(&usc->cmd_lock); q6usm_us_client_buf_free(dir, usc); q6usm_us_param_buf_free(dir, usc); } else { mutex_unlock(&usc->cmd_lock); rc = 0; } return rc; }