diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index 24d9bdec1f5c..d33993b96c82 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -496,7 +496,7 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) if (ret) { log_event_err("%s: GSI_EP_OP_STARTXFER failed: %d\n", __func__, ret); - return ret; + goto free_trb_ep_in; } d_port->in_xfer_rsc_index = usb_gsi_ep_op(d_port->in_ep, NULL, @@ -546,7 +546,7 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) if (ret) { log_event_err("%s: GSI_EP_OP_PREPARE_TRBS failed: %d\n", __func__, ret); - return ret; + goto end_xfer_ep_in; } ret = usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, @@ -554,7 +554,7 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) if (ret) { log_event_err("%s: GSI_EP_OP_STARTXFER failed: %d\n", __func__, ret); - return ret; + goto free_trb_ep_out; } d_port->out_xfer_rsc_index = @@ -632,7 +632,7 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) conn_params); if (ret) { log_event_err("%s: IPA connect failed %d", __func__, ret); - return ret; + goto end_xfer_ep_out; } log_event_dbg("%s: xdci_connect done", __func__); @@ -660,6 +660,23 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) d_port->out_request.db_reg_phs_addr_msb = ipa_out_channel_out_params.db_reg_phs_addr_msb; } + + return ret; + +end_xfer_ep_out: + if (d_port->out_ep) + usb_gsi_ep_op(d_port->out_ep, NULL, + GSI_EP_OP_ENDXFER); +free_trb_ep_out: + if (d_port->out_ep) + usb_gsi_ep_op(d_port->out_ep, &d_port->out_request, + GSI_EP_OP_FREE_TRBS); +end_xfer_ep_in: + usb_gsi_ep_op(d_port->in_ep, NULL, + GSI_EP_OP_ENDXFER); +free_trb_ep_in: + usb_gsi_ep_op(d_port->in_ep, &d_port->in_request, + GSI_EP_OP_FREE_TRBS); return ret; } @@ -907,7 +924,16 @@ static void ipa_work_handler(struct work_struct *w) break; } - ipa_connect_channels(d_port); + ret = ipa_connect_channels(d_port); + if (ret) { + log_event_err("%s: ipa_connect_channels failed\n", + __func__); + ipa_data_path_disable(d_port); + usb_gadget_autopm_put_async(d_port->gadget); + d_port->sm_state = STATE_INITIALIZED; + break; + } + d_port->sm_state = STATE_WAIT_FOR_IPA_RDY; log_event_dbg("%s: ST_INIT_EVT_SET_ALT", __func__); @@ -1046,7 +1072,14 @@ static void ipa_work_handler(struct work_struct *w) log_event_dbg("%s: get = %d", __func__, atomic_read(&gad_dev->power.usage_count)); - ipa_connect_channels(d_port); + ret = ipa_connect_channels(d_port); + if (ret) { + log_event_err("%s: ipa_connect_channels failed\n", + __func__); + usb_gadget_autopm_put_async(d_port->gadget); + break; + } + ipa_data_path_enable(d_port); d_port->sm_state = STATE_CONNECTED; log_event_dbg("%s: ST_HOST_NRDY_EVT_HRDY_", __func__);