static void bam2bam_data_disconnect_work(struct work_struct *w)
{
    struct bam_data_port *port =
        container_of(w, struct bam_data_port, disconnect_w);
    struct bam_data_ch_info *d = &port->data_ch;
    int ret;

    if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
        if (d->func_type == USB_FUNC_ECM)
            ecm_ipa_disconnect(d->ipa_params.priv);
        ret = usb_bam_disconnect_ipa(&d->ipa_params);
        if (ret)
            pr_err("usb_bam_disconnect_ipa failed: err:%d\n", ret);
        if (d->func_type == USB_FUNC_MBIM)
            teth_bridge_disconnect();

    }
}
static void bam2bam_data_disconnect_work(struct work_struct *w)
{
	struct bam_data_port *port =
			container_of(w, struct bam_data_port, disconnect_w);
	struct bam_data_ch_info *d = &port->data_ch;
	int ret;
	void *priv;

	if (!port->is_connected) {
		pr_info("%s: Already disconnected. Bailing out.\n", __func__);
		return;
	}

	disable_data_ep(port);

	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
		if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM)
			priv = d->ipa_params.priv;
		else
			priv = d->ul_params.teth_priv;

		if (d->func_type == USB_FUNC_ECM) {
			ecm_ipa_disconnect(priv);
		} else if (d->func_type == USB_FUNC_RNDIS) {
			rndis_ipa_pipe_disconnect_notify(priv);
			is_ipa_rndis_net_on = false;
		}

		ret = usb_bam_disconnect_ipa(&d->ipa_params);
		if (ret)
			pr_err("usb_bam_disconnect_ipa failed: err:%d\n", ret);
		if (d->func_type == USB_FUNC_MBIM)
			teth_bridge_disconnect(d->ipa_params.src_client);
	}

	port->is_connected = false;
	pr_debug("Disconnect workqueue done (port %p)\n", port);
}