Пример #1
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) {
		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);
			/*
			 * 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);
	}
}
Пример #2
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);
	}
}