Esempio n. 1
0
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;
#if CONFIG_ADSP_RPC_VER > 0x30001
    case RPC_ADSP_RTOS_MTOA_INIT_INFO_PROC:
    case RPC_ADSP_RTOS_MTOA_EVENT_INFO_PROC:
#else
    case RPC_ADSP_RTOS_MODEM_TO_APP_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;
}
Esempio n. 2
0
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;
	case RPC_ADSP_RTOS_MODEM_TO_APP_PROC:
		handle_adsp_rtos_mtoa_app(req);
		break;
	default:
		pr_err("adsp: unknowned proc %d\n", req->procedure);
		rpc_send_accepted_void_reply(
			rpc_cb_server_client, req->xid,
			RPC_ACCEPTSTAT_PROC_UNAVAIL);
		break;
	}
	return 0;
}
Esempio n. 3
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;
    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);

    if (event == RPC_ADSP_RTOS_INIT_INFO) {
        MM_INFO("INIT_INFO Event\n");
        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);
        if (iptr->image_count > IMG_MAX)
            iptr->image_count = IMG_MAX;
        iptr->num_queue_offsets = be32_to_cpu(sptr->num_queue_offsets);
        num_entries = iptr->num_queue_offsets;
        if (num_entries > ENTRIES_MAX) {
            num_entries = ENTRIES_MAX;
            iptr->num_queue_offsets = ENTRIES_MAX;
        }
        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);
        if (num_entries > ENTRIES_MAX)
            num_entries = ENTRIES_MAX;
        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);
#if CONFIG_ADSP_RPC_VER > 0x30001
        if (iptr->module_table_size > MODULES_MAX)
            iptr->module_table_size = MODULES_MAX;
#else
        if (iptr->module_table_size > ENTRIES_MAX)
            iptr->module_table_size = ENTRIES_MAX;
#endif
        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);
        if (iptr->mod_to_q_entries > ENTRIES_MAX)
            iptr->mod_to_q_entries = ENTRIES_MAX;
        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_DBG("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);
#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS
    event_addr = (uint32_t *)req;
    module->ops->event(module->driver_data,
                       EVENT_MSG_ID,
                       EVENT_LEN,
                       read_event);
#endif
    mutex_unlock(&module->lock);
}
Esempio n. 4
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;
#if defined(CONFIG_ARCH_MSM7227)
#else
	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);
#if defined(CONFIG_ARCH_MSM7227)
#else
	desc_field = be32_to_cpu(args->mtoa_pkt.desc_field);
#endif


#if defined(CONFIG_ARCH_MSM7227)
	if (event == RPC_ADSP_RTOS_INIT_INFO) {
#else
	if (desc_field == RPC_ADSP_RTOS_INIT_INFO) {
#endif
		pr_info("adsp:INIT_INFO Event\n");
		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;
#if 0
				pr_info("iptr->queue_offsets[%d][%d] = %x\n",
				i_no, q_idx, iptr->queue_offsets[i_no][q_idx]);
#endif
				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++;
#if 0
				pr_info("mtbl[%d] = %x\n", e_idx, mtbl[e_idx]);
#endif
			}
		}

		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]);

#if defined(CONFIG_ARCH_MSM7227)
		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++;
		}
#endif

		adsp_info.init_info_state = ADSP_STATE_INIT_INFO;
		wake_up(&adsp_info.init_info_wait);
		rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
						RPC_ACCEPTSTAT_SUCCESS);

		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);

	pr_info("adsp: 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) {
		pr_err("adsp: 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:
		pr_info("adsp: 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:
		pr_info("adsp: module %s: DISABLED\n", module->name);
		module->state = ADSP_STATE_DISABLED;
		wake_up(&module->state_wait);
		break;
	case RPC_ADSP_RTOS_SERVICE_RESET:
		pr_info("adsp: module %s: SERVICE_RESET\n", module->name);
		module->state = ADSP_STATE_DISABLED;
		wake_up(&module->state_wait);
		break;
	case RPC_ADSP_RTOS_CMD_SUCCESS:
		pr_info("adsp: module %s: CMD_SUCCESS\n", module->name);
		break;
	case RPC_ADSP_RTOS_CMD_FAIL:
		pr_info("adsp: module %s: CMD_FAIL\n", module->name);
		break;
	case RPC_ADSP_RTOS_DISABLE_FAIL:
		pr_info("adsp: module %s: DISABLE_FAIL\n", module->name);
		break;
	default:
		pr_info("adsp: unknown event %d\n", event);
		rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
					     RPC_ACCEPTSTAT_GARBAGE_ARGS);
		goto done;
	}
	rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
				     RPC_ACCEPTSTAT_SUCCESS);

	if (module->ops->modem_event != NULL)
		module->ops->modem_event(module->driver_data, image);
done:
	mutex_unlock(&module->lock);
	event_addr = (uint32_t *)req;
	module->ops->event(module->driver_data, EVENT_MSG_ID,
				EVENT_LEN, read_event);
}

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;
#if defined(CONFIG_ARCH_MSM7227)
	case RPC_ADSP_RTOS_MODEM_TO_APP_INIT_INFO_PROC:
	case RPC_ADSP_RTOS_MODEM_TO_APP_EVENT_INFO_PROC:
#else
	case RPC_ADSP_RTOS_MODEM_TO_APP_PROC:
#endif
		handle_adsp_rtos_mtoa_app(req);
		break;
	default:
		pr_err("adsp: 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, exit = 0;

	do {
		rc = msm_rpc_read(rpc_cb_server_client, &buffer, -1, -1);
		if (rc < 0) {
			pr_err("adsp: 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 (req->vers != rpc_adsp_rtos_mtoa_vers)
			goto bad_rpc;

		handle_adsp_rtos_mtoa(req);
		kfree(buffer);
		continue;

bad_rpc:
		pr_err("adsp: bogus rpc from modem\n");
		kfree(buffer);
	} while (!exit);
	do_exit(0);
}