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) {
				pr_err("diag: SMD sending in "
						   "packets upto %d bytes", r);
				buf = krealloc(buf, r, GFP_KERNEL);
			} else {
				pr_err("diag: SMD sending in "
				"packets more than %d bytes", MAX_IN_BUF_SIZE);
				return;
			}
		}
		if (r > 0) {
			if (!buf)
				printk(KERN_INFO "Out of diagmem for QDSP\n");
			else {
				APPEND_DEBUG('i');
				smd_read(driver->chqdsp, buf, r);
				APPEND_DEBUG('j');
#if  DIAG_XPST
				type = checkcmd_modem_epst(buf);
				if (type) {
					modem_to_userspace(buf, r, type, 0);
					return;
				}
#endif
				write_ptr_qdsp->length = r;
				*in_busy_qdsp_ptr = 1;
				diag_device_write(buf, QDSP_DATA,
							 write_ptr_qdsp);
			}
		}
	}
}
void __diag_smd_wcnss_send_req(void)
{
	void *buf = driver->buf_in_wcnss;
	int *in_busy_wcnss_ptr = &(driver->in_busy_wcnss);
	struct diag_request *write_ptr_wcnss = driver->write_ptr_wcnss;
#if  DIAG_XPST
	int type;
#endif

	if ((!driver->in_busy_wcnss) && driver->ch_wcnss && buf) {
		int r = smd_read_avail(driver->ch_wcnss);
		if (r > IN_BUF_SIZE) {
			if (r < MAX_IN_BUF_SIZE) {
				pr_err("diag: wcnss packets > %d bytes", r);
				buf = krealloc(buf, r, GFP_KERNEL);
			} else {
				pr_err("diag: wcnss pkt > %d", MAX_IN_BUF_SIZE);
				return;
			}
		}
		if (r > 0) {
			if (!buf) {
				pr_err("Out of diagmem for wcnss\n");
			} else {
				APPEND_DEBUG('i');
				smd_read(driver->ch_wcnss, buf, r);
				APPEND_DEBUG('j');
#if  DIAG_XPST
				type = checkcmd_modem_epst(buf);
				if (type) {
					modem_to_userspace(buf, r, type, 0);
					return;
				}
#endif
				write_ptr_wcnss->length = r;
				*in_busy_wcnss_ptr = 1;
				diag_device_write(buf, WCNSS_DATA,
					 write_ptr_wcnss);
			}
		}
	}
}
Example #3
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);
	}
}
Example #4
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);
			}
		}
	}
}
static void diag_hsic_read_complete_callback(void *ctxt, char *buf,
					int buf_size, int actual_size)
{
#if DIAG_XPST && defined(CONFIG_DIAG_BRIDGE_CODE)
	int type;
	static int pkt_hdr, first_pkt = 1;
#endif
	int err = -2, print_out_reason = 0;

	if (!driver->hsic_ch) {
		diagmem_free(driver, buf, POOL_TYPE_HSIC);
		pr_debug("diag: In %s: driver->hsic_ch == 0, actual_size: %d\n",
			__func__, actual_size);
		return;
	}

	if ((actual_size > 0) ||
		((actual_size == 0) && (driver->logging_mode == USB_MODE))) {
		if (!buf) {
			pr_err("diag: Out of diagmem for HSIC\n");
		} else {
			if (diag9k_debug_mask) {
				print_out_reason = 1;	
			} else if (driver->debug_dmbytes_recv > 0) {
				driver->debug_dmbytes_recv--;
				print_out_reason = 2;		
			} else if(driver->qxdmusb_drop &&
					driver->logging_mode == USB_MODE) {
				print_out_reason = 3;	
			}

			if (print_out_reason) {
				switch(print_out_reason) {
				case 1:
					print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 9K(first 16 bytes)", 16, 1,
						DUMP_PREFIX_ADDRESS, buf, 16, 1);
					break;
				case 2:
					print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 9K(for DM command)", 16, 1,
						DUMP_PREFIX_ADDRESS, buf, 16, 1);
					break;
				case 3:
					print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 9K(Unknown packet)", 16, 1,
						DUMP_PREFIX_ADDRESS, buf, 16, 1);
					break;
				default:
					break;
				}
			}
#if DIAG_XPST && defined(CONFIG_DIAG_BRIDGE_CODE)
			if (pkt_hdr || (first_pkt == 1)) {
				if (unlikely(first_pkt == 1)) first_pkt = 0;
				type = checkcmd_modem_epst(buf);
				if (type) {
					modem_to_userspace(buf, actual_size, type, 1);
					pkt_hdr = 1;
					if (driver->logging_mode == USB_MODE)
						diagmem_free(driver,
							(unsigned char *)buf, POOL_TYPE_HSIC);
					return;
				}
				pkt_hdr = 0;
			}

			if (actual_size == 0)
				pkt_hdr = 1;
			else if ((actual_size == 1 && *buf == CONTROL_CHAR) ||
					(*(buf+actual_size-1) == CONTROL_CHAR &&
					 *(buf+actual_size-2) != ESC_CHAR))
				pkt_hdr = 1;
#endif
			/*
			 * Send data in buf to be written on the
			 * appropriate device, e.g. USB MDM channel
			 */
			driver->write_len_mdm = actual_size;
			err = diag_device_write((void *)buf, HSIC_DATA, NULL);
			
			if (err) {
				diagmem_free(driver, buf, POOL_TYPE_HSIC);
				pr_err("diag: In %s, error calling diag_device_write, err: %d\n",
						__func__, err);
			}
		}
	} else {
		diagmem_free(driver, buf, POOL_TYPE_HSIC);
		pr_debug("diag: In %s: error status: %d\n", __func__,
				actual_size);
	}

	if (err &&
		((driver->logging_mode == MEMORY_DEVICE_MODE) ||
		(driver->usb_mdm_connected && !driver->hsic_suspend))) {
		queue_work(driver->diag_bridge_wq,
				 &driver->diag_read_hsic_work);
	}
}
Example #6
0
static void diag_hsic_read_complete_callback(void *ctxt, char *buf,
					int buf_size, int actual_size)
{
#if DIAG_XPST && defined(CONFIG_DIAGFWD_BRIDGE_CODE)
	int type;
	static int pkt_hdr = DIAG_BODY_OF_NEXT_PKT, first_pkt = 1;
#endif
	int err = -2;

	if (!driver->hsic_ch) {
		/*
		 * The HSIC channel is closed. Return the buffer to
		 * the pool.  Do not send it on.
		 */
		diagmem_free(driver, buf, POOL_TYPE_HSIC);
		pr_debug("diag: In %s: driver->hsic_ch == 0, actual_size: %d\n",
			__func__, actual_size);
		return;
	}

	/*
	 * Note that zero length is valid and still needs to be sent to
	 * the USB only when we are logging data to the USB
	 */
	if ((actual_size > 0) ||
		((actual_size == 0) && (driver->logging_mode == USB_MODE))) {
		if (!buf) {
			pr_err("diag: Out of diagmem for HSIC\n");
		} else {
			DIAGFWD_9K_RAWDATA(buf, "9K", DIAG_DBG_READ);
#if DIAG_XPST && defined(CONFIG_DIAGFWD_BRIDGE_CODE)
			/* HTC: only route to user space if the packet smd received
			 * is the head of the full packet to avoid route wrong packet
			 * to userspace. BTW, to avoid lost 1st packet (do not know if
			 * the head of packet), we always check 1st packet. It should
			 * be the 0xc sync packet.
			 * Note: The checkcmd only be applied if packet size > 0
			 */
			if ((pkt_hdr == DIAG_HEAD_OF_NEXT_PKT ||
				(first_pkt == 1)) && actual_size > 0) {
				if (unlikely(first_pkt == 1)) first_pkt = 0;
				type = checkcmd_modem_epst(buf);
				if (type) {
					modem_to_userspace(buf, actual_size, type, 1);
					pkt_hdr = DIAG_HEAD_OF_NEXT_PKT;
					/* HTC: release buffer to diagmem */
					diagmem_free(driver,
						(unsigned char *)buf, POOL_TYPE_HSIC);
					return;
				}
				pkt_hdr = DIAG_BODY_OF_NEXT_PKT;
			}

			/* HTC: Because 0 length packet from HSIC is allowed, so we
			 * should take care about the 0 length case. If we do the
			 * check out of boundary, it have chance to make unexpected
			 * result.
			 */
			if ((actual_size == 1 && *buf == CONTROL_CHAR) ||
					((actual_size >= 2) &&
					(*(buf+actual_size-1) == CONTROL_CHAR &&
					 *(buf+actual_size-2) != ESC_CHAR)))
				pkt_hdr = DIAG_HEAD_OF_NEXT_PKT;
#endif
			/*
			 * Send data in buf to be written on the
			 * appropriate device, e.g. USB MDM channel
			 */
			diag_bridge[HSIC].write_len = actual_size;
			err = diag_device_write((void *)buf, HSIC_DATA, NULL);
			/* If an error, return buffer to the pool */
			if (err) {
				diagmem_free(driver, buf, POOL_TYPE_HSIC);
				pr_err_ratelimited("diag: In %s, error calling diag_device_write, err: %d\n",
					__func__, err);
			}
		}
	} else {
		/*
		 * The buffer has an error status associated with it. Do not
		 * pass it on. Note that -ENOENT is sent when the diag bridge
		 * is closed.
		 */
		diagmem_free(driver, buf, POOL_TYPE_HSIC);
		pr_debug("diag: In %s: error status: %d\n", __func__,
			actual_size);
	}

	/*
	 * If for some reason there was no HSIC data to write to the
	 * mdm channel, set up another read
	 */
	if (err &&
		((driver->logging_mode == MEMORY_DEVICE_MODE) ||
		(diag_bridge[HSIC].usb_connected && !driver->hsic_suspend))) {
		queue_work(diag_bridge[HSIC].wq,
				 &driver->diag_read_hsic_work);
	}
}
void __diag_sdio_send_req(void)
{
	int r = 0;
	void *buf = NULL;
	int *in_busy_ptr = NULL;
	struct diag_request *write_ptr_modem = NULL;
	int retry = 0;
#if defined(CONFIG_MACH_VIGOR)
	int type;
#endif

	if (!driver->in_busy_sdio_1) {
		buf = driver->buf_in_sdio_1;
		write_ptr_modem = driver->write_ptr_mdm_1;
		in_busy_ptr = &(driver->in_busy_sdio_1);
	} else if (!driver->in_busy_sdio_2) {
		buf = driver->buf_in_sdio_2;
		write_ptr_modem = driver->write_ptr_mdm_2;
		in_busy_ptr = &(driver->in_busy_sdio_2);
	}

	APPEND_DEBUG('Z');
	if (driver->sdio_ch && buf) {
		r = sdio_read_avail(driver->sdio_ch);

		if (r > MAX_IN_BUF_SIZE) {
				DIAG_ERR("\n diag: SDIO sending"
					  " in packets more than %d bytes\n", r);
		}
		if (r > 0) {
			if (!buf)
				DIAG_INFO("Out of diagmem for SDIO\n");
			else {
drop:
				APPEND_DEBUG('i');
				sdio_read(driver->sdio_ch, buf, r);
				if ((driver->qxdm2sd_drop) && (driver->logging_mode == USB_MODE)) {
					/*Drop the diag payload */
					DIAG_INFO("%s:Drop the diag payload :%d\n", __func__, retry);
					print_hex_dump(KERN_DEBUG, "Drop Packet Data"
						" from 9K(first 16 bytes)", DUMP_PREFIX_ADDRESS, 16, 1, buf, 16, 1);
					driver->in_busy_sdio_1 = 0;
					driver->in_busy_sdio_2 = 0;
					r=sdio_read_avail(driver->sdio_ch);
					if (++retry > 20) {
						driver->qxdm2sd_drop = 0;
						return;
						}
					if (r)
						goto drop;
					else {
						driver->qxdm2sd_drop = 0;
						return;
						}
				}
				APPEND_DEBUG('j');

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

					}
				}
#if defined(CONFIG_MACH_VIGOR)
				type = checkcmd_modem_epst(buf);
				if (type) {
					modem_to_userspace(buf, r, type, 1);
					return;
				}
#endif

				write_ptr_modem->length = r;
				*in_busy_ptr = 1;
				diag_device_write(buf, SDIO_DATA,
						 write_ptr_modem);

			}
		}
	}
}
static void diag_hsic_read_complete_callback(void *ctxt, char *buf,
					int buf_size, int actual_size)
{
#if DIAG_XPST && defined(CONFIG_DIAGFWD_BRIDGE_CODE)
	int type;
	static int pkt_hdr = DIAG_BODY_OF_NEXT_PKT, first_pkt = 1;
#endif
	int err = -2;

	if (!driver->hsic_ch) {
		diagmem_free(driver, buf, POOL_TYPE_HSIC);
		pr_debug("diag: In %s: driver->hsic_ch == 0, actual_size: %d\n",
			__func__, actual_size);
		return;
	}

	if ((actual_size > 0) ||
		((actual_size == 0) && (driver->logging_mode == USB_MODE))) {
		if (!buf) {
			pr_err("diag: Out of diagmem for HSIC\n");
		} else {
			DIAGFWD_9K_RAWDATA(buf, "9K", DIAG_DBG_READ);
#if DIAG_XPST && defined(CONFIG_DIAGFWD_BRIDGE_CODE)
			if ((pkt_hdr == DIAG_HEAD_OF_NEXT_PKT ||
				(first_pkt == 1)) && actual_size > 0) {
				if (unlikely(first_pkt == 1)) first_pkt = 0;
				type = checkcmd_modem_epst(buf);
				if (type) {
					modem_to_userspace(buf, actual_size, type, 1);
					pkt_hdr = DIAG_HEAD_OF_NEXT_PKT;
					
					diagmem_free(driver,
						(unsigned char *)buf, POOL_TYPE_HSIC);
					return;
				}
				pkt_hdr = DIAG_BODY_OF_NEXT_PKT;
			}

			if ((actual_size == 1 && *buf == CONTROL_CHAR) ||
					((actual_size >= 2) &&
					(*(buf+actual_size-1) == CONTROL_CHAR &&
					 *(buf+actual_size-2) != ESC_CHAR)))
				pkt_hdr = DIAG_HEAD_OF_NEXT_PKT;
#endif
			/*
			 * Send data in buf to be written on the
			 * appropriate device, e.g. USB MDM channel
			 */
			diag_bridge[HSIC].write_len = actual_size;
			err = diag_device_write((void *)buf, HSIC_DATA, NULL);
			
			if (err) {
				diagmem_free(driver, buf, POOL_TYPE_HSIC);
				pr_err_ratelimited("diag: In %s, error calling diag_device_write, err: %d\n",
					__func__, err);
			}
		}
	} else {
		diagmem_free(driver, buf, POOL_TYPE_HSIC);
		pr_debug("diag: In %s: error status: %d\n", __func__,
			actual_size);
	}

	if (err &&
		((driver->logging_mode == MEMORY_DEVICE_MODE) ||
		(diag_bridge[HSIC].usb_connected && !driver->hsic_suspend))) {
		queue_work(diag_bridge[HSIC].wq,
				 &driver->diag_read_hsic_work);
	}
}
Example #9
0
void __diag_smd_send_req(void)
{
	void *buf = NULL;
	int *in_busy_ptr = NULL;
	struct diag_request *write_ptr_modem = NULL;
	int type;

	if (!driver->in_busy_1) {
		buf = driver->usb_buf_in_1;
		write_ptr_modem = driver->usb_write_ptr_1;
		in_busy_ptr = &(driver->in_busy_1);
	} else if (!driver->in_busy_2) {
		buf = driver->usb_buf_in_2;
		write_ptr_modem = driver->usb_write_ptr_2;
		in_busy_ptr = &(driver->in_busy_2);
	}

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

		if (r > USB_MAX_IN_BUF) {
			if (r < MAX_BUF_SIZE) {
				printk(KERN_ALERT "\n diag: SMD sending in "
						   "packets upto %d bytes", r);
				buf = krealloc(buf, r, GFP_KERNEL);
			} else {
				printk(KERN_ALERT "\n diag: SMD sending in "
				"packets more than %d bytes", MAX_BUF_SIZE);
				return;
			}
		}

		if (r > 0) {
			if (!buf)
				printk(KERN_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)", 16, 1, DUMP_PREFIX_ADDRESS, buf, 16, 1);
						break;
					case 2:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K(first 16 bytes)", 16, 1, DUMP_PREFIX_ADDRESS, buf, 16, 1);
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K(last 16 bytes) ", 16, 1, DUMP_PREFIX_ADDRESS, buf+r-16, 16, 1);
						break;
					default:
						print_hex_dump(KERN_DEBUG, "Read Packet Data"
						" from 7K ", 16, 1, DUMP_PREFIX_ADDRESS, buf, r, 1);

					}
				}

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

#endif

				APPEND_DEBUG('j');
				write_ptr_modem->length = r;
				*in_busy_ptr = 1;
				diag_device_write(buf, MODEM_DATA,
							 write_ptr_modem);
			}
		}
	}
}