static int diagcharmdm_write(struct file *file, const char __user *buf,
			      size_t count, loff_t *ppos)
{

	int err, pkt_type;
	int payload_size;
#if defined(CONFIG_MACH_MECHA)
	int ret = 0;
	unsigned char *tmp_buf = NULL;
#endif
#ifdef DIAG_DEBUG
	DIAG_INFO("%s:%s(parent:%s): tgid=%d\n", __func__,
	current->comm, current->parent->comm, current->tgid);
#endif
#if defined(CONFIG_MACH_MECHA)
	if (!sdio_diag_initialized) {
		DIAG_INFO("sdio diag isn't in embedded mode \n");
		return 0;
	}

	if (driver->logging_mode == MEMORY_DEVICE_MODE) {

		/* Get the packet type F3/log/event/Pkt response */
		err = copy_from_user((&pkt_type), buf, 4);
		/*First 4 bytes indicate the type of payload - ignore these */
		payload_size = count - 4;

		if (pkt_type == MEMORY_DEVICE_LOG_TYPE) {
			if (!mask_request_validate((unsigned char *)buf)) {
				DIAG_ERR("mask request Invalid ..cannot send to modem \n");
				return -EFAULT;
			}

			buf = buf + 4;
			tmp_buf = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
			memcpy(tmp_buf, buf, payload_size);
			msm_sdio_diag_write((void *)tmp_buf, payload_size);
			tmp_buf = NULL;
			return 0;
		}
	}
	return ret;
#else

#ifdef CONFIG_DIAG_OVER_USB
	if (((driver->logging_mode == USB_MODE) && (!driver->usb_connected)) ||
				(driver->logging_mode == NO_LOGGING_MODE)) {
		/*Drop the diag payload */
		return -EIO;
	}
#endif /* DIAG over USB */

	/* Get the packet type F3/log/event/Pkt response */
	err = copy_from_user((&pkt_type), buf, 4);
	/*First 4 bytes indicate the type of payload - ignore these */
	payload_size = count - 4;
	if (pkt_type == MEMORY_DEVICE_LOG_TYPE) {
			DIAGFWD_INFO("writing mask file\n");
		if (!mask_request_validate((unsigned char *)buf)) {
			DIAG_ERR("mask request Invalid ..cannot send to modem \n");
			return -EFAULT;
		}
		buf = buf + 4;
			if (driver->sdio_ch) {
				memcpy(buf_9k, buf, payload_size);
				sdio_write(driver->sdio_ch, buf_9k, payload_size);
			}
		return count;
	} else if(pkt_type == USERMODE_DIAGFWD) {

		buf += 4;

			if (driver->sdio_ch) {
				memcpy(buf_9k, buf, payload_size);
				sdio_write(driver->sdio_ch, buf_9k,payload_size);
			}

		return count;
	}
	return 0;
#endif
}
示例#2
0
void diag_process_hdlc(void *data, unsigned len)
{
	struct diag_hdlc_decode_type hdlc;
	int ret, type = 0;
#if HPST_FUN
	unsigned char *buf_9k = NULL;
	int path;
#endif
#ifdef DIAG_DEBUG
	int i;
	printk(KERN_INFO "\n HDLC decode function, len of data  %d\n", len);
#endif
	hdlc.dest_ptr = driver->hdlc_buf;
	hdlc.dest_size = USB_MAX_OUT_BUF;
	hdlc.src_ptr = data;
	hdlc.src_size = len;
	hdlc.src_idx = 0;
	hdlc.dest_idx = 0;
	hdlc.escaping = 0;

	ret = diag_hdlc_decode(&hdlc);

	if (ret) {
		type = diag_process_apps_pkt(driver->hdlc_buf,
							  hdlc.dest_idx - 3);
	} else if (driver->debug_flag) {
		printk(KERN_ERR "Packet dropped due to bad HDLC coding/CRC"
				" errors or partial packet received, packet"
				" length = %d\n", len);
		print_hex_dump(KERN_DEBUG, "Dropped Packet Data: ", 16, 1,
					   DUMP_PREFIX_ADDRESS, data, len, 1);
		driver->debug_flag = 0;
	}
#ifdef DIAG_DEBUG
	printk(KERN_INFO "\n hdlc.dest_idx = %d \n", hdlc.dest_idx);
	for (i = 0; i < hdlc.dest_idx; i++)
		printk(KERN_DEBUG "\t%x", *(((unsigned char *)
							driver->hdlc_buf)+i));
#endif
	/* ignore 2 bytes for CRC, one for 7E and send */
	if ((driver->ch) && (ret) && (type) && (hdlc.dest_idx > 3)) {
		APPEND_DEBUG('g');

#if HPST_FUN
/* check for hpst*/
		path = checkcmd_modem_hpst(data);

		switch (path) {
		case DM7K9K:
				printk(KERN_INFO "%s:DM7K9K\n", __func__);
				print_hex_dump(KERN_DEBUG, "HPST:DM Packet Data"
				" write to radio ", 16, 1, DUMP_PREFIX_ADDRESS, data, 16, 1);
				smd_write(driver->ch, data, len);
				buf_9k = kzalloc(len, GFP_KERNEL);
				memcpy(buf_9k, data, len);
				msm_sdio_diag_write((void *)buf_9k, len);
				buf_9k = NULL;
				break;
		case DM9KONLY:
				printk(KERN_INFO "%s:DM9KONLY\n", __func__);
				print_hex_dump(KERN_DEBUG, "HPST:DM Packet Data"
				" write to radio ", 16, 1, DUMP_PREFIX_ADDRESS, data, 16, 1);
				buf_9k = kzalloc(len, GFP_KERNEL);
				memcpy(buf_9k, data, len);
				msm_sdio_diag_write((void *)buf_9k, len);
				buf_9k = NULL;
				break;
		case DM7K9KDIFF:
				printk(KERN_INFO "%s:DM7K9KDIFF", __func__);
				print_hex_dump(KERN_DEBUG, "HPST:DM Packet Data"
				" write to radio ", 16, 1, DUMP_PREFIX_ADDRESS, data, 16, 1);
				if (((*(((uint8_t *)data)+3)) & 0xC0) == 0xC0) {
					printk(KERN_INFO "%s:DM7K9KDIFF to 9K\n", __func__);
					buf_9k = kzalloc(len, GFP_KERNEL);
					memcpy(buf_9k, data, len);
					msm_sdio_diag_write((void *)buf_9k, len);
					buf_9k = NULL;
				} else {
					printk(KERN_INFO "%s:DM7K9KDIFF to 7K\n", __func__);
					smd_write(driver->ch, data, len);
				}
				break;
		case DM7KONLY:
				printk(KERN_INFO "%s:DM7KONLY\n", __func__);
				print_hex_dump(KERN_DEBUG, "HPST:DM Packet Data"
				" write to radio ", 16, 1, DUMP_PREFIX_ADDRESS, data, 16, 1);
				smd_write(driver->ch, data, len);
				break;
		case NO_PST:
			smd_write(driver->ch, data, len);
			break;

		case NO_DEF_ID:
		case NO_DEF_ITEM:
		default:
				print_hex_dump(KERN_DEBUG, "HPST:DM Packet Data"
				" can't write to radio ", 16, 1, DUMP_PREFIX_ADDRESS, data, 16, 1);
		}
#else
		smd_write(driver->ch, data, len);
#endif
		APPEND_DEBUG('h');
#ifdef DIAG_DEBUG
		printk(KERN_INFO "writing data to SMD, pkt length %d \n", len);
		print_hex_dump(KERN_DEBUG, "Written Packet Data to SMD: ", 16,
			       1, DUMP_PREFIX_ADDRESS, data, len, 1);
#endif
	}

}