コード例 #1
0
static void adsp_rtos_mtoa_cb(void *context, uint32_t param,
					void *evt_buf, uint32_t len)
{
	struct adsp_rtos_mp_mtoa_s_type *args = NULL;
	uint32_t event = 0;
	uint32_t proc_id = 0;
	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;
	static uint32_t	init_info_completed;
	static uint32_t init_info_len =
				sizeof(struct adsp_rtos_mp_mtoa_header_type);
	static uint32_t	next_init_info_byte;
	static uint32_t expected_byte = 1;
	uint32_t hdr_len = sizeof(struct adsp_rtos_mp_mtoa_header_type);

	if (len) {
		args = (struct adsp_rtos_mp_mtoa_s_type *) evt_buf;
		event = args->mp_mtoa_header.event;
		proc_id = args->mp_mtoa_header.proc_id;
	}

	if (!init_info_completed && event == RPC_ADSP_RTOS_INIT_INFO) {
		memcpy(((char *)adsp_info.raw_event) + init_info_len,
						(char *)evt_buf + hdr_len + 4,
							len - ((hdr_len + 4)));
		init_info_len += (len - (hdr_len + 4));
		evt_buf += hdr_len;
		next_init_info_byte = *(uint32_t *) evt_buf;
		expected_byte += len;
		if (next_init_info_byte &&
				(expected_byte != next_init_info_byte)) {
			MM_ERR("INIT_INFO - expecting next byte to be %d\n"
				"\tbut ADSPSVC indicated next byte to be %d\n",
				expected_byte, next_init_info_byte);
			return;
		}
		if (!next_init_info_byte) {
			args = adsp_info.raw_event;
			args->mp_mtoa_header.event = event;
			args->mp_mtoa_header.proc_id = proc_id;
			init_info_completed = 1;
		} else
			return;
	}

	if (event == RPC_ADSP_RTOS_INIT_INFO) {
		MM_INFO("INIT_INFO Event\n");
		sptr = &args->adsp_rtos_mp_mtoa_data.mp_mtoa_init_packet;

		iptr = adsp_info.init_info_ptr;
		iptr->image_count = sptr->image_count;
		if (iptr->image_count > IMG_MAX)
			iptr->image_count = IMG_MAX;
		iptr->num_queue_offsets = 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 = qptr->offset;
				qtbl[e_idx].queue = qptr->queue;
				q_idx = qptr->queue;
				iptr->queue_offsets[i_no][q_idx] =
							qtbl[e_idx].offset;
				qptr++;
			}
		}

		num_entries = 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] = *mptr;
				mptr++;
			}
		}

		iptr->module_table_size = sptr->module_table_size;
		if (iptr->module_table_size > MODULES_MAX)
			iptr->module_table_size = MODULES_MAX;
		mptr = &sptr->module_entries[0];
		for (i_no = 0; i_no < iptr->module_table_size; i_no++)
			iptr->module_entries[i_no] = mptr[i_no];

		mqptr = &sptr->mod_to_q_tbl[0];
		mqtbl = &iptr->mod_to_q_tbl[0];
		iptr->mod_to_q_entries = 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 = mqptr->module;
			mqtbl[e_idx].q_type = mqptr->q_type;
			mqtbl[e_idx].q_max_len = mqptr->q_max_len;
			mqptr++;
		}

		adsp_info.init_info_state = ADSP_STATE_INIT_INFO;
		kfree(adsp_info.raw_event);
		wake_up(&adsp_info.init_info_wait);
		return;
	}
	pkt_ptr = &args->adsp_rtos_mp_mtoa_data.mp_mtoa_packet;
	module_id = pkt_ptr->module;
	image     = 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);
		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);
		mutex_unlock(&module->lock);
		return;
	}
#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS
	event_addr = (uint32_t *)evt_buf;
	if (module->ops)
		module->ops->event(module->driver_data,
					EVENT_MSG_ID,
					EVENT_LEN,
					read_event);
#endif
	mutex_unlock(&module->lock);
}
コード例 #2
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);
		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
	modem_event_addr = (uint32_t *)req;
	module->ops->event(module->driver_data, EVENT_MSG_ID,
				EVENT_LEN, read_modem_event);
#endif
}
コード例 #3
0
ファイル: adsp.c プロジェクト: JmzTaylor/kernel_gb_marvelc
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;
#if defined(CONFIG_ARCH_MSM7227)
	struct mod_to_queue_offsets	*mqptr;
	struct mod_to_queue_offsets	*mqtbl;
#endif
	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);
}