mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 16:16:15 -04:00
usb: f_gsi: Don't enable IPA data path if connect channel fails
ipa_connect_channels can return failure if gsi prepare trbs fail or start xfer fails. But currently driver is not checking for the failure and goes ahead to enable IPA data path. This leads the controller to access faulty addresses which cause kernel panic. Fix this by checking the failure returned from ipa_connect_channels. Also cleanup the error handling path. Change-Id: Ia1e8e17381e12231d8d78224ba3b07081f143212 Signed-off-by: Pratham Pratap <prathampratap@codeaurora.org>
This commit is contained in:
parent
8f4621b9e5
commit
9490c68a6f
1 changed files with 39 additions and 6 deletions
|
|
@ -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__);
|
||||
|
|
|
|||
Loading…
Reference in a new issue