Loading drivers/usb/gadget/function/f_gsi.c +49 −11 Original line number Diff line number Diff line Loading @@ -163,6 +163,8 @@ static int gsi_wakeup_host(struct f_gsi *gsi) if ((gadget->speed >= USB_SPEED_SUPER) && (gsi->func_is_suspended)) { log_event_dbg("%s: Calling usb_func_wakeup", __func__); ret = usb_func_wakeup(func); if (ret == -EAGAIN) gsi->func_wakeup_pending = true; } else { log_event_dbg("%s: Calling usb_gadget_wakeup", __func__); ret = usb_gadget_wakeup(gadget); Loading Loading @@ -1880,18 +1882,44 @@ static int queue_notification_request(struct f_gsi *gsi) { int ret; unsigned long flags; struct usb_function *func = &gsi->function; struct usb_request *req = gsi->c_port.notify_req; struct usb_ep *ep = gsi->c_port.notify; struct usb_gadget *gadget = func->config->cdev->gadget; if (!gsi->func_is_suspended) { ret = usb_ep_queue(gsi->c_port.notify, gsi->c_port.notify_req, GFP_ATOMIC); } else { if (gsi->func_wakeup_allowed) ret = usb_func_wakeup(&gsi->function); else ret = -EOPNOTSUPP; if (gsi->c_port.is_suspended) { /*For remote wakeup, queue the req from gsi_resume*/ spin_lock_irqsave(&gsi->c_port.lock, flags); gsi->c_port.notify_req_queued = false; spin_unlock_irqrestore(&gsi->c_port.lock, flags); if (gsi->rwake_inprogress) { log_event_dbg("%s remote-wakeup in progress\n", __func__); return -EBUSY; } if (!usb_gsi_remote_wakeup_allowed(func)) { log_event_dbg("%s remote-wakeup not capable\n", __func__); return -EOPNOTSUPP; } if (ret < 0 || gsi->func_is_suspended) { log_event_dbg("%s wakeup host\n", __func__); if (gadget->speed >= USB_SPEED_SUPER && gsi->func_is_suspended) { ret = usb_func_wakeup(func); if (ret == -EAGAIN) gsi->func_wakeup_pending = true; } else ret = usb_gadget_wakeup(gadget); gsi->rwake_inprogress = true; return ret; } ret = usb_ep_queue(ep, req, GFP_ATOMIC); if (ret < 0) { spin_lock_irqsave(&gsi->c_port.lock, flags); gsi->c_port.notify_req_queued = false; spin_unlock_irqrestore(&gsi->c_port.lock, flags); Loading Loading @@ -2523,6 +2551,8 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, gsi->data_id, gsi->data_interface_up); } gsi->c_port.is_suspended = false; gsi->func_wakeup_pending = false; atomic_set(&gsi->connected, 1); /* send 0 len pkt to qti to notify state change */ Loading Loading @@ -2606,6 +2636,7 @@ static void gsi_suspend(struct usb_function *f) return; } gsi->c_port.is_suspended = true; block_db = true; usb_gsi_ep_op(gsi->d_port.in_ep, (void *)&block_db, GSI_EP_OP_SET_CLR_BLOCK_DBL); Loading Loading @@ -2636,8 +2667,13 @@ static void gsi_resume(struct usb_function *f) * canceled. In this case resume is done by a Function Resume request. */ if ((cdev->gadget->speed >= USB_SPEED_SUPER) && gsi->func_is_suspended) gsi->func_is_suspended) { if (gsi->func_wakeup_pending) { usb_func_wakeup(&gsi->function); gsi->func_wakeup_pending = false; } return; } /* Keep timer enabled if user enabled using debugfs */ if (!gsi->debugfs_rw_timer_enable) Loading @@ -2646,6 +2682,8 @@ static void gsi_resume(struct usb_function *f) if (gsi->c_port.notify && !gsi->c_port.notify->desc) config_ep_by_speed(cdev->gadget, f, gsi->c_port.notify); gsi->c_port.is_suspended = false; /* Check any pending cpkt, and queue immediately on resume */ gsi_ctrl_send_notification(gsi); Loading Loading @@ -3304,7 +3342,7 @@ static void gsi_unbind(struct usb_configuration *c, struct usb_function *f) rmnet_gsi_string_defs[0].id = 0; mbim_gsi_string_defs[0].id = 0; qdss_gsi_string_defs[0].id = 0; gsi->func_wakeup_pending = false; if (gsi->prot_id == IPA_USB_RNDIS) { gsi->d_port.sm_state = STATE_UNINITIALIZED; rndis_deregister(gsi->params); Loading drivers/usb/gadget/function/f_gsi.h +2 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,7 @@ struct gsi_ctrl_port { atomic_t ctrl_online; bool is_open; bool is_suspended; wait_queue_head_t read_wq; Loading Loading @@ -274,6 +275,7 @@ struct f_gsi { /* function suspend status */ bool func_is_suspended; bool func_wakeup_allowed; bool func_wakeup_pending; const struct usb_endpoint_descriptor *in_ep_desc_backup; const struct usb_endpoint_descriptor *out_ep_desc_backup; Loading Loading
drivers/usb/gadget/function/f_gsi.c +49 −11 Original line number Diff line number Diff line Loading @@ -163,6 +163,8 @@ static int gsi_wakeup_host(struct f_gsi *gsi) if ((gadget->speed >= USB_SPEED_SUPER) && (gsi->func_is_suspended)) { log_event_dbg("%s: Calling usb_func_wakeup", __func__); ret = usb_func_wakeup(func); if (ret == -EAGAIN) gsi->func_wakeup_pending = true; } else { log_event_dbg("%s: Calling usb_gadget_wakeup", __func__); ret = usb_gadget_wakeup(gadget); Loading Loading @@ -1880,18 +1882,44 @@ static int queue_notification_request(struct f_gsi *gsi) { int ret; unsigned long flags; struct usb_function *func = &gsi->function; struct usb_request *req = gsi->c_port.notify_req; struct usb_ep *ep = gsi->c_port.notify; struct usb_gadget *gadget = func->config->cdev->gadget; if (!gsi->func_is_suspended) { ret = usb_ep_queue(gsi->c_port.notify, gsi->c_port.notify_req, GFP_ATOMIC); } else { if (gsi->func_wakeup_allowed) ret = usb_func_wakeup(&gsi->function); else ret = -EOPNOTSUPP; if (gsi->c_port.is_suspended) { /*For remote wakeup, queue the req from gsi_resume*/ spin_lock_irqsave(&gsi->c_port.lock, flags); gsi->c_port.notify_req_queued = false; spin_unlock_irqrestore(&gsi->c_port.lock, flags); if (gsi->rwake_inprogress) { log_event_dbg("%s remote-wakeup in progress\n", __func__); return -EBUSY; } if (!usb_gsi_remote_wakeup_allowed(func)) { log_event_dbg("%s remote-wakeup not capable\n", __func__); return -EOPNOTSUPP; } if (ret < 0 || gsi->func_is_suspended) { log_event_dbg("%s wakeup host\n", __func__); if (gadget->speed >= USB_SPEED_SUPER && gsi->func_is_suspended) { ret = usb_func_wakeup(func); if (ret == -EAGAIN) gsi->func_wakeup_pending = true; } else ret = usb_gadget_wakeup(gadget); gsi->rwake_inprogress = true; return ret; } ret = usb_ep_queue(ep, req, GFP_ATOMIC); if (ret < 0) { spin_lock_irqsave(&gsi->c_port.lock, flags); gsi->c_port.notify_req_queued = false; spin_unlock_irqrestore(&gsi->c_port.lock, flags); Loading Loading @@ -2523,6 +2551,8 @@ static int gsi_set_alt(struct usb_function *f, unsigned int intf, gsi->data_id, gsi->data_interface_up); } gsi->c_port.is_suspended = false; gsi->func_wakeup_pending = false; atomic_set(&gsi->connected, 1); /* send 0 len pkt to qti to notify state change */ Loading Loading @@ -2606,6 +2636,7 @@ static void gsi_suspend(struct usb_function *f) return; } gsi->c_port.is_suspended = true; block_db = true; usb_gsi_ep_op(gsi->d_port.in_ep, (void *)&block_db, GSI_EP_OP_SET_CLR_BLOCK_DBL); Loading Loading @@ -2636,8 +2667,13 @@ static void gsi_resume(struct usb_function *f) * canceled. In this case resume is done by a Function Resume request. */ if ((cdev->gadget->speed >= USB_SPEED_SUPER) && gsi->func_is_suspended) gsi->func_is_suspended) { if (gsi->func_wakeup_pending) { usb_func_wakeup(&gsi->function); gsi->func_wakeup_pending = false; } return; } /* Keep timer enabled if user enabled using debugfs */ if (!gsi->debugfs_rw_timer_enable) Loading @@ -2646,6 +2682,8 @@ static void gsi_resume(struct usb_function *f) if (gsi->c_port.notify && !gsi->c_port.notify->desc) config_ep_by_speed(cdev->gadget, f, gsi->c_port.notify); gsi->c_port.is_suspended = false; /* Check any pending cpkt, and queue immediately on resume */ gsi_ctrl_send_notification(gsi); Loading Loading @@ -3304,7 +3342,7 @@ static void gsi_unbind(struct usb_configuration *c, struct usb_function *f) rmnet_gsi_string_defs[0].id = 0; mbim_gsi_string_defs[0].id = 0; qdss_gsi_string_defs[0].id = 0; gsi->func_wakeup_pending = false; if (gsi->prot_id == IPA_USB_RNDIS) { gsi->d_port.sm_state = STATE_UNINITIALIZED; rndis_deregister(gsi->params); Loading
drivers/usb/gadget/function/f_gsi.h +2 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,7 @@ struct gsi_ctrl_port { atomic_t ctrl_online; bool is_open; bool is_suspended; wait_queue_head_t read_wq; Loading Loading @@ -274,6 +275,7 @@ struct f_gsi { /* function suspend status */ bool func_is_suspended; bool func_wakeup_allowed; bool func_wakeup_pending; const struct usb_endpoint_descriptor *in_ep_desc_backup; const struct usb_endpoint_descriptor *out_ep_desc_backup; Loading