162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * drivers/usb/core/generic.c - generic driver for USB devices (not interfaces) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * based on drivers/usb/usb.c which had the following copyrights: 862306a36Sopenharmony_ci * (C) Copyright Linus Torvalds 1999 962306a36Sopenharmony_ci * (C) Copyright Johannes Erdfelt 1999-2001 1062306a36Sopenharmony_ci * (C) Copyright Andreas Gal 1999 1162306a36Sopenharmony_ci * (C) Copyright Gregory P. Smith 1999 1262306a36Sopenharmony_ci * (C) Copyright Deti Fliegl 1999 (new USB architecture) 1362306a36Sopenharmony_ci * (C) Copyright Randy Dunlap 2000 1462306a36Sopenharmony_ci * (C) Copyright David Brownell 2000-2004 1562306a36Sopenharmony_ci * (C) Copyright Yggdrasil Computing, Inc. 2000 1662306a36Sopenharmony_ci * (usb_device_id matching changes by Adam J. Richter) 1762306a36Sopenharmony_ci * (C) Copyright Greg Kroah-Hartman 2002-2003 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * Released under the GPLv2 only. 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include <linux/usb.h> 2362306a36Sopenharmony_ci#include <linux/usb/hcd.h> 2462306a36Sopenharmony_ci#include <uapi/linux/usb/audio.h> 2562306a36Sopenharmony_ci#include "usb.h" 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic inline const char *plural(int n) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci return (n == 1 ? "" : "s"); 3062306a36Sopenharmony_ci} 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic int is_rndis(struct usb_interface_descriptor *desc) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci return desc->bInterfaceClass == USB_CLASS_COMM 3562306a36Sopenharmony_ci && desc->bInterfaceSubClass == 2 3662306a36Sopenharmony_ci && desc->bInterfaceProtocol == 0xff; 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic int is_activesync(struct usb_interface_descriptor *desc) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci return desc->bInterfaceClass == USB_CLASS_MISC 4262306a36Sopenharmony_ci && desc->bInterfaceSubClass == 1 4362306a36Sopenharmony_ci && desc->bInterfaceProtocol == 1; 4462306a36Sopenharmony_ci} 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic bool is_audio(struct usb_interface_descriptor *desc) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci return desc->bInterfaceClass == USB_CLASS_AUDIO; 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic bool is_uac3_config(struct usb_interface_descriptor *desc) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci return desc->bInterfaceProtocol == UAC_VERSION_3; 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ciint usb_choose_configuration(struct usb_device *udev) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci int i; 5962306a36Sopenharmony_ci int num_configs; 6062306a36Sopenharmony_ci int insufficient_power = 0; 6162306a36Sopenharmony_ci struct usb_host_config *c, *best; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci if (usb_device_is_owned(udev)) 6462306a36Sopenharmony_ci return 0; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci best = NULL; 6762306a36Sopenharmony_ci c = udev->config; 6862306a36Sopenharmony_ci num_configs = udev->descriptor.bNumConfigurations; 6962306a36Sopenharmony_ci for (i = 0; i < num_configs; (i++, c++)) { 7062306a36Sopenharmony_ci struct usb_interface_descriptor *desc = NULL; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci /* It's possible that a config has no interfaces! */ 7362306a36Sopenharmony_ci if (c->desc.bNumInterfaces > 0) 7462306a36Sopenharmony_ci desc = &c->intf_cache[0]->altsetting->desc; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci /* 7762306a36Sopenharmony_ci * HP's USB bus-powered keyboard has only one configuration 7862306a36Sopenharmony_ci * and it claims to be self-powered; other devices may have 7962306a36Sopenharmony_ci * similar errors in their descriptors. If the next test 8062306a36Sopenharmony_ci * were allowed to execute, such configurations would always 8162306a36Sopenharmony_ci * be rejected and the devices would not work as expected. 8262306a36Sopenharmony_ci * In the meantime, we run the risk of selecting a config 8362306a36Sopenharmony_ci * that requires external power at a time when that power 8462306a36Sopenharmony_ci * isn't available. It seems to be the lesser of two evils. 8562306a36Sopenharmony_ci * 8662306a36Sopenharmony_ci * Bugzilla #6448 reports a device that appears to crash 8762306a36Sopenharmony_ci * when it receives a GET_DEVICE_STATUS request! We don't 8862306a36Sopenharmony_ci * have any other way to tell whether a device is self-powered, 8962306a36Sopenharmony_ci * but since we don't use that information anywhere but here, 9062306a36Sopenharmony_ci * the call has been removed. 9162306a36Sopenharmony_ci * 9262306a36Sopenharmony_ci * Maybe the GET_DEVICE_STATUS call and the test below can 9362306a36Sopenharmony_ci * be reinstated when device firmwares become more reliable. 9462306a36Sopenharmony_ci * Don't hold your breath. 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_ci#if 0 9762306a36Sopenharmony_ci /* Rule out self-powered configs for a bus-powered device */ 9862306a36Sopenharmony_ci if (bus_powered && (c->desc.bmAttributes & 9962306a36Sopenharmony_ci USB_CONFIG_ATT_SELFPOWER)) 10062306a36Sopenharmony_ci continue; 10162306a36Sopenharmony_ci#endif 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci /* 10462306a36Sopenharmony_ci * The next test may not be as effective as it should be. 10562306a36Sopenharmony_ci * Some hubs have errors in their descriptor, claiming 10662306a36Sopenharmony_ci * to be self-powered when they are really bus-powered. 10762306a36Sopenharmony_ci * We will overestimate the amount of current such hubs 10862306a36Sopenharmony_ci * make available for each port. 10962306a36Sopenharmony_ci * 11062306a36Sopenharmony_ci * This is a fairly benign sort of failure. It won't 11162306a36Sopenharmony_ci * cause us to reject configurations that we should have 11262306a36Sopenharmony_ci * accepted. 11362306a36Sopenharmony_ci */ 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci /* Rule out configs that draw too much bus current */ 11662306a36Sopenharmony_ci if (usb_get_max_power(udev, c) > udev->bus_mA) { 11762306a36Sopenharmony_ci insufficient_power++; 11862306a36Sopenharmony_ci continue; 11962306a36Sopenharmony_ci } 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci /* 12262306a36Sopenharmony_ci * Select first configuration as default for audio so that 12362306a36Sopenharmony_ci * devices that don't comply with UAC3 protocol are supported. 12462306a36Sopenharmony_ci * But, still iterate through other configurations and 12562306a36Sopenharmony_ci * select UAC3 compliant config if present. 12662306a36Sopenharmony_ci */ 12762306a36Sopenharmony_ci if (desc && is_audio(desc)) { 12862306a36Sopenharmony_ci /* Always prefer the first found UAC3 config */ 12962306a36Sopenharmony_ci if (is_uac3_config(desc)) { 13062306a36Sopenharmony_ci best = c; 13162306a36Sopenharmony_ci break; 13262306a36Sopenharmony_ci } 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci /* If there is no UAC3 config, prefer the first config */ 13562306a36Sopenharmony_ci else if (i == 0) 13662306a36Sopenharmony_ci best = c; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci /* Unconditional continue, because the rest of the code 13962306a36Sopenharmony_ci * in the loop is irrelevant for audio devices, and 14062306a36Sopenharmony_ci * because it can reassign best, which for audio devices 14162306a36Sopenharmony_ci * we don't want. 14262306a36Sopenharmony_ci */ 14362306a36Sopenharmony_ci continue; 14462306a36Sopenharmony_ci } 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci /* When the first config's first interface is one of Microsoft's 14762306a36Sopenharmony_ci * pet nonstandard Ethernet-over-USB protocols, ignore it unless 14862306a36Sopenharmony_ci * this kernel has enabled the necessary host side driver. 14962306a36Sopenharmony_ci * But: Don't ignore it if it's the only config. 15062306a36Sopenharmony_ci */ 15162306a36Sopenharmony_ci if (i == 0 && num_configs > 1 && desc && 15262306a36Sopenharmony_ci (is_rndis(desc) || is_activesync(desc))) { 15362306a36Sopenharmony_ci#if !defined(CONFIG_USB_NET_RNDIS_HOST) && !defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) 15462306a36Sopenharmony_ci continue; 15562306a36Sopenharmony_ci#else 15662306a36Sopenharmony_ci best = c; 15762306a36Sopenharmony_ci#endif 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci /* From the remaining configs, choose the first one whose 16162306a36Sopenharmony_ci * first interface is for a non-vendor-specific class. 16262306a36Sopenharmony_ci * Reason: Linux is more likely to have a class driver 16362306a36Sopenharmony_ci * than a vendor-specific driver. */ 16462306a36Sopenharmony_ci else if (udev->descriptor.bDeviceClass != 16562306a36Sopenharmony_ci USB_CLASS_VENDOR_SPEC && 16662306a36Sopenharmony_ci (desc && desc->bInterfaceClass != 16762306a36Sopenharmony_ci USB_CLASS_VENDOR_SPEC)) { 16862306a36Sopenharmony_ci best = c; 16962306a36Sopenharmony_ci break; 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci /* If all the remaining configs are vendor-specific, 17362306a36Sopenharmony_ci * choose the first one. */ 17462306a36Sopenharmony_ci else if (!best) 17562306a36Sopenharmony_ci best = c; 17662306a36Sopenharmony_ci } 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci if (insufficient_power > 0) 17962306a36Sopenharmony_ci dev_info(&udev->dev, "rejected %d configuration%s " 18062306a36Sopenharmony_ci "due to insufficient available bus power\n", 18162306a36Sopenharmony_ci insufficient_power, plural(insufficient_power)); 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci if (best) { 18462306a36Sopenharmony_ci i = best->desc.bConfigurationValue; 18562306a36Sopenharmony_ci dev_dbg(&udev->dev, 18662306a36Sopenharmony_ci "configuration #%d chosen from %d choice%s\n", 18762306a36Sopenharmony_ci i, num_configs, plural(num_configs)); 18862306a36Sopenharmony_ci } else { 18962306a36Sopenharmony_ci i = -1; 19062306a36Sopenharmony_ci dev_warn(&udev->dev, 19162306a36Sopenharmony_ci "no configuration chosen from %d choice%s\n", 19262306a36Sopenharmony_ci num_configs, plural(num_configs)); 19362306a36Sopenharmony_ci } 19462306a36Sopenharmony_ci return i; 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_choose_configuration); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cistatic int __check_for_non_generic_match(struct device_driver *drv, void *data) 19962306a36Sopenharmony_ci{ 20062306a36Sopenharmony_ci struct usb_device *udev = data; 20162306a36Sopenharmony_ci struct usb_device_driver *udrv; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci if (!is_usb_device_driver(drv)) 20462306a36Sopenharmony_ci return 0; 20562306a36Sopenharmony_ci udrv = to_usb_device_driver(drv); 20662306a36Sopenharmony_ci if (udrv == &usb_generic_driver) 20762306a36Sopenharmony_ci return 0; 20862306a36Sopenharmony_ci return usb_driver_applicable(udev, udrv); 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_cistatic bool usb_generic_driver_match(struct usb_device *udev) 21262306a36Sopenharmony_ci{ 21362306a36Sopenharmony_ci if (udev->use_generic_driver) 21462306a36Sopenharmony_ci return true; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci /* 21762306a36Sopenharmony_ci * If any other driver wants the device, leave the device to this other 21862306a36Sopenharmony_ci * driver. 21962306a36Sopenharmony_ci */ 22062306a36Sopenharmony_ci if (bus_for_each_drv(&usb_bus_type, NULL, udev, __check_for_non_generic_match)) 22162306a36Sopenharmony_ci return false; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci return true; 22462306a36Sopenharmony_ci} 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ciint usb_generic_driver_probe(struct usb_device *udev) 22762306a36Sopenharmony_ci{ 22862306a36Sopenharmony_ci int err, c; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci /* Choose and set the configuration. This registers the interfaces 23162306a36Sopenharmony_ci * with the driver core and lets interface drivers bind to them. 23262306a36Sopenharmony_ci */ 23362306a36Sopenharmony_ci if (udev->authorized == 0) 23462306a36Sopenharmony_ci dev_err(&udev->dev, "Device is not authorized for usage\n"); 23562306a36Sopenharmony_ci else { 23662306a36Sopenharmony_ci c = usb_choose_configuration(udev); 23762306a36Sopenharmony_ci if (c >= 0) { 23862306a36Sopenharmony_ci err = usb_set_configuration(udev, c); 23962306a36Sopenharmony_ci if (err && err != -ENODEV) { 24062306a36Sopenharmony_ci dev_err(&udev->dev, "can't set config #%d, error %d\n", 24162306a36Sopenharmony_ci c, err); 24262306a36Sopenharmony_ci /* This need not be fatal. The user can try to 24362306a36Sopenharmony_ci * set other configurations. */ 24462306a36Sopenharmony_ci } 24562306a36Sopenharmony_ci } 24662306a36Sopenharmony_ci } 24762306a36Sopenharmony_ci /* USB device state == configured ... usable */ 24862306a36Sopenharmony_ci usb_notify_add_device(udev); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci return 0; 25162306a36Sopenharmony_ci} 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_civoid usb_generic_driver_disconnect(struct usb_device *udev) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci usb_notify_remove_device(udev); 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci /* if this is only an unbind, not a physical disconnect, then 25862306a36Sopenharmony_ci * unconfigure the device */ 25962306a36Sopenharmony_ci if (udev->actconfig) 26062306a36Sopenharmony_ci usb_set_configuration(udev, -1); 26162306a36Sopenharmony_ci} 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci#ifdef CONFIG_PM 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ciint usb_generic_driver_suspend(struct usb_device *udev, pm_message_t msg) 26662306a36Sopenharmony_ci{ 26762306a36Sopenharmony_ci int rc; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci /* Normal USB devices suspend through their upstream port. 27062306a36Sopenharmony_ci * Root hubs don't have upstream ports to suspend, 27162306a36Sopenharmony_ci * so we have to shut down their downstream HC-to-USB 27262306a36Sopenharmony_ci * interfaces manually by doing a bus (or "global") suspend. 27362306a36Sopenharmony_ci */ 27462306a36Sopenharmony_ci if (!udev->parent) 27562306a36Sopenharmony_ci rc = hcd_bus_suspend(udev, msg); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci /* 27862306a36Sopenharmony_ci * Non-root USB2 devices don't need to do anything for FREEZE 27962306a36Sopenharmony_ci * or PRETHAW. USB3 devices don't support global suspend and 28062306a36Sopenharmony_ci * needs to be selectively suspended. 28162306a36Sopenharmony_ci */ 28262306a36Sopenharmony_ci else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) 28362306a36Sopenharmony_ci && (udev->speed < USB_SPEED_SUPER)) 28462306a36Sopenharmony_ci rc = 0; 28562306a36Sopenharmony_ci else 28662306a36Sopenharmony_ci rc = usb_port_suspend(udev, msg); 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci if (rc == 0) 28962306a36Sopenharmony_ci usbfs_notify_suspend(udev); 29062306a36Sopenharmony_ci return rc; 29162306a36Sopenharmony_ci} 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ciint usb_generic_driver_resume(struct usb_device *udev, pm_message_t msg) 29462306a36Sopenharmony_ci{ 29562306a36Sopenharmony_ci int rc; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci /* Normal USB devices resume/reset through their upstream port. 29862306a36Sopenharmony_ci * Root hubs don't have upstream ports to resume or reset, 29962306a36Sopenharmony_ci * so we have to start up their downstream HC-to-USB 30062306a36Sopenharmony_ci * interfaces manually by doing a bus (or "global") resume. 30162306a36Sopenharmony_ci */ 30262306a36Sopenharmony_ci if (!udev->parent) 30362306a36Sopenharmony_ci rc = hcd_bus_resume(udev, msg); 30462306a36Sopenharmony_ci else 30562306a36Sopenharmony_ci rc = usb_port_resume(udev, msg); 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci if (rc == 0) 30862306a36Sopenharmony_ci usbfs_notify_resume(udev); 30962306a36Sopenharmony_ci return rc; 31062306a36Sopenharmony_ci} 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci#endif /* CONFIG_PM */ 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_cistruct usb_device_driver usb_generic_driver = { 31562306a36Sopenharmony_ci .name = "usb", 31662306a36Sopenharmony_ci .match = usb_generic_driver_match, 31762306a36Sopenharmony_ci .probe = usb_generic_driver_probe, 31862306a36Sopenharmony_ci .disconnect = usb_generic_driver_disconnect, 31962306a36Sopenharmony_ci#ifdef CONFIG_PM 32062306a36Sopenharmony_ci .suspend = usb_generic_driver_suspend, 32162306a36Sopenharmony_ci .resume = usb_generic_driver_resume, 32262306a36Sopenharmony_ci#endif 32362306a36Sopenharmony_ci .supports_autosuspend = 1, 32462306a36Sopenharmony_ci}; 325