/* this should be common code with rpc_servers.c */ static int adsp_rpc_thread(void *data) { void *buffer; struct rpc_request_hdr *req; int rc, exit = 0; do { rc = msm_rpc_read(rpc_cb_server_client, &buffer, -1, -1); if (rc < 0) { MM_ERR("could not read rpc: %d\n", rc); break; } req = (struct rpc_request_hdr *)buffer; req->type = be32_to_cpu(req->type); req->xid = be32_to_cpu(req->xid); req->rpc_vers = be32_to_cpu(req->rpc_vers); req->prog = be32_to_cpu(req->prog); req->vers = be32_to_cpu(req->vers); req->procedure = be32_to_cpu(req->procedure); if (req->type != 0) goto bad_rpc; if (req->rpc_vers != 2) goto bad_rpc; if (req->prog != rpc_adsp_rtos_mtoa_prog) goto bad_rpc; if (!msm_rpc_is_compatible_version(rpc_adsp_rtos_mtoa_vers, req->vers)) goto bad_rpc; handle_adsp_rtos_mtoa(req); kfree(buffer); continue; bad_rpc: MM_ERR("bogus rpc from modem\n"); kfree(buffer); } while (!exit); do_exit(0); }
static int hs_cb_func(struct msm_rpc_client *client, void *buffer, int in_size) { int rc = -1; struct rpc_request_hdr *hdr = buffer; hdr->type = be32_to_cpu(hdr->type); hdr->xid = be32_to_cpu(hdr->xid); hdr->rpc_vers = be32_to_cpu(hdr->rpc_vers); hdr->prog = be32_to_cpu(hdr->prog); hdr->vers = be32_to_cpu(hdr->vers); hdr->procedure = be32_to_cpu(hdr->procedure); if (hdr->type != 0) return rc; if (hdr->rpc_vers != 2) return rc; if (hdr->prog != HS_RPC_CB_PROG) return rc; if (!msm_rpc_is_compatible_version(HS_RPC_CB_VERS, hdr->vers)) return rc; process_hs_rpc_request(hdr->procedure, (void *) (hdr + 1)); msm_rpc_start_accepted_reply(client, hdr->xid, RPC_ACCEPTSTAT_SUCCESS); rc = msm_rpc_send_accepted_reply(client, 0); if (rc) { pr_err("%s: sending reply failed: %d\n", __func__, rc); return rc; } return 0; }
static void handle_adsp_rtos_mtoa_app(struct rpc_request_hdr *req) { struct rpc_adsp_rtos_modem_to_app_args_t *args = (struct rpc_adsp_rtos_modem_to_app_args_t *)req; uint32_t event; uint32_t proc_id; #ifdef CONFIG_MACH_MOT uint32_t desc_field; #endif uint32_t module_id; uint32_t image; struct msm_adsp_module *module; struct adsp_rtos_mp_mtoa_type *pkt_ptr; struct queue_to_offset_type *qptr; struct queue_to_offset_type *qtbl; struct mod_to_queue_offsets *mqptr; struct mod_to_queue_offsets *mqtbl; uint32_t *mptr; uint32_t *mtbl; uint32_t q_idx; uint32_t num_entries; uint32_t entries_per_image; struct adsp_rtos_mp_mtoa_init_info_type *iptr; struct adsp_rtos_mp_mtoa_init_info_type *sptr; int32_t i_no, e_idx; event = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.event); proc_id = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.proc_id); #ifdef CONFIG_MACH_MOT desc_field = be32_to_cpu(args->mtoa_pkt.desc_field); if (desc_field == RPC_ADSP_RTOS_INIT_INFO) { pr_info("adsp:INIT_INFO Event\n"); #else if (event == RPC_ADSP_RTOS_INIT_INFO) { MM_INFO("INIT_INFO Event\n"); #endif sptr = &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_init_packet; iptr = adsp_info.init_info_ptr; iptr->image_count = be32_to_cpu(sptr->image_count); iptr->num_queue_offsets = be32_to_cpu(sptr->num_queue_offsets); num_entries = iptr->num_queue_offsets; qptr = &sptr->queue_offsets_tbl[0][0]; for (i_no = 0; i_no < iptr->image_count; i_no++) { qtbl = &iptr->queue_offsets_tbl[i_no][0]; for (e_idx = 0; e_idx < num_entries; e_idx++) { qtbl[e_idx].offset = be32_to_cpu(qptr->offset); qtbl[e_idx].queue = be32_to_cpu(qptr->queue); q_idx = be32_to_cpu(qptr->queue); iptr->queue_offsets[i_no][q_idx] = qtbl[e_idx].offset; qptr++; } } num_entries = be32_to_cpu(sptr->num_task_module_entries); iptr->num_task_module_entries = num_entries; entries_per_image = num_entries / iptr->image_count; mptr = &sptr->task_to_module_tbl[0][0]; for (i_no = 0; i_no < iptr->image_count; i_no++) { mtbl = &iptr->task_to_module_tbl[i_no][0]; for (e_idx = 0; e_idx < entries_per_image; e_idx++) { mtbl[e_idx] = be32_to_cpu(*mptr); mptr++; } } iptr->module_table_size = be32_to_cpu(sptr->module_table_size); mptr = &sptr->module_entries[0]; for (i_no = 0; i_no < iptr->module_table_size; i_no++) iptr->module_entries[i_no] = be32_to_cpu(mptr[i_no]); mqptr = &sptr->mod_to_q_tbl[0]; mqtbl = &iptr->mod_to_q_tbl[0]; iptr->mod_to_q_entries = be32_to_cpu(sptr->mod_to_q_entries); for (e_idx = 0; e_idx < iptr->mod_to_q_entries; e_idx++) { mqtbl[e_idx].module = be32_to_cpu(mqptr->module); mqtbl[e_idx].q_type = be32_to_cpu(mqptr->q_type); mqtbl[e_idx].q_max_len = be32_to_cpu(mqptr->q_max_len); mqptr++; } adsp_info.init_info_state = ADSP_STATE_INIT_INFO; rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, RPC_ACCEPTSTAT_SUCCESS); wake_up(&adsp_info.init_info_wait); return; } pkt_ptr = &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet; module_id = be32_to_cpu(pkt_ptr->module); image = be32_to_cpu(pkt_ptr->image); MM_INFO("rpc event=%d, proc_id=%d, module=%d, image=%d\n", event, proc_id, module_id, image); module = find_adsp_module_by_id(&adsp_info, module_id); if (!module) { MM_ERR("module %d is not supported!\n", module_id); rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, RPC_ACCEPTSTAT_GARBAGE_ARGS); return; } mutex_lock(&module->lock); switch (event) { case RPC_ADSP_RTOS_MOD_READY: MM_INFO("module %s: READY\n", module->name); module->state = ADSP_STATE_ENABLED; wake_up(&module->state_wait); adsp_set_image(module->info, image); break; case RPC_ADSP_RTOS_MOD_DISABLE: MM_INFO("module %s: DISABLED\n", module->name); module->state = ADSP_STATE_DISABLED; wake_up(&module->state_wait); break; case RPC_ADSP_RTOS_SERVICE_RESET: MM_INFO("module %s: SERVICE_RESET\n", module->name); module->state = ADSP_STATE_DISABLED; wake_up(&module->state_wait); break; case RPC_ADSP_RTOS_CMD_SUCCESS: MM_INFO("module %s: CMD_SUCCESS\n", module->name); break; case RPC_ADSP_RTOS_CMD_FAIL: MM_INFO("module %s: CMD_FAIL\n", module->name); break; case RPC_ADSP_RTOS_DISABLE_FAIL: MM_INFO("module %s: DISABLE_FAIL\n", module->name); break; default: MM_ERR("unknown event %d\n", event); rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, RPC_ACCEPTSTAT_GARBAGE_ARGS); mutex_unlock(&module->lock); return; } rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, RPC_ACCEPTSTAT_SUCCESS); mutex_unlock(&module->lock); #ifdef CONFIG_MSM_ADSP_REPORT_EVENTS #ifdef CONFIG_MACH_MOT event_addr = (uint32_t *)req; module->ops->event(module->driver_data, EVENT_MSG_ID, EVENT_LEN, read_event); #else modem_event_addr = (uint32_t *)req; module->ops->event(module->driver_data, EVENT_MSG_ID, EVENT_LEN, read_modem_event); #endif #endif } static int handle_adsp_rtos_mtoa(struct rpc_request_hdr *req) { switch (req->procedure) { case RPC_ADSP_RTOS_MTOA_NULL_PROC: rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid, RPC_ACCEPTSTAT_SUCCESS); break; #ifdef CONFIG_MACH_MOT case RPC_ADSP_RTOS_MODEM_TO_APP_PROC: #else case RPC_ADSP_RTOS_MTOA_EVENT_INFO_PROC: #endif handle_adsp_rtos_mtoa_app(req); break; default: MM_ERR("unknowned proc %d\n", req->procedure); rpc_send_accepted_void_reply( rpc_cb_server_client, req->xid, RPC_ACCEPTSTAT_PROC_UNAVAIL); break; } return 0; } /* this should be common code with rpc_servers.c */ static int adsp_rpc_thread(void *data) { void *buffer; struct rpc_request_hdr *req; int rc; #ifdef CONFIG_MACH_MOT int exit =0; #endif do { rc = msm_rpc_read(rpc_cb_server_client, &buffer, -1, -1); if (rc < 0) { MM_ERR("could not read rpc: %d\n", rc); break; } req = (struct rpc_request_hdr *)buffer; req->type = be32_to_cpu(req->type); req->xid = be32_to_cpu(req->xid); req->rpc_vers = be32_to_cpu(req->rpc_vers); req->prog = be32_to_cpu(req->prog); req->vers = be32_to_cpu(req->vers); req->procedure = be32_to_cpu(req->procedure); if (req->type != 0) goto bad_rpc; if (req->rpc_vers != 2) goto bad_rpc; if (req->prog != rpc_adsp_rtos_mtoa_prog) goto bad_rpc; if (!msm_rpc_is_compatible_version(rpc_adsp_rtos_mtoa_vers, req->vers)) goto bad_rpc; handle_adsp_rtos_mtoa(req); kfree(buffer); continue; bad_rpc: MM_ERR("bogus rpc from modem\n"); kfree(buffer); #ifdef CONFIG_MACH_MOT } while (!exit); #else } while (1);