usb: gsi: Don't disable endpoints as part of flow control
Currently GSI endpoints are disabled when host enables flow control for RNDIS function. When these endpoints are enabled again as part of flow control disable, no transactions are observed on these endpoints. Fix this by not disabling the endpoints as part of flow control enable but just stop the active transfers on these endpoints. Change-Id: I391a7048188b2a63e2df993fcebf7a6e78eaef14 Signed-off-by: Sriharsha Allenki <sallenki@codeaurora.org>
This commit is contained in:
parent
63d54f82b9
commit
b8e7c7ca38
1 changed files with 33 additions and 27 deletions
|
@ -49,6 +49,7 @@ static struct gsi_inst_status {
|
|||
/* Deregister misc device and free instance structures */
|
||||
static void gsi_inst_clean(struct gsi_opts *opts);
|
||||
|
||||
static void gsi_rndis_ipa_reset_trigger(struct gsi_data_port *d_port);
|
||||
static void ipa_disconnect_handler(struct gsi_data_port *d_port);
|
||||
static int gsi_ctrl_send_notification(struct f_gsi *gsi);
|
||||
static int gsi_alloc_trb_buffer(struct f_gsi *gsi);
|
||||
|
@ -501,14 +502,11 @@ static void ipa_disconnect_handler(struct gsi_data_port *d_port)
|
|||
*/
|
||||
usb_gsi_ep_op(d_port->in_ep, (void *)&block_db,
|
||||
GSI_EP_OP_SET_CLR_BLOCK_DBL);
|
||||
gsi->in_ep_desc_backup = gsi->d_port.in_ep->desc;
|
||||
usb_gsi_ep_op(gsi->d_port.in_ep, NULL, GSI_EP_OP_DISABLE);
|
||||
}
|
||||
|
||||
if (gsi->d_port.out_ep) {
|
||||
gsi->out_ep_desc_backup = gsi->d_port.out_ep->desc;
|
||||
if (gsi->d_port.out_ep)
|
||||
usb_gsi_ep_op(gsi->d_port.out_ep, NULL, GSI_EP_OP_DISABLE);
|
||||
}
|
||||
|
||||
gsi->d_port.net_ready_trigger = false;
|
||||
}
|
||||
|
@ -617,6 +615,7 @@ static void ipa_work_handler(struct work_struct *w)
|
|||
struct usb_gadget *gadget = gsi->gadget;
|
||||
struct device *dev;
|
||||
struct device *gad_dev;
|
||||
bool block_db;
|
||||
|
||||
event = read_event(d_port);
|
||||
|
||||
|
@ -679,28 +678,6 @@ static void ipa_work_handler(struct work_struct *w)
|
|||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update desc and reconfigure USB GSI OUT and IN
|
||||
* endpoint for RNDIS Adaptor enable case.
|
||||
*/
|
||||
if (d_port->out_ep && !d_port->out_ep->desc &&
|
||||
gsi->out_ep_desc_backup) {
|
||||
d_port->out_ep->desc = gsi->out_ep_desc_backup;
|
||||
d_port->out_ep->ep_intr_num = 1;
|
||||
log_event_dbg("%s: OUT ep_op_config", __func__);
|
||||
usb_gsi_ep_op(d_port->out_ep,
|
||||
&d_port->out_request, GSI_EP_OP_CONFIG);
|
||||
}
|
||||
|
||||
if (d_port->in_ep && !d_port->in_ep->desc &&
|
||||
gsi->in_ep_desc_backup) {
|
||||
d_port->in_ep->desc = gsi->in_ep_desc_backup;
|
||||
d_port->in_ep->ep_intr_num = 2;
|
||||
log_event_dbg("%s: IN ep_op_config", __func__);
|
||||
usb_gsi_ep_op(d_port->in_ep,
|
||||
&d_port->in_request, GSI_EP_OP_CONFIG);
|
||||
}
|
||||
|
||||
ipa_connect_channels(d_port);
|
||||
ipa_data_path_enable(d_port);
|
||||
d_port->sm_state = STATE_CONNECTED;
|
||||
|
@ -762,7 +739,15 @@ static void ipa_work_handler(struct work_struct *w)
|
|||
if (event == EVT_HOST_NRDY) {
|
||||
log_event_dbg("%s: ST_CON_HOST_NRDY\n",
|
||||
__func__);
|
||||
ipa_disconnect_handler(d_port);
|
||||
block_db = true;
|
||||
/* stop USB ringing doorbell to GSI(OUT_EP) */
|
||||
usb_gsi_ep_op(d_port->in_ep, (void *)&block_db,
|
||||
GSI_EP_OP_SET_CLR_BLOCK_DBL);
|
||||
gsi_rndis_ipa_reset_trigger(d_port);
|
||||
usb_gsi_ep_op(d_port->in_ep, NULL,
|
||||
GSI_EP_OP_ENDXFER);
|
||||
usb_gsi_ep_op(d_port->out_ep, NULL,
|
||||
GSI_EP_OP_ENDXFER);
|
||||
}
|
||||
|
||||
ipa_disconnect_work_handler(d_port);
|
||||
|
@ -1471,6 +1456,27 @@ static void gsi_rndis_open(struct f_gsi *rndis)
|
|||
rndis_signal_connect(rndis->params);
|
||||
}
|
||||
|
||||
static void gsi_rndis_ipa_reset_trigger(struct gsi_data_port *d_port)
|
||||
{
|
||||
struct f_gsi *rndis = d_port_to_gsi(d_port);
|
||||
unsigned long flags;
|
||||
|
||||
if (!rndis) {
|
||||
log_event_err("%s: gsi prot ctx is %pK", __func__, rndis);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&rndis->d_port.lock, flags);
|
||||
if (!rndis) {
|
||||
log_event_err("%s: No RNDIS instance", __func__);
|
||||
spin_unlock_irqrestore(&rndis->d_port.lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
rndis->d_port.net_ready_trigger = false;
|
||||
spin_unlock_irqrestore(&rndis->d_port.lock, flags);
|
||||
}
|
||||
|
||||
void gsi_rndis_flow_ctrl_enable(bool enable, struct rndis_params *param)
|
||||
{
|
||||
struct f_gsi *rndis = param->v;
|
||||
|
|
Loading…
Add table
Reference in a new issue