From 7b0acdb1b00c97a35c2a0b0f31a1953b9a1b41e4 Mon Sep 17 00:00:00 2001 From: Manu Gautam Date: Mon, 6 Feb 2017 17:21:12 -0800 Subject: [PATCH 1/2] USB: f_fs: Disable USB LPM on bus_suspend with ADB ADB function is mainly used for debugging, hence it is not expected to allow USB LPM followed by system suspend in device bus suspend. Driver also doesn't handle usb_ep_dequeue failure in LPM when adbd is interrupted by signal as buffer is left queued to the hardware after usb_ep_dequeue failure and can cause memory corruption. In addition to above comments, when controller is in lpm there is a chance that ffs_ioctl can issue clear halt as a part of which send_gadget_ep_cmd will be called where registers are accessed with clock's turned off leading to crash due to unclocked access. Hence do not allow usb lpm with adb. Change-Id: Ib89c80318dcdd0dbb35d122a2ab77fb61f83518e Signed-off-by: Manu Gautam Signed-off-by: Mayank Rana Signed-off-by: Jack Pham Signed-off-by: Rohith Kollalsi --- drivers/usb/gadget/function/f_fs.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 046ecba2074f..653484529579 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -3589,6 +3589,8 @@ static int ffs_func_set_alt(struct usb_function *f, { struct ffs_function *func = ffs_func_from_usb(f); struct ffs_data *ffs = func->ffs; + struct f_fs_opts *opts = + container_of(f->fi, struct f_fs_opts, func_inst); int ret = 0, intf; ffs_log("enter: alt %d", (int)alt); @@ -3602,6 +3604,9 @@ static int ffs_func_set_alt(struct usb_function *f, if (ffs->func) { ffs_func_eps_disable(ffs->func); ffs->func = NULL; + /* matching put to allow LPM on disconnect */ + if (!strcmp(opts->dev->name, "adb")) + usb_gadget_autopm_put_async(ffs->gadget); } if (ffs->state == FFS_DEACTIVATED) { @@ -3622,8 +3627,15 @@ static int ffs_func_set_alt(struct usb_function *f, ffs->func = func; ret = ffs_func_eps_enable(func); - if (likely(ret >= 0)) + if (likely(ret >= 0)) { ffs_event_add(ffs, FUNCTIONFS_ENABLE); + /* Disable USB LPM later on bus_suspend for adb */ + if (!strcmp(opts->dev->name, "adb")) + usb_gadget_autopm_get_async(ffs->gadget); + } + + ffs_log("exit: ret %d", ret); + return ret; } @@ -3634,6 +3646,7 @@ static void ffs_func_disable(struct usb_function *f) ffs_log("enter"); ffs_func_set_alt(f, 0, (unsigned)-1); + ffs_log("exit"); } static int ffs_func_setup(struct usb_function *f, From da0ce57aed4ba7b3763b471c01c4f5247e1cfae8 Mon Sep 17 00:00:00 2001 From: Rohith Kollalsi Date: Mon, 6 Sep 2021 20:27:24 +0530 Subject: [PATCH 2/2] USB: u_ether: Prevent unclocked access when running rndis interface down When in rndis composition, if device is disabled in device manager, usb enters low power mode. Then if rndis interface is put down, ep_disable is called leading to crash due to unclocked access as clocks are turned off when usb enters lpm. Fix this by waking up the controller, then performing ep_disable operation and then putting controller back to lpm. Change-Id: I45d29ef2e2678a3d6383d3fdd5550c8b8e156875 Signed-off-by: Rohith Kollalsi --- drivers/usb/gadget/function/u_ether.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 3daf39be7f3c..bd8890914517 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -650,6 +650,8 @@ static int eth_stop(struct net_device *net) dev->net->stats.rx_errors, dev->net->stats.tx_errors ); + usb_gadget_autopm_get(dev->gadget); + /* ensure there are no more active requests */ spin_lock_irqsave(&dev->lock, flags); if (dev->port_usb) { @@ -682,6 +684,7 @@ static int eth_stop(struct net_device *net) } } spin_unlock_irqrestore(&dev->lock, flags); + usb_gadget_autopm_put_async(dev->gadget); return 0; }