Loading drivers/platform/msm/ipa/ipa_api.c +7 −26 Original line number Diff line number Diff line Loading @@ -2675,23 +2675,16 @@ int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, } EXPORT_SYMBOL(ipa_usb_init_teth_prot); int ipa_usb_request_xdci_channel(struct ipa_usb_xdci_chan_params *params, struct ipa_req_chan_out_params *out_params) int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, struct ipa_usb_xdci_chan_params *dl_chan_params, struct ipa_req_chan_out_params *ul_out_params, struct ipa_req_chan_out_params *dl_out_params, struct ipa_usb_xdci_connect_params *connect_params) { int ret; IPA_API_DISPATCH_RETURN(ipa_usb_request_xdci_channel, params, out_params); return ret; } EXPORT_SYMBOL(ipa_usb_request_xdci_channel); int ipa_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) { int ret; IPA_API_DISPATCH_RETURN(ipa_usb_xdci_connect, params); IPA_API_DISPATCH_RETURN(ipa_usb_xdci_connect, ul_chan_params, dl_chan_params, ul_out_params, dl_out_params, connect_params); return ret; } Loading @@ -2709,18 +2702,6 @@ int ipa_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, } EXPORT_SYMBOL(ipa_usb_xdci_disconnect); int ipa_usb_release_xdci_channel(u32 clnt_hdl, enum ipa_usb_teth_prot teth_prot) { int ret; IPA_API_DISPATCH_RETURN(ipa_usb_release_xdci_channel, clnt_hdl, teth_prot); return ret; } EXPORT_SYMBOL(ipa_usb_release_xdci_channel); int ipa_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot) { int ret; Loading drivers/platform/msm/ipa/ipa_api.h +5 −8 Original line number Diff line number Diff line Loading @@ -332,19 +332,16 @@ struct ipa_api_controller { int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, void*), void *user_data); int (*ipa_usb_request_xdci_channel)( struct ipa_usb_xdci_chan_params *params, struct ipa_req_chan_out_params *out_params); int (*ipa_usb_xdci_connect)( struct ipa_usb_xdci_connect_params *params); struct ipa_usb_xdci_chan_params *ul_chan_params, struct ipa_usb_xdci_chan_params *dl_chan_params, struct ipa_req_chan_out_params *ul_out_params, struct ipa_req_chan_out_params *dl_out_params, struct ipa_usb_xdci_connect_params *connect_params); int (*ipa_usb_xdci_disconnect)(u32 ul_clnt_hdl, u32 dl_clnt_hdl, enum ipa_usb_teth_prot teth_prot); int (*ipa_usb_release_xdci_channel)(u32 clnt_hdl, enum ipa_usb_teth_prot teth_prot); int (*ipa_usb_deinit_teth_prot)(enum ipa_usb_teth_prot teth_prot); int (*ipa_usb_xdci_suspend)(u32 ul_clnt_hdl, u32 dl_clnt_hdl, Loading drivers/platform/msm/ipa/ipa_v3/ipa_client.c +1 −5 Original line number Diff line number Diff line Loading @@ -1237,9 +1237,7 @@ int ipa3_set_usb_max_packet_size( return 0; } int ipa3_xdci_connect(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid, void (*client_notify)(void *priv, enum ipa_dp_evt_type evt, unsigned long data)) int ipa3_xdci_connect(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid) { struct ipa3_ep_context *ep; int result = -EFAULT; Loading @@ -1257,7 +1255,6 @@ int ipa3_xdci_connect(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid, ipa3_inc_client_enable_clks(); ep->client_notify = client_notify; if (xferrscidx_valid) { ep->chan_scratch.xdci.xferrscidx = xferrscidx; gsi_res = gsi_write_channel_scratch(ep->gsi_chan_hdl, Loading Loading @@ -1453,7 +1450,6 @@ int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id) goto stop_chan_fail; } ep->client_notify = NULL; ipa3_dec_client_disable_clks(); IPADBG("ipa3_xdci_disconnect: exit\n"); Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +6 −10 Original line number Diff line number Diff line Loading @@ -1639,9 +1639,7 @@ int ipa3_reset_gsi_event_ring(u32 clnt_hdl); int ipa3_set_usb_max_packet_size( enum ipa_usb_max_usb_packet_size usb_max_packet_size); int ipa3_xdci_connect(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid, void (*client_notify)(void *priv, enum ipa_dp_evt_type evt, unsigned long data)); int ipa3_xdci_connect(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid); int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id); Loading @@ -1661,17 +1659,15 @@ int ipa3_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, void *), void *user_data); int ipa3_usb_request_xdci_channel(struct ipa_usb_xdci_chan_params *params, struct ipa_req_chan_out_params *out_params); int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params); int ipa3_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, struct ipa_usb_xdci_chan_params *dl_chan_params, struct ipa_req_chan_out_params *ul_out_params, struct ipa_req_chan_out_params *dl_out_params, struct ipa_usb_xdci_connect_params *connect_params); int ipa3_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, enum ipa_usb_teth_prot teth_prot); int ipa3_usb_release_xdci_channel(u32 clnt_hdl, enum ipa_usb_teth_prot teth_prot); int ipa3_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot); int ipa3_usb_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, Loading drivers/platform/msm/ipa/ipa_v3/ipa_usb.c +191 −141 Original line number Diff line number Diff line Loading @@ -31,9 +31,18 @@ #define IPA_USB_ERR(fmt, args...) \ pr_err(IPA_USB_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) typedef void (*ipa_usb_callback)(void *priv, enum ipa_dp_evt_type evt, unsigned long data); struct ipa_usb_xdci_connect_params_internal { enum ipa_usb_max_usb_packet_size max_pkt_size; u32 ipa_to_usb_clnt_hdl; u8 ipa_to_usb_xferrscidx; bool ipa_to_usb_xferrscidx_valid; u32 usb_to_ipa_clnt_hdl; u8 usb_to_ipa_xferrscidx; bool usb_to_ipa_xferrscidx_valid; enum ipa_usb_teth_prot teth_prot; struct ipa_usb_teth_prot_params teth_prot_params; u32 max_supported_bandwidth_mbps; }; enum ipa3_usb_teth_prot_state { IPA_USB_TETH_PROT_INITIALIZED, Loading Loading @@ -569,6 +578,7 @@ int ipa3_usb_cons_release_resource_cb(void) ipa3_usb_ctx->rm_ctx.cons_requested = false; break; case IPA_USB_CONNECTED: case IPA_USB_INITIALIZED: break; default: IPA_USB_ERR("received cons_release_cb in bad state: %s!\n", Loading Loading @@ -884,26 +894,24 @@ static bool ipa3_usb_check_chan_params(struct ipa_usb_xdci_chan_params *params) return true; } int ipa3_usb_request_xdci_channel(struct ipa_usb_xdci_chan_params *params, static int ipa3_usb_request_xdci_channel( struct ipa_usb_xdci_chan_params *params, struct ipa_req_chan_out_params *out_params) { int result = -EFAULT; struct ipa_request_gsi_channel_params chan_params; mutex_lock(&ipa3_usb_ctx->general_mutex); IPA_USB_DBG("ipa3_usb_request_xdci_channel: entry\n"); if (params == NULL || out_params == NULL || !ipa3_usb_check_chan_params(params)) { IPA_USB_ERR("bad parameters.\n"); result = -EINVAL; goto bad_params; return -EINVAL; } if (!ipa3_usb_check_legal_op(IPA_USB_REQUEST_CHANNEL, (params->teth_prot == IPA_USB_DIAG))) { IPA_USB_ERR("Illegal operation.\n"); result = -EPERM; goto bad_params; return -EPERM; } memset(&chan_params, 0, sizeof(struct ipa_request_gsi_channel_params)); Loading Loading @@ -1012,19 +1020,69 @@ int ipa3_usb_request_xdci_channel(struct ipa_usb_xdci_chan_params *params, result = ipa3_request_gsi_channel(&chan_params, out_params); if (result) { IPA_USB_ERR("failed to allocate GSI channel\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return result; } IPA_USB_DBG("ipa3_usb_request_xdci_channel: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; } bad_params: mutex_unlock(&ipa3_usb_ctx->general_mutex); static int ipa3_usb_release_diag_channel(u32 clnt_hdl) { int result = 0; /* Release DIAG channel */ result = ipa3_release_gsi_channel(clnt_hdl); if (result) { IPA_USB_ERR("failed to release DIAG channel.\n"); return result; } /* Change ipa_usb_diag state to INITIALIZED */ if (!ipa3_usb_set_diag_state(IPA_USB_INITIALIZED)) IPA_USB_ERR("failed to change DIAG state to initialized\n"); return 0; } static int ipa3_usb_release_xdci_channel(u32 clnt_hdl, enum ipa_usb_teth_prot teth_prot) { int result = 0; IPA_USB_DBG("ipa3_usb_release_xdci_channel: entry\n"); if (teth_prot > IPA_USB_MAX_TETH_PROT_SIZE) { IPA_USB_ERR("bad parameter.\n"); return -EINVAL; } if (!ipa3_usb_check_legal_op(IPA_USB_RELEASE_CHANNEL, (teth_prot == IPA_USB_DIAG))) { IPA_USB_ERR("Illegal operation.\n"); return -EPERM; } if (teth_prot == IPA_USB_DIAG) { result = ipa3_usb_release_diag_channel(clnt_hdl); IPA_USB_DBG("ipa3_usb_release_xdci_channel: exit\n"); return result; } /* Release channel */ result = ipa3_release_gsi_channel(clnt_hdl); if (result) { IPA_USB_ERR("failed to deallocate channel.\n"); return result; } /* Change ipa_usb state to INITIALIZED */ if (!ipa3_usb_set_state(IPA_USB_INITIALIZED)) IPA_USB_ERR("failed to change state to initialized\n"); IPA_USB_DBG("ipa3_usb_release_xdci_channel: exit\n"); return 0; } static int ipa3_usb_request_prod(void) { int result; Loading Loading @@ -1077,7 +1135,7 @@ static int ipa3_usb_release_prod(void) } static bool ipa3_usb_check_connect_params( struct ipa_usb_xdci_connect_params *params) struct ipa_usb_xdci_connect_params_internal *params) { IPA_USB_DBG("ul xferrscidx = %d\n", params->usb_to_ipa_xferrscidx); IPA_USB_DBG("dl xferrscidx = %d\n", params->ipa_to_usb_xferrscidx); Loading Loading @@ -1136,7 +1194,7 @@ static int ipa3_usb_connect_teth_bridge( } static int ipa3_usb_connect_teth_prot( struct ipa_usb_xdci_connect_params *params) struct ipa_usb_xdci_connect_params_internal *params) { int result; struct teth_bridge_connect_params teth_bridge_params; Loading Loading @@ -1341,46 +1399,15 @@ static int ipa3_usb_disconnect_teth_prot(enum ipa_usb_teth_prot teth_prot) return result; } static ipa_usb_callback ipa3_usb_get_client_notify_cb( enum ipa_usb_teth_prot teth_prot, bool is_tx) { switch (teth_prot) { case IPA_USB_RNDIS: if (is_tx) return ipa3_usb_ctx->teth_prot_ctx[IPA_USB_RNDIS]. teth_prot_params.rndis.ipa_tx_notify; else return ipa3_usb_ctx->teth_prot_ctx[IPA_USB_RNDIS]. teth_prot_params.rndis.ipa_rx_notify; case IPA_USB_ECM: if (is_tx) return ipa3_usb_ctx->teth_prot_ctx[IPA_USB_ECM]. teth_prot_params.ecm.ecm_ipa_tx_dp_notify; else return ipa3_usb_ctx->teth_prot_ctx[IPA_USB_ECM]. teth_prot_params.ecm.ecm_ipa_rx_dp_notify; case IPA_USB_RMNET: case IPA_USB_MBIM: return ipa3_usb_ctx->teth_bridge_params.usb_notify_cb; case IPA_USB_DIAG: return NULL; default: return NULL; } return NULL; } static int ipa3_usb_xdci_connect_diag( struct ipa_usb_xdci_connect_params *params) struct ipa_usb_xdci_connect_params_internal *params) { int result = -EFAULT; /* Start DIAG channel */ result = ipa3_xdci_connect(params->ipa_to_usb_clnt_hdl, params->ipa_to_usb_xferrscidx, params->ipa_to_usb_xferrscidx_valid, ipa3_usb_get_client_notify_cb(IPA_USB_DIAG, true)); params->ipa_to_usb_xferrscidx_valid); if (result) { IPA_USB_ERR("failed to connect DIAG channel.\n"); return result; Loading @@ -1407,30 +1434,27 @@ connect_teth_prot_fail: return result; } int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) static int ipa3_usb_xdci_connect_internal( struct ipa_usb_xdci_connect_params_internal *params) { int result = -EFAULT; struct ipa_rm_perf_profile profile; mutex_lock(&ipa3_usb_ctx->general_mutex); IPA_USB_DBG("ipa3_usb_xdci_connect: entry\n"); if (params == NULL || !ipa3_usb_check_connect_params(params)) { IPA_USB_ERR("bad parameters.\n"); result = -EINVAL; goto bad_params; return -EINVAL; } if (!ipa3_usb_check_legal_op(IPA_USB_CONNECT, (params->teth_prot == IPA_USB_DIAG))) { IPA_USB_ERR("Illegal operation.\n"); result = -EPERM; goto bad_params; return -EPERM; } if (params->teth_prot == IPA_USB_DIAG) { result = ipa3_usb_xdci_connect_diag(params); IPA_USB_DBG("ipa3_usb_xdci_connect: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return result; } Loading @@ -1438,7 +1462,7 @@ int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) result = ipa3_set_usb_max_packet_size(params->max_pkt_size); if (result) { IPA_USB_ERR("failed setting xDCI EE scratch field\n"); goto bad_params; return result; } /* Set USB_PROD & USB_CONS perf profile */ Loading @@ -1448,25 +1472,24 @@ int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) &profile); if (result) { IPA_USB_ERR("failed to set USB_PROD perf profile.\n"); goto bad_params; return result; } result = ipa_rm_set_perf_profile(ipa3_usb_ctx->rm_ctx.cons_params.name, &profile); if (result) { IPA_USB_ERR("failed to set USB_CONS perf profile.\n"); goto bad_params; return result; } /* Request USB_PROD */ result = ipa3_usb_request_prod(); if (result) goto bad_params; return result; /* Start UL channel */ result = ipa3_xdci_connect(params->usb_to_ipa_clnt_hdl, params->usb_to_ipa_xferrscidx, params->usb_to_ipa_xferrscidx_valid, ipa3_usb_get_client_notify_cb(params->teth_prot, false)); params->usb_to_ipa_xferrscidx_valid); if (result) { IPA_USB_ERR("failed to connect UL channel.\n"); goto connect_ul_fail; Loading @@ -1475,8 +1498,7 @@ int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) /* Start DL channel */ result = ipa3_xdci_connect(params->ipa_to_usb_clnt_hdl, params->ipa_to_usb_xferrscidx, params->ipa_to_usb_xferrscidx_valid, ipa3_usb_get_client_notify_cb(params->teth_prot, true)); params->ipa_to_usb_xferrscidx_valid); if (result) { IPA_USB_ERR("failed to connect DL channel.\n"); goto connect_dl_fail; Loading @@ -1494,7 +1516,6 @@ int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) } IPA_USB_DBG("ipa3_usb_xdci_connect: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; state_change_connected_fail: Loading @@ -1509,6 +1530,80 @@ connect_dl_fail: ipa3_reset_gsi_event_ring(params->usb_to_ipa_clnt_hdl); connect_ul_fail: ipa3_usb_release_prod(); return result; } int ipa3_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, struct ipa_usb_xdci_chan_params *dl_chan_params, struct ipa_req_chan_out_params *ul_out_params, struct ipa_req_chan_out_params *dl_out_params, struct ipa_usb_xdci_connect_params *connect_params) { int result = -EFAULT; struct ipa_usb_xdci_connect_params_internal conn_params; mutex_lock(&ipa3_usb_ctx->general_mutex); IPA_USB_DBG("ipa3_usb_xdci_connect: entry\n"); if (dl_chan_params == NULL || dl_out_params == NULL || (connect_params->teth_prot != IPA_USB_DIAG && (ul_chan_params == NULL || ul_out_params == NULL)) || connect_params == NULL) { IPA_USB_ERR("bad parameters.\n"); result = -EINVAL; goto bad_params; } if (connect_params->teth_prot != IPA_USB_DIAG) { result = ipa3_usb_request_xdci_channel(ul_chan_params, ul_out_params); if (result) { IPA_USB_ERR("failed to allocate UL channel.\n"); return result; } } result = ipa3_usb_request_xdci_channel(dl_chan_params, dl_out_params); if (result) { IPA_USB_ERR("failed to allocate DL channel.\n"); goto alloc_dl_chan_fail; } memset(&conn_params, 0, sizeof(struct ipa_usb_xdci_connect_params_internal)); conn_params.max_pkt_size = connect_params->max_pkt_size; conn_params.ipa_to_usb_clnt_hdl = dl_out_params->clnt_hdl; conn_params.ipa_to_usb_xferrscidx = connect_params->ipa_to_usb_xferrscidx; conn_params.ipa_to_usb_xferrscidx_valid = connect_params->ipa_to_usb_xferrscidx_valid; if (connect_params->teth_prot != IPA_USB_DIAG) { conn_params.usb_to_ipa_clnt_hdl = ul_out_params->clnt_hdl; conn_params.usb_to_ipa_xferrscidx = connect_params->usb_to_ipa_xferrscidx; conn_params.usb_to_ipa_xferrscidx_valid = connect_params->usb_to_ipa_xferrscidx_valid; } conn_params.teth_prot = connect_params->teth_prot; conn_params.teth_prot_params = connect_params->teth_prot_params; conn_params.max_supported_bandwidth_mbps = connect_params->max_supported_bandwidth_mbps; result = ipa3_usb_xdci_connect_internal(&conn_params); if (result) { IPA_USB_ERR("failed to connect.\n"); goto connect_fail; } IPA_USB_DBG("ipa3_usb_xdci_connect: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; connect_fail: ipa3_usb_release_xdci_channel(dl_out_params->clnt_hdl, dl_chan_params->teth_prot); alloc_dl_chan_fail: if (connect_params->teth_prot != IPA_USB_DIAG) ipa3_usb_release_xdci_channel(ul_out_params->clnt_hdl, ul_chan_params->teth_prot); bad_params: mutex_unlock(&ipa3_usb_ctx->general_mutex); return result; Loading Loading @@ -1539,15 +1634,21 @@ static int ipa3_usb_xdci_disconnect_diag(u32 dl_clnt_hdl) return result; } /* Change diag state to STOPPED */ if (!ipa3_usb_set_diag_state(IPA_USB_STOPPED)) IPA_USB_ERR("failed to change diag state to stopped\n"); result = ipa3_usb_release_xdci_channel(dl_clnt_hdl, IPA_USB_DIAG); if (result) { IPA_USB_ERR("failed to release DIAG channel.\n"); return result; } /* Disconnect DIAG */ result = ipa3_usb_disconnect_teth_prot(IPA_USB_DIAG); if (result) return result; /* Change diag state to STOPPED */ if (!ipa3_usb_set_diag_state(IPA_USB_STOPPED)) IPA_USB_ERR("failed to change diag state to stopped\n"); return 0; } Loading Loading @@ -1664,7 +1765,7 @@ int ipa3_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, result = ipa3_reset_gsi_event_ring(ul_clnt_hdl); if (result) { IPA_USB_ERR("failed to reset UL event ring.\n"); return result; goto bad_params; } /* Reset DL channel */ Loading @@ -1678,7 +1779,25 @@ int ipa3_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, result = ipa3_reset_gsi_event_ring(dl_clnt_hdl); if (result) { IPA_USB_ERR("failed to reset DL event ring.\n"); return result; goto bad_params; } /* Change ipa_usb state to STOPPED */ if (!ipa3_usb_set_state(IPA_USB_STOPPED)) IPA_USB_ERR("failed to change state to stopped\n"); if (teth_prot != IPA_USB_DIAG) { result = ipa3_usb_release_xdci_channel(ul_clnt_hdl, teth_prot); if (result) { IPA_USB_ERR("failed to release UL channel.\n"); goto bad_params; } } result = ipa3_usb_release_xdci_channel(dl_clnt_hdl, teth_prot); if (result) { IPA_USB_ERR("failed to release DL channel.\n"); goto bad_params; } /* Disconnect tethering protocol */ Loading @@ -1698,10 +1817,6 @@ int ipa3_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, } else spin_unlock_irqrestore(&ipa3_usb_ctx->state_lock, flags); /* Change ipa_usb state to STOPPED */ if (!ipa3_usb_set_state(IPA_USB_STOPPED)) IPA_USB_ERR("failed to change state to stopped\n"); IPA_USB_DBG("ipa3_usb_xdci_disconnect: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; Loading @@ -1712,71 +1827,6 @@ bad_params: } static int ipa3_usb_release_diag_channel(u32 clnt_hdl) { int result = 0; /* Release DIAG channel */ result = ipa3_release_gsi_channel(clnt_hdl); if (result) { IPA_USB_ERR("failed to release DIAG channel.\n"); return result; } /* Change ipa_usb_diag state to INITIALIZED */ if (!ipa3_usb_set_diag_state(IPA_USB_INITIALIZED)) IPA_USB_ERR("failed to change DIAG state to initialized\n"); return 0; } int ipa3_usb_release_xdci_channel(u32 clnt_hdl, enum ipa_usb_teth_prot teth_prot) { int result = 0; mutex_lock(&ipa3_usb_ctx->general_mutex); IPA_USB_DBG("ipa3_usb_release_xdci_channel: entry\n"); if (teth_prot > IPA_USB_MAX_TETH_PROT_SIZE) { IPA_USB_ERR("bad parameter.\n"); result = -EINVAL; goto bad_params; } if (!ipa3_usb_check_legal_op(IPA_USB_RELEASE_CHANNEL, (teth_prot == IPA_USB_DIAG))) { IPA_USB_ERR("Illegal operation.\n"); result = -EPERM; goto bad_params; } if (teth_prot == IPA_USB_DIAG) { result = ipa3_usb_release_diag_channel(clnt_hdl); IPA_USB_DBG("ipa3_usb_release_xdci_channel: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return result; } /* Release channel */ result = ipa3_release_gsi_channel(clnt_hdl); if (result) { IPA_USB_ERR("failed to deallocate channel.\n"); goto bad_params; } /* Change ipa_usb state to INITIALIZED */ if (!ipa3_usb_set_state(IPA_USB_INITIALIZED)) IPA_USB_ERR("failed to change state to initialized\n"); IPA_USB_DBG("ipa3_usb_release_xdci_channel: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; bad_params: mutex_unlock(&ipa3_usb_ctx->general_mutex); return result; } int ipa3_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot) { int result = -EFAULT; Loading Loading
drivers/platform/msm/ipa/ipa_api.c +7 −26 Original line number Diff line number Diff line Loading @@ -2675,23 +2675,16 @@ int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, } EXPORT_SYMBOL(ipa_usb_init_teth_prot); int ipa_usb_request_xdci_channel(struct ipa_usb_xdci_chan_params *params, struct ipa_req_chan_out_params *out_params) int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, struct ipa_usb_xdci_chan_params *dl_chan_params, struct ipa_req_chan_out_params *ul_out_params, struct ipa_req_chan_out_params *dl_out_params, struct ipa_usb_xdci_connect_params *connect_params) { int ret; IPA_API_DISPATCH_RETURN(ipa_usb_request_xdci_channel, params, out_params); return ret; } EXPORT_SYMBOL(ipa_usb_request_xdci_channel); int ipa_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) { int ret; IPA_API_DISPATCH_RETURN(ipa_usb_xdci_connect, params); IPA_API_DISPATCH_RETURN(ipa_usb_xdci_connect, ul_chan_params, dl_chan_params, ul_out_params, dl_out_params, connect_params); return ret; } Loading @@ -2709,18 +2702,6 @@ int ipa_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, } EXPORT_SYMBOL(ipa_usb_xdci_disconnect); int ipa_usb_release_xdci_channel(u32 clnt_hdl, enum ipa_usb_teth_prot teth_prot) { int ret; IPA_API_DISPATCH_RETURN(ipa_usb_release_xdci_channel, clnt_hdl, teth_prot); return ret; } EXPORT_SYMBOL(ipa_usb_release_xdci_channel); int ipa_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot) { int ret; Loading
drivers/platform/msm/ipa/ipa_api.h +5 −8 Original line number Diff line number Diff line Loading @@ -332,19 +332,16 @@ struct ipa_api_controller { int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, void*), void *user_data); int (*ipa_usb_request_xdci_channel)( struct ipa_usb_xdci_chan_params *params, struct ipa_req_chan_out_params *out_params); int (*ipa_usb_xdci_connect)( struct ipa_usb_xdci_connect_params *params); struct ipa_usb_xdci_chan_params *ul_chan_params, struct ipa_usb_xdci_chan_params *dl_chan_params, struct ipa_req_chan_out_params *ul_out_params, struct ipa_req_chan_out_params *dl_out_params, struct ipa_usb_xdci_connect_params *connect_params); int (*ipa_usb_xdci_disconnect)(u32 ul_clnt_hdl, u32 dl_clnt_hdl, enum ipa_usb_teth_prot teth_prot); int (*ipa_usb_release_xdci_channel)(u32 clnt_hdl, enum ipa_usb_teth_prot teth_prot); int (*ipa_usb_deinit_teth_prot)(enum ipa_usb_teth_prot teth_prot); int (*ipa_usb_xdci_suspend)(u32 ul_clnt_hdl, u32 dl_clnt_hdl, Loading
drivers/platform/msm/ipa/ipa_v3/ipa_client.c +1 −5 Original line number Diff line number Diff line Loading @@ -1237,9 +1237,7 @@ int ipa3_set_usb_max_packet_size( return 0; } int ipa3_xdci_connect(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid, void (*client_notify)(void *priv, enum ipa_dp_evt_type evt, unsigned long data)) int ipa3_xdci_connect(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid) { struct ipa3_ep_context *ep; int result = -EFAULT; Loading @@ -1257,7 +1255,6 @@ int ipa3_xdci_connect(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid, ipa3_inc_client_enable_clks(); ep->client_notify = client_notify; if (xferrscidx_valid) { ep->chan_scratch.xdci.xferrscidx = xferrscidx; gsi_res = gsi_write_channel_scratch(ep->gsi_chan_hdl, Loading Loading @@ -1453,7 +1450,6 @@ int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id) goto stop_chan_fail; } ep->client_notify = NULL; ipa3_dec_client_disable_clks(); IPADBG("ipa3_xdci_disconnect: exit\n"); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +6 −10 Original line number Diff line number Diff line Loading @@ -1639,9 +1639,7 @@ int ipa3_reset_gsi_event_ring(u32 clnt_hdl); int ipa3_set_usb_max_packet_size( enum ipa_usb_max_usb_packet_size usb_max_packet_size); int ipa3_xdci_connect(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid, void (*client_notify)(void *priv, enum ipa_dp_evt_type evt, unsigned long data)); int ipa3_xdci_connect(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid); int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id); Loading @@ -1661,17 +1659,15 @@ int ipa3_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, void *), void *user_data); int ipa3_usb_request_xdci_channel(struct ipa_usb_xdci_chan_params *params, struct ipa_req_chan_out_params *out_params); int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params); int ipa3_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, struct ipa_usb_xdci_chan_params *dl_chan_params, struct ipa_req_chan_out_params *ul_out_params, struct ipa_req_chan_out_params *dl_out_params, struct ipa_usb_xdci_connect_params *connect_params); int ipa3_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, enum ipa_usb_teth_prot teth_prot); int ipa3_usb_release_xdci_channel(u32 clnt_hdl, enum ipa_usb_teth_prot teth_prot); int ipa3_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot); int ipa3_usb_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, Loading
drivers/platform/msm/ipa/ipa_v3/ipa_usb.c +191 −141 Original line number Diff line number Diff line Loading @@ -31,9 +31,18 @@ #define IPA_USB_ERR(fmt, args...) \ pr_err(IPA_USB_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) typedef void (*ipa_usb_callback)(void *priv, enum ipa_dp_evt_type evt, unsigned long data); struct ipa_usb_xdci_connect_params_internal { enum ipa_usb_max_usb_packet_size max_pkt_size; u32 ipa_to_usb_clnt_hdl; u8 ipa_to_usb_xferrscidx; bool ipa_to_usb_xferrscidx_valid; u32 usb_to_ipa_clnt_hdl; u8 usb_to_ipa_xferrscidx; bool usb_to_ipa_xferrscidx_valid; enum ipa_usb_teth_prot teth_prot; struct ipa_usb_teth_prot_params teth_prot_params; u32 max_supported_bandwidth_mbps; }; enum ipa3_usb_teth_prot_state { IPA_USB_TETH_PROT_INITIALIZED, Loading Loading @@ -569,6 +578,7 @@ int ipa3_usb_cons_release_resource_cb(void) ipa3_usb_ctx->rm_ctx.cons_requested = false; break; case IPA_USB_CONNECTED: case IPA_USB_INITIALIZED: break; default: IPA_USB_ERR("received cons_release_cb in bad state: %s!\n", Loading Loading @@ -884,26 +894,24 @@ static bool ipa3_usb_check_chan_params(struct ipa_usb_xdci_chan_params *params) return true; } int ipa3_usb_request_xdci_channel(struct ipa_usb_xdci_chan_params *params, static int ipa3_usb_request_xdci_channel( struct ipa_usb_xdci_chan_params *params, struct ipa_req_chan_out_params *out_params) { int result = -EFAULT; struct ipa_request_gsi_channel_params chan_params; mutex_lock(&ipa3_usb_ctx->general_mutex); IPA_USB_DBG("ipa3_usb_request_xdci_channel: entry\n"); if (params == NULL || out_params == NULL || !ipa3_usb_check_chan_params(params)) { IPA_USB_ERR("bad parameters.\n"); result = -EINVAL; goto bad_params; return -EINVAL; } if (!ipa3_usb_check_legal_op(IPA_USB_REQUEST_CHANNEL, (params->teth_prot == IPA_USB_DIAG))) { IPA_USB_ERR("Illegal operation.\n"); result = -EPERM; goto bad_params; return -EPERM; } memset(&chan_params, 0, sizeof(struct ipa_request_gsi_channel_params)); Loading Loading @@ -1012,19 +1020,69 @@ int ipa3_usb_request_xdci_channel(struct ipa_usb_xdci_chan_params *params, result = ipa3_request_gsi_channel(&chan_params, out_params); if (result) { IPA_USB_ERR("failed to allocate GSI channel\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return result; } IPA_USB_DBG("ipa3_usb_request_xdci_channel: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; } bad_params: mutex_unlock(&ipa3_usb_ctx->general_mutex); static int ipa3_usb_release_diag_channel(u32 clnt_hdl) { int result = 0; /* Release DIAG channel */ result = ipa3_release_gsi_channel(clnt_hdl); if (result) { IPA_USB_ERR("failed to release DIAG channel.\n"); return result; } /* Change ipa_usb_diag state to INITIALIZED */ if (!ipa3_usb_set_diag_state(IPA_USB_INITIALIZED)) IPA_USB_ERR("failed to change DIAG state to initialized\n"); return 0; } static int ipa3_usb_release_xdci_channel(u32 clnt_hdl, enum ipa_usb_teth_prot teth_prot) { int result = 0; IPA_USB_DBG("ipa3_usb_release_xdci_channel: entry\n"); if (teth_prot > IPA_USB_MAX_TETH_PROT_SIZE) { IPA_USB_ERR("bad parameter.\n"); return -EINVAL; } if (!ipa3_usb_check_legal_op(IPA_USB_RELEASE_CHANNEL, (teth_prot == IPA_USB_DIAG))) { IPA_USB_ERR("Illegal operation.\n"); return -EPERM; } if (teth_prot == IPA_USB_DIAG) { result = ipa3_usb_release_diag_channel(clnt_hdl); IPA_USB_DBG("ipa3_usb_release_xdci_channel: exit\n"); return result; } /* Release channel */ result = ipa3_release_gsi_channel(clnt_hdl); if (result) { IPA_USB_ERR("failed to deallocate channel.\n"); return result; } /* Change ipa_usb state to INITIALIZED */ if (!ipa3_usb_set_state(IPA_USB_INITIALIZED)) IPA_USB_ERR("failed to change state to initialized\n"); IPA_USB_DBG("ipa3_usb_release_xdci_channel: exit\n"); return 0; } static int ipa3_usb_request_prod(void) { int result; Loading Loading @@ -1077,7 +1135,7 @@ static int ipa3_usb_release_prod(void) } static bool ipa3_usb_check_connect_params( struct ipa_usb_xdci_connect_params *params) struct ipa_usb_xdci_connect_params_internal *params) { IPA_USB_DBG("ul xferrscidx = %d\n", params->usb_to_ipa_xferrscidx); IPA_USB_DBG("dl xferrscidx = %d\n", params->ipa_to_usb_xferrscidx); Loading Loading @@ -1136,7 +1194,7 @@ static int ipa3_usb_connect_teth_bridge( } static int ipa3_usb_connect_teth_prot( struct ipa_usb_xdci_connect_params *params) struct ipa_usb_xdci_connect_params_internal *params) { int result; struct teth_bridge_connect_params teth_bridge_params; Loading Loading @@ -1341,46 +1399,15 @@ static int ipa3_usb_disconnect_teth_prot(enum ipa_usb_teth_prot teth_prot) return result; } static ipa_usb_callback ipa3_usb_get_client_notify_cb( enum ipa_usb_teth_prot teth_prot, bool is_tx) { switch (teth_prot) { case IPA_USB_RNDIS: if (is_tx) return ipa3_usb_ctx->teth_prot_ctx[IPA_USB_RNDIS]. teth_prot_params.rndis.ipa_tx_notify; else return ipa3_usb_ctx->teth_prot_ctx[IPA_USB_RNDIS]. teth_prot_params.rndis.ipa_rx_notify; case IPA_USB_ECM: if (is_tx) return ipa3_usb_ctx->teth_prot_ctx[IPA_USB_ECM]. teth_prot_params.ecm.ecm_ipa_tx_dp_notify; else return ipa3_usb_ctx->teth_prot_ctx[IPA_USB_ECM]. teth_prot_params.ecm.ecm_ipa_rx_dp_notify; case IPA_USB_RMNET: case IPA_USB_MBIM: return ipa3_usb_ctx->teth_bridge_params.usb_notify_cb; case IPA_USB_DIAG: return NULL; default: return NULL; } return NULL; } static int ipa3_usb_xdci_connect_diag( struct ipa_usb_xdci_connect_params *params) struct ipa_usb_xdci_connect_params_internal *params) { int result = -EFAULT; /* Start DIAG channel */ result = ipa3_xdci_connect(params->ipa_to_usb_clnt_hdl, params->ipa_to_usb_xferrscidx, params->ipa_to_usb_xferrscidx_valid, ipa3_usb_get_client_notify_cb(IPA_USB_DIAG, true)); params->ipa_to_usb_xferrscidx_valid); if (result) { IPA_USB_ERR("failed to connect DIAG channel.\n"); return result; Loading @@ -1407,30 +1434,27 @@ connect_teth_prot_fail: return result; } int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) static int ipa3_usb_xdci_connect_internal( struct ipa_usb_xdci_connect_params_internal *params) { int result = -EFAULT; struct ipa_rm_perf_profile profile; mutex_lock(&ipa3_usb_ctx->general_mutex); IPA_USB_DBG("ipa3_usb_xdci_connect: entry\n"); if (params == NULL || !ipa3_usb_check_connect_params(params)) { IPA_USB_ERR("bad parameters.\n"); result = -EINVAL; goto bad_params; return -EINVAL; } if (!ipa3_usb_check_legal_op(IPA_USB_CONNECT, (params->teth_prot == IPA_USB_DIAG))) { IPA_USB_ERR("Illegal operation.\n"); result = -EPERM; goto bad_params; return -EPERM; } if (params->teth_prot == IPA_USB_DIAG) { result = ipa3_usb_xdci_connect_diag(params); IPA_USB_DBG("ipa3_usb_xdci_connect: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return result; } Loading @@ -1438,7 +1462,7 @@ int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) result = ipa3_set_usb_max_packet_size(params->max_pkt_size); if (result) { IPA_USB_ERR("failed setting xDCI EE scratch field\n"); goto bad_params; return result; } /* Set USB_PROD & USB_CONS perf profile */ Loading @@ -1448,25 +1472,24 @@ int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) &profile); if (result) { IPA_USB_ERR("failed to set USB_PROD perf profile.\n"); goto bad_params; return result; } result = ipa_rm_set_perf_profile(ipa3_usb_ctx->rm_ctx.cons_params.name, &profile); if (result) { IPA_USB_ERR("failed to set USB_CONS perf profile.\n"); goto bad_params; return result; } /* Request USB_PROD */ result = ipa3_usb_request_prod(); if (result) goto bad_params; return result; /* Start UL channel */ result = ipa3_xdci_connect(params->usb_to_ipa_clnt_hdl, params->usb_to_ipa_xferrscidx, params->usb_to_ipa_xferrscidx_valid, ipa3_usb_get_client_notify_cb(params->teth_prot, false)); params->usb_to_ipa_xferrscidx_valid); if (result) { IPA_USB_ERR("failed to connect UL channel.\n"); goto connect_ul_fail; Loading @@ -1475,8 +1498,7 @@ int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) /* Start DL channel */ result = ipa3_xdci_connect(params->ipa_to_usb_clnt_hdl, params->ipa_to_usb_xferrscidx, params->ipa_to_usb_xferrscidx_valid, ipa3_usb_get_client_notify_cb(params->teth_prot, true)); params->ipa_to_usb_xferrscidx_valid); if (result) { IPA_USB_ERR("failed to connect DL channel.\n"); goto connect_dl_fail; Loading @@ -1494,7 +1516,6 @@ int ipa3_usb_xdci_connect(struct ipa_usb_xdci_connect_params *params) } IPA_USB_DBG("ipa3_usb_xdci_connect: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; state_change_connected_fail: Loading @@ -1509,6 +1530,80 @@ connect_dl_fail: ipa3_reset_gsi_event_ring(params->usb_to_ipa_clnt_hdl); connect_ul_fail: ipa3_usb_release_prod(); return result; } int ipa3_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, struct ipa_usb_xdci_chan_params *dl_chan_params, struct ipa_req_chan_out_params *ul_out_params, struct ipa_req_chan_out_params *dl_out_params, struct ipa_usb_xdci_connect_params *connect_params) { int result = -EFAULT; struct ipa_usb_xdci_connect_params_internal conn_params; mutex_lock(&ipa3_usb_ctx->general_mutex); IPA_USB_DBG("ipa3_usb_xdci_connect: entry\n"); if (dl_chan_params == NULL || dl_out_params == NULL || (connect_params->teth_prot != IPA_USB_DIAG && (ul_chan_params == NULL || ul_out_params == NULL)) || connect_params == NULL) { IPA_USB_ERR("bad parameters.\n"); result = -EINVAL; goto bad_params; } if (connect_params->teth_prot != IPA_USB_DIAG) { result = ipa3_usb_request_xdci_channel(ul_chan_params, ul_out_params); if (result) { IPA_USB_ERR("failed to allocate UL channel.\n"); return result; } } result = ipa3_usb_request_xdci_channel(dl_chan_params, dl_out_params); if (result) { IPA_USB_ERR("failed to allocate DL channel.\n"); goto alloc_dl_chan_fail; } memset(&conn_params, 0, sizeof(struct ipa_usb_xdci_connect_params_internal)); conn_params.max_pkt_size = connect_params->max_pkt_size; conn_params.ipa_to_usb_clnt_hdl = dl_out_params->clnt_hdl; conn_params.ipa_to_usb_xferrscidx = connect_params->ipa_to_usb_xferrscidx; conn_params.ipa_to_usb_xferrscidx_valid = connect_params->ipa_to_usb_xferrscidx_valid; if (connect_params->teth_prot != IPA_USB_DIAG) { conn_params.usb_to_ipa_clnt_hdl = ul_out_params->clnt_hdl; conn_params.usb_to_ipa_xferrscidx = connect_params->usb_to_ipa_xferrscidx; conn_params.usb_to_ipa_xferrscidx_valid = connect_params->usb_to_ipa_xferrscidx_valid; } conn_params.teth_prot = connect_params->teth_prot; conn_params.teth_prot_params = connect_params->teth_prot_params; conn_params.max_supported_bandwidth_mbps = connect_params->max_supported_bandwidth_mbps; result = ipa3_usb_xdci_connect_internal(&conn_params); if (result) { IPA_USB_ERR("failed to connect.\n"); goto connect_fail; } IPA_USB_DBG("ipa3_usb_xdci_connect: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; connect_fail: ipa3_usb_release_xdci_channel(dl_out_params->clnt_hdl, dl_chan_params->teth_prot); alloc_dl_chan_fail: if (connect_params->teth_prot != IPA_USB_DIAG) ipa3_usb_release_xdci_channel(ul_out_params->clnt_hdl, ul_chan_params->teth_prot); bad_params: mutex_unlock(&ipa3_usb_ctx->general_mutex); return result; Loading Loading @@ -1539,15 +1634,21 @@ static int ipa3_usb_xdci_disconnect_diag(u32 dl_clnt_hdl) return result; } /* Change diag state to STOPPED */ if (!ipa3_usb_set_diag_state(IPA_USB_STOPPED)) IPA_USB_ERR("failed to change diag state to stopped\n"); result = ipa3_usb_release_xdci_channel(dl_clnt_hdl, IPA_USB_DIAG); if (result) { IPA_USB_ERR("failed to release DIAG channel.\n"); return result; } /* Disconnect DIAG */ result = ipa3_usb_disconnect_teth_prot(IPA_USB_DIAG); if (result) return result; /* Change diag state to STOPPED */ if (!ipa3_usb_set_diag_state(IPA_USB_STOPPED)) IPA_USB_ERR("failed to change diag state to stopped\n"); return 0; } Loading Loading @@ -1664,7 +1765,7 @@ int ipa3_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, result = ipa3_reset_gsi_event_ring(ul_clnt_hdl); if (result) { IPA_USB_ERR("failed to reset UL event ring.\n"); return result; goto bad_params; } /* Reset DL channel */ Loading @@ -1678,7 +1779,25 @@ int ipa3_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, result = ipa3_reset_gsi_event_ring(dl_clnt_hdl); if (result) { IPA_USB_ERR("failed to reset DL event ring.\n"); return result; goto bad_params; } /* Change ipa_usb state to STOPPED */ if (!ipa3_usb_set_state(IPA_USB_STOPPED)) IPA_USB_ERR("failed to change state to stopped\n"); if (teth_prot != IPA_USB_DIAG) { result = ipa3_usb_release_xdci_channel(ul_clnt_hdl, teth_prot); if (result) { IPA_USB_ERR("failed to release UL channel.\n"); goto bad_params; } } result = ipa3_usb_release_xdci_channel(dl_clnt_hdl, teth_prot); if (result) { IPA_USB_ERR("failed to release DL channel.\n"); goto bad_params; } /* Disconnect tethering protocol */ Loading @@ -1698,10 +1817,6 @@ int ipa3_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, } else spin_unlock_irqrestore(&ipa3_usb_ctx->state_lock, flags); /* Change ipa_usb state to STOPPED */ if (!ipa3_usb_set_state(IPA_USB_STOPPED)) IPA_USB_ERR("failed to change state to stopped\n"); IPA_USB_DBG("ipa3_usb_xdci_disconnect: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; Loading @@ -1712,71 +1827,6 @@ bad_params: } static int ipa3_usb_release_diag_channel(u32 clnt_hdl) { int result = 0; /* Release DIAG channel */ result = ipa3_release_gsi_channel(clnt_hdl); if (result) { IPA_USB_ERR("failed to release DIAG channel.\n"); return result; } /* Change ipa_usb_diag state to INITIALIZED */ if (!ipa3_usb_set_diag_state(IPA_USB_INITIALIZED)) IPA_USB_ERR("failed to change DIAG state to initialized\n"); return 0; } int ipa3_usb_release_xdci_channel(u32 clnt_hdl, enum ipa_usb_teth_prot teth_prot) { int result = 0; mutex_lock(&ipa3_usb_ctx->general_mutex); IPA_USB_DBG("ipa3_usb_release_xdci_channel: entry\n"); if (teth_prot > IPA_USB_MAX_TETH_PROT_SIZE) { IPA_USB_ERR("bad parameter.\n"); result = -EINVAL; goto bad_params; } if (!ipa3_usb_check_legal_op(IPA_USB_RELEASE_CHANNEL, (teth_prot == IPA_USB_DIAG))) { IPA_USB_ERR("Illegal operation.\n"); result = -EPERM; goto bad_params; } if (teth_prot == IPA_USB_DIAG) { result = ipa3_usb_release_diag_channel(clnt_hdl); IPA_USB_DBG("ipa3_usb_release_xdci_channel: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return result; } /* Release channel */ result = ipa3_release_gsi_channel(clnt_hdl); if (result) { IPA_USB_ERR("failed to deallocate channel.\n"); goto bad_params; } /* Change ipa_usb state to INITIALIZED */ if (!ipa3_usb_set_state(IPA_USB_INITIALIZED)) IPA_USB_ERR("failed to change state to initialized\n"); IPA_USB_DBG("ipa3_usb_release_xdci_channel: exit\n"); mutex_unlock(&ipa3_usb_ctx->general_mutex); return 0; bad_params: mutex_unlock(&ipa3_usb_ctx->general_mutex); return result; } int ipa3_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot) { int result = -EFAULT; Loading