diff options
Diffstat (limited to 'drivers/usb/gadget')
159 files changed, 1020 insertions, 1068 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 35cc641d9f31..31cce7805eb2 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -130,7 +130,7 @@ config USB_GADGET_STORAGE_NUM_BUFFERS config U_SERIAL_CONSOLE bool "Serial gadget console support" - depends on USB_G_SERIAL + depends on USB_U_SERIAL help It supports the serial gadget can be used as a console. diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 598a67d6ba05..130dad7130b6 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB peripheral controller drivers # diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index dd74c99d6ce1..77c7ecca816a 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * composite.c - infrastructure for Composite USB Gadgets * * Copyright (C) 2006-2008 David Brownell - * - * 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. */ /* #define VERBOSE_DEBUG */ @@ -150,7 +146,6 @@ int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f, struct usb_ep *_ep) { - struct usb_composite_dev *cdev = get_gadget_data(g); struct usb_endpoint_descriptor *chosen_desc = NULL; struct usb_descriptor_header **speed_desc = NULL; @@ -170,20 +165,20 @@ int config_ep_by_speed(struct usb_gadget *g, want_comp_desc = 1; break; } - /* else: Fall trough */ + /* fall through */ case USB_SPEED_SUPER: if (gadget_is_superspeed(g)) { speed_desc = f->ss_descriptors; want_comp_desc = 1; break; } - /* else: Fall trough */ + /* fall through */ case USB_SPEED_HIGH: if (gadget_is_dualspeed(g)) { speed_desc = f->hs_descriptors; break; } - /* else: fall through */ + /* fall through */ default: speed_desc = f->fs_descriptors; } @@ -224,13 +219,18 @@ ep_found: case USB_ENDPOINT_XFER_ISOC: /* mult: bits 1:0 of bmAttributes */ _ep->mult = (comp_desc->bmAttributes & 0x3) + 1; + /* fall through */ case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_INT: _ep->maxburst = comp_desc->bMaxBurst + 1; break; default: - if (comp_desc->bMaxBurst != 0) + if (comp_desc->bMaxBurst != 0) { + struct usb_composite_dev *cdev; + + cdev = get_gadget_data(g); ERROR(cdev, "ep0 bMaxBurst must be 0\n"); + } _ep->maxburst = 1; break; } @@ -2026,6 +2026,8 @@ static DEVICE_ATTR_RO(suspended); static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) { struct usb_composite_dev *cdev = get_gadget_data(gadget); + struct usb_gadget_strings *gstr = cdev->driver->strings[0]; + struct usb_string *dev_str = gstr->strings; /* composite_disconnect() must already have been called * by the underlying peripheral controller driver! @@ -2045,6 +2047,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) composite_dev_cleanup(cdev); + if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer) + dev_str[USB_GADGET_MANUFACTURER_IDX].s = ""; + kfree(cdev->def_manufacturer); kfree(cdev); set_gadget_data(gadget, NULL); diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index 17a6077b89a4..2d115353424c 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * usb/gadget/config.c -- simplify building config descriptors * * Copyright (C) 2003 David Brownell - * - * 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. */ #include <linux/errno.h> diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index a22a892de7b7..efba66ca0719 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/configfs.h> #include <linux/module.h> #include <linux/slab.h> @@ -505,13 +506,13 @@ static struct configfs_attribute *gadget_config_attrs[] = { NULL, }; -static struct config_item_type gadget_config_type = { +static const struct config_item_type gadget_config_type = { .ct_item_ops = &gadget_config_item_ops, .ct_attrs = gadget_config_attrs, .ct_owner = THIS_MODULE, }; -static struct config_item_type gadget_root_type = { +static const struct config_item_type gadget_root_type = { .ct_item_ops = &gadget_root_item_ops, .ct_attrs = gadget_root_attrs, .ct_owner = THIS_MODULE, @@ -593,7 +594,7 @@ static struct configfs_group_operations functions_ops = { .drop_item = &function_drop, }; -static struct config_item_type functions_type = { +static const struct config_item_type functions_type = { .ct_group_ops = &functions_ops, .ct_owner = THIS_MODULE, }; @@ -694,7 +695,7 @@ static struct configfs_group_operations config_desc_ops = { .drop_item = &config_desc_drop, }; -static struct config_item_type config_desc_type = { +static const struct config_item_type config_desc_type = { .ct_group_ops = &config_desc_ops, .ct_owner = THIS_MODULE, }; @@ -1143,11 +1144,12 @@ static struct configfs_attribute *interf_grp_attrs[] = { NULL }; -int usb_os_desc_prepare_interf_dir(struct config_group *parent, - int n_interf, - struct usb_os_desc **desc, - char **names, - struct module *owner) +struct config_group *usb_os_desc_prepare_interf_dir( + struct config_group *parent, + int n_interf, + struct usb_os_desc **desc, + char **names, + struct module *owner) { struct config_group *os_desc_group; struct config_item_type *os_desc_type, *interface_type; @@ -1159,7 +1161,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); if (!vlabuf) - return -ENOMEM; + return ERR_PTR(-ENOMEM); os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group); os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type); @@ -1184,7 +1186,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, configfs_add_default_group(&d->group, os_desc_group); } - return 0; + return os_desc_group; } EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir); @@ -1475,7 +1477,7 @@ static struct configfs_group_operations gadgets_ops = { .drop_item = &gadgets_drop, }; -static struct config_item_type gadgets_type = { +static const struct config_item_type gadgets_type = { .ct_group_ops = &gadgets_ops, .ct_owner = THIS_MODULE, }; diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h index 36c468c4f5e9..3b6f5298b2e8 100644 --- a/drivers/usb/gadget/configfs.h +++ b/drivers/usb/gadget/configfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef USB__GADGET__CONFIGFS__H #define USB__GADGET__CONFIGFS__H @@ -5,11 +6,12 @@ void unregister_gadget_item(struct config_item *item); -int usb_os_desc_prepare_interf_dir(struct config_group *parent, - int n_interf, - struct usb_os_desc **desc, - char **names, - struct module *owner); +struct config_group *usb_os_desc_prepare_interf_dir( + struct config_group *parent, + int n_interf, + struct usb_os_desc **desc, + char **names, + struct module *owner); static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item) { diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 30fdab0ae383..71b15c65b90f 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * epautoconf.c -- endpoint autoconfiguration for usb gadget drivers * * Copyright (C) 2004 David Brownell - * - * 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. */ #include <linux/kernel.h> diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 86e825269947..5d3a6cf02218 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB peripheral controller drivers # diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index 5e3828d9dac7..9fc98de83624 100644 --- a/drivers/usb/gadget/function/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_acm.c -- USB CDC serial (ACM) function driver * @@ -6,10 +7,6 @@ * Copyright (C) 2008 by Nokia Corporation * Copyright (C) 2009 by Samsung Electronics * Author: Michal Nazarewicz (mina86@mina86.com) - * - * This software is distributed under the terms of the GNU General - * Public License ("GPL") as published by the Free Software Foundation, - * either version 2 of that License or (at your option) any later version. */ /* #define VERBOSE_DEBUG */ @@ -786,7 +783,7 @@ static struct configfs_attribute *acm_attrs[] = { NULL, }; -static struct config_item_type acm_func_type = { +static const struct config_item_type acm_func_type = { .ct_item_ops = &acm_item_ops, .ct_attrs = acm_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index 4c488d15b6f6..b104ed0c1ab5 100644 --- a/drivers/usb/gadget/function/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_ecm.c -- USB CDC Ethernet (ECM) link function driver * * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2008 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. */ /* #define VERBOSE_DEBUG */ @@ -845,7 +841,7 @@ static struct configfs_attribute *ecm_attrs[] = { NULL, }; -static struct config_item_type ecm_func_type = { +static const struct config_item_type ecm_func_type = { .ct_item_ops = &ecm_item_ops, .ct_attrs = ecm_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index 007ec6e4a5d4..37557651b600 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_eem.c -- USB CDC Ethernet (EEM) link function driver * * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2008 Nokia Corporation * Copyright (C) 2009 EF Johnson Technologies - * - * 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. */ #include <linux/kernel.h> @@ -556,7 +552,7 @@ static struct configfs_attribute *eem_attrs[] = { NULL, }; -static struct config_item_type eem_func_type = { +static const struct config_item_type eem_func_type = { .ct_item_ops = &eem_item_ops, .ct_attrs = eem_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index d21874b35cf6..b6cf5ab5a0a1 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_fs.c -- user mode file system API for USB composite function controllers * @@ -7,11 +8,6 @@ * Based on inode.c (GadgetFS) which was: * Copyright (C) 2003-2004 David Brownell * Copyright (C) 2003 Agilent Technologies - * - * 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. */ @@ -46,7 +42,8 @@ static void ffs_data_get(struct ffs_data *ffs); static void ffs_data_put(struct ffs_data *ffs); /* Creates new ffs_data object. */ -static struct ffs_data *__must_check ffs_data_new(void) __attribute__((malloc)); +static struct ffs_data *__must_check ffs_data_new(const char *dev_name) + __attribute__((malloc)); /* Opened counter handling. */ static void ffs_data_opened(struct ffs_data *ffs); @@ -780,11 +777,12 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep, struct usb_request *req) { struct ffs_io_data *io_data = req->context; + struct ffs_data *ffs = io_data->ffs; ENTER(); INIT_WORK(&io_data->work, ffs_user_copy_worker); - schedule_work(&io_data->work); + queue_work(ffs->io_completion_wq, &io_data->work); } static void __ffs_epfile_read_buffer_free(struct ffs_epfile *epfile) @@ -961,10 +959,9 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) /* In the meantime, endpoint got disabled or changed. */ ret = -ESHUTDOWN; } else if (halt) { - /* Halt */ - if (likely(epfile->ep == ep) && !WARN_ON(!ep->ep)) - usb_ep_set_halt(ep->ep); - ret = -EBADMSG; + ret = usb_ep_set_halt(ep->ep); + if (!ret) + ret = -EBADMSG; } else if (unlikely(data_len == -EINVAL)) { /* * Sanity Check: even though data_len can't be used @@ -1015,7 +1012,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) else ret = ep->status; goto error_mutex; - } else if (!(req = usb_ep_alloc_request(ep->ep, GFP_KERNEL))) { + } else if (!(req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC))) { ret = -ENOMEM; } else { req->buf = data; @@ -1501,7 +1498,7 @@ ffs_fs_mount(struct file_system_type *t, int flags, if (unlikely(ret < 0)) return ERR_PTR(ret); - ffs = ffs_data_new(); + ffs = ffs_data_new(dev_name); if (unlikely(!ffs)) return ERR_PTR(-ENOMEM); ffs->file_perms = data.perms; @@ -1611,6 +1608,7 @@ static void ffs_data_put(struct ffs_data *ffs) BUG_ON(waitqueue_active(&ffs->ev.waitq) || waitqueue_active(&ffs->ep0req_completion.wait) || waitqueue_active(&ffs->wait)); + destroy_workqueue(ffs->io_completion_wq); kfree(ffs->dev_name); kfree(ffs); } @@ -1643,7 +1641,7 @@ static void ffs_data_closed(struct ffs_data *ffs) ffs_data_put(ffs); } -static struct ffs_data *ffs_data_new(void) +static struct ffs_data *ffs_data_new(const char *dev_name) { struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL); if (unlikely(!ffs)) @@ -1651,6 +1649,12 @@ static struct ffs_data *ffs_data_new(void) ENTER(); + ffs->io_completion_wq = alloc_ordered_workqueue("%s", 0, dev_name); + if (!ffs->io_completion_wq) { + kfree(ffs); + return NULL; + } + refcount_set(&ffs->ref, 1); atomic_set(&ffs->opened, 0); ffs->state = FFS_READ_DESCRIPTORS; @@ -2278,9 +2282,18 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, int i; if (len < sizeof(*d) || - d->bFirstInterfaceNumber >= ffs->interfaces_count || - !d->Reserved1) + d->bFirstInterfaceNumber >= ffs->interfaces_count) return -EINVAL; + if (d->Reserved1 != 1) { + /* + * According to the spec, Reserved1 must be set to 1 + * but older kernels incorrectly rejected non-zero + * values. We fix it here to avoid returning EINVAL + * in response to values we used to accept. + */ + pr_debug("usb_ext_compat_desc::Reserved1 forced to 1\n"); + d->Reserved1 = 1; + } for (i = 0; i < ARRAY_SIZE(d->Reserved2); ++i) if (d->Reserved2[i]) return -EINVAL; @@ -3377,7 +3390,7 @@ static struct configfs_item_operations ffs_item_ops = { .release = ffs_attr_release, }; -static struct config_item_type ffs_func_type = { +static const struct config_item_type ffs_func_type = { .ct_item_ops = &ffs_item_ops, .ct_owner = THIS_MODULE, }; @@ -3669,6 +3682,7 @@ static void ffs_closed(struct ffs_data *ffs) goto done; ffs_obj->desc_ready = false; + ffs_obj->ffs_data = NULL; if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags) && ffs_obj->ffs_closed_callback) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 5eea44823ca0..daae35318a3a 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_hid.c -- USB HID function driver * * Copyright (C) 2010 Fabien Chouteau <fabien.chouteau@barco.com> - * - * 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. */ #include <linux/kernel.h> @@ -44,6 +40,7 @@ struct f_hidg { /* configuration */ unsigned char bInterfaceSubClass; unsigned char bInterfaceProtocol; + unsigned char protocol; unsigned short report_desc_length; char *report_desc; unsigned short report_length; @@ -527,7 +524,9 @@ static int hidg_setup(struct usb_function *f, case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | HID_REQ_GET_PROTOCOL): VDBG(cdev, "get_protocol\n"); - goto stall; + length = min_t(unsigned int, length, 1); + ((u8 *) req->buf)[0] = hidg->protocol; + goto respond; break; case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 @@ -539,6 +538,17 @@ static int hidg_setup(struct usb_function *f, case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | HID_REQ_SET_PROTOCOL): VDBG(cdev, "set_protocol\n"); + if (value > HID_REPORT_PROTOCOL) + goto stall; + length = 0; + /* + * We assume that programs implementing the Boot protocol + * are also compatible with the Report Protocol + */ + if (hidg->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) { + hidg->protocol = value; + goto respond; + } goto stall; break; @@ -768,6 +778,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) /* set descriptor dynamic values */ hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; + hidg->protocol = HID_REPORT_PROTOCOL; hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_ss_in_comp_desc.wBytesPerInterval = cpu_to_le16(hidg->report_length); @@ -977,7 +988,7 @@ static struct configfs_attribute *hid_attrs[] = { NULL, }; -static struct config_item_type hid_func_type = { +static const struct config_item_type hid_func_type = { .ct_item_ops = &hidg_item_ops, .ct_attrs = hid_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index e70093835e14..1803646b3678 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_loopback.c - USB peripheral loopback configuration driver * * 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. */ /* #define VERBOSE_DEBUG */ @@ -556,7 +552,7 @@ static struct configfs_attribute *lb_attrs[] = { NULL, }; -static struct config_item_type lb_func_type = { +static const struct config_item_type lb_func_type = { .ct_item_ops = &lb_item_ops, .ct_attrs = lb_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index f95bddd6513f..acecd13dcbd9 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * f_mass_storage.c -- Mass Storage USB Composite Function * @@ -307,8 +308,6 @@ struct fsg_common { struct completion thread_notifier; struct task_struct *thread_task; - /* Callback functions. */ - const struct fsg_operations *ops; /* Gadget's private data. */ void *private_data; @@ -686,9 +685,8 @@ static int do_read(struct fsg_common *common) /* Perform the read */ file_offset_tmp = file_offset; - nread = vfs_read(curlun->filp, - (char __user *)bh->buf, - amount, &file_offset_tmp); + nread = kernel_read(curlun->filp, bh->buf, amount, + &file_offset_tmp); VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long)file_offset, (int)nread); if (signal_pending(current)) @@ -883,8 +881,8 @@ static int do_write(struct fsg_common *common) /* Perform the write */ file_offset_tmp = file_offset; - nwritten = vfs_write(curlun->filp, (char __user *)bh->buf, - amount, &file_offset_tmp); + nwritten = kernel_write(curlun->filp, bh->buf, amount, + &file_offset_tmp); VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, (unsigned long long)file_offset, (int)nwritten); if (signal_pending(current)) @@ -1021,9 +1019,8 @@ static int do_verify(struct fsg_common *common) /* Perform the read */ file_offset_tmp = file_offset; - nread = vfs_read(curlun->filp, - (char __user *) bh->buf, - amount, &file_offset_tmp); + nread = kernel_read(curlun->filp, bh->buf, amount, + &file_offset_tmp); VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, (int) nread); @@ -2440,6 +2437,7 @@ static void handle_exception(struct fsg_common *common) static int fsg_main_thread(void *common_) { struct fsg_common *common = common_; + int i; /* * Allow the thread to be killed by a signal, but set the signal mask @@ -2453,13 +2451,6 @@ static int fsg_main_thread(void *common_) /* Allow the thread to be frozen */ set_freezable(); - /* - * Arrange for userspace references to be interpreted as kernel - * pointers. That way we can pass a kernel pointer to a routine - * that expects a __user pointer and it will work okay. - */ - set_fs(get_ds()); - /* The main loop */ while (common->state != FSG_STATE_TERMINATED) { if (exception_in_progress(common) || signal_pending(current)) { @@ -2485,21 +2476,16 @@ static int fsg_main_thread(void *common_) common->thread_task = NULL; spin_unlock_irq(&common->lock); - if (!common->ops || !common->ops->thread_exits - || common->ops->thread_exits(common) < 0) { - int i; + /* Eject media from all LUNs */ - down_write(&common->filesem); - for (i = 0; i < ARRAY_SIZE(common->luns); i++) { - struct fsg_lun *curlun = common->luns[i]; - if (!curlun || !fsg_lun_is_open(curlun)) - continue; + down_write(&common->filesem); + for (i = 0; i < ARRAY_SIZE(common->luns); i++) { + struct fsg_lun *curlun = common->luns[i]; + if (curlun && fsg_lun_is_open(curlun)) fsg_lun_close(curlun); - curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; - } - up_write(&common->filesem); } + up_write(&common->filesem); /* Let fsg_unbind() know the thread has exited */ complete_and_exit(&common->thread_notifier, 0); @@ -2690,13 +2676,6 @@ void fsg_common_remove_luns(struct fsg_common *common) } EXPORT_SYMBOL_GPL(fsg_common_remove_luns); -void fsg_common_set_ops(struct fsg_common *common, - const struct fsg_operations *ops) -{ - common->ops = ops; -} -EXPORT_SYMBOL_GPL(fsg_common_set_ops); - void fsg_common_free_buffers(struct fsg_common *common) { _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); @@ -3162,7 +3141,7 @@ static struct configfs_attribute *fsg_lun_attrs[] = { NULL, }; -static struct config_item_type fsg_lun_type = { +static const struct config_item_type fsg_lun_type = { .ct_item_ops = &fsg_lun_item_ops, .ct_attrs = fsg_lun_attrs, .ct_owner = THIS_MODULE, @@ -3353,7 +3332,7 @@ static struct configfs_group_operations fsg_group_ops = { .drop_item = fsg_lun_drop, }; -static struct config_item_type fsg_func_type = { +static const struct config_item_type fsg_func_type = { .ct_item_ops = &fsg_item_ops, .ct_group_ops = &fsg_group_ops, .ct_attrs = fsg_attrs, diff --git a/drivers/usb/gadget/function/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h index d3902313b8ac..58857fcf199f 100644 --- a/drivers/usb/gadget/function/f_mass_storage.h +++ b/drivers/usb/gadget/function/f_mass_storage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef USB_F_MASS_STORAGE_H #define USB_F_MASS_STORAGE_H @@ -60,17 +61,6 @@ struct fsg_module_parameters { struct fsg_common; /* FSF callback functions */ -struct fsg_operations { - /* - * Callback function to call when thread exits. If no - * callback is set or it returns value lower then zero MSF - * will force eject all LUNs it operates on (including those - * marked as non-removable or with prevent_medium_removal flag - * set). - */ - int (*thread_exits)(struct fsg_common *common); -}; - struct fsg_lun_opts { struct config_group group; struct fsg_lun *lun; @@ -142,9 +132,6 @@ void fsg_common_remove_lun(struct fsg_lun *lun); void fsg_common_remove_luns(struct fsg_common *common); -void fsg_common_set_ops(struct fsg_common *common, - const struct fsg_operations *ops); - int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, unsigned int id, const char *name, const char **name_pfx); diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a5719f271bf0..4eb96b91cc40 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_midi.c -- USB MIDI class function driver * @@ -15,8 +16,6 @@ * and drivers/usb/gadget/midi.c, * Copyright (C) 2006 Thumtronics Pty Ltd. * Ben Williamson <ben.williamson@greyinnovation.com> - * - * Licensed under the GPL-2 or later. */ #include <linux/kernel.h> @@ -98,6 +97,7 @@ struct f_midi { DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *); spinlock_t transmit_lock; unsigned int in_last_port; + unsigned char free_ref; struct gmidi_in_port in_ports_array[/* in_ports */]; }; @@ -108,6 +108,7 @@ static inline struct f_midi *func_to_midi(struct usb_function *f) } static void f_midi_transmit(struct f_midi *midi); +static void f_midi_rmidi_free(struct snd_rawmidi *rmidi); DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); @@ -163,6 +164,13 @@ static struct usb_endpoint_descriptor bulk_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; +static struct usb_ss_ep_comp_descriptor bulk_out_ss_comp_desc = { + .bLength = sizeof(bulk_out_ss_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + /* B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor */ static struct usb_ms_endpoint_descriptor_16 ms_out_desc = { /* .bLength = DYNAMIC */ @@ -180,6 +188,13 @@ static struct usb_endpoint_descriptor bulk_in_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; +static struct usb_ss_ep_comp_descriptor bulk_in_ss_comp_desc = { + .bLength = sizeof(bulk_in_ss_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + /* B.6.2 Class-specific MS Bulk IN Endpoint Descriptor */ static struct usb_ms_endpoint_descriptor_16 ms_in_desc = { /* .bLength = DYNAMIC */ @@ -755,13 +770,13 @@ static void f_midi_out_trigger(struct snd_rawmidi_substream *substream, int up) clear_bit(substream->number, &midi->out_triggered); } -static struct snd_rawmidi_ops gmidi_in_ops = { +static const struct snd_rawmidi_ops gmidi_in_ops = { .open = f_midi_in_open, .close = f_midi_in_close, .trigger = f_midi_in_trigger, }; -static struct snd_rawmidi_ops gmidi_out_ops = { +static const struct snd_rawmidi_ops gmidi_out_ops = { .open = f_midi_out_open, .close = f_midi_out_close, .trigger = f_midi_out_trigger @@ -818,6 +833,8 @@ static int f_midi_register_card(struct f_midi *midi) SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; rmidi->private_data = midi; + rmidi->private_free = f_midi_rmidi_free; + midi->free_ref++; /* * Yes, rawmidi OUTPUT = USB IN, and rawmidi INPUT = USB OUT. @@ -853,7 +870,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) struct usb_composite_dev *cdev = c->cdev; struct f_midi *midi = func_to_midi(f); struct usb_string *us; - int status, n, jack = 1, i = 0; + int status, n, jack = 1, i = 0, endpoint_descriptor_index = 0; midi->gadget = cdev->gadget; tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi); @@ -895,7 +912,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) goto fail; /* allocate temporary function list */ - midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function), + midi_function = kcalloc((MAX_PORTS * 4) + 11, sizeof(*midi_function), GFP_KERNEL); if (!midi_function) { status = -ENOMEM; @@ -985,6 +1002,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) ms_in_desc.bNumEmbMIDIJack = midi->out_ports; /* ... and add them to the list */ + endpoint_descriptor_index = i; midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc; midi_function[i++] = (struct usb_descriptor_header *) &ms_out_desc; midi_function[i++] = (struct usb_descriptor_header *) &bulk_in_desc; @@ -1009,13 +1027,34 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) goto fail_f_midi; } + if (gadget_is_superspeed(c->cdev->gadget)) { + bulk_in_desc.wMaxPacketSize = cpu_to_le16(1024); + bulk_out_desc.wMaxPacketSize = cpu_to_le16(1024); + i = endpoint_descriptor_index; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_out_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_out_ss_comp_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &ms_out_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_in_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_in_ss_comp_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &ms_in_desc; + f->ss_descriptors = usb_copy_descriptors(midi_function); + if (!f->ss_descriptors) + goto fail_f_midi; + } + kfree(midi_function); return 0; fail_f_midi: kfree(midi_function); - usb_free_descriptors(f->hs_descriptors); + usb_free_all_descriptors(f); fail: f_midi_unregister_card(midi); fail_register: @@ -1149,7 +1188,7 @@ static struct configfs_attribute *midi_attrs[] = { NULL, }; -static struct config_item_type midi_func_type = { +static const struct config_item_type midi_func_type = { .ct_item_ops = &midi_item_ops, .ct_attrs = midi_attrs, .ct_owner = THIS_MODULE, @@ -1197,14 +1236,21 @@ static void f_midi_free(struct usb_function *f) midi = func_to_midi(f); opts = container_of(f->fi, struct f_midi_opts, func_inst); - kfree(midi->id); mutex_lock(&opts->lock); - kfifo_free(&midi->in_req_fifo); - kfree(midi); - --opts->refcnt; + if (!--midi->free_ref) { + kfree(midi->id); + kfifo_free(&midi->in_req_fifo); + kfree(midi); + --opts->refcnt; + } mutex_unlock(&opts->lock); } +static void f_midi_rmidi_free(struct snd_rawmidi *rmidi) +{ + f_midi_free(rmidi->private_data); +} + static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = f->config->cdev; @@ -1219,7 +1265,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) card = midi->card; midi->card = NULL; if (card) - snd_card_free(card); + snd_card_free_when_closed(card); usb_free_all_descriptors(f); } @@ -1263,6 +1309,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) midi->buflen = opts->buflen; midi->qlen = opts->qlen; midi->in_last_port = 0; + midi->free_ref = 1; status = kfifo_alloc(&midi->in_req_fifo, midi->qlen, GFP_KERNEL); if (status) diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 24e34cfcb4bd..c5bce8e22983 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_ncm.c -- USB CDC Network (NCM) link function driver * @@ -8,11 +9,6 @@ * * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2008 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. */ #include <linux/kernel.h> @@ -925,8 +921,6 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) */ ncm->port.is_zlp_ok = gadget_is_zlp_supported(cdev->gadget); - ncm->port.no_skb_reserve = - gadget_avoids_skb_reserve(cdev->gadget); ncm->port.cdc_filter = DEFAULT_FILTER; DBG(cdev, "activate ncm\n"); net = gether_connect(&ncm->port); @@ -1570,7 +1564,7 @@ static struct configfs_attribute *ncm_attrs[] = { NULL, }; -static struct config_item_type ncm_func_type = { +static const struct config_item_type ncm_func_type = { .ct_item_ops = &ncm_item_ops, .ct_attrs = ncm_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_obex.c b/drivers/usb/gadget/function/f_obex.c index d43e86cea74f..55b7f57d2dc7 100644 --- a/drivers/usb/gadget/function/f_obex.c +++ b/drivers/usb/gadget/function/f_obex.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_obex.c -- USB CDC OBEX function driver * @@ -5,11 +6,6 @@ * Contact: Felipe Balbi <felipe.balbi@nokia.com> * * Based on f_acm.c by Al Borchers and David Brownell. - * - * 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. */ /* #define VERBOSE_DEBUG */ @@ -411,7 +407,7 @@ static struct configfs_attribute *acm_attrs[] = { NULL, }; -static struct config_item_type obex_func_type = { +static const struct config_item_type obex_func_type = { .ct_item_ops = &obex_item_ops, .ct_attrs = acm_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index 9c4c58e4a1a2..7889bcc0509a 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * f_phonet.c -- USB CDC Phonet function * * Copyright (C) 2007-2008 Nokia Corporation. All rights reserved. * * Author: Rémi Denis-Courmont - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. */ #include <linux/mm.h> @@ -215,6 +212,7 @@ static void pn_tx_complete(struct usb_ep *ep, struct usb_request *req) case -ESHUTDOWN: /* disconnected */ case -ECONNRESET: /* disabled */ dev->stats.tx_aborted_errors++; + /* fall through */ default: dev->stats.tx_errors++; } @@ -362,6 +360,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req) /* Do resubmit in these cases: */ case -EOVERFLOW: /* request buffer overflow */ dev->stats.rx_over_errors++; + /* fall through */ default: dev->stats.rx_errors++; break; @@ -599,7 +598,7 @@ static struct configfs_attribute *phonet_attrs[] = { NULL, }; -static struct config_item_type phonet_func_type = { +static const struct config_item_type phonet_func_type = { .ct_item_ops = &phonet_item_ops, .ct_attrs = phonet_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 8df244fc9d80..dd607b99eb1d 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_printer.c - USB printer function driver * @@ -8,11 +9,6 @@ * * Copyright (C) 2003-2005 David Brownell * Copyright (C) 2006 Craig W. Nadler - * - * 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. */ #include <linux/module.h> @@ -555,6 +551,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) size_t size; /* Amount of data in a TX request. */ size_t bytes_copied = 0; struct usb_request *req; + int value; DBG(dev, "printer_write trying to send %d bytes\n", (int)len); @@ -634,7 +631,11 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) return -EAGAIN; } - if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { + /* here, we unlock, and only unlock, to avoid deadlock. */ + spin_unlock(&dev->lock); + value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); + spin_lock(&dev->lock); + if (value) { list_add(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock_printer_io); @@ -1256,7 +1257,7 @@ static struct configfs_attribute *printer_attrs[] = { NULL, }; -static struct config_item_type printer_func_type = { +static const struct config_item_type printer_func_type = { .ct_item_ops = &printer_item_ops, .ct_attrs = printer_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 16562e461121..d48df36622b7 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_rndis.c -- RNDIS link function driver * @@ -6,11 +7,6 @@ * Copyright (C) 2008 Nokia Corporation * Copyright (C) 2009 Samsung Electronics * Author: Michal Nazarewicz (mina86@mina86.com) - * - * 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. */ /* #define VERBOSE_DEBUG */ @@ -691,6 +687,10 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc; } + rndis_iad_descriptor.bFunctionClass = rndis_opts->class; + rndis_iad_descriptor.bFunctionSubClass = rndis_opts->subclass; + rndis_iad_descriptor.bFunctionProtocol = rndis_opts->protocol; + /* * in drivers/usb/gadget/configfs.c:configfs_composite_bind() * configurations are bound in sequence with list_for_each_entry, @@ -866,15 +866,27 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis); /* f_rndis_opts_ifname */ USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis); +/* f_rndis_opts_class */ +USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, class); + +/* f_rndis_opts_subclass */ +USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, subclass); + +/* f_rndis_opts_protocol */ +USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, protocol); + static struct configfs_attribute *rndis_attrs[] = { &rndis_opts_attr_dev_addr, &rndis_opts_attr_host_addr, &rndis_opts_attr_qmult, &rndis_opts_attr_ifname, + &rndis_opts_attr_class, + &rndis_opts_attr_subclass, + &rndis_opts_attr_protocol, NULL, }; -static struct config_item_type rndis_func_type = { +static const struct config_item_type rndis_func_type = { .ct_item_ops = &rndis_item_ops, .ct_attrs = rndis_attrs, .ct_owner = THIS_MODULE, @@ -892,6 +904,7 @@ static void rndis_free_inst(struct usb_function_instance *f) free_netdev(opts->net); } + kfree(opts->rndis_interf_group); /* single VLA chunk */ kfree(opts); } @@ -900,6 +913,7 @@ static struct usb_function_instance *rndis_alloc_inst(void) struct f_rndis_opts *opts; struct usb_os_desc *descs[1]; char *names[1]; + struct config_group *rndis_interf_group; opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) @@ -916,12 +930,22 @@ static struct usb_function_instance *rndis_alloc_inst(void) } INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop); + opts->class = rndis_iad_descriptor.bFunctionClass; + opts->subclass = rndis_iad_descriptor.bFunctionSubClass; + opts->protocol = rndis_iad_descriptor.bFunctionProtocol; + descs[0] = &opts->rndis_os_desc; names[0] = "rndis"; config_group_init_type_name(&opts->func_inst.group, "", &rndis_func_type); - usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, - names, THIS_MODULE); + rndis_interf_group = + usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, + names, THIS_MODULE); + if (IS_ERR(rndis_interf_group)) { + rndis_free_inst(&opts->func_inst); + return ERR_CAST(rndis_interf_group); + } + opts->rndis_interf_group = rndis_interf_group; return &opts->func_inst; } diff --git a/drivers/usb/gadget/function/f_serial.c b/drivers/usb/gadget/function/f_serial.c index cb00ada21d9c..c860f30a0ea2 100644 --- a/drivers/usb/gadget/function/f_serial.c +++ b/drivers/usb/gadget/function/f_serial.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_serial.c - generic USB serial function driver * * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) * Copyright (C) 2008 by David Brownell * Copyright (C) 2008 by Nokia Corporation - * - * This software is distributed under the terms of the GNU General - * Public License ("GPL") as published by the Free Software Foundation, - * either version 2 of that License or (at your option) any later version. */ #include <linux/slab.h> @@ -281,7 +278,7 @@ static struct configfs_attribute *acm_attrs[] = { NULL, }; -static struct config_item_type serial_func_type = { +static const struct config_item_type serial_func_type = { .ct_item_ops = &serial_item_ops, .ct_attrs = acm_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 8784fa12ea2c..9cdef108fb1b 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_sourcesink.c - USB peripheral source/sink configuration driver * * 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. */ /* #define VERBOSE_DEBUG */ @@ -1230,7 +1226,7 @@ static struct configfs_attribute *ss_attrs[] = { NULL, }; -static struct config_item_type ss_func_type = { +static const struct config_item_type ss_func_type = { .ct_item_ops = &ss_item_ops, .ct_attrs = ss_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c index 434b983f3b4c..4d945254905d 100644 --- a/drivers/usb/gadget/function/f_subset.c +++ b/drivers/usb/gadget/function/f_subset.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_subset.c -- "CDC Subset" Ethernet link function driver * * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2008 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. */ #include <linux/slab.h> @@ -412,7 +408,7 @@ static struct configfs_attribute *gether_attrs[] = { NULL, }; -static struct config_item_type gether_func_type = { +static const struct config_item_type gether_func_type = { .ct_item_ops = &gether_item_ops, .ct_attrs = gether_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index a82e2bd5ea34..da81cf16b850 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1,10 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* Target based USB-Gadget * * UAS protocol handling, target callbacks, configfs handling, * BBB (USB Mass Storage Class Bulk-Only (BBB) and Transport protocol handling. * * Author: Sebastian Andrzej Siewior <bigeasy at linutronix dot de> - * License: GPLv2 as published by FSF. */ #include <linux/kernel.h> #include <linux/module.h> @@ -1145,6 +1145,7 @@ static int usbg_submit_command(struct f_uas *fu, default: pr_debug_once("Unsupported prio_attr: %02x.\n", cmd_iu->prio_attr); + /* fall through */ case UAS_SIMPLE_TAG: cmd->prio_attr = TCM_SIMPLE_TAG; break; @@ -2166,7 +2167,7 @@ static struct configfs_item_operations tcm_item_ops = { .release = tcm_attr_release, }; -static struct config_item_type tcm_func_type = { +static const struct config_item_type tcm_func_type = { .ct_item_ops = &tcm_item_ops, .ct_owner = THIS_MODULE, }; diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 29efbedc91f9..2746a926a8d9 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_uac1.c -- USB Audio Class 1.0 Function (using u_audio API) * @@ -10,11 +11,6 @@ * This file is based on f_uac1.c which is * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org> * Copyright (C) 2008 Analog Devices, Inc - * - * 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. */ #include <linux/usb/audio.h> @@ -709,7 +705,7 @@ static struct configfs_attribute *f_uac1_attrs[] = { NULL, }; -static struct config_item_type f_uac1_func_type = { +static const struct config_item_type f_uac1_func_type = { .ct_item_ops = &f_uac1_item_ops, .ct_attrs = f_uac1_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c index 5d229e72912e..04f4b2862256 100644 --- a/drivers/usb/gadget/function/f_uac1_legacy.c +++ b/drivers/usb/gadget/function/f_uac1_legacy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_audio.c -- USB Audio class function driver * @@ -5,8 +6,6 @@ * Copyright (C) 2008 Analog Devices, Inc * * Enter bugs at http://blackfin.uclinux.org/ - * - * Licensed under the GPL-2 or later. */ #include <linux/slab.h> @@ -921,7 +920,7 @@ static struct configfs_attribute *f_uac1_attrs[] = { NULL, }; -static struct config_item_type f_uac1_func_type = { +static const struct config_item_type f_uac1_func_type = { .ct_item_ops = &f_uac1_item_ops, .ct_attrs = f_uac1_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index f05c3f3e6103..11fe788b4308 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_uac2.c -- USB Audio Class 2.0 Function * * Copyright (C) 2011 * Yadwinder Singh (yadi.brar01@gmail.com) * Jaswinder Singh (jaswinder.singh@linaro.org) - * - * 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. */ #include <linux/usb/audio.h> @@ -921,7 +917,7 @@ static struct configfs_attribute *f_uac2_attrs[] = { NULL, }; -static struct config_item_type f_uac2_func_type = { +static const struct config_item_type f_uac2_func_type = { .ct_item_ops = &f_uac2_item_ops, .ct_attrs = f_uac2_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index f8a1881609a2..439eba660e95 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * uvc_gadget.c -- USB Video Class Gadget driver * * Copyright (C) 2009-2010 * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - * - * 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. */ #include <linux/kernel.h> diff --git a/drivers/usb/gadget/function/f_uvc.h b/drivers/usb/gadget/function/f_uvc.h index d0a73bdcbba1..81defe4557fe 100644 --- a/drivers/usb/gadget/function/f_uvc.h +++ b/drivers/usb/gadget/function/f_uvc.h @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * f_uvc.h -- USB Video Class Gadget driver * * Copyright (C) 2009-2010 * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - * - * 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. */ #ifndef _F_UVC_H_ diff --git a/drivers/usb/gadget/function/g_zero.h b/drivers/usb/gadget/function/g_zero.h index 492924d0d599..98b8462ad538 100644 --- a/drivers/usb/gadget/function/g_zero.h +++ b/drivers/usb/gadget/function/g_zero.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This header declares the utility functions used by "Gadget Zero", plus * interfaces to its two single-configuration function drivers. diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index d6341045c631..51dd3e90b06c 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RNDIS MSG parser * * Authors: Benedikt Spranger, Pengutronix * Robert Schwebel, Pengutronix * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2, as published by the Free Software Foundation. - * * This software was originally developed in conformance with * Microsoft's Remote NDIS Specification License Agreement. * diff --git a/drivers/usb/gadget/function/rndis.h b/drivers/usb/gadget/function/rndis.h index 21e0430ffb98..c7e3a70ce6c1 100644 --- a/drivers/usb/gadget/function/rndis.h +++ b/drivers/usb/gadget/function/rndis.h @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RNDIS Definitions for Remote NDIS * * Authors: Benedikt Spranger, Pengutronix * Robert Schwebel, Pengutronix * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2, as published by the Free Software Foundation. - * * This software was originally developed in conformance with * Microsoft's Remote NDIS Specification License Agreement. */ diff --git a/drivers/usb/gadget/function/storage_common.c b/drivers/usb/gadget/function/storage_common.c index 8fbf6861690d..f7e6c42558eb 100644 --- a/drivers/usb/gadget/function/storage_common.c +++ b/drivers/usb/gadget/function/storage_common.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * storage_common.c -- Common definitions for mass storage functionality * * Copyright (C) 2003-2008 Alan Stern * Copyeight (C) 2009 Samsung Electronics * Author: Michal Nazarewicz (mina86@mina86.com) - * - * 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. */ /* diff --git a/drivers/usb/gadget/function/storage_common.h b/drivers/usb/gadget/function/storage_common.h index e0814a960132..e5e3a2553aaa 100644 --- a/drivers/usb/gadget/function/storage_common.h +++ b/drivers/usb/gadget/function/storage_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef USB_STORAGE_COMMON_H #define USB_STORAGE_COMMON_H diff --git a/drivers/usb/gadget/function/tcm.h b/drivers/usb/gadget/function/tcm.h index a27e6e34db0b..3cd565794ad7 100644 --- a/drivers/usb/gadget/function/tcm.h +++ b/drivers/usb/gadget/function/tcm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TARGET_USB_GADGET_H__ #define __TARGET_USB_GADGET_H__ diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 5dd73b9e5172..a72295c953bb 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * u_audio.c -- interface to USB gadget "ALSA sound card" utilities * @@ -9,16 +10,6 @@ * Copyright (C) 2011 * Yadwinder Singh (yadi.brar01@gmail.com) * Jaswinder Singh (jaswinder.singh@linaro.org) - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> @@ -79,7 +70,7 @@ struct snd_uac_chip { unsigned int p_framesize; }; -static struct snd_pcm_hardware uac_pcm_hardware = { +static const struct snd_pcm_hardware uac_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, @@ -354,7 +345,7 @@ static int uac_pcm_null(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops uac_pcm_ops = { +static const struct snd_pcm_ops uac_pcm_ops = { .open = uac_pcm_open, .close = uac_pcm_null, .ioctl = snd_pcm_lib_ioctl, diff --git a/drivers/usb/gadget/function/u_audio.h b/drivers/usb/gadget/function/u_audio.h index 07e13784cbb8..81d3d4ed6dfb 100644 --- a/drivers/usb/gadget/function/u_audio.h +++ b/drivers/usb/gadget/function/u_audio.h @@ -1,19 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * u_audio.h -- interface to USB gadget "ALSA sound card" utilities * * Copyright (C) 2016 * Author: Ruslan Bilovol <ruslan.bilovol@gmail.com> - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef __U_AUDIO_H diff --git a/drivers/usb/gadget/function/u_ecm.h b/drivers/usb/gadget/function/u_ecm.h index 262cc03cc2c0..050aa672ee7f 100644 --- a/drivers/usb/gadget/function/u_ecm.h +++ b/drivers/usb/gadget/function/u_ecm.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_ecm.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_ECM_H diff --git a/drivers/usb/gadget/function/u_eem.h b/drivers/usb/gadget/function/u_eem.h index e3ae97874c4f..de3828d3e8f0 100644 --- a/drivers/usb/gadget/function/u_eem.h +++ b/drivers/usb/gadget/function/u_eem.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_eem.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_EEM_H diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index a8b40d07e927..6fcda62f55ea 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * u_ether.c -- Ethernet-over-USB link layer utilities for Gadget stack * * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger * Copyright (C) 2008 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. */ /* #define VERBOSE_DEBUG */ @@ -1073,7 +1069,7 @@ struct net_device *gether_connect(struct gether *link) if (result == 0) { dev->zlp = link->is_zlp_ok; - dev->no_skb_reserve = link->no_skb_reserve; + dev->no_skb_reserve = gadget_avoids_skb_reserve(dev->gadget); DBG(dev, "qlen %d\n", qlen(dev->gadget, dev->qmult)); dev->header_len = link->header_len; diff --git a/drivers/usb/gadget/function/u_ether.h b/drivers/usb/gadget/function/u_ether.h index 81d94a7ae4b4..332307d54292 100644 --- a/drivers/usb/gadget/function/u_ether.h +++ b/drivers/usb/gadget/function/u_ether.h @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * u_ether.h -- interface to USB gadget "ethernet link" utilities * * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger * Copyright (C) 2008 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. */ #ifndef __U_ETHER_H @@ -64,7 +60,6 @@ struct gether { struct usb_ep *out_ep; bool is_zlp_ok; - bool no_skb_reserve; u16 cdc_filter; diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h index c71133de17e7..cd33cee4d78b 100644 --- a/drivers/usb/gadget/function/u_ether_configfs.h +++ b/drivers/usb/gadget/function/u_ether_configfs.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_ether_configfs.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __U_ETHER_CONFIGFS_H @@ -153,4 +150,39 @@ out: \ \ CONFIGFS_ATTR_RO(_f_##_opts_, ifname) +#define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \ + static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\ + char *page) \ + { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ + int ret; \ + \ + mutex_lock(&opts->lock); \ + ret = sprintf(page, "%02x\n", opts->_n_); \ + mutex_unlock(&opts->lock); \ + \ + return ret; \ + } \ + \ + static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\ + const char *page, \ + size_t len) \ + { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ + int ret; \ + u8 val; \ + \ + mutex_lock(&opts->lock); \ + ret = sscanf(page, "%02hhx", &val); \ + if (ret > 0) { \ + opts->_n_ = val; \ + ret = len; \ + } \ + mutex_unlock(&opts->lock); \ + \ + return ret; \ + } \ + \ + CONFIGFS_ATTR(_f_##_opts_, _n_) + #endif /* __U_ETHER_CONFIGFS_H */ diff --git a/drivers/usb/gadget/function/u_fs.h b/drivers/usb/gadget/function/u_fs.h index 540f1c48c1a8..c3aba4dfa958 100644 --- a/drivers/usb/gadget/function/u_fs.h +++ b/drivers/usb/gadget/function/u_fs.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_fs.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_FFS_H @@ -279,6 +276,7 @@ struct ffs_data { } file_perms; struct eventfd_ctx *ffs_eventfd; + struct workqueue_struct *io_completion_wq; bool no_disconnect; struct work_struct reset_work; diff --git a/drivers/usb/gadget/function/u_gether.h b/drivers/usb/gadget/function/u_gether.h index d4078426ba5d..5b7e2eb90336 100644 --- a/drivers/usb/gadget/function/u_gether.h +++ b/drivers/usb/gadget/function/u_gether.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_gether.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_GETHER_H diff --git a/drivers/usb/gadget/function/u_hid.h b/drivers/usb/gadget/function/u_hid.h index aaa0e368a159..2f5ca4bfa7ff 100644 --- a/drivers/usb/gadget/function/u_hid.h +++ b/drivers/usb/gadget/function/u_hid.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_hid.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_HID_H diff --git a/drivers/usb/gadget/function/u_midi.h b/drivers/usb/gadget/function/u_midi.h index 22510189758e..5599aa5fc977 100644 --- a/drivers/usb/gadget/function/u_midi.h +++ b/drivers/usb/gadget/function/u_midi.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_midi.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_MIDI_H diff --git a/drivers/usb/gadget/function/u_ncm.h b/drivers/usb/gadget/function/u_ncm.h index ce0f3a78ca13..67324f983343 100644 --- a/drivers/usb/gadget/function/u_ncm.h +++ b/drivers/usb/gadget/function/u_ncm.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_ncm.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_NCM_H diff --git a/drivers/usb/gadget/function/u_phonet.h b/drivers/usb/gadget/function/u_phonet.h index 98ced18779ea..12fb613f85d1 100644 --- a/drivers/usb/gadget/function/u_phonet.h +++ b/drivers/usb/gadget/function/u_phonet.h @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * u_phonet.h - interface to Phonet * * Copyright (C) 2007-2008 by Nokia Corporation - * - * This software is distributed under the terms of the GNU General - * Public License ("GPL") as published by the Free Software Foundation, - * either version 2 of that License or (at your option) any later version. */ #ifndef __U_PHONET_H diff --git a/drivers/usb/gadget/function/u_printer.h b/drivers/usb/gadget/function/u_printer.h index 8d30b7577f87..6088ff744194 100644 --- a/drivers/usb/gadget/function/u_printer.h +++ b/drivers/usb/gadget/function/u_printer.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_printer.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_PRINTER_H diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h index 4eafd5050545..d65fb4ebac3c 100644 --- a/drivers/usb/gadget/function/u_rndis.h +++ b/drivers/usb/gadget/function/u_rndis.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_rndis.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_RNDIS_H @@ -26,9 +23,14 @@ struct f_rndis_opts { bool bound; bool borrowed_net; + struct config_group *rndis_interf_group; struct usb_os_desc rndis_os_desc; char rndis_ext_compat_id[16]; + u8 class; + u8 subclass; + u8 protocol; + /* * Read/write access to configfs attributes is handled by configfs. * diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 9b0805f55ad7..4d653d2960d4 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * u_serial.c - utilities for USB gadget "serial port"/TTY support * @@ -9,10 +10,6 @@ * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2000 Peter Berger (pberger@brimson.com) * Copyright (C) 2000 Al Borchers (alborchers@steinerpoint.com) - * - * This software is distributed under the terms of the GNU General - * Public License ("GPL") as published by the Free Software Foundation, - * either version 2 of that License or (at your option) any later version. */ /* #define VERBOSE_DEBUG */ @@ -537,7 +534,7 @@ static void gs_rx_push(unsigned long _port) } /* push data to (open) tty */ - if (req->actual) { + if (req->actual && tty) { char *packet = req->buf; unsigned size = req->actual; unsigned n; @@ -1078,6 +1075,7 @@ static void gs_complete_out(struct usb_ep *ep, struct usb_request *req) default: pr_warn("%s: unexpected %s status %d\n", __func__, ep->name, req->status); + /* fall through */ case 0: /* normal completion */ spin_lock(&info->con_lock); diff --git a/drivers/usb/gadget/function/u_serial.h b/drivers/usb/gadget/function/u_serial.h index c20210c0babd..9acaac1cbb75 100644 --- a/drivers/usb/gadget/function/u_serial.h +++ b/drivers/usb/gadget/function/u_serial.h @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * u_serial.h - interface to USB gadget "serial port"/TTY utilities * * Copyright (C) 2008 David Brownell * Copyright (C) 2008 by Nokia Corporation - * - * This software is distributed under the terms of the GNU General - * Public License ("GPL") as published by the Free Software Foundation, - * either version 2 of that License or (at your option) any later version. */ #ifndef __U_SERIAL_H diff --git a/drivers/usb/gadget/function/u_tcm.h b/drivers/usb/gadget/function/u_tcm.h index 0bd751e0483f..3f7ccecb0f9b 100644 --- a/drivers/usb/gadget/function/u_tcm.h +++ b/drivers/usb/gadget/function/u_tcm.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_tcm.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_TCM_H diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index 6f188fd8633f..6f1a9d73defe 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_uac1.h - Utility definitions for UAC1 function * * Copyright (C) 2016 Ruslan Bilovol <ruslan.bilovol@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __U_UAC1_H diff --git a/drivers/usb/gadget/function/u_uac1_legacy.c b/drivers/usb/gadget/function/u_uac1_legacy.c index fa4684a1c54c..cbc868d117af 100644 --- a/drivers/usb/gadget/function/u_uac1_legacy.c +++ b/drivers/usb/gadget/function/u_uac1_legacy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * u_uac1.c -- ALSA audio utilities for Gadget stack * @@ -5,8 +6,6 @@ * Copyright (C) 2008 Analog Devices, Inc * * Enter bugs at http://blackfin.uclinux.org/ - * - * Licensed under the GPL-2 or later. */ #include <linux/kernel.h> diff --git a/drivers/usb/gadget/function/u_uac1_legacy.h b/drivers/usb/gadget/function/u_uac1_legacy.h index d715b1af56a4..dd69e408a3d9 100644 --- a/drivers/usb/gadget/function/u_uac1_legacy.h +++ b/drivers/usb/gadget/function/u_uac1_legacy.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * u_uac1.h -- interface to USB gadget "ALSA AUDIO" utilities * @@ -5,8 +6,6 @@ * Copyright (C) 2008 Analog Devices, Inc * * Enter bugs at http://blackfin.uclinux.org/ - * - * Licensed under the GPL-2 or later. */ #ifndef __U_UAC1_LEGACY_H diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h index 19eeb83538a5..8362ee572e1e 100644 --- a/drivers/usb/gadget/function/u_uac2.h +++ b/drivers/usb/gadget/function/u_uac2.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_uac2.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_UAC2_H diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h index 4676b60a5063..d00d3ded71c0 100644 --- a/drivers/usb/gadget/function/u_uvc.h +++ b/drivers/usb/gadget/function/u_uvc.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_uvc.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef U_UVC_H diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 11d70dead32b..a64e07e61f8c 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * uvc_gadget.h -- USB Video Class Gadget driver * * Copyright (C) 2009-2010 * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - * - * 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. */ #ifndef _UVC_GADGET_H_ diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index 844cb738bafd..c9b8cc4aae5a 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * uvc_configfs.c * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include "u_uvc.h" #include "uvc_configfs.h" @@ -127,7 +124,7 @@ static struct configfs_attribute *uvcg_control_header_attrs[] = { NULL, }; -static struct config_item_type uvcg_control_header_type = { +static const struct config_item_type uvcg_control_header_type = { .ct_attrs = uvcg_control_header_attrs, .ct_owner = THIS_MODULE, }; @@ -170,7 +167,7 @@ static struct configfs_group_operations uvcg_control_header_grp_ops = { .drop_item = uvcg_control_header_drop, }; -static struct config_item_type uvcg_control_header_grp_type = { +static const struct config_item_type uvcg_control_header_grp_type = { .ct_group_ops = &uvcg_control_header_grp_ops, .ct_owner = THIS_MODULE, }; @@ -265,7 +262,7 @@ static struct configfs_attribute *uvcg_default_processing_attrs[] = { NULL, }; -static struct config_item_type uvcg_default_processing_type = { +static const struct config_item_type uvcg_default_processing_type = { .ct_attrs = uvcg_default_processing_attrs, .ct_owner = THIS_MODULE, }; @@ -277,7 +274,7 @@ static struct uvcg_processing_grp { struct config_group group; } uvcg_processing_grp; -static struct config_item_type uvcg_processing_grp_type = { +static const struct config_item_type uvcg_processing_grp_type = { .ct_owner = THIS_MODULE, }; @@ -382,7 +379,7 @@ static struct configfs_attribute *uvcg_default_camera_attrs[] = { NULL, }; -static struct config_item_type uvcg_default_camera_type = { +static const struct config_item_type uvcg_default_camera_type = { .ct_attrs = uvcg_default_camera_attrs, .ct_owner = THIS_MODULE, }; @@ -394,7 +391,7 @@ static struct uvcg_camera_grp { struct config_group group; } uvcg_camera_grp; -static struct config_item_type uvcg_camera_grp_type = { +static const struct config_item_type uvcg_camera_grp_type = { .ct_owner = THIS_MODULE, }; @@ -460,7 +457,7 @@ static struct configfs_attribute *uvcg_default_output_attrs[] = { NULL, }; -static struct config_item_type uvcg_default_output_type = { +static const struct config_item_type uvcg_default_output_type = { .ct_attrs = uvcg_default_output_attrs, .ct_owner = THIS_MODULE, }; @@ -472,7 +469,7 @@ static struct uvcg_output_grp { struct config_group group; } uvcg_output_grp; -static struct config_item_type uvcg_output_grp_type = { +static const struct config_item_type uvcg_output_grp_type = { .ct_owner = THIS_MODULE, }; @@ -481,7 +478,7 @@ static struct uvcg_terminal_grp { struct config_group group; } uvcg_terminal_grp; -static struct config_item_type uvcg_terminal_grp_type = { +static const struct config_item_type uvcg_terminal_grp_type = { .ct_owner = THIS_MODULE, }; @@ -586,7 +583,7 @@ static struct configfs_item_operations uvcg_control_class_item_ops = { .drop_link = uvcg_control_class_drop_link, }; -static struct config_item_type uvcg_control_class_type = { +static const struct config_item_type uvcg_control_class_type = { .ct_item_ops = &uvcg_control_class_item_ops, .ct_owner = THIS_MODULE, }; @@ -596,7 +593,7 @@ static struct uvcg_control_class_grp { struct config_group group; } uvcg_control_class_grp; -static struct config_item_type uvcg_control_class_grp_type = { +static const struct config_item_type uvcg_control_class_grp_type = { .ct_owner = THIS_MODULE, }; @@ -605,7 +602,7 @@ static struct uvcg_control_grp { struct config_group group; } uvcg_control_grp; -static struct config_item_type uvcg_control_grp_type = { +static const struct config_item_type uvcg_control_grp_type = { .ct_owner = THIS_MODULE, }; @@ -857,7 +854,7 @@ static struct configfs_attribute *uvcg_streaming_header_attrs[] = { NULL, }; -static struct config_item_type uvcg_streaming_header_type = { +static const struct config_item_type uvcg_streaming_header_type = { .ct_item_ops = &uvcg_streaming_header_item_ops, .ct_attrs = uvcg_streaming_header_attrs, .ct_owner = THIS_MODULE, @@ -901,7 +898,7 @@ static struct configfs_group_operations uvcg_streaming_header_grp_ops = { .drop_item = uvcg_streaming_header_drop, }; -static struct config_item_type uvcg_streaming_header_grp_type = { +static const struct config_item_type uvcg_streaming_header_grp_type = { .ct_group_ops = &uvcg_streaming_header_grp_ops, .ct_owner = THIS_MODULE, }; @@ -1150,7 +1147,7 @@ static struct configfs_attribute *uvcg_frame_attrs[] = { NULL, }; -static struct config_item_type uvcg_frame_type = { +static const struct config_item_type uvcg_frame_type = { .ct_attrs = uvcg_frame_attrs, .ct_owner = THIS_MODULE, }; @@ -1419,7 +1416,7 @@ static struct configfs_attribute *uvcg_uncompressed_attrs[] = { NULL, }; -static struct config_item_type uvcg_uncompressed_type = { +static const struct config_item_type uvcg_uncompressed_type = { .ct_group_ops = &uvcg_uncompressed_group_ops, .ct_attrs = uvcg_uncompressed_attrs, .ct_owner = THIS_MODULE, @@ -1469,7 +1466,7 @@ static struct configfs_group_operations uvcg_uncompressed_grp_ops = { .drop_item = uvcg_uncompressed_drop, }; -static struct config_item_type uvcg_uncompressed_grp_type = { +static const struct config_item_type uvcg_uncompressed_grp_type = { .ct_group_ops = &uvcg_uncompressed_grp_ops, .ct_owner = THIS_MODULE, }; @@ -1619,7 +1616,7 @@ static struct configfs_attribute *uvcg_mjpeg_attrs[] = { NULL, }; -static struct config_item_type uvcg_mjpeg_type = { +static const struct config_item_type uvcg_mjpeg_type = { .ct_group_ops = &uvcg_mjpeg_group_ops, .ct_attrs = uvcg_mjpeg_attrs, .ct_owner = THIS_MODULE, @@ -1663,7 +1660,7 @@ static struct configfs_group_operations uvcg_mjpeg_grp_ops = { .drop_item = uvcg_mjpeg_drop, }; -static struct config_item_type uvcg_mjpeg_grp_type = { +static const struct config_item_type uvcg_mjpeg_grp_type = { .ct_group_ops = &uvcg_mjpeg_grp_ops, .ct_owner = THIS_MODULE, }; @@ -1728,7 +1725,7 @@ static struct configfs_attribute *uvcg_default_color_matching_attrs[] = { NULL, }; -static struct config_item_type uvcg_default_color_matching_type = { +static const struct config_item_type uvcg_default_color_matching_type = { .ct_attrs = uvcg_default_color_matching_attrs, .ct_owner = THIS_MODULE, }; @@ -1740,7 +1737,7 @@ static struct uvcg_color_matching_grp { struct config_group group; } uvcg_color_matching_grp; -static struct config_item_type uvcg_color_matching_grp_type = { +static const struct config_item_type uvcg_color_matching_grp_type = { .ct_owner = THIS_MODULE, }; @@ -2085,7 +2082,7 @@ static struct configfs_item_operations uvcg_streaming_class_item_ops = { .drop_link = uvcg_streaming_class_drop_link, }; -static struct config_item_type uvcg_streaming_class_type = { +static const struct config_item_type uvcg_streaming_class_type = { .ct_item_ops = &uvcg_streaming_class_item_ops, .ct_owner = THIS_MODULE, }; @@ -2095,7 +2092,7 @@ static struct uvcg_streaming_class_grp { struct config_group group; } uvcg_streaming_class_grp; -static struct config_item_type uvcg_streaming_class_grp_type = { +static const struct config_item_type uvcg_streaming_class_grp_type = { .ct_owner = THIS_MODULE, }; @@ -2104,7 +2101,7 @@ static struct uvcg_streaming_grp { struct config_group group; } uvcg_streaming_grp; -static struct config_item_type uvcg_streaming_grp_type = { +static const struct config_item_type uvcg_streaming_grp_type = { .ct_owner = THIS_MODULE, }; @@ -2190,7 +2187,7 @@ static struct configfs_attribute *uvc_attrs[] = { NULL, }; -static struct config_item_type uvc_func_type = { +static const struct config_item_type uvc_func_type = { .ct_item_ops = &uvc_item_ops, .ct_attrs = uvc_attrs, .ct_owner = THIS_MODULE, diff --git a/drivers/usb/gadget/function/uvc_configfs.h b/drivers/usb/gadget/function/uvc_configfs.h index 085e67be7c71..8549c0b27b9d 100644 --- a/drivers/usb/gadget/function/uvc_configfs.h +++ b/drivers/usb/gadget/function/uvc_configfs.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * uvc_configfs.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef UVC_CONFIGFS_H #define UVC_CONFIGFS_H diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 6377e9fee6e5..278d50ff1eea 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * uvc_queue.c -- USB Video Class driver - Buffers management * * Copyright (C) 2005-2010 * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - * - * 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. */ #include <linux/atomic.h> diff --git a/drivers/usb/gadget/function/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h index ac461a9a1a70..51ee94e5cf2b 100644 --- a/drivers/usb/gadget/function/uvc_queue.h +++ b/drivers/usb/gadget/function/uvc_queue.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _UVC_QUEUE_H_ #define _UVC_QUEUE_H_ diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index 3e22b45687d3..f3069db6f08e 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * uvc_v4l2.c -- USB Video Class Gadget driver * * Copyright (C) 2009-2010 * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - * - * 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. */ #include <linux/kernel.h> @@ -354,7 +350,7 @@ static unsigned long uvcg_v4l2_get_unmapped_area(struct file *file, } #endif -struct v4l2_file_operations uvc_v4l2_fops = { +const struct v4l2_file_operations uvc_v4l2_fops = { .owner = THIS_MODULE, .open = uvc_v4l2_open, .release = uvc_v4l2_release, diff --git a/drivers/usb/gadget/function/uvc_v4l2.h b/drivers/usb/gadget/function/uvc_v4l2.h index 2683b92fda65..a75e9c397446 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.h +++ b/drivers/usb/gadget/function/uvc_v4l2.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * uvc_v4l2.h -- USB Video Class Gadget driver * @@ -7,16 +8,12 @@ * Copyright (c) 2013 Samsung Electronics Co., Ltd. * http://www.samsung.com * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __UVC_V4L2_H__ #define __UVC_V4L2_H__ extern const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops; -extern struct v4l2_file_operations uvc_v4l2_fops; +extern const struct v4l2_file_operations uvc_v4l2_fops; #endif /* __UVC_V4L2_H__ */ diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 0f01c04d7cbd..d3567b90343a 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * uvc_video.c -- USB Video Class Gadget driver * * Copyright (C) 2009-2010 * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - * - * 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. */ #include <linux/kernel.h> diff --git a/drivers/usb/gadget/function/uvc_video.h b/drivers/usb/gadget/function/uvc_video.h index ef00f06fa00b..6c20aa75f966 100644 --- a/drivers/usb/gadget/function/uvc_video.h +++ b/drivers/usb/gadget/function/uvc_video.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * uvc_video.h -- USB Video Class Gadget driver * @@ -7,10 +8,6 @@ * Copyright (c) 2013 Samsung Electronics Co., Ltd. * http://www.samsung.com * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __UVC_VIDEO_H__ #define __UVC_VIDEO_H__ diff --git a/drivers/usb/gadget/functions.c b/drivers/usb/gadget/functions.c index b13f839e7368..203361a64212 100644 --- a/drivers/usb/gadget/functions.c +++ b/drivers/usb/gadget/functions.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index a12fb459dbd9..784bf86dad4f 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig @@ -479,7 +479,7 @@ endif # or video class gadget drivers), or specific hardware, here. config USB_G_WEBCAM tristate "USB Webcam Gadget" - depends on VIDEO_DEV + depends on VIDEO_V4L2 select USB_LIBCOMPOSITE select VIDEOBUF2_VMALLOC select USB_F_UVC diff --git a/drivers/usb/gadget/legacy/Makefile b/drivers/usb/gadget/legacy/Makefile index 7f485f25705e..abd0c3e66a05 100644 --- a/drivers/usb/gadget/legacy/Makefile +++ b/drivers/usb/gadget/legacy/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB gadget drivers # diff --git a/drivers/usb/gadget/legacy/acm_ms.c b/drivers/usb/gadget/legacy/acm_ms.c index c39de65a448b..af16672d5118 100644 --- a/drivers/usb/gadget/legacy/acm_ms.c +++ b/drivers/usb/gadget/legacy/acm_ms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * acm_ms.c -- Composite driver, with ACM and mass storage support * @@ -7,11 +8,6 @@ * Modified: Klaus Schwarzkopf <schwarzkopf@sensortherm.de> * * Heavily based on multi.c and cdc2.c - * - * 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. */ #include <linux/kernel.h> diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index 1f5cdbe162df..7b11dce98b94 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * audio.c -- Audio gadget driver * @@ -5,8 +6,6 @@ * Copyright (C) 2008 Analog Devices, Inc * * Enter bugs at http://blackfin.uclinux.org/ - * - * Licensed under the GPL-2 or later. */ /* #define VERBOSE_DEBUG */ diff --git a/drivers/usb/gadget/legacy/cdc2.c b/drivers/usb/gadget/legacy/cdc2.c index 51c08682de84..da1c37933ca1 100644 --- a/drivers/usb/gadget/legacy/cdc2.c +++ b/drivers/usb/gadget/legacy/cdc2.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * cdc2.c -- CDC Composite driver, with ECM and ACM support * * Copyright (C) 2008 David Brownell * Copyright (C) 2008 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. */ #include <linux/kernel.h> diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 99ca3dabc4f3..e1d566c9918a 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dbgp.c -- EHCI Debug Port device gadget * diff --git a/drivers/usb/gadget/legacy/ether.c b/drivers/usb/gadget/legacy/ether.c index 25a2c2e48592..30313b233680 100644 --- a/drivers/usb/gadget/legacy/ether.c +++ b/drivers/usb/gadget/legacy/ether.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ether.c -- Ethernet gadget driver, with CDC and non-CDC options * * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger * Copyright (C) 2008 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. */ /* #define VERBOSE_DEBUG */ diff --git a/drivers/usb/gadget/legacy/g_ffs.c b/drivers/usb/gadget/legacy/g_ffs.c index 6da7316f8e87..b640ed3fcf70 100644 --- a/drivers/usb/gadget/legacy/g_ffs.c +++ b/drivers/usb/gadget/legacy/g_ffs.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * g_ffs.c -- user mode file system API for USB composite function controllers * * Copyright (C) 2010 Samsung Electronics * Author: Michal Nazarewicz <mina86@mina86.com> - * - * 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. */ #define pr_fmt(fmt) "g_ffs: " fmt diff --git a/drivers/usb/gadget/legacy/gmidi.c b/drivers/usb/gadget/legacy/gmidi.c index 0bf39c3ccdb1..9eea2d18f2bf 100644 --- a/drivers/usb/gadget/legacy/gmidi.c +++ b/drivers/usb/gadget/legacy/gmidi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * gmidi.c -- USB MIDI Gadget Driver * @@ -5,9 +6,6 @@ * Developed for Thumtronics by Grey Innovation * Ben Williamson <ben.williamson@greyinnovation.com> * - * This software is distributed under the terms of the GNU General Public - * License ("GPL") version 2, as published by the Free Software Foundation. - * * This code is based in part on: * * Gadget Zero driver, Copyright (C) 2003-2004 David Brownell. diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index a71a884f79fc..c4eda7fe7ab4 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * hid.c -- HID Composite driver * * Based on multi.c * * Copyright (C) 2010 Fabien Chouteau <fabien.chouteau@barco.com> - * - * 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. */ diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 684900fcfe24..9343ec436485 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * inode.c -- user mode filesystem api for usb gadget controllers * * Copyright (C) 2003-2004 David Brownell * Copyright (C) 2003 Agilent Technologies - * - * 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. */ @@ -28,7 +24,7 @@ #include <linux/aio.h> #include <linux/uio.h> #include <linux/refcount.h> - +#include <linux/delay.h> #include <linux/device.h> #include <linux/moduleparam.h> @@ -116,6 +112,7 @@ enum ep0_state { struct dev_data { spinlock_t lock; refcount_t count; + int udc_usage; enum ep0_state state; /* P: lock */ struct usb_gadgetfs_event event [N_EVENT]; unsigned ev_next; @@ -513,9 +510,9 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) INIT_WORK(&priv->work, ep_user_copy_worker); schedule_work(&priv->work); } - spin_unlock(&epdata->dev->lock); usb_ep_free_request(ep, req); + spin_unlock(&epdata->dev->lock); put_ep(epdata); } @@ -939,9 +936,11 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) struct usb_request *req = dev->req; if ((retval = setup_req (ep, req, 0)) == 0) { + ++dev->udc_usage; spin_unlock_irq (&dev->lock); retval = usb_ep_queue (ep, req, GFP_KERNEL); spin_lock_irq (&dev->lock); + --dev->udc_usage; } dev->state = STATE_DEV_CONNECTED; @@ -983,11 +982,14 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) retval = -EIO; else { len = min (len, (size_t)dev->req->actual); -// FIXME don't call this with the spinlock held ... + ++dev->udc_usage; + spin_unlock_irq(&dev->lock); if (copy_to_user (buf, dev->req->buf, len)) retval = -EFAULT; else retval = len; + spin_lock_irq(&dev->lock); + --dev->udc_usage; clean_req (dev->gadget->ep0, dev->req); /* NOTE userspace can't yet choose to stall */ } @@ -1131,6 +1133,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) retval = setup_req (dev->gadget->ep0, dev->req, len); if (retval == 0) { dev->state = STATE_DEV_CONNECTED; + ++dev->udc_usage; spin_unlock_irq (&dev->lock); if (copy_from_user (dev->req->buf, buf, len)) retval = -EFAULT; @@ -1142,6 +1145,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) GFP_KERNEL); } spin_lock_irq(&dev->lock); + --dev->udc_usage; if (retval < 0) { clean_req (dev->gadget->ep0, dev->req); } else @@ -1243,9 +1247,21 @@ static long dev_ioctl (struct file *fd, unsigned code, unsigned long value) struct usb_gadget *gadget = dev->gadget; long ret = -ENOTTY; - if (gadget->ops->ioctl) + spin_lock_irq(&dev->lock); + if (dev->state == STATE_DEV_OPENED || + dev->state == STATE_DEV_UNBOUND) { + /* Not bound to a UDC */ + } else if (gadget->ops->ioctl) { + ++dev->udc_usage; + spin_unlock_irq(&dev->lock); + ret = gadget->ops->ioctl (gadget, code, value); + spin_lock_irq(&dev->lock); + --dev->udc_usage; + } + spin_unlock_irq(&dev->lock); + return ret; } @@ -1463,10 +1479,12 @@ delegate: if (value < 0) break; + ++dev->udc_usage; spin_unlock (&dev->lock); value = usb_ep_queue (gadget->ep0, dev->req, GFP_KERNEL); spin_lock (&dev->lock); + --dev->udc_usage; if (value < 0) { clean_req (gadget->ep0, dev->req); break; @@ -1490,8 +1508,12 @@ delegate: req->length = value; req->zero = value < w_length; + ++dev->udc_usage; spin_unlock (&dev->lock); value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL); + spin_lock(&dev->lock); + --dev->udc_usage; + spin_unlock(&dev->lock); if (value < 0) { DBG (dev, "ep_queue --> %d\n", value); req->status = 0; @@ -1518,21 +1540,24 @@ static void destroy_ep_files (struct dev_data *dev) /* break link to FS */ ep = list_first_entry (&dev->epfiles, struct ep_data, epfiles); list_del_init (&ep->epfiles); + spin_unlock_irq (&dev->lock); + dentry = ep->dentry; ep->dentry = NULL; parent = d_inode(dentry->d_parent); /* break link to controller */ + mutex_lock(&ep->lock); if (ep->state == STATE_EP_ENABLED) (void) usb_ep_disable (ep->ep); ep->state = STATE_EP_UNBOUND; usb_ep_free_request (ep->ep, ep->req); ep->ep = NULL; + mutex_unlock(&ep->lock); + wake_up (&ep->wait); put_ep (ep); - spin_unlock_irq (&dev->lock); - /* break link to dcache */ inode_lock(parent); d_delete (dentry); @@ -1603,6 +1628,11 @@ gadgetfs_unbind (struct usb_gadget *gadget) spin_lock_irq (&dev->lock); dev->state = STATE_DEV_UNBOUND; + while (dev->udc_usage > 0) { + spin_unlock_irq(&dev->lock); + usleep_range(1000, 2000); + spin_lock_irq(&dev->lock); + } spin_unlock_irq (&dev->lock); destroy_ep_files (dev); diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c index e99ab57ee3e5..ef3d25259b0e 100644 --- a/drivers/usb/gadget/legacy/mass_storage.c +++ b/drivers/usb/gadget/legacy/mass_storage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * mass_storage.c -- Mass Storage USB Gadget * @@ -5,11 +6,6 @@ * Copyright (C) 2009 Samsung Electronics * Author: Michal Nazarewicz <mina86@mina86.com> * All rights reserved. - * - * 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. */ @@ -107,15 +103,6 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); -static unsigned long msg_registered; -static void msg_cleanup(void); - -static int msg_thread_exits(struct fsg_common *common) -{ - msg_cleanup(); - return 0; -} - static int msg_do_config(struct usb_configuration *c) { struct fsg_opts *opts; @@ -154,9 +141,6 @@ static struct usb_configuration msg_config_driver = { static int msg_bind(struct usb_composite_dev *cdev) { - static const struct fsg_operations ops = { - .thread_exits = msg_thread_exits, - }; struct fsg_opts *opts; struct fsg_config config; int status; @@ -173,8 +157,6 @@ static int msg_bind(struct usb_composite_dev *cdev) if (status) goto fail; - fsg_common_set_ops(opts->common, &ops); - status = fsg_common_set_cdev(opts->common, cdev, config.can_stall); if (status) goto fail_set_cdev; @@ -256,18 +238,12 @@ MODULE_LICENSE("GPL"); static int __init msg_init(void) { - int ret; - - ret = usb_composite_probe(&msg_driver); - set_bit(0, &msg_registered); - - return ret; + return usb_composite_probe(&msg_driver); } module_init(msg_init); -static void msg_cleanup(void) +static void __exit msg_cleanup(void) { - if (test_and_clear_bit(0, &msg_registered)) - usb_composite_unregister(&msg_driver); + usb_composite_unregister(&msg_driver); } module_exit(msg_cleanup); diff --git a/drivers/usb/gadget/legacy/multi.c b/drivers/usb/gadget/legacy/multi.c index a70a406580ea..50515f9e1022 100644 --- a/drivers/usb/gadget/legacy/multi.c +++ b/drivers/usb/gadget/legacy/multi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * multi.c -- Multifunction Composite driver * @@ -5,11 +6,6 @@ * Copyright (C) 2008 Nokia Corporation * Copyright (C) 2009 Samsung Electronics * Author: Michal Nazarewicz (mina86@mina86.com) - * - * 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. */ diff --git a/drivers/usb/gadget/legacy/ncm.c b/drivers/usb/gadget/legacy/ncm.c index 0aba68253e3d..fcee1ee0bf66 100644 --- a/drivers/usb/gadget/legacy/ncm.c +++ b/drivers/usb/gadget/legacy/ncm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ncm.c -- NCM gadget driver * @@ -9,11 +10,6 @@ * Copyright (C) 2003-2005,2008 David Brownell * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger * Copyright (C) 2008 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. */ /* #define DEBUG */ diff --git a/drivers/usb/gadget/legacy/nokia.c b/drivers/usb/gadget/legacy/nokia.c index b1e535f4022e..978c1a34a932 100644 --- a/drivers/usb/gadget/legacy/nokia.c +++ b/drivers/usb/gadget/legacy/nokia.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * nokia.c -- Nokia Composite Gadget Driver * @@ -9,10 +10,6 @@ * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) * Copyright (C) 2008 by David Brownell * Copyright (C) 2008 by Nokia Corporation - * - * This software is distributed under the terms of the GNU General - * Public License ("GPL") as published by the Free Software Foundation, - * version 2 of that License. */ #include <linux/kernel.h> diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 4c9cfff34a03..57858f0c2b6c 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * printer.c -- Printer gadget driver * * Copyright (C) 2003-2005 David Brownell * Copyright (C) 2006 Craig W. Nadler - * - * 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. */ #include <linux/module.h> diff --git a/drivers/usb/gadget/legacy/serial.c b/drivers/usb/gadget/legacy/serial.c index 9d89adce756d..de30d7628eef 100644 --- a/drivers/usb/gadget/legacy/serial.c +++ b/drivers/usb/gadget/legacy/serial.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * serial.c -- USB gadget serial driver * * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) * Copyright (C) 2008 by David Brownell * Copyright (C) 2008 by Nokia Corporation - * - * This software is distributed under the terms of the GNU General - * Public License ("GPL") as published by the Free Software Foundation, - * either version 2 of that License or (at your option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 0b0bb98319cd..682bf99dcf76 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -1,10 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* Target based USB-Gadget * * UAS protocol handling, target callbacks, configfs handling, * BBB (USB Mass Storage Class Bulk-Only (BBB) and Transport protocol handling. * * Author: Sebastian Andrzej Siewior <bigeasy at linutronix dot de> - * License: GPLv2 as published by FSF. */ #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c index f9661cd627c8..6b86568c9157 100644 --- a/drivers/usb/gadget/legacy/webcam.c +++ b/drivers/usb/gadget/legacy/webcam.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * webcam.c -- USB webcam gadget driver * * Copyright (C) 2009-2010 * Laurent Pinchart (laurent.pinchart@ideasonboard.com) - * - * 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. */ #include <linux/kernel.h> @@ -436,5 +432,4 @@ module_usb_composite_driver(webcam_driver); MODULE_AUTHOR("Laurent Pinchart"); MODULE_DESCRIPTION("Webcam Video Gadget"); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1.0"); diff --git a/drivers/usb/gadget/legacy/zero.c b/drivers/usb/gadget/legacy/zero.c index d02e2ce73ea5..6e84b44c8a3b 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. */ /* @@ -154,10 +150,11 @@ static struct usb_gadget_strings *dev_strings[] = { /*-------------------------------------------------------------------------*/ 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; /* unconfigured devices can't issue wakeups */ @@ -282,7 +279,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)) diff --git a/drivers/usb/gadget/u_f.c b/drivers/usb/gadget/u_f.c index 18839732c840..dbaa46eee853 100644 --- a/drivers/usb/gadget/u_f.c +++ b/drivers/usb/gadget/u_f.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_f.c -- USB function utilities for Gadget stack * @@ -5,10 +6,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include "u_f.h" diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h index 7d53a4773d1a..c3fbef2bb5db 100644 --- a/drivers/usb/gadget/u_f.h +++ b/drivers/usb/gadget/u_f.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_f.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __U_F_H__ diff --git a/drivers/usb/gadget/u_os_desc.h b/drivers/usb/gadget/u_os_desc.h index 947b7ddff691..8acd21779ac8 100644 --- a/drivers/usb/gadget/u_os_desc.h +++ b/drivers/usb/gadget/u_os_desc.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * u_os_desc.h * @@ -7,10 +8,6 @@ * http://www.samsung.com * * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __U_OS_DESC_H__ diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 7cd5c969fcbe..1e9567091d86 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -273,6 +273,7 @@ config USB_SNP_CORE config USB_SNP_UDC_PLAT tristate "Synopsys USB 2.0 Device controller" depends on USB_GADGET && OF && HAS_DMA + depends on EXTCON || EXTCON=n select USB_GADGET_DUALSPEED select USB_SNP_CORE default ARCH_BCM_IPROC diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile index ea9e1c7f1923..ce865b129fd6 100644 --- a/drivers/usb/gadget/udc/Makefile +++ b/drivers/usb/gadget/udc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # define_trace.h needs to know how to find our header CFLAGS_trace.o := -I$(src) diff --git a/drivers/usb/gadget/udc/amd5536udc.h b/drivers/usb/gadget/udc/amd5536udc.h index 4fe22d432af2..dfdef6a28904 100644 --- a/drivers/usb/gadget/udc/amd5536udc.h +++ b/drivers/usb/gadget/udc/amd5536udc.h @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * amd5536.h -- header for AMD 5536 UDC high/full speed USB device controller * * Copyright (C) 2007 AMD (http://www.amd.com) * Author: Thomas Dahlmann - * - * 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. */ #ifndef AMD5536UDC_H diff --git a/drivers/usb/gadget/udc/amd5536udc_pci.c b/drivers/usb/gadget/udc/amd5536udc_pci.c index 57a13f080a79..57b6f66331cf 100644 --- a/drivers/usb/gadget/udc/amd5536udc_pci.c +++ b/drivers/usb/gadget/udc/amd5536udc_pci.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * amd5536udc_pci.c -- AMD 5536 UDC high/full speed USB device controller * * Copyright (C) 2005-2007 AMD (http://www.amd.com) * Author: Thomas Dahlmann - * - * 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. */ /* diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 8bc78418d40e..ad743a8493be 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * at91_udc -- driver for at91-series USB peripheral controller * * Copyright (C) 2004 by Thomas Rathbone * Copyright (C) 2005 by HP Labs * Copyright (C) 2005 by David Brownell - * - * 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. */ #undef VERBOSE_DEBUG @@ -1554,9 +1550,9 @@ static void at91_vbus_timer_work(struct work_struct *work) mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT); } -static void at91_vbus_timer(unsigned long data) +static void at91_vbus_timer(struct timer_list *t) { - struct at91_udc *udc = (struct at91_udc *)data; + struct at91_udc *udc = from_timer(udc, t, vbus_timer); /* * If we are polling vbus it is likely that the gpio is on an @@ -1922,8 +1918,7 @@ static int at91udc_probe(struct platform_device *pdev) if (udc->board.vbus_polled) { INIT_WORK(&udc->vbus_timer_work, at91_vbus_timer_work); - setup_timer(&udc->vbus_timer, at91_vbus_timer, - (unsigned long)udc); + timer_setup(&udc->vbus_timer, at91_vbus_timer, 0); mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT); } else { diff --git a/drivers/usb/gadget/udc/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h index 9bbe72764f31..fd58c5b81826 100644 --- a/drivers/usb/gadget/udc/at91_udc.h +++ b/drivers/usb/gadget/udc/at91_udc.h @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2004 by Thomas Rathbone, HP Labs * Copyright (C) 2005 by Ivan Kokshaysky * Copyright (C) 2006 by SAN People - * - * 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. */ #ifndef AT91_UDC_H diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 98d71400f8a1..075eaaa8a408 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for the Atmel USBA high speed USB device controller * * Copyright (C) 2005-2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/clk.h> #include <linux/clk/at91_pmc.h> @@ -29,6 +26,8 @@ #include <linux/of_gpio.h> #include "atmel_usba_udc.h" +#define USBA_VBUS_IRQFLAGS (IRQF_ONESHOT \ + | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING) #ifdef CONFIG_USB_GADGET_DEBUG_FS #include <linux/debugfs.h> @@ -2361,7 +2360,7 @@ static int usba_udc_probe(struct platform_device *pdev) IRQ_NOAUTOEN); ret = devm_request_threaded_irq(&pdev->dev, gpio_to_irq(udc->vbus_pin), NULL, - usba_vbus_irq_thread, IRQF_ONESHOT, + usba_vbus_irq_thread, USBA_VBUS_IRQFLAGS, "atmel_usba_udc", udc); if (ret) { udc->vbus_pin = -ENODEV; diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h index f8ebe0389bd4..860a00a6fdd0 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.h +++ b/drivers/usb/gadget/udc/atmel_usba_udc.h @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for the Atmel USBA high speed USB device controller * * Copyright (C) 2005-2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __LINUX_USB_GADGET_USBA_UDC_H__ #define __LINUX_USB_GADGET_USBA_UDC_H__ diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index f78503203f42..29f254793592 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bcm63xx_udc.c -- BCM63xx UDC high/full speed USB device controller * * Copyright (C) 2012 Kevin Cernekee <cernekee@gmail.com> * Copyright (C) 2012 Broadcom 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. */ #include <linux/bitops.h> diff --git a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig index eb8b55392360..c74ac25dddcd 100644 --- a/drivers/usb/gadget/udc/bdc/Kconfig +++ b/drivers/usb/gadget/udc/bdc/Kconfig @@ -1,6 +1,7 @@ config USB_BDC_UDC tristate "Broadcom USB3.0 device controller IP driver(BDC)" depends on USB_GADGET && HAS_DMA + default ARCH_BRCMSTB help BDC is Broadcom's USB3.0 device controller IP. If your SOC has a BDC IP diff --git a/drivers/usb/gadget/udc/bdc/Makefile b/drivers/usb/gadget/udc/bdc/Makefile index 5cf6a3bcdf0f..52cb5ea48bbe 100644 --- a/drivers/usb/gadget/udc/bdc/Makefile +++ b/drivers/usb/gadget/udc/bdc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_USB_BDC_UDC) += bdc.o bdc-y := bdc_core.o bdc_cmd.o bdc_ep.o bdc_udc.o diff --git a/drivers/usb/gadget/udc/bdc/bdc.h b/drivers/usb/gadget/udc/bdc/bdc.h index 916d47135cac..6e1e881dc51e 100644 --- a/drivers/usb/gadget/udc/bdc/bdc.h +++ b/drivers/usb/gadget/udc/bdc/bdc.h @@ -1,15 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bdc.h - header for the BRCM BDC USB3.0 device controller * * Copyright (C) 2014 Broadcom Corporation * * Author: Ashwini Pahuja - * - * 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. - * */ #ifndef __LINUX_BDC_H__ @@ -27,8 +22,8 @@ #include <linux/usb/gadget.h> #include <asm/unaligned.h> -#define BRCM_BDC_NAME "bdc_usb3" -#define BRCM_BDC_DESC "BDC device controller driver" +#define BRCM_BDC_NAME "bdc" +#define BRCM_BDC_DESC "Broadcom USB Device Controller driver" #define DMA_ADDR_INVALID (~(dma_addr_t)0) @@ -83,14 +78,14 @@ #define BDC_DVCSA 0x50 #define BDC_DVCSB 0x54 -#define BDC_EPSTS0(n) (0x60 + (n * 0x10)) -#define BDC_EPSTS1(n) (0x64 + (n * 0x10)) -#define BDC_EPSTS2(n) (0x68 + (n * 0x10)) -#define BDC_EPSTS3(n) (0x6c + (n * 0x10)) -#define BDC_EPSTS4(n) (0x70 + (n * 0x10)) -#define BDC_EPSTS5(n) (0x74 + (n * 0x10)) -#define BDC_EPSTS6(n) (0x78 + (n * 0x10)) -#define BDC_EPSTS7(n) (0x7c + (n * 0x10)) +#define BDC_EPSTS0 0x60 +#define BDC_EPSTS1 0x64 +#define BDC_EPSTS2 0x68 +#define BDC_EPSTS3 0x6c +#define BDC_EPSTS4 0x70 +#define BDC_EPSTS5 0x74 +#define BDC_EPSTS6 0x78 +#define BDC_EPSTS7 0x7c #define BDC_SRRBAL(n) (0x200 + (n * 0x10)) #define BDC_SRRBAH(n) (0x204 + (n * 0x10)) #define BDC_SRRINT(n) (0x208 + (n * 0x10)) @@ -413,6 +408,9 @@ struct bdc { /* device lock */ spinlock_t lock; + /* generic phy */ + struct phy **phys; + int num_phys; /* num of endpoints for a particular instantiation of IP */ unsigned int num_eps; /* @@ -454,6 +452,7 @@ struct bdc { * Func Wake packet every 2.5 secs. Refer to USB3 spec section 8.5.6.4 */ struct delayed_work func_wake_notify; + struct clk *clk; }; static inline u32 bdc_readl(void __iomem *base, u32 offset) diff --git a/drivers/usb/gadget/udc/bdc/bdc_cmd.c b/drivers/usb/gadget/udc/bdc/bdc_cmd.c index 6e920f1dce02..6305bf2c8b59 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_cmd.c +++ b/drivers/usb/gadget/udc/bdc/bdc_cmd.c @@ -1,15 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bdc_cmd.c - BRCM BDC USB3.0 device controller * * Copyright (C) 2014 Broadcom Corporation * * Author: Ashwini Pahuja - * - * 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. - * */ #include <linux/scatterlist.h> #include <linux/slab.h> diff --git a/drivers/usb/gadget/udc/bdc/bdc_cmd.h b/drivers/usb/gadget/udc/bdc/bdc_cmd.h index 61d0e3bf9853..29cc988a671a 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_cmd.h +++ b/drivers/usb/gadget/udc/bdc/bdc_cmd.h @@ -1,15 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bdc_cmd.h - header for the BDC debug functions * * Copyright (C) 2014 Broadcom Corporation * * Author: Ashwini Pahuja - * - * 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. - * */ #ifndef __LINUX_BDC_CMD_H__ #define __LINUX_BDC_CMD_H__ diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index e9bd8d4abca0..01b44e159623 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -1,15 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bdc_core.c - BRCM BDC USB3.0 device controller core operations * * Copyright (C) 2014 Broadcom Corporation * * Author: Ashwini Pahuja - * - * 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. - * */ #include <linux/module.h> #include <linux/kernel.h> @@ -24,9 +19,11 @@ #include <linux/dma-mapping.h> #include <linux/dmapool.h> #include <linux/of.h> +#include <linux/phy/phy.h> #include <linux/moduleparam.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> +#include <linux/clk.h> #include "bdc.h" #include "bdc_dbg.h" @@ -444,6 +441,43 @@ static int bdc_hw_init(struct bdc *bdc) return 0; } +static int bdc_phy_init(struct bdc *bdc) +{ + int phy_num; + int ret; + + for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) { + ret = phy_init(bdc->phys[phy_num]); + if (ret) + goto err_exit_phy; + ret = phy_power_on(bdc->phys[phy_num]); + if (ret) { + phy_exit(bdc->phys[phy_num]); + goto err_exit_phy; + } + } + + return 0; + +err_exit_phy: + while (--phy_num >= 0) { + phy_power_off(bdc->phys[phy_num]); + phy_exit(bdc->phys[phy_num]); + } + + return ret; +} + +static void bdc_phy_exit(struct bdc *bdc) +{ + int phy_num; + + for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) { + phy_power_off(bdc->phys[phy_num]); + phy_exit(bdc->phys[phy_num]); + } +} + static int bdc_probe(struct platform_device *pdev) { struct bdc *bdc; @@ -452,12 +486,29 @@ static int bdc_probe(struct platform_device *pdev) int irq; u32 temp; struct device *dev = &pdev->dev; + struct clk *clk; + int phy_num; dev_dbg(dev, "%s()\n", __func__); + + clk = devm_clk_get(dev, "sw_usbd"); + if (IS_ERR(clk)) { + dev_info(dev, "Clock not found in Device Tree\n"); + clk = NULL; + } + + ret = clk_prepare_enable(clk); + if (ret) { + dev_err(dev, "could not enable clock\n"); + return ret; + } + bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL); if (!bdc) return -ENOMEM; + bdc->clk = clk; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bdc->regs = devm_ioremap_resource(dev, res); if (IS_ERR(bdc->regs)) { @@ -473,35 +524,66 @@ static int bdc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, bdc); bdc->irq = irq; bdc->dev = dev; - dev_dbg(bdc->dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq); + dev_dbg(dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq); + + bdc->num_phys = of_count_phandle_with_args(dev->of_node, + "phys", "#phy-cells"); + if (bdc->num_phys > 0) { + bdc->phys = devm_kcalloc(dev, bdc->num_phys, + sizeof(struct phy *), GFP_KERNEL); + if (!bdc->phys) + return -ENOMEM; + } else { + bdc->num_phys = 0; + } + dev_info(dev, "Using %d phy(s)\n", bdc->num_phys); + + for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) { + bdc->phys[phy_num] = devm_of_phy_get_by_index( + dev, dev->of_node, phy_num); + if (IS_ERR(bdc->phys[phy_num])) { + ret = PTR_ERR(bdc->phys[phy_num]); + dev_err(bdc->dev, + "BDC phy specified but not found:%d\n", ret); + return ret; + } + } + + ret = bdc_phy_init(bdc); + if (ret) { + dev_err(bdc->dev, "BDC phy init failure:%d\n", ret); + return ret; + } temp = bdc_readl(bdc->regs, BDC_BDCCAP1); if ((temp & BDC_P64) && !dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { - dev_dbg(bdc->dev, "Using 64-bit address\n"); + dev_dbg(dev, "Using 64-bit address\n"); } else { - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); if (ret) { - dev_err(bdc->dev, "No suitable DMA config available, abort\n"); + dev_err(dev, + "No suitable DMA config available, abort\n"); return -ENOTSUPP; } - dev_dbg(bdc->dev, "Using 32-bit address\n"); + dev_dbg(dev, "Using 32-bit address\n"); } ret = bdc_hw_init(bdc); if (ret) { - dev_err(bdc->dev, "BDC init failure:%d\n", ret); - return ret; + dev_err(dev, "BDC init failure:%d\n", ret); + goto phycleanup; } ret = bdc_udc_init(bdc); if (ret) { - dev_err(bdc->dev, "BDC Gadget init failure:%d\n", ret); + dev_err(dev, "BDC Gadget init failure:%d\n", ret); goto cleanup; } return 0; cleanup: bdc_hw_exit(bdc); - +phycleanup: + bdc_phy_exit(bdc); return ret; } @@ -513,13 +595,55 @@ static int bdc_remove(struct platform_device *pdev) dev_dbg(bdc->dev, "%s ()\n", __func__); bdc_udc_exit(bdc); bdc_hw_exit(bdc); + bdc_phy_exit(bdc); + clk_disable_unprepare(bdc->clk); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int bdc_suspend(struct device *dev) +{ + struct bdc *bdc = dev_get_drvdata(dev); + + clk_disable_unprepare(bdc->clk); + return 0; +} + +static int bdc_resume(struct device *dev) +{ + struct bdc *bdc = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(bdc->clk); + if (ret) { + dev_err(bdc->dev, "err enabling the clock\n"); + return ret; + } + ret = bdc_reinit(bdc); + if (ret) { + dev_err(bdc->dev, "err in bdc reinit\n"); + return ret; + } return 0; } +#endif /* CONFIG_PM_SLEEP */ + +static SIMPLE_DEV_PM_OPS(bdc_pm_ops, bdc_suspend, + bdc_resume); + +static const struct of_device_id bdc_of_match[] = { + { .compatible = "brcm,bdc-v0.16" }, + { .compatible = "brcm,bdc" }, + { /* sentinel */ } +}; + static struct platform_driver bdc_driver = { .driver = { .name = BRCM_BDC_NAME, + .pm = &bdc_pm_ops, + .of_match_table = bdc_of_match, }, .probe = bdc_probe, .remove = bdc_remove, diff --git a/drivers/usb/gadget/udc/bdc/bdc_dbg.c b/drivers/usb/gadget/udc/bdc/bdc_dbg.c index 5945dbc47825..7ba7448ad743 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_dbg.c +++ b/drivers/usb/gadget/udc/bdc/bdc_dbg.c @@ -1,15 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bdc_dbg.c - BRCM BDC USB3.0 device controller debug functions * * Copyright (C) 2014 Broadcom Corporation * * Author: Ashwini Pahuja - * - * 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. - * */ #include "bdc.h" @@ -40,28 +35,28 @@ void bdc_dump_epsts(struct bdc *bdc) { u32 temp; - temp = bdc_readl(bdc->regs, BDC_EPSTS0(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS0); dev_vdbg(bdc->dev, "BDC_EPSTS0:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS1(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS1); dev_vdbg(bdc->dev, "BDC_EPSTS1:0x%x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS2(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS2); dev_vdbg(bdc->dev, "BDC_EPSTS2:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS3(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS3); dev_vdbg(bdc->dev, "BDC_EPSTS3:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS4(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS4); dev_vdbg(bdc->dev, "BDC_EPSTS4:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS5(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS5); dev_vdbg(bdc->dev, "BDC_EPSTS5:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS6(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS6); dev_vdbg(bdc->dev, "BDC_EPSTS6:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS7(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS7); dev_vdbg(bdc->dev, "BDC_EPSTS7:0x%08x\n", temp); } diff --git a/drivers/usb/gadget/udc/bdc/bdc_dbg.h b/drivers/usb/gadget/udc/bdc/bdc_dbg.h index 338a6c701315..373d5abffbb8 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_dbg.h +++ b/drivers/usb/gadget/udc/bdc/bdc_dbg.h @@ -1,15 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bdc_dbg.h - header for the BDC debug functions * * Copyright (C) 2014 Broadcom Corporation * * Author: Ashwini Pahuja - * - * 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. - * */ #ifndef __LINUX_BDC_DBG_H__ #define __LINUX_BDC_DBG_H__ diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index ff1ef24d1777..f40d4c13cfa4 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bdc_ep.c - BRCM BDC USB3.0 device controller endpoint related functions * @@ -6,12 +7,6 @@ * Author: Ashwini Pahuja * * Based on drivers under drivers/usb/ - * - * 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. - * */ #include <linux/module.h> #include <linux/pci.h> @@ -777,9 +772,9 @@ static int ep_dequeue(struct bdc_ep *ep, struct bdc_req *req) */ /* The current hw dequeue pointer */ - tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0(0)); + tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0); deq_ptr_64 = tmp_32; - tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS1(0)); + tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS1); deq_ptr_64 |= ((u64)tmp_32 << 32); /* we have the dma addr of next bd that will be fetched by hardware */ diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.h b/drivers/usb/gadget/udc/bdc/bdc_ep.h index 8a6b36cbf2ea..a37ff8033b4f 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.h +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.h @@ -1,15 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bdc_ep.h - header for the BDC debug functions * * Copyright (C) 2014 Broadcom Corporation * * Author: Ashwini Pahuja - * - * 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. - * */ #ifndef __LINUX_BDC_EP_H__ #define __LINUX_BDC_EP_H__ diff --git a/drivers/usb/gadget/udc/bdc/bdc_pci.c b/drivers/usb/gadget/udc/bdc/bdc_pci.c index 02968842b359..1e940f054cb8 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_pci.c +++ b/drivers/usb/gadget/udc/bdc/bdc_pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bdc_pci.c - BRCM BDC USB3.0 device controller PCI interface file. * @@ -6,12 +7,6 @@ * Author: Ashwini Pahuja * * Based on drivers under drivers/usb/ - * - * 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. - * */ #include <linux/kernel.h> diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c index aae7458d8986..7bfd58c846f7 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_udc.c +++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * bdc_udc.c - BRCM BDC USB3.0 device controller gagdet ops * @@ -6,12 +7,6 @@ * Author: Ashwini Pahuja * * Based on drivers under drivers/usb/gadget/udc/ - * - * 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. - * */ #include <linux/module.h> #include <linux/pci.h> @@ -249,6 +244,7 @@ void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport) disconn = true; else if ((uspc & BDC_PCS) && !BDC_PST(uspc)) connected = true; + clear_flags |= BDC_PCC; } /* Change in VBus and VBus is present */ @@ -259,16 +255,16 @@ void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport) bdc_softconn(bdc); usb_gadget_set_state(&bdc->gadget, USB_STATE_POWERED); } - clear_flags = BDC_VBC; + clear_flags |= BDC_VBC; } else if ((uspc & BDC_PRS) || (uspc & BDC_PRC) || disconn) { /* Hot reset, warm reset, 2.0 bus reset or disconn */ dev_dbg(bdc->dev, "Port reset or disconn\n"); bdc_uspc_disconnected(bdc, disconn); - clear_flags = BDC_PCC|BDC_PCS|BDC_PRS|BDC_PRC; + clear_flags |= BDC_PRC; } else if ((uspc & BDC_PSC) && (uspc & BDC_PCS)) { /* Change in Link state */ handle_link_state_change(bdc, uspc); - clear_flags = BDC_PSC|BDC_PCS; + clear_flags |= BDC_PSC; } /* diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index e6f04eee95c4..1b3efb14aec7 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /** * udc.c - Core UDC Framework * * Copyright (C) 2010 Texas Instruments * Author: Felipe Balbi <balbi@ti.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 of - * the License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> @@ -812,6 +801,8 @@ int usb_gadget_map_request_by_dev(struct device *dev, dev_err(dev, "failed to map buffer\n"); return -EFAULT; } + + req->dma_mapped = 1; } return 0; @@ -836,9 +827,10 @@ void usb_gadget_unmap_request_by_dev(struct device *dev, is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); req->num_mapped_sgs = 0; - } else { + } else if (req->dma_mapped) { dma_unmap_single(dev, req->dma, req->length, is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + req->dma_mapped = 0; } } EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev); @@ -909,7 +901,7 @@ int usb_gadget_ep_match_desc(struct usb_gadget *gadget, return 0; type = usb_endpoint_type(desc); - max = 0x7ff & usb_endpoint_maxp(desc); + max = usb_endpoint_maxp(desc); if (usb_endpoint_dir_in(desc) && !ep->caps.dir_in) return 0; @@ -1077,8 +1069,12 @@ static inline void usb_gadget_udc_stop(struct usb_udc *udc) static inline void usb_gadget_udc_set_speed(struct usb_udc *udc, enum usb_device_speed speed) { - if (udc->gadget->ops->udc_set_speed) - udc->gadget->ops->udc_set_speed(udc->gadget, speed); + if (udc->gadget->ops->udc_set_speed) { + enum usb_device_speed s; + + s = min(speed, udc->gadget->max_speed); + udc->gadget->ops->udc_set_speed(udc->gadget, s); + } } /** @@ -1130,6 +1126,7 @@ static int check_pending_gadget_drivers(struct usb_udc *udc) * @release: a gadget release function. * * Returns zero on success, negative errno otherwise. + * Calls the gadget release function in the latter case. */ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, void (*release)(struct device *dev)) @@ -1137,10 +1134,6 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, struct usb_udc *udc; int ret = -ENOMEM; - udc = kzalloc(sizeof(*udc), GFP_KERNEL); - if (!udc) - goto err1; - dev_set_name(&gadget->dev, "gadget"); INIT_WORK(&gadget->work, usb_gadget_state_work); gadget->dev.parent = parent; @@ -1150,9 +1143,11 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, else gadget->dev.release = usb_udc_nop_release; - ret = device_register(&gadget->dev); - if (ret) - goto err2; + device_initialize(&gadget->dev); + + udc = kzalloc(sizeof(*udc), GFP_KERNEL); + if (!udc) + goto err_put_gadget; device_initialize(&udc->dev); udc->dev.release = usb_udc_release; @@ -1161,7 +1156,11 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, udc->dev.parent = parent; ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj)); if (ret) - goto err3; + goto err_put_udc; + + ret = device_add(&gadget->dev); + if (ret) + goto err_put_udc; udc->gadget = gadget; gadget->udc = udc; @@ -1171,7 +1170,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, ret = device_add(&udc->dev); if (ret) - goto err4; + goto err_unlist_udc; usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED); udc->vbus = true; @@ -1179,28 +1178,26 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, /* pick up one of pending gadget drivers */ ret = check_pending_gadget_drivers(udc); if (ret) - goto err5; + goto err_del_udc; mutex_unlock(&udc_lock); return 0; -err5: + err_del_udc: device_del(&udc->dev); -err4: + err_unlist_udc: list_del(&udc->list); mutex_unlock(&udc_lock); -err3: - put_device(&udc->dev); device_del(&gadget->dev); -err2: - put_device(&gadget->dev); - kfree(udc); + err_put_udc: + put_device(&udc->dev); -err1: + err_put_gadget: + put_device(&gadget->dev); return ret; } EXPORT_SYMBOL_GPL(usb_add_gadget_udc_release); @@ -1314,8 +1311,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri udc->dev.driver = &driver->driver; udc->gadget->dev.driver = &driver->driver; - if (driver->max_speed < udc->gadget->max_speed) - usb_gadget_udc_set_speed(udc, driver->max_speed); + usb_gadget_udc_set_speed(udc, driver->max_speed); ret = driver->bind(udc->gadget, driver); if (ret) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 3c3760315910..d0128f92ec5a 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * dummy_hcd.c -- Dummy/Loopback USB host and device emulator driver. * @@ -5,11 +6,6 @@ * * Copyright (C) 2003 David Brownell * Copyright (C) 2003-2005 Alan Stern - * - * 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. */ @@ -23,6 +19,8 @@ * * Having this all in one kernel can help some stages of development, * bypassing some hardware (and driver) issues. UML could help too. + * + * Note: The emulation does not include isochronous transfers! */ #include <linux/module.h> @@ -137,6 +135,9 @@ static const struct { .caps = _caps, \ } +/* we don't provide isochronous endpoints since we don't support them */ +#define TYPE_BULK_OR_INT (USB_EP_CAPS_TYPE_BULK | USB_EP_CAPS_TYPE_INT) + /* everyone has ep0 */ EP_INFO(ep0name, USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL, USB_EP_CAPS_DIR_ALL)), @@ -145,64 +146,72 @@ static const struct { USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), EP_INFO("ep2out-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), +/* EP_INFO("ep3in-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)), EP_INFO("ep4out-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)), +*/ EP_INFO("ep5in-int", USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep6in-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), EP_INFO("ep7out-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), +/* EP_INFO("ep8in-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)), EP_INFO("ep9out-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)), +*/ EP_INFO("ep10in-int", USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep11in-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), EP_INFO("ep12out-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), +/* EP_INFO("ep13in-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)), EP_INFO("ep14out-iso", USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)), +*/ EP_INFO("ep15in-int", USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)), + /* or like sa1100: two fixed function endpoints */ EP_INFO("ep1out-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep2in-bulk", USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), + /* and now some generic EPs so we have enough in multi config */ EP_INFO("ep3out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep4in", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep5out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep6out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep7in", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep8out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep9in", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep10out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep11out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep12in", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep13out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), EP_INFO("ep14in", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_IN)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_IN)), EP_INFO("ep15out", - USB_EP_CAPS(USB_EP_CAPS_TYPE_ALL, USB_EP_CAPS_DIR_OUT)), + USB_EP_CAPS(TYPE_BULK_OR_INT, USB_EP_CAPS_DIR_OUT)), #undef EP_INFO }; @@ -237,6 +246,8 @@ struct dummy_hcd { struct usb_device *udev; struct list_head urbp_list; + struct urbp *next_frame_urbp; + u32 stream_en_ep; u8 num_stream[30 / 2]; @@ -253,11 +264,13 @@ struct dummy { */ struct dummy_ep ep[DUMMY_ENDPOINTS]; int address; + int callback_usage; struct usb_gadget gadget; struct usb_gadget_driver *driver; struct dummy_request fifo_req; u8 fifo_buf[FIFO_SIZE]; u16 devstatus; + unsigned ints_enabled:1; unsigned udc_suspended:1; unsigned pullup:1; @@ -375,11 +388,10 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) USB_PORT_STAT_CONNECTION) == 0) dum_hcd->port_status |= (USB_PORT_STAT_C_CONNECTION << 16); - if ((dum_hcd->port_status & - USB_PORT_STAT_ENABLE) == 1 && - (dum_hcd->port_status & - USB_SS_PORT_LS_U0) == 1 && - dum_hcd->rh_state != DUMMY_RH_SUSPENDED) + if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) && + (dum_hcd->port_status & + USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 && + dum_hcd->rh_state != DUMMY_RH_SUSPENDED) dum_hcd->active = 1; } } else { @@ -416,6 +428,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) static void set_link_state(struct dummy_hcd *dum_hcd) { struct dummy *dum = dum_hcd->dum; + unsigned int power_bit; dum_hcd->active = 0; if (dum->pullup) @@ -426,32 +439,43 @@ static void set_link_state(struct dummy_hcd *dum_hcd) return; set_link_state_by_speed(dum_hcd); + power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ? + USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER); if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || dum_hcd->active) dum_hcd->resuming = 0; /* Currently !connected or in reset */ - if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || + if ((dum_hcd->port_status & power_bit) == 0 || (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { - unsigned disconnect = USB_PORT_STAT_CONNECTION & + unsigned int disconnect = power_bit & dum_hcd->old_status & (~dum_hcd->port_status); - unsigned reset = USB_PORT_STAT_RESET & + unsigned int reset = USB_PORT_STAT_RESET & (~dum_hcd->old_status) & dum_hcd->port_status; /* Report reset and disconnect events to the driver */ - if (dum->driver && (disconnect || reset)) { + if (dum->ints_enabled && (disconnect || reset)) { stop_activity(dum); + ++dum->callback_usage; + spin_unlock(&dum->lock); if (reset) usb_gadget_udc_reset(&dum->gadget, dum->driver); else dum->driver->disconnect(&dum->gadget); + spin_lock(&dum->lock); + --dum->callback_usage; } - } else if (dum_hcd->active != dum_hcd->old_active) { + } else if (dum_hcd->active != dum_hcd->old_active && + dum->ints_enabled) { + ++dum->callback_usage; + spin_unlock(&dum->lock); if (dum_hcd->old_active && dum->driver->suspend) dum->driver->suspend(&dum->gadget); else if (!dum_hcd->old_active && dum->driver->resume) dum->driver->resume(&dum->gadget); + spin_lock(&dum->lock); + --dum->callback_usage; } dum_hcd->old_status = dum_hcd->port_status; @@ -541,10 +565,12 @@ static int dummy_enable(struct usb_ep *_ep, if (max <= 1024) break; /* save a return statement */ + /* fall through */ case USB_SPEED_FULL: if (max <= 64) break; /* save a return statement */ + /* fall through */ default: if (max <= 8) break; @@ -562,6 +588,7 @@ static int dummy_enable(struct usb_ep *_ep, if (max <= 1024) break; /* save a return statement */ + /* fall through */ case USB_SPEED_FULL: if (max <= 1023) break; @@ -972,8 +999,11 @@ static int dummy_udc_start(struct usb_gadget *g, * can't enumerate without help from the driver we're binding. */ + spin_lock_irq(&dum->lock); dum->devstatus = 0; dum->driver = driver; + dum->ints_enabled = 1; + spin_unlock_irq(&dum->lock); return 0; } @@ -984,6 +1014,16 @@ static int dummy_udc_stop(struct usb_gadget *g) struct dummy *dum = dum_hcd->dum; spin_lock_irq(&dum->lock); + dum->ints_enabled = 0; + stop_activity(dum); + + /* emulate synchronize_irq(): wait for callbacks to finish */ + while (dum->callback_usage > 0) { + spin_unlock_irq(&dum->lock); + usleep_range(1000, 2000); + spin_lock_irq(&dum->lock); + } + dum->driver = NULL; spin_unlock_irq(&dum->lock); @@ -1037,7 +1077,12 @@ static int dummy_udc_probe(struct platform_device *pdev) memzero_explicit(&dum->gadget, sizeof(struct usb_gadget)); dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; - dum->gadget.max_speed = USB_SPEED_SUPER; + if (mod_data.is_super_speed) + dum->gadget.max_speed = USB_SPEED_SUPER; + else if (mod_data.is_high_speed) + dum->gadget.max_speed = USB_SPEED_HIGH; + else + dum->gadget.max_speed = USB_SPEED_FULL; dum->gadget.dev.parent = &pdev->dev; init_dummy_udc_hw(dum); @@ -1246,6 +1291,8 @@ static int dummy_urb_enqueue( list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list); urb->hcpriv = urbp; + if (!dum_hcd->next_frame_urbp) + dum_hcd->next_frame_urbp = urbp; if (usb_pipetype(urb->pipe) == PIPE_CONTROL) urb->error_count = 1; /* mark as a new urb */ @@ -1521,6 +1568,8 @@ static struct dummy_ep *find_endpoint(struct dummy *dum, u8 address) if (!is_active((dum->gadget.speed == USB_SPEED_SUPER ? dum->ss_hcd : dum->hs_hcd))) return NULL; + if (!dum->ints_enabled) + return NULL; if ((address & ~USB_DIR_IN) == 0) return &dum->ep[0]; for (i = 1; i < DUMMY_ENDPOINTS; i++) { @@ -1722,9 +1771,9 @@ static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb, /* drive both sides of the transfers; looks like irq handlers to * both drivers except the callbacks aren't in_irq(). */ -static void dummy_timer(unsigned long _dum_hcd) +static void dummy_timer(struct timer_list *t) { - struct dummy_hcd *dum_hcd = (struct dummy_hcd *) _dum_hcd; + struct dummy_hcd *dum_hcd = from_timer(dum_hcd, t, timer); struct dummy *dum = dum_hcd->dum; struct urbp *urbp, *tmp; unsigned long flags; @@ -1732,6 +1781,7 @@ static void dummy_timer(unsigned long _dum_hcd) int i; /* simplistic model for one frame's bandwidth */ + /* FIXME: account for transaction and packet overhead */ switch (dum->gadget.speed) { case USB_SPEED_LOW: total = 8/*bytes*/ * 12/*packets*/; @@ -1762,6 +1812,7 @@ static void dummy_timer(unsigned long _dum_hcd) spin_unlock_irqrestore(&dum->lock, flags); return; } + dum_hcd->next_frame_urbp = NULL; for (i = 0; i < DUMMY_ENDPOINTS; i++) { if (!ep_info[i].name) @@ -1775,22 +1826,21 @@ restart: struct dummy_request *req; u8 address; struct dummy_ep *ep = NULL; - int type; int status = -EINPROGRESS; + /* stop when we reach URBs queued after the timer interrupt */ + if (urbp == dum_hcd->next_frame_urbp) + break; + urb = urbp->urb; if (urb->unlinked) goto return_urb; else if (dum_hcd->rh_state != DUMMY_RH_RUNNING) continue; - type = usb_pipetype(urb->pipe); - /* used up this frame's non-periodic bandwidth? - * FIXME there's infinite bandwidth for control and - * periodic transfers ... unrealistic. - */ - if (total <= 0 && type == PIPE_BULK) - continue; + /* Used up this frame's bandwidth? */ + if (total <= 0) + break; /* find the gadget's ep for this request (if configured) */ address = usb_pipeendpoint (urb->pipe); @@ -1857,10 +1907,12 @@ restart: * until setup() returns; no reentrancy issues etc. */ if (value > 0) { + ++dum->callback_usage; spin_unlock(&dum->lock); value = dum->driver->setup(&dum->gadget, &setup); spin_lock(&dum->lock); + --dum->callback_usage; if (value >= 0) { /* no delays (max 64KB data stage) */ @@ -1886,13 +1938,17 @@ restart: limit = total; switch (usb_pipetype(urb->pipe)) { case PIPE_ISOCHRONOUS: - /* FIXME is it urb->interval since the last xfer? - * use urb->iso_frame_desc[i]. - * complete whether or not ep has requests queued. - * report random errors, to debug drivers. + /* + * We don't support isochronous. But if we did, + * here are some of the issues we'd have to face: + * + * Is it urb->interval since the last xfer? + * Use urb->iso_frame_desc[i]. + * Complete whether or not ep has requests queued. + * Report random errors, to debug drivers. */ limit = max(limit, periodic_bytes(dum, ep)); - status = -ENOSYS; + status = -EINVAL; /* fail all xfers */ break; case PIPE_INTERRUPT: @@ -2389,9 +2445,7 @@ static DEVICE_ATTR_RO(urbs); static int dummy_start_ss(struct dummy_hcd *dum_hcd) { - init_timer(&dum_hcd->timer); - dum_hcd->timer.function = dummy_timer; - dum_hcd->timer.data = (unsigned long)dum_hcd; + timer_setup(&dum_hcd->timer, dummy_timer, 0); dum_hcd->rh_state = DUMMY_RH_RUNNING; dum_hcd->stream_en_ep = 0; INIT_LIST_HEAD(&dum_hcd->urbp_list); @@ -2420,9 +2474,7 @@ static int dummy_start(struct usb_hcd *hcd) return dummy_start_ss(dum_hcd); spin_lock_init(&dum_hcd->dum->lock); - init_timer(&dum_hcd->timer); - dum_hcd->timer.function = dummy_timer; - dum_hcd->timer.data = (unsigned long)dum_hcd; + timer_setup(&dum_hcd->timer, dummy_timer, 0); dum_hcd->rh_state = DUMMY_RH_RUNNING; INIT_LIST_HEAD(&dum_hcd->urbp_list); @@ -2561,8 +2613,6 @@ static struct hc_driver dummy_hcd = { .product_desc = "Dummy host controller", .hcd_priv_size = sizeof(struct dummy_hcd), - .flags = HCD_USB3 | HCD_SHARED, - .reset = dummy_setup, .start = dummy_start, .stop = dummy_stop, @@ -2591,8 +2641,12 @@ static int dummy_hcd_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); dum = *((void **)dev_get_platdata(&pdev->dev)); - if (!mod_data.is_super_speed) + if (mod_data.is_super_speed) + dummy_hcd.flags = HCD_USB3 | HCD_SHARED; + else if (mod_data.is_high_speed) dummy_hcd.flags = HCD_USB2; + else + dummy_hcd.flags = HCD_USB11; hs_hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev)); if (!hs_hcd) return -ENOMEM; @@ -2776,7 +2830,7 @@ static int __init init(void) if (retval < 0) { i--; while (i >= 0) - platform_device_del(the_udc_pdev[i]); + platform_device_del(the_udc_pdev[i--]); goto err_add_udc; } } diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c index 78d0204e3e20..53a48f561458 100644 --- a/drivers/usb/gadget/udc/fotg210-udc.c +++ b/drivers/usb/gadget/udc/fotg210-udc.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * FOTG210 UDC Driver supports Bulk transfer so far * * Copyright (C) 2013 Faraday Technology Corporation * * Author : Yuan-Hsin Chen <yhchen@faraday-tech.com> - * - * 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; version 2 of the License. */ #include <linux/dma-mapping.h> diff --git a/drivers/usb/gadget/udc/fotg210.h b/drivers/usb/gadget/udc/fotg210.h index bbf991bcbe7c..08c32957503b 100644 --- a/drivers/usb/gadget/udc/fotg210.h +++ b/drivers/usb/gadget/udc/fotg210.h @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Faraday FOTG210 USB OTG controller * * Copyright (C) 2013 Faraday Technology Corporation * Author: Yuan-Hsin Chen <yhchen@faraday-tech.com> - * - * 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. */ #include <linux/kernel.h> diff --git a/drivers/usb/gadget/udc/fsl_mxc_udc.c b/drivers/usb/gadget/udc/fsl_mxc_udc.c index f16e149c5b3e..f29cf5c6160c 100644 --- a/drivers/usb/gadget/udc/fsl_mxc_udc.c +++ b/drivers/usb/gadget/udc/fsl_mxc_udc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2009 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> @@ -5,11 +6,6 @@ * Description: * Helper routines for i.MX3x SoCs from Freescale, needed by the fsl_usb2_udc.c * driver to function correctly on these systems. - * - * 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. */ #include <linux/clk.h> #include <linux/delay.h> diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 303328ce59ee..2707be628298 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * driver/usb/gadget/fsl_qe_udc.c * @@ -11,11 +12,6 @@ * Freescle QE/CPM USB Pheripheral Controller Driver * The controller can be found on MPC8360, MPC8272, and etc. * MPC8360 Rev 1.1 may need QE mircocode update - * - * 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. */ #undef USB_TRACE @@ -62,7 +58,7 @@ static const char *const ep_name[] = { "ep3", }; -static struct usb_endpoint_descriptor qe_ep0_desc = { +static const struct usb_endpoint_descriptor qe_ep0_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.h b/drivers/usb/gadget/udc/fsl_qe_udc.h index 7026919fc901..2c537a904ee7 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.h +++ b/drivers/usb/gadget/udc/fsl_qe_udc.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * drivers/usb/gadget/qe_udc.h * @@ -8,11 +9,6 @@ * * Description: * Freescale USB device/endpoint management registers - * - * 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. */ #ifndef __FSL_QE_UDC_H diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index 6f2f71c054be..d606d4f13098 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2004-2007,2011-2012 Freescale Semiconductor, Inc. * All rights reserved. @@ -10,11 +11,6 @@ * This can be found on MPC8349E/MPC8313E/MPC5121E cpus. * The driver is previously named as mpc_udc. Based on bare board * code from Dave Liu and Shlomi Gridish. - * - * 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. */ #undef VERBOSE diff --git a/drivers/usb/gadget/udc/fsl_usb2_udc.h b/drivers/usb/gadget/udc/fsl_usb2_udc.h index e92b8408b6f6..4ba651ae9048 100644 --- a/drivers/usb/gadget/udc/fsl_usb2_udc.h +++ b/drivers/usb/gadget/udc/fsl_usb2_udc.h @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2004,2012 Freescale Semiconductor, Inc * All rights reserved. * - * 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. - * * Freescale USB device/endpoint management registers */ #ifndef __FSL_USB2_UDC_H diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index e0c1b0099265..263804d154a7 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Fusb300 UDC (USB gadget) * * Copyright (C) 2010 Faraday Technology Corp. * * Author : Yuan-hsin Chen <yhchen@faraday-tech.com> - * - * 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; version 2 of the License. */ #include <linux/dma-mapping.h> #include <linux/err.h> diff --git a/drivers/usb/gadget/udc/fusb300_udc.h b/drivers/usb/gadget/udc/fusb300_udc.h index ad39f892d200..eb3d6d379ba7 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.h +++ b/drivers/usb/gadget/udc/fusb300_udc.h @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Fusb300 UDC (USB gadget) * * Copyright (C) 2010 Faraday Technology Corp. * * Author : Yuan-hsin Chen <yhchen@faraday-tech.com> - * - * 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; version 2 of the License. */ diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c index 8433c22900dc..4504d0b202db 100644 --- a/drivers/usb/gadget/udc/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Toshiba TC86C001 ("Goku-S") USB Device Controller driver * @@ -5,10 +6,6 @@ * by Stuart Lynne, Tom Rushworth, and Bruce Balden * Copyright (C) 2002 Toshiba Corporation * Copyright (C) 2003 MontaVista Software (source@mvista.com) - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ /* @@ -127,11 +124,15 @@ goku_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) mode = 0; max = get_unaligned_le16(&desc->wMaxPacketSize); switch (max) { - case 64: mode++; - case 32: mode++; - case 16: mode++; - case 8: mode <<= 3; - break; + case 64: + mode++; /* fall through */ + case 32: + mode++; /* fall through */ + case 16: + mode++; /* fall through */ + case 8: + mode <<= 3; + break; default: return -EINVAL; } diff --git a/drivers/usb/gadget/udc/goku_udc.h b/drivers/usb/gadget/udc/goku_udc.h index 86d2adafe149..26601bf4e7a9 100644 --- a/drivers/usb/gadget/udc/goku_udc.h +++ b/drivers/usb/gadget/udc/goku_udc.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Toshiba TC86C001 ("Goku-S") USB Device Controller driver * @@ -5,10 +6,6 @@ * by Stuart Lynne, Tom Rushworth, and Bruce Balden * Copyright (C) 2002 Toshiba Corporation * Copyright (C) 2003 MontaVista Software (source@mvista.com) - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ /* diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index 1f9941145746..b3fb1bbdb854 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * USB Peripheral Controller driver for Aeroflex Gaisler GRUSBDC. * @@ -9,11 +10,6 @@ * Full documentation of the GRUSBDC core can be found here: * http://www.gaisler.com/products/grlib/grip.pdf * - * 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. - * * Contributors: * - Andreas Larsson <andreas@gaisler.com> * - Marko Isomaki @@ -1261,7 +1257,7 @@ static int gr_handle_in_ep(struct gr_ep *ep) if (!req->last_desc) return 0; - if (ACCESS_ONCE(req->last_desc->ctrl) & GR_DESC_IN_CTRL_EN) + if (READ_ONCE(req->last_desc->ctrl) & GR_DESC_IN_CTRL_EN) return 0; /* Not put in hardware buffers yet */ if (gr_read32(&ep->regs->epstat) & (GR_EPSTAT_B1 | GR_EPSTAT_B0)) @@ -1290,7 +1286,7 @@ static int gr_handle_out_ep(struct gr_ep *ep) if (!req->curr_desc) return 0; - ctrl = ACCESS_ONCE(req->curr_desc->ctrl); + ctrl = READ_ONCE(req->curr_desc->ctrl); if (ctrl & GR_DESC_OUT_CTRL_EN) return 0; /* Not received yet */ @@ -1538,7 +1534,7 @@ static int gr_ep_enable(struct usb_ep *_ep, * Bits 10-0 set the max payload. 12-11 set the number of * additional transactions. */ - max = 0x7ff & usb_endpoint_maxp(desc); + max = usb_endpoint_maxp(desc); nt = usb_endpoint_maxp_mult(desc) - 1; buffer_size = GR_BUFFER_SIZE(epctrl); if (nt && (mode == 0 || mode == 2)) { diff --git a/drivers/usb/gadget/udc/gr_udc.h b/drivers/usb/gadget/udc/gr_udc.h index 4297c4e8021f..3e913268c8c5 100644 --- a/drivers/usb/gadget/udc/gr_udc.h +++ b/drivers/usb/gadget/udc/gr_udc.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * USB Peripheral Controller driver for Aeroflex Gaisler GRUSBDC. * @@ -9,11 +10,6 @@ * Full documentation of the GRUSBDC core can be found here: * http://www.gaisler.com/products/grlib/grip.pdf * - * 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. - * * Contributors: * - Andreas Larsson <andreas@gaisler.com> * - Marko Isomaki diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 8f32b5ee7734..b0781771704e 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * USB Gadget driver for LPC32xx * @@ -12,20 +13,6 @@ * * Note: This driver is based on original work done by Mike James for * the LPC3180. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/clk.h> diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c index 46ce7bc15f2b..a8288df6aadf 100644 --- a/drivers/usb/gadget/udc/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * M66592 UDC (USB gadget) * * Copyright (C) 2006-2007 Renesas Solutions Corp. * * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - * - * 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; version 2 of the License. */ #include <linux/module.h> @@ -1262,9 +1259,9 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) return IRQ_HANDLED; } -static void m66592_timer(unsigned long _m66592) +static void m66592_timer(struct timer_list *t) { - struct m66592 *m66592 = (struct m66592 *)_m66592; + struct m66592 *m66592 = from_timer(m66592, t, timer); unsigned long flags; u16 tmp; @@ -1592,9 +1589,7 @@ static int m66592_probe(struct platform_device *pdev) m66592->gadget.max_speed = USB_SPEED_HIGH; m66592->gadget.name = udc_name; - init_timer(&m66592->timer); - m66592->timer.function = m66592_timer; - m66592->timer.data = (unsigned long)m66592; + timer_setup(&m66592->timer, m66592_timer, 0); m66592->reg = reg; ret = request_irq(ires->start, m66592_irq, IRQF_SHARED, diff --git a/drivers/usb/gadget/udc/m66592-udc.h b/drivers/usb/gadget/udc/m66592-udc.h index 96d49d7bfb6b..01a64685b8a3 100644 --- a/drivers/usb/gadget/udc/m66592-udc.h +++ b/drivers/usb/gadget/udc/m66592-udc.h @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * M66592 UDC (USB gadget) * * Copyright (C) 2006-2007 Renesas Solutions Corp. * * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - * - * 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; version 2 of the License. */ #ifndef __M66592_UDC_H__ diff --git a/drivers/usb/gadget/udc/mv_u3d.h b/drivers/usb/gadget/udc/mv_u3d.h index e32a787ac373..982625b7197a 100644 --- a/drivers/usb/gadget/udc/mv_u3d.h +++ b/drivers/usb/gadget/udc/mv_u3d.h @@ -1,9 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2011 Marvell International Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. */ #ifndef __MV_U3D_H diff --git a/drivers/usb/gadget/udc/mv_u3d_core.c b/drivers/usb/gadget/udc/mv_u3d_core.c index 772049afe166..35e02a8d0091 100644 --- a/drivers/usb/gadget/udc/mv_u3d_core.c +++ b/drivers/usb/gadget/udc/mv_u3d_core.c @@ -1,9 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2011 Marvell International Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. */ #include <linux/module.h> diff --git a/drivers/usb/gadget/udc/mv_udc.h b/drivers/usb/gadget/udc/mv_udc.h index be77f207dbaf..b3f759c0962c 100644 --- a/drivers/usb/gadget/udc/mv_udc.h +++ b/drivers/usb/gadget/udc/mv_udc.h @@ -1,10 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2011 Marvell International Ltd. All rights reserved. - * - * 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. */ #ifndef __MV_UDC_H diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 8a708d0a1042..95f52232493b 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2011 Marvell International Ltd. All rights reserved. * Author: Chao Xie <chao.xie@marvell.com> * Neil Zhang <zhangwm@marvell.com> - * - * 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. */ #include <linux/module.h> @@ -39,7 +35,6 @@ #include "mv_udc.h" #define DRIVER_DESC "Marvell PXA USB Device Controller driver" -#define DRIVER_VERSION "8 Nov 2010" #define ep_dir(ep) (((ep)->ep_num == 0) ? \ ((ep)->udc->ep0_dir) : ((ep)->direction)) @@ -2427,5 +2422,4 @@ module_platform_driver(udc_driver); MODULE_ALIAS("platform:mv-udc"); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Chao Xie <chao.xie@marvell.com>"); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 8f85a51bd2b3..660878a19505 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Driver for PLX NET2272 USB device controller * * Copyright (C) 2005-2006 PLX Technology, Inc. * Copyright (C) 2006-2011 Analog Devices, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/delay.h> diff --git a/drivers/usb/gadget/udc/net2272.h b/drivers/usb/gadget/udc/net2272.h index 69bc9c3c6ce4..8e644627992d 100644 --- a/drivers/usb/gadget/udc/net2272.h +++ b/drivers/usb/gadget/udc/net2272.h @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * PLX NET2272 high/full speed USB device controller * * Copyright (C) 2005-2006 PLX Technology, Inc. * Copyright (C) 2006-2011 Analog Devices, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NET2272_H__ diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index f608c1f85e61..318246d8b2e2 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Driver for the PLX NET2280 USB device controller. * Specs and errata are available from <http://www.plxtech.com>. @@ -31,11 +32,6 @@ * * Modified Ricardo Ribalda Qtechnology AS to provide compatibility * with usb 338x chip. Based on PLX driver - * - * 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. */ #include <linux/module.h> diff --git a/drivers/usb/gadget/udc/net2280.h b/drivers/usb/gadget/udc/net2280.h index 1088c3745999..b65a797544d7 100644 --- a/drivers/usb/gadget/udc/net2280.h +++ b/drivers/usb/gadget/udc/net2280.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * NetChip 2280 high/full speed USB device controller. * Unlike many such controllers, this one talks PCI. @@ -7,11 +8,6 @@ * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) * Copyright (C) 2003 David Brownell * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS - * - * 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. */ #include <linux/usb/net2280.h> diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index f05ba6825bfe..dc35a54bad90 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * omap_udc.c -- for OMAP full speed udc; most chips support OTG. * @@ -5,11 +6,6 @@ * Copyright (C) 2004-2005 David Brownell * * OMAP2 & DMA support by Kyungmin Park <kyungmin.park@samsung.com> - * - * 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. */ #undef DEBUG @@ -1858,9 +1854,9 @@ static irqreturn_t omap_udc_irq(int irq, void *_udc) #define PIO_OUT_TIMEOUT (jiffies + HZ/3) #define HALF_FULL(f) (!((f)&(UDC_NON_ISO_FIFO_FULL|UDC_NON_ISO_FIFO_EMPTY))) -static void pio_out_timer(unsigned long _ep) +static void pio_out_timer(struct timer_list *t) { - struct omap_ep *ep = (void *) _ep; + struct omap_ep *ep = from_timer(ep, t, timer); unsigned long flags; u16 stat_flg; @@ -2546,9 +2542,7 @@ omap_ep_setup(char *name, u8 addr, u8 type, } if (dbuf && addr) epn_rxtx |= UDC_EPN_RX_DB; - init_timer(&ep->timer); - ep->timer.function = pio_out_timer; - ep->timer.data = (unsigned long) ep; + timer_setup(&ep->timer, pio_out_timer, 0); } if (addr) epn_rxtx |= UDC_EPN_RX_VALID; diff --git a/drivers/usb/gadget/udc/omap_udc.h b/drivers/usb/gadget/udc/omap_udc.h index 26974196cf44..00f9e608e755 100644 --- a/drivers/usb/gadget/udc/omap_udc.h +++ b/drivers/usb/gadget/udc/omap_udc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * omap_udc.h -- for omap 3.2 udc, with OTG support * diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index 84dcbcd756f0..afaea11ec771 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -1,9 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. - * - * 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; version 2 of the License. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/kernel.h> diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index a238da906115..0e3f5faa000e 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Intel PXA25x and IXP4xx on-chip full speed USB device controllers * @@ -6,11 +7,6 @@ * Copyright (C) 2003 Benedikt Spranger, Pengutronix * Copyright (C) 2003 David Brownell * Copyright (C) 2003 Joshua Wise - * - * 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. */ /* #define VERBOSE_DEBUG */ @@ -1628,9 +1624,9 @@ static inline void clear_ep_state (struct pxa25x_udc *dev) nuke(&dev->ep[i], -ECONNABORTED); } -static void udc_watchdog(unsigned long _dev) +static void udc_watchdog(struct timer_list *t) { - struct pxa25x_udc *dev = (void *)_dev; + struct pxa25x_udc *dev = from_timer(dev, t, timer); local_irq_disable(); if (dev->ep0state == EP0_STALL @@ -2417,9 +2413,7 @@ static int pxa25x_udc_probe(struct platform_device *pdev) gpio_direction_output(dev->mach->gpio_pullup, 0); } - init_timer(&dev->timer); - dev->timer.function = udc_watchdog; - dev->timer.data = (unsigned long) dev; + timer_setup(&dev->timer, udc_watchdog, 0); the_controller = dev; platform_set_drvdata(pdev, dev); diff --git a/drivers/usb/gadget/udc/pxa25x_udc.h b/drivers/usb/gadget/udc/pxa25x_udc.h index a458bec2536d..ccc6b921f067 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.h +++ b/drivers/usb/gadget/udc/pxa25x_udc.h @@ -1,14 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Intel PXA25x on-chip full speed USB device controller * * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix * Copyright (C) 2003 David Brownell - * - * - * 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. */ #ifndef __LINUX_USB_GADGET_PXA25X_H diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index d48e239660c3..be2761f1b3f5 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Handles the Intel 27x USB Device Controller (UDC) * * Inspired by original driver by Frank Becker, David Brownell, and others. * Copyright (C) 2008 Robert Jarzmik - * - * 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. */ #include <linux/module.h> #include <linux/kernel.h> diff --git a/drivers/usb/gadget/udc/pxa27x_udc.h b/drivers/usb/gadget/udc/pxa27x_udc.h index cea2cb79b30c..1128d39a4255 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.h +++ b/drivers/usb/gadget/udc/pxa27x_udc.h @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * linux/drivers/usb/gadget/pxa27x_udc.h * Intel PXA27x on-chip full speed USB device controller * * Inspired by original driver by Frank Becker, David Brownell, and others. * Copyright (C) 2008 Robert Jarzmik - * - * 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. */ #ifndef __LINUX_USB_GADGET_PXA27X_H diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index 118ad70f1af0..a3ecce62662b 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * R8A66597 UDC (USB gadget) * * Copyright (C) 2006-2009 Renesas Solutions Corp. * * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - * - * 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; version 2 of the License. */ #include <linux/module.h> @@ -1517,9 +1514,9 @@ static irqreturn_t r8a66597_irq(int irq, void *_r8a66597) return IRQ_HANDLED; } -static void r8a66597_timer(unsigned long _r8a66597) +static void r8a66597_timer(struct timer_list *t) { - struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597; + struct r8a66597 *r8a66597 = from_timer(r8a66597, t, timer); unsigned long flags; u16 tmp; @@ -1877,9 +1874,7 @@ static int r8a66597_probe(struct platform_device *pdev) r8a66597->gadget.max_speed = USB_SPEED_HIGH; r8a66597->gadget.name = udc_name; - init_timer(&r8a66597->timer); - r8a66597->timer.function = r8a66597_timer; - r8a66597->timer.data = (unsigned long)r8a66597; + timer_setup(&r8a66597->timer, r8a66597_timer, 0); r8a66597->reg = reg; if (r8a66597->pdata->on_chip) { diff --git a/drivers/usb/gadget/udc/r8a66597-udc.h b/drivers/usb/gadget/udc/r8a66597-udc.h index 45c4b2df1785..9a115caba661 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.h +++ b/drivers/usb/gadget/udc/r8a66597-udc.h @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * R8A66597 UDC * * Copyright (C) 2007-2009 Renesas Solutions Corp. * * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> - * - * 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; version 2 of the License. */ #ifndef __R8A66597_H__ diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index e1de8fe599a3..6e87af248367 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -1,25 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Renesas USB3.0 Peripheral driver (USB gadget) * - * Copyright (C) 2015 Renesas Electronics 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; version 2 of the License. + * Copyright (C) 2015-2017 Renesas Electronics Corporation */ +#include <linux/debugfs.h> #include <linux/delay.h> #include <linux/dma-mapping.h> #include <linux/err.h> -#include <linux/extcon.h> +#include <linux/extcon-provider.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> #include <linux/of_device.h> +#include <linux/phy/phy.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/sizes.h> #include <linux/slab.h> +#include <linux/sys_soc.h> +#include <linux/uaccess.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> @@ -251,7 +252,7 @@ #define USB3_EP0_SS_MAX_PACKET_SIZE 512 #define USB3_EP0_HSFS_MAX_PACKET_SIZE 64 #define USB3_EP0_BUF_SIZE 8 -#define USB3_MAX_NUM_PIPES 30 +#define USB3_MAX_NUM_PIPES 6 /* This includes PIPE 0 */ #define USB3_WAIT_US 3 #define USB3_DMA_NUM_SETTING_AREA 4 /* @@ -331,6 +332,7 @@ struct renesas_usb3 { struct usb_gadget_driver *driver; struct extcon_dev *extcon; struct work_struct extcon_work; + struct phy *phy; struct renesas_usb3_ep *usb3_ep; int num_usb3_eps; @@ -347,6 +349,7 @@ struct renesas_usb3 { bool workaround_for_vbus; bool extcon_host; /* check id and set EXTCON_USB_HOST */ bool extcon_usb; /* check vbus and set EXTCON_USB */ + bool forced_b_device; }; #define gadget_to_renesas_usb3(_gadget) \ @@ -663,7 +666,9 @@ static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev) spin_lock_irqsave(&usb3->lock, flags); usb3_set_mode(usb3, host); usb3_vbus_out(usb3, a_dev); - if (!host && a_dev) /* for A-Peripheral */ + /* for A-Peripheral or forced B-device mode */ + if ((!host && a_dev) || + (usb3->workaround_for_vbus && usb3->forced_b_device)) usb3_connect(usb3); spin_unlock_irqrestore(&usb3->lock, flags); } @@ -677,7 +682,7 @@ static void usb3_check_id(struct renesas_usb3 *usb3) { usb3->extcon_host = usb3_is_a_device(usb3); - if (usb3->extcon_host) + if (usb3->extcon_host && !usb3->forced_b_device) usb3_mode_config(usb3, true, true); else usb3_mode_config(usb3, false, false); @@ -1032,7 +1037,7 @@ static int usb3_write_pipe(struct renesas_usb3_ep *usb3_ep, usb3_ep->ep.maxpacket); u8 *buf = usb3_req->req.buf + usb3_req->req.actual; u32 tmp = 0; - bool is_last; + bool is_last = !len ? true : false; if (usb3_wait_pipe_status(usb3_ep, PX_STA_BUFSTS) < 0) return -EBUSY; @@ -1053,7 +1058,8 @@ static int usb3_write_pipe(struct renesas_usb3_ep *usb3_ep, usb3_write(usb3, tmp, fifo_reg); } - is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); + if (!is_last) + is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); /* Send the data */ usb3_set_px_con_send(usb3_ep, len, is_last); @@ -1144,7 +1150,8 @@ static void usb3_start_pipe0(struct renesas_usb3_ep *usb3_ep, usb3_set_p0_con_for_ctrl_read_data(usb3); } else { usb3_clear_bit(usb3, P0_MOD_DIR, USB3_P0_MOD); - usb3_set_p0_con_for_ctrl_write_data(usb3); + if (usb3_req->req.length) + usb3_set_p0_con_for_ctrl_write_data(usb3); } usb3_p0_xfer(usb3_ep, usb3_req); @@ -2047,7 +2054,16 @@ static u32 usb3_calc_ramarea(int ram_size) static u32 usb3_calc_rammap_val(struct renesas_usb3_ep *usb3_ep, const struct usb_endpoint_descriptor *desc) { - return usb3_ep->rammap_val | PN_RAMMAP_MPKT(usb_endpoint_maxp(desc)); + int i; + static const u32 max_packet_array[] = {8, 16, 32, 64, 512}; + u32 mpkt = PN_RAMMAP_MPKT(1024); + + for (i = 0; i < ARRAY_SIZE(max_packet_array); i++) { + if (usb_endpoint_maxp(desc) <= max_packet_array[i]) + mpkt = PN_RAMMAP_MPKT(max_packet_array[i]); + } + + return usb3_ep->rammap_val | mpkt; } static int usb3_enable_pipe_n(struct renesas_usb3_ep *usb3_ep, @@ -2192,7 +2208,7 @@ static void renesas_usb3_ep_fifo_flush(struct usb_ep *_ep) } } -static struct usb_ep_ops renesas_usb3_ep_ops = { +static const struct usb_ep_ops renesas_usb3_ep_ops = { .enable = renesas_usb3_ep_enable, .disable = renesas_usb3_ep_disable, @@ -2222,7 +2238,9 @@ static int renesas_usb3_start(struct usb_gadget *gadget, /* hook up the driver */ usb3->driver = driver; - pm_runtime_enable(usb3_to_dev(usb3)); + if (usb3->phy) + phy_init(usb3->phy); + pm_runtime_get_sync(usb3_to_dev(usb3)); renesas_usb3_init_controller(usb3); @@ -2239,8 +2257,10 @@ static int renesas_usb3_stop(struct usb_gadget *gadget) usb3->driver = NULL; renesas_usb3_stop_controller(usb3); + if (usb3->phy) + phy_exit(usb3->phy); + pm_runtime_put(usb3_to_dev(usb3)); - pm_runtime_disable(usb3_to_dev(usb3)); return 0; } @@ -2283,6 +2303,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr, if (!usb3->driver) return -ENODEV; + if (usb3->forced_b_device) + return -EBUSY; + if (!strncmp(buf, "host", strlen("host"))) new_mode_is_host = true; else if (!strncmp(buf, "peripheral", strlen("peripheral"))) @@ -2310,6 +2333,70 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(role); +static int renesas_usb3_b_device_show(struct seq_file *s, void *unused) +{ + struct renesas_usb3 *usb3 = s->private; + + seq_printf(s, "%d\n", usb3->forced_b_device); + + return 0; +} + +static int renesas_usb3_b_device_open(struct inode *inode, struct file *file) +{ + return single_open(file, renesas_usb3_b_device_show, inode->i_private); +} + +static ssize_t renesas_usb3_b_device_write(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct renesas_usb3 *usb3 = s->private; + char buf[32]; + + if (!usb3->driver) + return -ENODEV; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (!strncmp(buf, "1", 1)) + usb3->forced_b_device = true; + else + usb3->forced_b_device = false; + + /* Let this driver call usb3_connect() anyway */ + usb3_check_id(usb3); + + return count; +} + +static const struct file_operations renesas_usb3_b_device_fops = { + .open = renesas_usb3_b_device_open, + .write = renesas_usb3_b_device_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void renesas_usb3_debugfs_init(struct renesas_usb3 *usb3, + struct device *dev) +{ + struct dentry *root, *file; + + root = debugfs_create_dir(dev_name(dev), NULL); + if (IS_ERR_OR_NULL(root)) { + dev_info(dev, "%s: Can't create the root\n", __func__); + return; + } + + file = debugfs_create_file("b_device", 0644, root, usb3, + &renesas_usb3_b_device_fops); + if (!file) + dev_info(dev, "%s: Can't create debugfs mode\n", __func__); +} + /*------- platform_driver ------------------------------------------------*/ static int renesas_usb3_remove(struct platform_device *pdev) { @@ -2321,6 +2408,9 @@ static int renesas_usb3_remove(struct platform_device *pdev) renesas_usb3_dma_free_prd(usb3, &pdev->dev); __renesas_usb3_ep_free_request(usb3->ep0_req); + if (usb3->phy) + phy_put(usb3->phy); + pm_runtime_disable(usb3_to_dev(usb3)); return 0; } @@ -2432,22 +2522,40 @@ static void renesas_usb3_init_ram(struct renesas_usb3 *usb3, struct device *dev, } } -static const struct renesas_usb3_priv renesas_usb3_priv_r8a7795 = { +static const struct renesas_usb3_priv renesas_usb3_priv_r8a7795_es1 = { .ramsize_per_ramif = SZ_16K, .num_ramif = 2, .ramsize_per_pipe = SZ_4K, .workaround_for_vbus = true, }; +static const struct renesas_usb3_priv renesas_usb3_priv_gen3 = { + .ramsize_per_ramif = SZ_16K, + .num_ramif = 4, + .ramsize_per_pipe = SZ_4K, +}; + static const struct of_device_id usb3_of_match[] = { { .compatible = "renesas,r8a7795-usb3-peri", - .data = &renesas_usb3_priv_r8a7795, + .data = &renesas_usb3_priv_gen3, + }, + { + .compatible = "renesas,rcar-gen3-usb3-peri", + .data = &renesas_usb3_priv_gen3, }, { }, }; MODULE_DEVICE_TABLE(of, usb3_of_match); +static const struct soc_device_attribute renesas_usb3_quirks_match[] = { + { + .soc_id = "r8a7795", .revision = "ES1.*", + .data = &renesas_usb3_priv_r8a7795_es1, + }, + { /* sentinel */ }, +}; + static const unsigned int renesas_usb3_cable[] = { EXTCON_USB, EXTCON_USB_HOST, @@ -2458,18 +2566,21 @@ static int renesas_usb3_probe(struct platform_device *pdev) { struct renesas_usb3 *usb3; struct resource *res; - const struct of_device_id *match; int irq, ret; const struct renesas_usb3_priv *priv; + const struct soc_device_attribute *attr; - match = of_match_node(usb3_of_match, pdev->dev.of_node); - if (!match) - return -ENODEV; - priv = match->data; + attr = soc_device_match(renesas_usb3_quirks_match); + if (attr) + priv = attr->data; + else + priv = of_device_get_match_data(&pdev->dev); irq = platform_get_irq(pdev, 0); - if (irq < 0) - return -ENODEV; + if (irq < 0) { + dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq); + return irq; + } usb3 = devm_kzalloc(&pdev->dev, sizeof(*usb3), GFP_KERNEL); if (!usb3) @@ -2525,9 +2636,20 @@ static int renesas_usb3_probe(struct platform_device *pdev) if (ret < 0) goto err_dev_create; + /* + * This is an optional. So, if this driver cannot get a phy, + * this driver will not handle a phy anymore. + */ + usb3->phy = devm_phy_get(&pdev->dev, "usb"); + if (IS_ERR(usb3->phy)) + usb3->phy = NULL; + usb3->workaround_for_vbus = priv->workaround_for_vbus; - dev_info(&pdev->dev, "probed\n"); + renesas_usb3_debugfs_init(usb3, &pdev->dev); + + dev_info(&pdev->dev, "probed%s\n", usb3->phy ? " with phy" : ""); + pm_runtime_enable(usb3_to_dev(usb3)); return 0; @@ -2543,11 +2665,49 @@ err_alloc_prd: return ret; } +#ifdef CONFIG_PM_SLEEP +static int renesas_usb3_suspend(struct device *dev) +{ + struct renesas_usb3 *usb3 = dev_get_drvdata(dev); + + /* Not started */ + if (!usb3->driver) + return 0; + + renesas_usb3_stop_controller(usb3); + if (usb3->phy) + phy_exit(usb3->phy); + pm_runtime_put(dev); + + return 0; +} + +static int renesas_usb3_resume(struct device *dev) +{ + struct renesas_usb3 *usb3 = dev_get_drvdata(dev); + + /* Not started */ + if (!usb3->driver) + return 0; + + if (usb3->phy) + phy_init(usb3->phy); + pm_runtime_get_sync(dev); + renesas_usb3_init_controller(usb3); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(renesas_usb3_pm_ops, renesas_usb3_suspend, + renesas_usb3_resume); + static struct platform_driver renesas_usb3_driver = { .probe = renesas_usb3_probe, .remove = renesas_usb3_remove, .driver = { .name = (char *)udc_name, + .pm = &renesas_usb3_pm_ops, .of_match_table = of_match_ptr(usb3_of_match), }, }; diff --git a/drivers/usb/gadget/udc/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c index 42587b738a1f..31c7c5587cf9 100644 --- a/drivers/usb/gadget/udc/s3c-hsudc.c +++ b/drivers/usb/gadget/udc/s3c-hsudc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* linux/drivers/usb/gadget/s3c-hsudc.c * * Copyright (c) 2010 Samsung Electronics Co., Ltd. @@ -8,11 +9,7 @@ * The S3C24XX USB 2.0 high-speed USB controller supports upto 9 endpoints. * Each endpoint can be configured as either in or out endpoint. Endpoints * can be configured for Bulk or Interrupt transfer mode. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ + */ #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index 4643a01262b4..f154f49e98c8 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * linux/drivers/usb/gadget/s3c2410_udc.c * @@ -5,11 +6,6 @@ * * Copyright (C) 2004-2007 Herbert Pötzl - Arnaud Patard * Additional cleanups by Ben Dooks <ben-linux@fluff.org> - * - * 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. */ #define pr_fmt(fmt) "s3c2410_udc: " fmt @@ -51,7 +47,6 @@ #include "s3c2410_udc.h" #define DRIVER_DESC "S3C2410 USB Device Controller Gadget" -#define DRIVER_VERSION "29 Apr 2007" #define DRIVER_AUTHOR "Herbert Pötzl <herbert@13thfloor.at>, " \ "Arnaud Patard <arnaud.patard@rtp-net.org>" @@ -1996,7 +1991,7 @@ static int __init udc_init(void) { int retval; - dprintk(DEBUG_NORMAL, "%s: version %s\n", gadget_name, DRIVER_VERSION); + dprintk(DEBUG_NORMAL, "%s\n", gadget_name); s3c2410_udc_debugfs_root = debugfs_create_dir(gadget_name, NULL); if (IS_ERR(s3c2410_udc_debugfs_root)) { @@ -2027,5 +2022,4 @@ module_exit(udc_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/udc/s3c2410_udc.h b/drivers/usb/gadget/udc/s3c2410_udc.h index 93bf225f1969..bdcaa8dd300f 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.h +++ b/drivers/usb/gadget/udc/s3c2410_udc.h @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * linux/drivers/usb/gadget/s3c2410_udc.h * Samsung on-chip full speed USB device controllers * * Copyright (C) 2004-2007 Herbert Pötzl - Arnaud Patard * Additional cleanups by Ben Dooks <ben-linux@fluff.org> - * - * 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. */ #ifndef _S3C2410_UDC_H diff --git a/drivers/usb/gadget/udc/snps_udc_core.c b/drivers/usb/gadget/udc/snps_udc_core.c index 38a165dbf924..d4da47f4f6f4 100644 --- a/drivers/usb/gadget/udc/snps_udc_core.c +++ b/drivers/usb/gadget/udc/snps_udc_core.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * amd5536.c -- AMD 5536 UDC high/full speed USB device controller * * Copyright (C) 2005-2007 AMD (http://www.amd.com) * Author: Thomas Dahlmann - * - * 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. */ /* @@ -1733,7 +1729,7 @@ static void udc_soft_reset(struct udc *dev) } /* RDE timer callback to set RDE bit */ -static void udc_timer_function(unsigned long v) +static void udc_timer_function(struct timer_list *unused) { u32 tmp; @@ -1813,7 +1809,7 @@ static void udc_handle_halt_state(struct udc_ep *ep) } /* Stall timer callback to poll S bit and set it again after */ -static void udc_pollstall_timer_function(unsigned long v) +static void udc_pollstall_timer_function(struct timer_list *unused) { struct udc_ep *ep; int halted = 0; @@ -3067,14 +3063,12 @@ void udc_remove(struct udc *dev) stop_timer++; if (timer_pending(&udc_timer)) wait_for_completion(&on_exit); - if (udc_timer.data) - del_timer_sync(&udc_timer); + del_timer_sync(&udc_timer); /* remove pollstall timer */ stop_pollstall_timer++; if (timer_pending(&udc_pollstall_timer)) wait_for_completion(&on_pollstall_exit); - if (udc_pollstall_timer.data) - del_timer_sync(&udc_pollstall_timer); + del_timer_sync(&udc_pollstall_timer); udc = NULL; } EXPORT_SYMBOL_GPL(udc_remove); @@ -3164,10 +3158,6 @@ int udc_probe(struct udc *dev) u32 reg; int retval; - /* mark timer as not initialized */ - udc_timer.data = 0; - udc_pollstall_timer.data = 0; - /* device struct setup */ dev->gadget.ops = &udc_ops; @@ -3207,13 +3197,8 @@ int udc_probe(struct udc *dev) goto finished; /* timer init */ - init_timer(&udc_timer); - udc_timer.function = udc_timer_function; - udc_timer.data = 1; - /* timer pollstall init */ - init_timer(&udc_pollstall_timer); - udc_pollstall_timer.function = udc_pollstall_timer_function; - udc_pollstall_timer.data = 1; + timer_setup(&udc_timer, udc_timer_function, 0); + timer_setup(&udc_pollstall_timer, udc_pollstall_timer_function, 0); /* set SD */ reg = readl(&dev->regs->ctl); diff --git a/drivers/usb/gadget/udc/snps_udc_plat.c b/drivers/usb/gadget/udc/snps_udc_plat.c index f7b4d0f159e4..32f1d3e90c26 100644 --- a/drivers/usb/gadget/udc/snps_udc_plat.c +++ b/drivers/usb/gadget/udc/snps_udc_plat.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * snps_udc_plat.c - Synopsys UDC Platform Driver * * Copyright (C) 2016 Broadcom - * - * 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 version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/extcon.h> @@ -184,7 +176,7 @@ static int udc_plat_probe(struct platform_device *pdev) goto exit_phy; } - ret = extcon_get_cable_state_(udc->edev, EXTCON_USB); + ret = extcon_get_state(udc->edev, EXTCON_USB); if (ret < 0) { dev_err(dev, "Can't get cable state\n"); goto exit_extcon; @@ -273,7 +265,7 @@ static int udc_plat_suspend(struct device *dev) udc = dev_get_drvdata(dev); stop_udc(udc); - if (extcon_get_cable_state_(udc->edev, EXTCON_USB) > 0) { + if (extcon_get_state(udc->edev, EXTCON_USB) > 0) { dev_dbg(udc->dev, "device -> idle\n"); stop_udc(udc); } @@ -303,7 +295,7 @@ static int udc_plat_resume(struct device *dev) return ret; } - if (extcon_get_cable_state_(udc->edev, EXTCON_USB) > 0) { + if (extcon_get_state(udc->edev, EXTCON_USB) > 0) { dev_dbg(udc->dev, "idle -> device\n"); start_udc(udc); } diff --git a/drivers/usb/gadget/udc/trace.c b/drivers/usb/gadget/udc/trace.c index 8c551ab91ad8..7430624c0bd7 100644 --- a/drivers/usb/gadget/udc/trace.c +++ b/drivers/usb/gadget/udc/trace.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /** * trace.c - USB Gadget Framework Trace Support * * Copyright (C) 2016 Intel Corporation * Author: Felipe Balbi <felipe.balbi@linux.intel.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 of - * the License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define CREATE_TRACE_POINTS diff --git a/drivers/usb/gadget/udc/trace.h b/drivers/usb/gadget/udc/trace.h index da29874b5366..f07ddb3f4bb9 100644 --- a/drivers/usb/gadget/udc/trace.h +++ b/drivers/usb/gadget/udc/trace.h @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /** * udc.c - Core UDC Framework * * Copyright (C) 2016 Intel Corporation * Author: Felipe Balbi <felipe.balbi@linux.intel.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 of - * the License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #undef TRACE_SYSTEM diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c index de207a90571e..7da2b9ce8cb3 100644 --- a/drivers/usb/gadget/udc/udc-xilinx.c +++ b/drivers/usb/gadget/udc/udc-xilinx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Xilinx USB peripheral controller driver * @@ -8,12 +9,6 @@ * * Some parts of this driver code is based on the driver for at91-series * USB peripheral controller (at91_udc.c). - * - * 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. */ #include <linux/delay.h> diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index 73a4dfba0edb..566ab261e8b7 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c @@ -1,10 +1,6 @@ +// SPDX-License-Identifier: LGPL-2.1+ /* * Copyright (C) 2003 David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. */ #include <linux/errno.h> |

