aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-03-26 13:08:25 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-03-26 13:08:25 -0700
commit710f5d627a98e86f821aceb840b8f2f1fcc6cf75 (patch)
treeb1cd55a33cfdb8e872d7189333570079efc908ac /drivers/usb/core
parentMerge branch 'i2c/for-mergewindow' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux (diff)
parentusb: gadget: fsl_qe_udc: Add missing semicolon in qe_ep_dequeue() (diff)
downloadlinux-dev-710f5d627a98e86f821aceb840b8f2f1fcc6cf75.tar.xz
linux-dev-710f5d627a98e86f821aceb840b8f2f1fcc6cf75.zip
Merge tag 'usb-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/Thunderbolt updates from Greg KH: "Here is the big set of USB and Thunderbolt changes for 5.18-rc1. Nothing major in here, just lots of little improvements and cleanups and new device support. Highlights are: - list iterator fixups for when we walk past the end of the list (a common problem that was cut/pasted in almost all USB gadget drivers) - xen USB driver "hardening" for malicious hosts - xhci driver updates and fixes for more hardware types - xhci debug cable fixes to make it actually work again - usb gadget audio driver improvements - usb gadget storage fixes to work with OS-X - lots of other small usb gadget fixes and updates - USB DWC3 driver improvements for more hardware types - Lots of other small USB driver improvements - DTS updates for some USB platforms All of these have been in linux-next for a while with no reported issues" * tag 'usb-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (172 commits) usb: gadget: fsl_qe_udc: Add missing semicolon in qe_ep_dequeue() dt-bindings: usb: mtk-xhci: add compatible for mt8186 usb: dwc3: Issue core soft reset before enabling run/stop usb: gadget: Makefile: remove ccflags-y USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c usb: gadget: eliminate anonymous module_init & module_exit usb: usbip: eliminate anonymous module_init & module_exit xen/usb: harden xen_hcd against malicious backends usb: dwc3: gadget: Wait for ep0 xfers to complete during dequeue usb: dwc3: gadget: move cmd_endtransfer to extra function usb: dwc3: gadget: ep_queue simplify isoc start condition xen/usb: don't use arbitrary_virt_to_machine() usb: isp1760: remove redundant max_packet() macro usb: oxu210hp-hcd: remove redundant call to max_packet() macro usb: common: usb-conn-gpio: Make VBUS supply completely optional USB: storage: ums-realtek: fix error code in rts51x_read_mem() usb: early: xhci-dbc: Fix xdbc number parsing usb: early: xhci-dbc: Remove duplicate keep parsing x86/tsc: Be consistent about use_tsc_delay() usb: gadget: udc: s3c2410: remove usage of list iterator past the loop body ...
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/devio.c32
-rw-r--r--drivers/usb/core/hcd-pci.c2
-rw-r--r--drivers/usb/core/hub.c21
-rw-r--r--drivers/usb/core/usb-acpi.c2
-rw-r--r--drivers/usb/core/usb.c8
5 files changed, 39 insertions, 26 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index fa66e6e58792..6abb7294e919 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -139,30 +139,42 @@ MODULE_PARM_DESC(usbfs_memory_mb,
/* Hard limit, necessary to avoid arithmetic overflow */
#define USBFS_XFER_MAX (UINT_MAX / 2 - 1000000)
-static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */
+static DEFINE_SPINLOCK(usbfs_memory_usage_lock);
+static u64 usbfs_memory_usage; /* Total memory currently allocated */
/* Check whether it's okay to allocate more memory for a transfer */
static int usbfs_increase_memory_usage(u64 amount)
{
- u64 lim;
+ u64 lim, total_mem;
+ unsigned long flags;
+ int ret;
lim = READ_ONCE(usbfs_memory_mb);
lim <<= 20;
- atomic64_add(amount, &usbfs_memory_usage);
-
- if (lim > 0 && atomic64_read(&usbfs_memory_usage) > lim) {
- atomic64_sub(amount, &usbfs_memory_usage);
- return -ENOMEM;
- }
+ ret = 0;
+ spin_lock_irqsave(&usbfs_memory_usage_lock, flags);
+ total_mem = usbfs_memory_usage + amount;
+ if (lim > 0 && total_mem > lim)
+ ret = -ENOMEM;
+ else
+ usbfs_memory_usage = total_mem;
+ spin_unlock_irqrestore(&usbfs_memory_usage_lock, flags);
- return 0;
+ return ret;
}
/* Memory for a transfer is being deallocated */
static void usbfs_decrease_memory_usage(u64 amount)
{
- atomic64_sub(amount, &usbfs_memory_usage);
+ unsigned long flags;
+
+ spin_lock_irqsave(&usbfs_memory_usage_lock, flags);
+ if (amount > usbfs_memory_usage)
+ usbfs_memory_usage = 0;
+ else
+ usbfs_memory_usage -= amount;
+ spin_unlock_irqrestore(&usbfs_memory_usage_lock, flags);
}
static int connected(struct usb_dev_state *ps)
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index dd44e37a454a..8176bc81a635 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -248,7 +248,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id,
hcd->rsrc_len, driver->description))
break;
}
- if (region == PCI_ROM_RESOURCE) {
+ if (region == PCI_STD_NUM_BARS) {
dev_dbg(&dev->dev, "no i/o regions available\n");
retval = -EBUSY;
goto put_hcd;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 47a1c8bddf86..1460857026e0 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2983,8 +2983,12 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
status);
}
- /* Check for disconnect or reset */
- if (status == 0 || status == -ENOTCONN || status == -ENODEV) {
+ /*
+ * Check for disconnect or reset, and bail out after several
+ * reset attempts to avoid warm reset loop.
+ */
+ if (status == 0 || status == -ENOTCONN || status == -ENODEV ||
+ (status == -EBUSY && i == PORT_RESET_TRIES - 1)) {
usb_clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_RESET);
@@ -5005,6 +5009,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
retval = usb_get_bos_descriptor(udev);
if (!retval) {
udev->lpm_capable = usb_device_supports_lpm(udev);
+ udev->lpm_disable_count = 1;
usb_set_lpm_parameters(udev);
}
}
@@ -5928,16 +5933,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
*/
usb_disable_usb2_hardware_lpm(udev);
- /* Disable LPM while we reset the device and reinstall the alt settings.
- * Device-initiated LPM, and system exit latency settings are cleared
- * when the device is reset, so we have to set them up again.
- */
- ret = usb_unlocked_disable_lpm(udev);
- if (ret) {
- dev_err(&udev->dev, "%s Failed to disable LPM\n", __func__);
- goto re_enumerate_no_bos;
- }
-
bos = udev->bos;
udev->bos = NULL;
@@ -6042,8 +6037,6 @@ done:
re_enumerate:
usb_release_bos_descriptor(udev);
udev->bos = bos;
-re_enumerate_no_bos:
- /* LPM state doesn't matter when we're about to destroy the device. */
hub_port_logical_disconnect(parent_hub, port1);
return -ENODEV;
}
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index 50b2fc7fcc0e..bb1da35eb891 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -166,7 +166,7 @@ usb_acpi_get_companion_for_port(struct usb_port *port_dev)
if (!parent_handle)
return NULL;
- acpi_bus_get_device(parent_handle, &adev);
+ adev = acpi_fetch_acpi_dev(parent_handle);
port1 = port_dev->portnum;
}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 2ce3667ec6fa..2f71636af6e1 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -688,6 +688,10 @@ EXPORT_SYMBOL_GPL(usb_alloc_dev);
* Drivers for USB interfaces should normally record such references in
* their probe() methods, when they bind to an interface, and release
* them by calling usb_put_dev(), in their disconnect() methods.
+ * However, if a driver does not access the usb_device structure after
+ * its disconnect() method returns then refcounting is not necessary,
+ * because the USB core guarantees that a usb_device will not be
+ * deallocated until after all of its interface drivers have been unbound.
*
* Return: A pointer to the device with the incremented reference counter.
*/
@@ -722,6 +726,10 @@ EXPORT_SYMBOL_GPL(usb_put_dev);
* Drivers for USB interfaces should normally record such references in
* their probe() methods, when they bind to an interface, and release
* them by calling usb_put_intf(), in their disconnect() methods.
+ * However, if a driver does not access the usb_interface structure after
+ * its disconnect() method returns then refcounting is not necessary,
+ * because the USB core guarantees that a usb_interface will not be
+ * deallocated until after its driver has been unbound.
*
* Return: A pointer to the interface with the incremented reference counter.
*/