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); } }
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); } }