static void diag_hsic_read_complete(void *ctxt, char *buf, int len,
				    int actual_size)
{
	int err = 0;
	int index = (int)(uintptr_t)ctxt;
	struct diag_hsic_info *ch = NULL;

	if (index < 0 || index >= NUM_HSIC_DEV) {
		pr_err_ratelimited("diag: In %s, invalid HSIC index %d\n",
				   __func__, index);
		return;
	}
	ch = &diag_hsic[index];

	/*
	 * Don't pass on the buffer if the channel is closed when a pending read
	 * completes. Also, actual size can be negative error codes - do not
	 * pass on the buffer.
	 */
	if (!ch->opened || actual_size <= 0)
		goto fail;
	err = diag_remote_dev_read_done(ch->dev_id, buf, actual_size);
	if (err)
		goto fail;
	return;

fail:
	diagmem_free(driver, buf, ch->mempool);
	queue_work(ch->hsic_wq, &ch->read_work);
	return;
}
static void diag_smux_event(void *priv, int event_type, const void *metadata)
{
	int len = 0;
	int id = (int)priv;
	unsigned char *rx_buf = NULL;
	struct diag_smux_info *ch = NULL;

	if (id < 0 || id >= NUM_SMUX_DEV)
		return;

	ch = &diag_smux[id];
	if (metadata) {
		len = ((struct smux_meta_read *)metadata)->len;
		rx_buf = ((struct smux_meta_read *)metadata)->buffer;
	}

	switch (event_type) {
	case SMUX_CONNECTED:
		pr_info("diag: SMUX_CONNECTED received, ch: %d\n", ch->id);
		ch->opened = 1;
		ch->in_busy = 0;
		break;
	case SMUX_DISCONNECTED:
		ch->opened = 0;
		msm_smux_close(ch->lcid);
		pr_info("diag: SMUX_DISCONNECTED received, ch: %d\n", ch->id);
		break;
	case SMUX_WRITE_DONE:
		DIAGFWD_DBUG("diag: SMUX Write done, ch: %d\n", ch->id);
		diag_remote_dev_write_done(ch->dev_id, rx_buf, len, ch->id);
		break;
	case SMUX_WRITE_FAIL:
		pr_info("diag: SMUX Write Failed, ch: %d\n", ch->id);
		break;
	case SMUX_READ_FAIL:
		pr_info("diag: SMUX Read Failed, ch: %d\n", ch->id);
		break;
	case SMUX_READ_DONE:
		ch->read_buf = rx_buf;
		ch->read_len = len;
		ch->in_busy = 1;
		diag_remote_dev_read_done(ch->dev_id, ch->read_buf,
					  ch->read_len);
		break;
	};
}