/*
 * diagfwd_disconnect_bridge is called when the USB mdm channel
 * is disconnected
 */
int diagfwd_disconnect_bridge(int process_cable)
{
    pr_debug("DIAG in %s\n", __func__);

    /* If the usb cable is being disconnected */
    if (process_cable) {
        driver->usb_mdm_connected = 0;
        usb_diag_free_req(driver->mdm_ch);
    }

    if (driver->logging_mode != MEMORY_DEVICE_MODE) {
        if (driver->hsic_device_enabled) {
            driver->in_busy_hsic_write_on_device = 1;
            driver->in_busy_hsic_read_on_device = 1;
            driver->in_busy_hsic_write = 1;
            driver->in_busy_hsic_read = 1;
            /* Turn off communication over usb mdm and hsic */
            return diag_hsic_close();
        } else if (driver->diag_smux_enabled) {
            driver->in_busy_smux = 1;
            driver->lcid = LCID_INVALID;
            /* Turn off communication over usb mdm and smux */
            msm_smux_close(LCID_VALID);
        }
    }
    return 0;
}
int diagfwd_disconnect_bridge(int process_cable)
{
	DIAGFWD_INFO("diag: In %s, process_cable: %d\n", __func__, process_cable);

	
	if (process_cable) {
		driver->usb_mdm_connected = 0;
		driver->qxdmusb_drop = 1;
		usb_diag_free_req(driver->mdm_ch);
	}

	if (driver->hsic_device_enabled &&
			driver->logging_mode != MEMORY_DEVICE_MODE) {
#if 0
		driver->in_busy_hsic_read_on_device = 1;
		driver->in_busy_hsic_write = 1;
		
		return diag_hsic_close();
#endif
	} else if (driver->diag_smux_enabled &&
			driver->logging_mode == USB_MODE) {
		driver->in_busy_smux = 1;
		driver->lcid = LCID_INVALID;
#if 0
		driver->smux_connected = 0;
#endif
		
		msm_smux_close(LCID_VALID);
	}
	return 0;
}
static void ghsuart_ctrl_disconnect_w(struct work_struct *w)
{
	struct ghsuart_ctrl_port	*port =
			container_of(w, struct ghsuart_ctrl_port, disconnect_w);

	if (!test_bit(CH_OPENED, &port->channel_sts))
		return;

	msm_smux_close(port->ch_id);
	clear_bit(CH_OPENED, &port->channel_sts);
}
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;
	};
}
/*
 * diagfwd_disconnect_bridge is called when the USB mdm channel
 * is disconnected. So disconnect should happen for all bridges
 */
int diagfwd_disconnect_bridge(int process_cable)
{
	int i;
	pr_debug("diag: In %s, process_cable: %d\n", __func__, process_cable);

	for (i = 0; i < MAX_BRIDGES; i++) {
		if (diag_bridge[i].enabled) {
			mutex_lock(&diag_bridge[i].bridge_mutex);
			/* If the usb cable is being disconnected */
			if (process_cable) {
				diag_bridge[i].usb_connected = 0;
				usb_diag_free_req(diag_bridge[i].ch);
				driver->qxdmusb_drop = 1;
			}

			if (i == SMUX) {
				if (driver->diag_smux_enabled &&
					driver->logging_mode == USB_MODE) {
					driver->in_busy_smux = 1;
					driver->lcid = LCID_INVALID;
					driver->smux_connected = 0;
					/*
					 * Turn off communication over usb
					 * and smux
					 */
					msm_smux_close(LCID_VALID);
				}
			}  else {
				if (diag_hsic[i].hsic_device_enabled &&
				     (driver->logging_mode != MEMORY_DEVICE_MODE
				     || !diag_hsic[i].hsic_data_requested)) {
#if !DIAG_XPST
					diag_hsic[i].
						in_busy_hsic_read_on_device = 1;
					diag_hsic[i].in_busy_hsic_write = 1;
					/* Turn off communication over usb
					 * and HSIC */
					diag_hsic_close(i);
#endif
				}
			}
			mutex_unlock(&diag_bridge[i].bridge_mutex);
		}
	}
	return 0;
}
static int smux_close(int id)
{
	struct diag_smux_info *ch = NULL;

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

	ch = &diag_smux[id];
	if (!ch->enabled) {
		DIAGFWD_DBUG("diag: SMUX channel is not enabled id: %d\n", ch->id);
		return -ENODEV;
	}

	msm_smux_close(ch->lcid);
	ch->opened = 0;
	ch->in_busy = 1;
	kfree(ch->read_buf);
	ch->read_buf = NULL;
	return 0;
}
void diag_smux_event(void *priv, int event_type, const void *metadata)
{
	unsigned char *rx_buf;
	int len;

	switch (event_type) {
	case SMUX_CONNECTED:
		pr_info("diag: SMUX_CONNECTED received\n");
		driver->smux_connected = 1;
		driver->in_busy_smux = 0;
		/* read data from USB MDM channel & Initiate first write */
		queue_work(diag_bridge[SMUX].wq,
			   &diag_bridge[SMUX].diag_read_work);
		break;
	case SMUX_DISCONNECTED:
		driver->smux_connected = 0;
		driver->lcid = LCID_INVALID;
		msm_smux_close(LCID_VALID);
		pr_info("diag: SMUX_DISCONNECTED received\n");
		break;
	case SMUX_WRITE_DONE:
		pr_debug("diag: SMUX Write done\n");
		break;
	case SMUX_WRITE_FAIL:
		pr_info("diag: SMUX Write Failed\n");
		break;
	case SMUX_READ_FAIL:
		pr_info("diag: SMUX Read Failed\n");
		break;
	case SMUX_READ_DONE:
		len = ((struct smux_meta_read *)metadata)->len;
		rx_buf = ((struct smux_meta_read *)metadata)->buffer;
		driver->write_ptr_mdm->length = len;
		diag_device_write(driver->buf_in_smux, SMUX_DATA,
						 driver->write_ptr_mdm);
		break;
	};
}
示例#8
0
static int smux_rmnet_remove(struct platform_device *pdev)
{
	int i;
	int r;
	struct rmnet_private *p;

	for (i = 0; i < RMNET_SMUX_DEVICE_COUNT; i++) {
		p = netdev_priv(netdevs[i]);

		if (p != NULL) {
			r =  msm_smux_close(p->ch_id);

			if (r < 0) {
				DBG0("%s: ch=%d close failed with rc %d\n",
				     __func__, p->ch_id, r);
				continue;
			}
			netif_carrier_off(netdevs[i]);
			netif_stop_queue(netdevs[i]);
		}
	}
	return 0;
}
int diagfwd_disconnect_bridge(int process_cable)
{
	int i;
	pr_debug("diag: In %s, process_cable: %d\n", __func__, process_cable);

	for (i = 0; i < MAX_BRIDGES; i++) {
		if (diag_bridge[i].enabled) {
			mutex_lock(&diag_bridge[i].bridge_mutex);
			
			if (process_cable) {
				diag_bridge[i].usb_connected = 0;
				usb_diag_free_req(diag_bridge[i].ch);
				driver->qxdmusb_drop = 1;
			}

			if (i == HSIC && driver->hsic_device_enabled &&
				 driver->logging_mode != MEMORY_DEVICE_MODE) {
#if !DIAG_XPST
				driver->in_busy_hsic_read_on_device = 1;
				driver->in_busy_hsic_write = 1;
				
				diag_hsic_close();
#endif
			} else if (i == SMUX && driver->diag_smux_enabled &&
					driver->logging_mode == USB_MODE) {
				driver->in_busy_smux = 1;
				driver->lcid = LCID_INVALID;
				driver->smux_connected = 0;
				
				msm_smux_close(LCID_VALID);
			}
			mutex_unlock(&diag_bridge[i].bridge_mutex);
		}
	}
	return 0;
}