diff options
Diffstat (limited to 'drivers/usb/gadget/legacy/zero.c')
| -rw-r--r-- | drivers/usb/gadget/legacy/zero.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/drivers/usb/gadget/legacy/zero.c b/drivers/usb/gadget/legacy/zero.c index d02e2ce73ea5..08a21bd0c2ba 100644 --- a/drivers/usb/gadget/legacy/zero.c +++ b/drivers/usb/gadget/legacy/zero.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * zero.c -- Gadget Zero, for USB development * * Copyright (C) 2003-2008 David Brownell * Copyright (C) 2008 by Nokia Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ /* @@ -15,8 +11,8 @@ * can write a hardware-agnostic gadget driver running inside a USB device. * Some hardware details are visible, but don't affect most of the driver. * - * Use it with the Linux host/master side "usbtest" driver to get a basic - * functional test of your device-side usb stack, or with "usb-skeleton". + * Use it with the Linux host side "usbtest" driver to get a basic functional + * test of your device-side usb stack, or with "usb-skeleton". * * It supports two similar configurations. One sinks whatever the usb host * writes, and in return sources zeroes. The other loops whatever the host @@ -151,14 +147,22 @@ static struct usb_gadget_strings *dev_strings[] = { NULL, }; +static struct usb_function *func_lb; +static struct usb_function_instance *func_inst_lb; + +static struct usb_function *func_ss; +static struct usb_function_instance *func_inst_ss; + /*-------------------------------------------------------------------------*/ static struct timer_list autoresume_timer; +static struct usb_composite_dev *autoresume_cdev; -static void zero_autoresume(unsigned long _c) +static void zero_autoresume(struct timer_list *unused) { - struct usb_composite_dev *cdev = (void *)_c; + struct usb_composite_dev *cdev = autoresume_cdev; struct usb_gadget *g = cdev->gadget; + int status; /* unconfigured devices can't issue wakeups */ if (!cdev->config) @@ -168,10 +172,18 @@ static void zero_autoresume(unsigned long _c) * more significant than just a timer firing; likely * because of some direct user request. */ - if (g->speed != USB_SPEED_UNKNOWN) { - int status = usb_gadget_wakeup(g); - INFO(cdev, "%s --> %d\n", __func__, status); + if (g->speed == USB_SPEED_UNKNOWN) + return; + + if (g->speed >= USB_SPEED_SUPER) { + if (loopdefault) + status = usb_func_wakeup(func_lb); + else + status = usb_func_wakeup(func_ss); + } else { + status = usb_gadget_wakeup(g); } + INFO(cdev, "%s --> %d\n", __func__, status); } static void zero_suspend(struct usb_composite_dev *cdev) @@ -197,7 +209,7 @@ static void zero_suspend(struct usb_composite_dev *cdev) static void zero_resume(struct usb_composite_dev *cdev) { DBG(cdev, "%s\n", __func__); - del_timer(&autoresume_timer); + timer_delete(&autoresume_timer); } /*-------------------------------------------------------------------------*/ @@ -209,9 +221,6 @@ static struct usb_configuration loopback_driver = { /* .iConfiguration = DYNAMIC */ }; -static struct usb_function *func_ss; -static struct usb_function_instance *func_inst_ss; - static int ss_config_setup(struct usb_configuration *c, const struct usb_ctrlrequest *ctrl) { @@ -251,9 +260,6 @@ module_param_named(isoc_maxburst, gzero_options.isoc_maxburst, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)"); -static struct usb_function *func_lb; -static struct usb_function_instance *func_inst_lb; - module_param_named(qlen, gzero_options.qlen, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(qlen, "depth of loopback queue"); @@ -282,7 +288,8 @@ static int zero_bind(struct usb_composite_dev *cdev) device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; device_desc.iSerialNumber = strings_dev[USB_GADGET_SERIAL_IDX].id; - setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); + autoresume_cdev = cdev; + timer_setup(&autoresume_timer, zero_autoresume, 0); func_inst_ss = usb_get_function_instance("SourceSink"); if (IS_ERR(func_inst_ss)) @@ -400,7 +407,7 @@ err_put_func_inst_ss: static int zero_unbind(struct usb_composite_dev *cdev) { - del_timer_sync(&autoresume_timer); + timer_delete_sync(&autoresume_timer); if (!IS_ERR_OR_NULL(func_ss)) usb_put_function(func_ss); usb_put_function_instance(func_inst_ss); @@ -427,4 +434,5 @@ static struct usb_composite_driver zero_driver = { module_usb_composite_driver(zero_driver); MODULE_AUTHOR("David Brownell"); +MODULE_DESCRIPTION("Gadget Zero, for USB development"); MODULE_LICENSE("GPL"); |
