Beispiel #1
0
static void diag_update_msg_mask(int start, int end , uint8_t *buf)
{
	int found = 0;
	int first;
	int last;
	uint8_t *ptr = driver->msg_masks;
	uint8_t *ptr_buffer_start = &(*(driver->msg_masks));
	uint8_t *ptr_buffer_end = &(*(driver->msg_masks)) + MSG_MASK_SIZE;
	unsigned long flags;

	/*mutex_lock(&driver->diagchar_mutex);*/
	spin_lock_irqsave(&driver->diagchar_lock, flags);
	/* First SSID can be zero : So check that last is non-zero */

	while (*(uint32_t *)(ptr + 4)) {
		first = *(uint32_t *)ptr;
		ptr += 4;
		last = *(uint32_t *)ptr;
		ptr += 4;
		if (start >= first && start <= last) {
			ptr += (start - first)*4;
			if (end <= last)
				if (CHK_OVERFLOW(ptr_buffer_start, ptr,
						  ptr_buffer_end,
						  (((end - start)+1)*4)))
						memcpy(ptr, buf , ((end - start)+1)*4);
					else
					DIAGFWD_ERR("Not enough"
							 " buffer space for"
							 " MSG_MASK\n");
			else
				printk(KERN_INFO "Unable to copy"
						 " mask change\n");

			found = 1;
			break;
		} else {
			ptr += ((last - first) + 1)*4;
		}
	}
	/* Entry was not found - add new table */
	if (!found) {
		if (CHK_OVERFLOW(ptr_buffer_start, ptr, ptr_buffer_end,
				  8 + ((end - start) + 1)*4)) {
			memcpy(ptr, &(start) , 4);
			ptr += 4;
			memcpy(ptr, &(end), 4);
			ptr += 4;
			memcpy(ptr, buf , ((end - start) + 1)*4);
		} else
			DIAGFWD_ERR(" Not enough buffer"
					 " space for MSG_MASK\n");
	}

	/*mutex_unlock(&driver->diagchar_mutex);*/
	spin_unlock_irqrestore(&driver->diagchar_lock, flags);

	diag_print_mask_table();

}
Beispiel #2
0
static void diag_update_pkt_buffer(unsigned char *buf)
{
	unsigned char *ptr = driver->pkt_buf;
	unsigned char *temp = buf;

	mutex_lock(&driver->diagchar_mutex);
	if (CHK_OVERFLOW(ptr, ptr, ptr + PKT_SIZE, driver->pkt_length))
		memcpy(ptr, temp , driver->pkt_length);
	else
		DIAGFWD_ERR(" Not enough buffer space for PKT_RESP\n");
	mutex_unlock(&driver->diagchar_mutex);
}
Beispiel #3
0
int diagfwd_read_complete(struct diag_request *diag_read_ptr)
{
	int status = diag_read_ptr->status;
	unsigned char *buf = diag_read_ptr->buf;

	/* Determine if the read complete is for data on legacy/mdm ch */
	if (buf == (void *)driver->usb_buf_out) {
		driver->read_len_legacy = diag_read_ptr->actual;
		APPEND_DEBUG('s');
#ifdef DIAG_DEBUG
	printk(KERN_INFO "read data from USB, pkt length %d \n",
		    diag_read_ptr->actual);
	print_hex_dump(KERN_DEBUG, "Read Packet Data from USB: ", DUMP_PREFIX_ADDRESS, 16, 1,
		       diag_read_ptr->buf,
		       diag_read_ptr->actual, 1);
#endif /* DIAG DEBUG */
	if (driver->nohdlc) {
		driver->usb_read_ptr->buf = driver->usb_buf_out;
		driver->usb_read_ptr->length = USB_MAX_OUT_BUF;
		usb_diag_read(driver->legacy_ch, driver->usb_read_ptr);
		return 0;
	}
	if (driver->logging_mode == USB_MODE) {
#ifdef CONFIG_ARCH_MSM8X60_LTE
		if (diag_ch_sdio) {
			driver->read_len_mdm = diag_read_ptr->actual;
			diagfwd_read_complete_sdio();
		} else
#endif
			{
			if (status != -ECONNRESET && status != -ESHUTDOWN)
				queue_work(driver->diag_wq,
					&(driver->diag_proc_hdlc_work));
			else
					queue_work(driver->diag_wq,
						 &(driver->diag_read_work));
			}
		}
	}
#if defined(CONFIG_ARCH_MSM8X60_LTE)
	else if (buf == (void *)driver->usb_buf_mdm_out) {
		driver->read_len_mdm = diag_read_ptr->actual;
		diagfwd_read_complete_sdio();
	}
#endif
	else
		DIAGFWD_ERR("diag: Unknown buffer ptr from USB");

	return 0;
}
Beispiel #4
0
int diagfwd_connect(void)
{
	int err;

	DIAGFWD_INFO("%s\n", __func__);
	if (!driver->usb_connected) {
		err = usb_diag_alloc_req(driver->legacy_ch, N_LEGACY_WRITE,
			N_LEGACY_READ);
		if (err)
			DIAGFWD_ERR("diag: unable to allocate USB requests");
	}

	driver->in_busy_1 = 0;
	driver->in_busy_2 = 0;
	driver->in_busy_qdsp_1 = 0;
	driver->in_busy_qdsp_2 = 0;
#if defined(CONFIG_MACH_MECHA)
	driver->in_busy_mdm_1 = 0;
	driver->in_busy_mdm_2 = 0;
#endif
	/* Poll SMD channels to check for data*/
	queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
	queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));

#if defined(CONFIG_ARCH_MSM8X60_LTE)
	driver->in_busy_sdio_1 = 0;
	driver->in_busy_sdio_2 = 0;
	if (diag_ch_sdio) {
		if (driver->legacy_ch && !IS_ERR(driver->legacy_ch))
			diagfwd_connect_sdio();
		else
			DIAGFWD_INFO("diag:No data from SDIO without  USB LEGACY ch");

	} else {
		if ((!driver->usb_connected) && driver->mdm_ch && !IS_ERR(driver->mdm_ch))
			diagfwd_connect_sdio();
		else
			DIAGFWD_INFO("diag:No data from SDIO without  USB MDM ch");

		queue_work(driver->diag_sdio_wq, &(driver->diag_read_mdm_work));
	}

#endif
	driver->usb_connected = 1;
	/* Poll USB channel to check for data*/
	queue_work(driver->diag_wq, &(driver->diag_read_work));

	return 0;
}
Beispiel #5
0
static void diag_update_event_mask(uint8_t *buf, int toggle, int num_bits)
{
	uint8_t *ptr = driver->event_masks;
	uint8_t *temp = buf + 2;

	mutex_lock(&driver->diagchar_mutex);
	if (!toggle)
		memset(ptr, 0 , EVENT_MASK_SIZE);
	else
		if (CHK_OVERFLOW(ptr, ptr,
				 ptr+EVENT_MASK_SIZE,
				  num_bits/8 + 1))
			memcpy(ptr, temp , num_bits/8 + 1);
		else
			DIAGFWD_ERR("Not enough buffer space "
					 "for EVENT_MASK\n");
	mutex_unlock(&driver->diagchar_mutex);
}
Beispiel #6
0
void diag_usb_legacy_notifier(void *priv, unsigned event,
			struct diag_request *d_req)
{
	switch (event) {
	case USB_DIAG_CONNECT:
		diagfwd_connect();
		break;
	case USB_DIAG_DISCONNECT:
		diagfwd_disconnect();
		break;
	case USB_DIAG_READ_DONE:
		diagfwd_read_complete(d_req);
		break;
	case USB_DIAG_WRITE_DONE:
		diagfwd_write_complete(d_req);
		break;
	default:
		DIAGFWD_ERR("Unknown event from USB diag\n");
		break;
	}
}
Beispiel #7
0
static void diag_update_log_mask(int equip_id, uint8_t *buf, int num_items)
{
	uint8_t *temp = buf;
	struct mask_info {
		int equip_id;
		int index;
	};
	int i = 0;
	unsigned char *ptr_data;
	int offset = 8*MAX_EQUIP_ID;
	struct mask_info *ptr = (struct mask_info *)driver->log_masks;

	mutex_lock(&driver->diagchar_mutex);
	/* Check if we already know index of this equipment ID */
	for (i = 0; i < MAX_EQUIP_ID; i++) {
		if ((ptr->equip_id == equip_id) && (ptr->index != 0)) {
			offset = ptr->index;
			break;
		}
		if ((ptr->equip_id == 0) && (ptr->index == 0)) {
			/*Reached a null entry */
			ptr->equip_id = equip_id;
			ptr->index = driver->log_masks_length;
			offset = driver->log_masks_length;
			driver->log_masks_length += ((num_items+7)/8);
			break;
		}
		ptr++;
	}
	ptr_data = driver->log_masks + offset;
	if (CHK_OVERFLOW(ptr_data, ptr_data, ptr_data + LOG_MASK_SIZE,
				  (num_items+7)/8))
		memcpy(ptr_data, temp , (num_items+7)/8);
	else
		DIAGFWD_ERR(" Not enough buffer space for LOG_MASK\n");
	mutex_unlock(&driver->diagchar_mutex);
}
Beispiel #8
0
void __diag_smd_send_req(void)
{
	void *buf = NULL;
	int *in_busy_ptr = NULL;
	struct diag_request *write_ptr_modem = NULL;
#if  DIAG_XPST
	int type;
#endif

#ifdef SDQXDM_DEBUG
	static struct timeval t0 = {0, 0}, t1;
	static int full = 0, empty = 0;
	long diff;
#endif

	if (!driver->in_busy_1) {
		buf = driver->buf_in_1;
		write_ptr_modem = driver->write_ptr_1;
		in_busy_ptr = &(driver->in_busy_1);
	} else if (!driver->in_busy_2) {
		buf = driver->buf_in_2;
		write_ptr_modem = driver->write_ptr_2;
		in_busy_ptr = &(driver->in_busy_2);
	}

	if (driver->ch && buf) {
		int r = smd_read_avail(driver->ch);

		if (r > IN_BUF_SIZE) {
			if (r < MAX_IN_BUF_SIZE) {
				DIAGFWD_INFO("\n diag: SMD sending in "
						   "packets upto %d bytes", r);
				buf = krealloc(buf, r, GFP_KERNEL);
			} else {
				DIAGFWD_ERR("\n diag: SMD sending in "
				"packets more than %d bytes", MAX_IN_BUF_SIZE);
				return;
			}
		}
		if (r > 0) {
			if (!buf)
				DIAGFWD_INFO("Out of diagmem for a9\n");
			else {
				/* APPEND_DEBUG('i'); */
				smd_read(driver->ch, buf, r);

				if (diag7k_debug_mask) {
					switch (diag7k_debug_mask) {
					case 1:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K(first 16 bytes)", DUMP_PREFIX_ADDRESS, 16, 1, buf, 16, 1);
						break;
					case 2:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K(first 16 bytes)", DUMP_PREFIX_ADDRESS, 16, 1, buf, 16, 1);
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K(last 16 bytes) ", DUMP_PREFIX_ADDRESS, 16, 1, buf+r-16, 16, 1);
						break;
					default:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K ", DUMP_PREFIX_ADDRESS, 16, 1, buf, r, 1);

					}
				}

#if DIAG_XPST
				type = checkcmd_modem_epst(buf);
				if (type) {
					modem_to_userspace(buf, r, type, 0);
					return;
				}
#endif

#ifdef SDQXDM_DEBUG
				if (full) {
					pr_err("[diag-dbg] buffer become available %d %d, read %d\n", driver->in_busy_1, driver->in_busy_2, r);
					full = 0;
				}
				do_gettimeofday(&t1);
				diff = (t1.tv_sec-t0.tv_sec)*1000 + (t1.tv_usec-t0.tv_usec)/1000;
				if (diff > 1000) {
					pr_err("[diag-dbg] Over time (%ld) %ld.%04ld -> %ld.%04ld empty = %d\n", diff, (long)t0.tv_sec, t0.tv_usec/1000, (long)t1.tv_sec, t1.tv_usec/1000, empty);
				}
				write_ptr_modem->second = t1.tv_sec;
				t0 = t1;
				empty = 0;
#endif

				/* APPEND_DEBUG('j'); */
				write_ptr_modem->length = r;
				*in_busy_ptr = 1;
				diag_device_write(buf, MODEM_DATA,
							 write_ptr_modem);
			}
		}
#ifdef SDQXDM_DEBUG
		else {
			empty++;
		}
#endif
	}
	else {
#ifdef SDQXDM_DEBUG
		if (!full && driver->ch)
			pr_info("[diag-dbg] Buffer full, %d bytes pending.\n", smd_read_avail(driver->ch));
		full = 1;
#endif
		wake_lock_timeout(&driver->wake_lock, HZ);
	}
}
Beispiel #9
0
void __diag_smd_qdsp_send_req(void)
{
	void *buf = NULL;
	int *in_busy_qdsp_ptr = NULL;
	struct diag_request *write_ptr_qdsp = NULL;
#if  DIAG_XPST
	int type;
#endif
	if (!driver->in_busy_qdsp_1) {
		buf = driver->buf_in_qdsp_1;
		write_ptr_qdsp = driver->write_ptr_qdsp_1;
		in_busy_qdsp_ptr = &(driver->in_busy_qdsp_1);
	} else if (!driver->in_busy_qdsp_2) {
		buf = driver->buf_in_qdsp_2;
		write_ptr_qdsp = driver->write_ptr_qdsp_2;
		in_busy_qdsp_ptr = &(driver->in_busy_qdsp_2);
	}

	if (driver->chqdsp && buf) {
		int r = smd_read_avail(driver->chqdsp);

		if (r > IN_BUF_SIZE) {
			if (r < MAX_IN_BUF_SIZE) {
				DIAGFWD_INFO("\n diag: SMD sending in "
						   "packets upto %d bytes", r);
				buf = krealloc(buf, r, GFP_KERNEL);
			} else {
				DIAGFWD_ERR("\n diag: SMD sending in "
				"packets more than %d bytes", MAX_IN_BUF_SIZE);
			return;
		}
		}
		if (r > 0) {
			if (!buf)
				DIAGFWD_INFO("Out of diagmem for QDSP\n");
			else {
				/* APPEND_DEBUG('i'); */
					smd_read(driver->chqdsp, buf, r);

				if (diag7k_debug_mask) {
					switch (diag7k_debug_mask) {
					case 1:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from qdsp(first 16 bytes)", DUMP_PREFIX_ADDRESS, 16, 1, buf, 16, 1);
						break;
					case 2:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from qdsp(first 16 bytes)", DUMP_PREFIX_ADDRESS, 16, 1, buf, 16, 1);
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from qdsp(last 16 bytes) ", DUMP_PREFIX_ADDRESS, 16, 1, buf+r-16, 16, 1);
						break;
					default:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from qdsp ", DUMP_PREFIX_ADDRESS, 16, 1, buf, r, 1);

					}
				}
#if  DIAG_XPST

		type = checkcmd_modem_epst(buf);
		if (type) {
			modem_to_userspace(buf, r, type, 0);
			return;
		}

#endif
			/* APPEND_DEBUG('j'); */
				write_ptr_qdsp->length = r;
				*in_busy_qdsp_ptr = 1;
				diag_device_write(buf, QDSP_DATA,
							 write_ptr_qdsp);
			}
		}
	}
}
Beispiel #10
0
int diagfwd_init(void)
{
	diag_debug_buf_idx = 0;
	driver->read_len_legacy = 0;
	if (driver->buf_in_1 == NULL)
		driver->buf_in_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
		if (driver->buf_in_1 == NULL)
			goto err;
	if (driver->buf_in_2 == NULL)
		driver->buf_in_2 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
		if (driver->buf_in_2 == NULL)
			goto err;
	if (driver->buf_in_qdsp_1 == NULL)
		driver->buf_in_qdsp_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
		if (driver->buf_in_qdsp_1 == NULL)
			goto err;
	if (driver->buf_in_qdsp_2 == NULL)
		driver->buf_in_qdsp_2 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
		if (driver->buf_in_qdsp_2 == NULL)
			goto err;
	if (driver->usb_buf_out  == NULL &&
	     (driver->usb_buf_out = kzalloc(USB_MAX_OUT_BUF,
					 GFP_KERNEL)) == NULL)
		goto err;
	if (driver->hdlc_buf == NULL
	    && (driver->hdlc_buf = kzalloc(HDLC_MAX, GFP_KERNEL)) == NULL)
		goto err;
	if (driver->msg_masks == NULL
	    && (driver->msg_masks = kzalloc(MSG_MASK_SIZE,
					     GFP_KERNEL)) == NULL)
		goto err;
	if (driver->log_masks == NULL &&
	    (driver->log_masks = kzalloc(LOG_MASK_SIZE, GFP_KERNEL)) == NULL)
		goto err;
	driver->log_masks_length = 8*MAX_EQUIP_ID;
	if (driver->event_masks == NULL &&
	    (driver->event_masks = kzalloc(EVENT_MASK_SIZE,
					    GFP_KERNEL)) == NULL)
		goto err;
	if (driver->client_map == NULL &&
	    (driver->client_map = kzalloc
	     ((driver->num_clients) * sizeof(struct diag_client_map),
		   GFP_KERNEL)) == NULL)
		goto err;
#if defined(CONFIG_MACH_MECHA) //|| defined(CONFIG_ARCH_MSM8X60_LTE)
	if (driver->buf_in_mdm_1 == NULL)
		driver->buf_in_mdm_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
		if (driver->buf_in_mdm_1 == NULL)
			goto err;
	if (driver->buf_in_mdm_2 == NULL)
		driver->buf_in_mdm_2 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
		if (driver->buf_in_mdm_2 == NULL)
			goto err;
#endif
#if defined(CONFIG_MACH_MECHA) || defined(CONFIG_ARCH_MSM8X60_LTE)
	if (driver->mdmclient_map == NULL &&
	    (driver->mdmclient_map = kzalloc
	     ((driver->num_mdmclients) * sizeof(struct diag_client_map),
		   GFP_KERNEL)) == NULL)
		goto err;
#endif
	if (driver->buf_tbl == NULL)
			driver->buf_tbl = kzalloc(buf_tbl_size *
			  sizeof(struct diag_write_device), GFP_KERNEL);
	if (driver->buf_tbl == NULL)
		goto err;
#if 0//defined(CONFIG_MACH_MECHA) || defined(CONFIG_ARCH_MSM8X60_LTE)
	if (driver->mdmbuf_tbl == NULL)
			driver->mdmbuf_tbl = kzalloc(buf_tbl_size *
			  sizeof(struct diag_write_device), GFP_KERNEL);
	if (driver->mdmbuf_tbl == NULL)
		goto err;
#endif
	if (driver->data_ready == NULL &&
	     (driver->data_ready = kzalloc(driver->num_clients * sizeof(int)
					 , GFP_KERNEL)) == NULL)
		goto err;
#if defined(CONFIG_MACH_MECHA) || defined(CONFIG_ARCH_MSM8X60_LTE)
	if (driver->mdmdata_ready == NULL &&
	     (driver->mdmdata_ready = kzalloc(driver->num_mdmclients * sizeof(struct
					 diag_client_map), GFP_KERNEL)) == NULL)
		goto err;
#endif
	if (driver->table == NULL &&
	     (driver->table = kzalloc(diag_max_registration*
				      sizeof(struct diag_master_table),
				       GFP_KERNEL)) == NULL)
		goto err;
	if (driver->write_ptr_1 == NULL)
		driver->write_ptr_1 = kzalloc(
			sizeof(struct diag_request), GFP_KERNEL);
		if (driver->write_ptr_1 == NULL)
					goto err;
	if (driver->write_ptr_2 == NULL)
		driver->write_ptr_2 = kzalloc(
			sizeof(struct diag_request), GFP_KERNEL);
		if (driver->write_ptr_2 == NULL)
			goto err;
	if (driver->write_ptr_qdsp_1 == NULL)
		driver->write_ptr_qdsp_1 = kzalloc(
			sizeof(struct diag_request), GFP_KERNEL);
		if (driver->write_ptr_qdsp_1 == NULL)
			goto err;
	if (driver->write_ptr_qdsp_2 == NULL)
		driver->write_ptr_qdsp_2 = kzalloc(
			sizeof(struct diag_request), GFP_KERNEL);
		if (driver->write_ptr_qdsp_2 == NULL)
			goto err;
#if defined(CONFIG_MACH_MECHA) //|| defined(CONFIG_ARCH_MSM8X60_LTE)
	if (driver->write_ptr_mdm_1 == NULL)
			driver->write_ptr_mdm_1 = kzalloc(
				sizeof(struct diag_request), GFP_KERNEL);
			if (driver->write_ptr_mdm_1 == NULL)
					goto err;
	if (driver->write_ptr_mdm_2 == NULL)
			driver->write_ptr_mdm_2 = kzalloc(
				sizeof(struct diag_request), GFP_KERNEL);
			if (driver->write_ptr_mdm_2 == NULL)
					goto err;
#endif
	if (driver->usb_read_ptr == NULL)
			driver->usb_read_ptr = kzalloc(
				sizeof(struct diag_request), GFP_KERNEL);
			if (driver->usb_read_ptr == NULL)
				goto err;
	if (driver->pkt_buf == NULL &&
	     (driver->pkt_buf = kzalloc(PKT_SIZE,
					 GFP_KERNEL)) == NULL)
		goto err;
#ifdef CONFIG_DIAG_NO_MODEM
	if (driver->apps_rsp_buf == NULL)
			driver->apps_rsp_buf = kzalloc(150, GFP_KERNEL);
		if (driver->apps_rsp_buf == NULL)
			goto err;
#endif
	driver->diag_wq = create_singlethread_workqueue("diag_wq");
#ifdef CONFIG_DIAG_OVER_USB
	INIT_WORK(&(driver->diag_proc_hdlc_work), diag_process_hdlc_fn);
	INIT_WORK(&(driver->diag_read_work), diag_read_work_fn);
	diag_setup();
#ifndef CONFIG_ARCH_MSM8X60_LTE
	driver->legacy_ch = usb_diag_open(DIAG_LEGACY, driver,
			diag_usb_legacy_notifier);
	if (IS_ERR(driver->legacy_ch)) {
		DIAGFWD_ERR("Unable to open USB diag legacy channel\n");
		goto err;
	}
#endif
#endif
	mutex_init(&driver->smd_lock);
#ifdef CONFIG_ARCH_MSM8X60_LTE
#if defined(CONFIG_USB_ANDROID_LTE_DIAG)
	diag_ch_sdio = 0;
	diagfwd_sdio_init(DIAG_MDM);
#else
	diag_ch_sdio = 1;
	diagfwd_sdio_init(DIAG_LEGACY);
#endif
#endif
	platform_driver_register(&msm_smd_ch1_driver);

	DIAGFWD_INFO("\n diag_debug_buf %p %p\n", diag_debug_buf, &diag_debug_buf);
	DIAGFWD_INFO("\n diag_debug_buf_idx %p\n", &diag_debug_buf_idx);


#if defined(CONFIG_MACH_MECHA)
	if (sdio_diag_init_enable)
		sdio_diag_init();
#endif
	return diag_ch_sdio;
err:
		DIAGFWD_INFO("\n Could not initialize diag buffers\n");
		kfree(driver->buf_in_1);
		kfree(driver->buf_in_2);
		kfree(driver->buf_in_qdsp_1);
		kfree(driver->buf_in_qdsp_2);
		kfree(driver->usb_buf_out);
		kfree(driver->hdlc_buf);
		kfree(driver->msg_masks);
		kfree(driver->log_masks);
		kfree(driver->event_masks);
		kfree(driver->client_map);
		kfree(driver->buf_tbl);
		kfree(driver->data_ready);
#if defined(CONFIG_MACH_MECHA) //|| defined(CONFIG_ARCH_MSM8X60_LTE)
		kfree(driver->mdmclient_map);
		//kfree(driver->mdmbuf_tbl);
		kfree(driver->mdmdata_ready);
#endif
		kfree(driver->table);
		kfree(driver->pkt_buf);
		kfree(driver->write_ptr_1);
		kfree(driver->write_ptr_2);
		kfree(driver->write_ptr_qdsp_1);
		kfree(driver->write_ptr_qdsp_2);
#if defined(CONFIG_MACH_MECHA) //|| defined(CONFIG_ARCH_MSM8X60_LTE)
		kfree(driver->write_ptr_mdm_1);
		kfree(driver->write_ptr_mdm_2);
#endif
		kfree(driver->usb_read_ptr);
#ifdef CONFIG_DIAG_NO_MODEM
		kfree(driver->apps_rsp_buf);
#endif
		if (driver->diag_wq)
			destroy_workqueue(driver->diag_wq);
		return 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;
	DIAGFWD_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) {
		DIAGFWD_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 CONFIG_DIAG_NO_MODEM
	if (type == 1) { /* implies this packet is NOT meant for apps */
		if (driver->chqdsp)
			smd_write(driver->chqdsp, driver->hdlc_buf,
							 hdlc.dest_idx - 3);
		type = 0;
	}
#endif /* NO MODEM present */

#ifdef DIAG_DEBUG
	printk(KERN_INFO "\n hdlc.dest_idx = %d", hdlc.dest_idx);
	for (i = 0; i < hdlc.dest_idx; i++)
		printk(KERN_DEBUG "\t%x", *(((unsigned char *)
							driver->hdlc_buf)+i));
#endif /* DIAG DEBUG */
	/* ignore 2 bytes for CRC, one for 7E and send */
	if ((driver->ch) && (ret) && (type) && (hdlc.dest_idx > 3)) {
		APPEND_DEBUG('g');
#if defined(CONFIG_ARCH_MSM8X60_LTE) || defined(CONFIG_ARCH_MSM8X60)
		smd_write(driver->ch, driver->hdlc_buf, hdlc.dest_idx - 3);
#else //defined(CONFIG_MACH_MECHA)
		smd_write(driver->ch, data, len);
#endif
		if (diag7k_debug_mask)
		print_hex_dump(KERN_DEBUG, "Written Packet Data to SMD: ", 16,
			       1, DUMP_PREFIX_ADDRESS, data, len, 1);
		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 /* DIAG DEBUG */
	}

}