diff options
Diffstat (limited to 'drivers/usb/core')
| -rw-r--r-- | drivers/usb/core/Makefile | 5 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.c | 8 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 43 | ||||
| -rw-r--r-- | drivers/usb/core/message.c | 2 | ||||
| -rw-r--r-- | drivers/usb/core/quirks.c | 2 | ||||
| -rw-r--r-- | drivers/usb/core/trace.c | 6 | ||||
| -rw-r--r-- | drivers/usb/core/trace.h | 61 | ||||
| -rw-r--r-- | drivers/usb/core/usb.c | 2 |
8 files changed, 102 insertions, 27 deletions
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 766000b4939e..60ea76160122 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -3,10 +3,13 @@ # Makefile for USB Core files and filesystem # +# define_trace.h needs to know how to find our header +CFLAGS_trace.o := -I$(src) + usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o usbcore-y += devio.o notify.o generic.o quirks.o devices.o -usbcore-y += phy.o port.o +usbcore-y += phy.o port.o trace.o usbcore-$(CONFIG_OF) += of.o usbcore-$(CONFIG_USB_XHCI_SIDEBAND) += offload.o diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 9dd79769cad1..24feb0de1c00 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2696,18 +2696,18 @@ static void hcd_release(struct kref *kref) kfree(hcd); } -struct usb_hcd *usb_get_hcd (struct usb_hcd *hcd) +struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd) { if (hcd) - kref_get (&hcd->kref); + kref_get(&hcd->kref); return hcd; } EXPORT_SYMBOL_GPL(usb_get_hcd); -void usb_put_hcd (struct usb_hcd *hcd) +void usb_put_hcd(struct usb_hcd *hcd) { if (hcd) - kref_put (&hcd->kref, hcd_release); + kref_put(&hcd->kref, hcd_release); } EXPORT_SYMBOL_GPL(usb_put_hcd); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 256fe8c86828..be50d03034a9 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -28,6 +28,7 @@ #include <linux/usb/otg.h> #include <linux/usb/quirks.h> #include <linux/workqueue.h> +#include <linux/minmax.h> #include <linux/mutex.h> #include <linux/random.h> #include <linux/pm_qos.h> @@ -40,6 +41,7 @@ #include "hub.h" #include "phy.h" #include "otg_productlist.h" +#include "trace.h" #define USB_VENDOR_GENESYS_LOGIC 0x05e3 #define USB_VENDOR_SMSC 0x0424 @@ -277,10 +279,7 @@ static void usb_set_lpm_pel(struct usb_device *udev, * device and the parent hub into U0. The exit latency is the bigger of * the device exit latency or the hub exit latency. */ - if (udev_exit_latency > hub_exit_latency) - first_link_pel = udev_exit_latency * 1000; - else - first_link_pel = hub_exit_latency * 1000; + first_link_pel = max(udev_exit_latency, hub_exit_latency) * 1000; /* * When the hub starts to receive the LFPS, there is a slight delay for @@ -294,10 +293,7 @@ static void usb_set_lpm_pel(struct usb_device *udev, * According to figure C-7 in the USB 3.0 spec, the PEL for this device * is the greater of the two exit latencies. */ - if (first_link_pel > hub_pel) - udev_lpm_params->pel = first_link_pel; - else - udev_lpm_params->pel = hub_pel; + udev_lpm_params->pel = max(first_link_pel, hub_pel); } /* @@ -2147,6 +2143,21 @@ static void update_port_device_state(struct usb_device *udev) } } +static void update_usb_device_state(struct usb_device *udev, + enum usb_device_state new_state) +{ + if (udev->state == USB_STATE_SUSPENDED && + new_state != USB_STATE_SUSPENDED) + udev->active_duration -= jiffies; + else if (new_state == USB_STATE_SUSPENDED && + udev->state != USB_STATE_SUSPENDED) + udev->active_duration += jiffies; + + udev->state = new_state; + update_port_device_state(udev); + trace_usb_set_device_state(udev); +} + static void recursively_mark_NOTATTACHED(struct usb_device *udev) { struct usb_hub *hub = usb_hub_to_struct_hub(udev); @@ -2156,10 +2167,7 @@ static void recursively_mark_NOTATTACHED(struct usb_device *udev) if (hub->ports[i]->child) recursively_mark_NOTATTACHED(hub->ports[i]->child); } - if (udev->state == USB_STATE_SUSPENDED) - udev->active_duration -= jiffies; - udev->state = USB_STATE_NOTATTACHED; - update_port_device_state(udev); + update_usb_device_state(udev, USB_STATE_NOTATTACHED); } /** @@ -2209,14 +2217,7 @@ void usb_set_device_state(struct usb_device *udev, else wakeup = 0; } - if (udev->state == USB_STATE_SUSPENDED && - new_state != USB_STATE_SUSPENDED) - udev->active_duration -= jiffies; - else if (new_state == USB_STATE_SUSPENDED && - udev->state != USB_STATE_SUSPENDED) - udev->active_duration += jiffies; - udev->state = new_state; - update_port_device_state(udev); + update_usb_device_state(udev, new_state); } else recursively_mark_NOTATTACHED(udev); spin_unlock_irqrestore(&device_state_lock, flags); @@ -6077,7 +6078,7 @@ int usb_hub_init(void) * device was gone before the EHCI controller had handed its port * over to the companion full-speed controller. */ - hub_wq = alloc_workqueue("usb_hub_wq", WQ_FREEZABLE, 0); + hub_wq = alloc_workqueue("usb_hub_wq", WQ_FREEZABLE | WQ_PERCPU, 0); if (hub_wq) return 0; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index d2b2787be409..6138468c67c4 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -2431,7 +2431,7 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, break; case USB_CDC_MBIM_EXTENDED_TYPE: if (elength < sizeof(struct usb_cdc_mbim_extended_desc)) - break; + goto next_desc; hdr->usb_cdc_mbim_extended_desc = (struct usb_cdc_mbim_extended_desc *)buffer; break; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f5bc53875330..47f589c4104a 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -467,6 +467,8 @@ static const struct usb_device_id usb_quirk_list[] = { /* Huawei 4G LTE module */ { USB_DEVICE(0x12d1, 0x15bb), .driver_info = USB_QUIRK_DISCONNECT_SUSPEND }, + { USB_DEVICE(0x12d1, 0x15c1), .driver_info = + USB_QUIRK_DISCONNECT_SUSPEND }, { USB_DEVICE(0x12d1, 0x15c3), .driver_info = USB_QUIRK_DISCONNECT_SUSPEND }, diff --git a/drivers/usb/core/trace.c b/drivers/usb/core/trace.c new file mode 100644 index 000000000000..607bcf639d27 --- /dev/null +++ b/drivers/usb/core/trace.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Google LLC + */ +#define CREATE_TRACE_POINTS +#include "trace.h" diff --git a/drivers/usb/core/trace.h b/drivers/usb/core/trace.h new file mode 100644 index 000000000000..903e57dc273a --- /dev/null +++ b/drivers/usb/core/trace.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2025 Google LLC + */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM usbcore + +#if !defined(_USB_CORE_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _USB_CORE_TRACE_H + +#include <linux/types.h> +#include <linux/tracepoint.h> +#include <linux/usb.h> + +DECLARE_EVENT_CLASS(usb_core_log_usb_device, + TP_PROTO(struct usb_device *udev), + TP_ARGS(udev), + TP_STRUCT__entry( + __string(name, dev_name(&udev->dev)) + __field(enum usb_device_speed, speed) + __field(enum usb_device_state, state) + __field(unsigned short, bus_mA) + __field(unsigned, authorized) + ), + TP_fast_assign( + __assign_str(name); + __entry->speed = udev->speed; + __entry->state = udev->state; + __entry->bus_mA = udev->bus_mA; + __entry->authorized = udev->authorized; + ), + TP_printk("usb %s speed %s state %s %dmA [%s]", + __get_str(name), + usb_speed_string(__entry->speed), + usb_state_string(__entry->state), + __entry->bus_mA, + __entry->authorized ? "authorized" : "unauthorized") +); + +DEFINE_EVENT(usb_core_log_usb_device, usb_set_device_state, + TP_PROTO(struct usb_device *udev), + TP_ARGS(udev) +); + +DEFINE_EVENT(usb_core_log_usb_device, usb_alloc_dev, + TP_PROTO(struct usb_device *udev), + TP_ARGS(udev) +); + + +#endif /* _USB_CORE_TRACE_H */ + +/* this part has to be here */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . + +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace + +#include <trace/define_trace.h> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index b6b0b8489523..e740f7852bcd 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -46,6 +46,7 @@ #include <linux/dma-mapping.h> #include "hub.h" +#include "trace.h" const char *usbcore_name = "usbcore"; @@ -746,6 +747,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, #endif dev->authorized = usb_dev_authorized(dev, usb_hcd); + trace_usb_alloc_dev(dev); return dev; } EXPORT_SYMBOL_GPL(usb_alloc_dev); |
