18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * drivers/usb/driver.c - most of the driver model stuff for usb 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * based on drivers/usb/usb.c which had the following copyrights: 88c2ecf20Sopenharmony_ci * (C) Copyright Linus Torvalds 1999 98c2ecf20Sopenharmony_ci * (C) Copyright Johannes Erdfelt 1999-2001 108c2ecf20Sopenharmony_ci * (C) Copyright Andreas Gal 1999 118c2ecf20Sopenharmony_ci * (C) Copyright Gregory P. Smith 1999 128c2ecf20Sopenharmony_ci * (C) Copyright Deti Fliegl 1999 (new USB architecture) 138c2ecf20Sopenharmony_ci * (C) Copyright Randy Dunlap 2000 148c2ecf20Sopenharmony_ci * (C) Copyright David Brownell 2000-2004 158c2ecf20Sopenharmony_ci * (C) Copyright Yggdrasil Computing, Inc. 2000 168c2ecf20Sopenharmony_ci * (usb_device_id matching changes by Adam J. Richter) 178c2ecf20Sopenharmony_ci * (C) Copyright Greg Kroah-Hartman 2002-2003 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * Released under the GPLv2 only. 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * NOTE! This is not actually a driver at all, rather this is 228c2ecf20Sopenharmony_ci * just a collection of helper routines that implement the 238c2ecf20Sopenharmony_ci * matching, probing, releasing, suspending and resuming for 248c2ecf20Sopenharmony_ci * real drivers. 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#include <linux/device.h> 298c2ecf20Sopenharmony_ci#include <linux/slab.h> 308c2ecf20Sopenharmony_ci#include <linux/export.h> 318c2ecf20Sopenharmony_ci#include <linux/usb.h> 328c2ecf20Sopenharmony_ci#include <linux/usb/quirks.h> 338c2ecf20Sopenharmony_ci#include <linux/usb/hcd.h> 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#include "usb.h" 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci/* 398c2ecf20Sopenharmony_ci * Adds a new dynamic USBdevice ID to this driver, 408c2ecf20Sopenharmony_ci * and cause the driver to probe for all devices again. 418c2ecf20Sopenharmony_ci */ 428c2ecf20Sopenharmony_cissize_t usb_store_new_id(struct usb_dynids *dynids, 438c2ecf20Sopenharmony_ci const struct usb_device_id *id_table, 448c2ecf20Sopenharmony_ci struct device_driver *driver, 458c2ecf20Sopenharmony_ci const char *buf, size_t count) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci struct usb_dynid *dynid; 488c2ecf20Sopenharmony_ci u32 idVendor = 0; 498c2ecf20Sopenharmony_ci u32 idProduct = 0; 508c2ecf20Sopenharmony_ci unsigned int bInterfaceClass = 0; 518c2ecf20Sopenharmony_ci u32 refVendor, refProduct; 528c2ecf20Sopenharmony_ci int fields = 0; 538c2ecf20Sopenharmony_ci int retval = 0; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci fields = sscanf(buf, "%x %x %x %x %x", &idVendor, &idProduct, 568c2ecf20Sopenharmony_ci &bInterfaceClass, &refVendor, &refProduct); 578c2ecf20Sopenharmony_ci if (fields < 2) 588c2ecf20Sopenharmony_ci return -EINVAL; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); 618c2ecf20Sopenharmony_ci if (!dynid) 628c2ecf20Sopenharmony_ci return -ENOMEM; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&dynid->node); 658c2ecf20Sopenharmony_ci dynid->id.idVendor = idVendor; 668c2ecf20Sopenharmony_ci dynid->id.idProduct = idProduct; 678c2ecf20Sopenharmony_ci dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; 688c2ecf20Sopenharmony_ci if (fields > 2 && bInterfaceClass) { 698c2ecf20Sopenharmony_ci if (bInterfaceClass > 255) { 708c2ecf20Sopenharmony_ci retval = -EINVAL; 718c2ecf20Sopenharmony_ci goto fail; 728c2ecf20Sopenharmony_ci } 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci dynid->id.bInterfaceClass = (u8)bInterfaceClass; 758c2ecf20Sopenharmony_ci dynid->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS; 768c2ecf20Sopenharmony_ci } 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci if (fields > 4) { 798c2ecf20Sopenharmony_ci const struct usb_device_id *id = id_table; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci if (!id) { 828c2ecf20Sopenharmony_ci retval = -ENODEV; 838c2ecf20Sopenharmony_ci goto fail; 848c2ecf20Sopenharmony_ci } 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci for (; id->match_flags; id++) 878c2ecf20Sopenharmony_ci if (id->idVendor == refVendor && id->idProduct == refProduct) 888c2ecf20Sopenharmony_ci break; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci if (id->match_flags) { 918c2ecf20Sopenharmony_ci dynid->id.driver_info = id->driver_info; 928c2ecf20Sopenharmony_ci } else { 938c2ecf20Sopenharmony_ci retval = -ENODEV; 948c2ecf20Sopenharmony_ci goto fail; 958c2ecf20Sopenharmony_ci } 968c2ecf20Sopenharmony_ci } 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci spin_lock(&dynids->lock); 998c2ecf20Sopenharmony_ci list_add_tail(&dynid->node, &dynids->list); 1008c2ecf20Sopenharmony_ci spin_unlock(&dynids->lock); 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci retval = driver_attach(driver); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci if (retval) 1058c2ecf20Sopenharmony_ci return retval; 1068c2ecf20Sopenharmony_ci return count; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cifail: 1098c2ecf20Sopenharmony_ci kfree(dynid); 1108c2ecf20Sopenharmony_ci return retval; 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_store_new_id); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cissize_t usb_show_dynids(struct usb_dynids *dynids, char *buf) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci struct usb_dynid *dynid; 1178c2ecf20Sopenharmony_ci size_t count = 0; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci list_for_each_entry(dynid, &dynids->list, node) 1208c2ecf20Sopenharmony_ci if (dynid->id.bInterfaceClass != 0) 1218c2ecf20Sopenharmony_ci count += scnprintf(&buf[count], PAGE_SIZE - count, "%04x %04x %02x\n", 1228c2ecf20Sopenharmony_ci dynid->id.idVendor, dynid->id.idProduct, 1238c2ecf20Sopenharmony_ci dynid->id.bInterfaceClass); 1248c2ecf20Sopenharmony_ci else 1258c2ecf20Sopenharmony_ci count += scnprintf(&buf[count], PAGE_SIZE - count, "%04x %04x\n", 1268c2ecf20Sopenharmony_ci dynid->id.idVendor, dynid->id.idProduct); 1278c2ecf20Sopenharmony_ci return count; 1288c2ecf20Sopenharmony_ci} 1298c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_show_dynids); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistatic ssize_t new_id_show(struct device_driver *driver, char *buf) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci struct usb_driver *usb_drv = to_usb_driver(driver); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci return usb_show_dynids(&usb_drv->dynids, buf); 1368c2ecf20Sopenharmony_ci} 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic ssize_t new_id_store(struct device_driver *driver, 1398c2ecf20Sopenharmony_ci const char *buf, size_t count) 1408c2ecf20Sopenharmony_ci{ 1418c2ecf20Sopenharmony_ci struct usb_driver *usb_drv = to_usb_driver(driver); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci return usb_store_new_id(&usb_drv->dynids, usb_drv->id_table, driver, buf, count); 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_cistatic DRIVER_ATTR_RW(new_id); 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci/* 1488c2ecf20Sopenharmony_ci * Remove a USB device ID from this driver 1498c2ecf20Sopenharmony_ci */ 1508c2ecf20Sopenharmony_cistatic ssize_t remove_id_store(struct device_driver *driver, const char *buf, 1518c2ecf20Sopenharmony_ci size_t count) 1528c2ecf20Sopenharmony_ci{ 1538c2ecf20Sopenharmony_ci struct usb_dynid *dynid, *n; 1548c2ecf20Sopenharmony_ci struct usb_driver *usb_driver = to_usb_driver(driver); 1558c2ecf20Sopenharmony_ci u32 idVendor; 1568c2ecf20Sopenharmony_ci u32 idProduct; 1578c2ecf20Sopenharmony_ci int fields; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci fields = sscanf(buf, "%x %x", &idVendor, &idProduct); 1608c2ecf20Sopenharmony_ci if (fields < 2) 1618c2ecf20Sopenharmony_ci return -EINVAL; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci spin_lock(&usb_driver->dynids.lock); 1648c2ecf20Sopenharmony_ci list_for_each_entry_safe(dynid, n, &usb_driver->dynids.list, node) { 1658c2ecf20Sopenharmony_ci struct usb_device_id *id = &dynid->id; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci if ((id->idVendor == idVendor) && 1688c2ecf20Sopenharmony_ci (id->idProduct == idProduct)) { 1698c2ecf20Sopenharmony_ci list_del(&dynid->node); 1708c2ecf20Sopenharmony_ci kfree(dynid); 1718c2ecf20Sopenharmony_ci break; 1728c2ecf20Sopenharmony_ci } 1738c2ecf20Sopenharmony_ci } 1748c2ecf20Sopenharmony_ci spin_unlock(&usb_driver->dynids.lock); 1758c2ecf20Sopenharmony_ci return count; 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistatic ssize_t remove_id_show(struct device_driver *driver, char *buf) 1798c2ecf20Sopenharmony_ci{ 1808c2ecf20Sopenharmony_ci return new_id_show(driver, buf); 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_cistatic DRIVER_ATTR_RW(remove_id); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_cistatic int usb_create_newid_files(struct usb_driver *usb_drv) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci int error = 0; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci if (usb_drv->no_dynamic_id) 1898c2ecf20Sopenharmony_ci goto exit; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci if (usb_drv->probe != NULL) { 1928c2ecf20Sopenharmony_ci error = driver_create_file(&usb_drv->drvwrap.driver, 1938c2ecf20Sopenharmony_ci &driver_attr_new_id); 1948c2ecf20Sopenharmony_ci if (error == 0) { 1958c2ecf20Sopenharmony_ci error = driver_create_file(&usb_drv->drvwrap.driver, 1968c2ecf20Sopenharmony_ci &driver_attr_remove_id); 1978c2ecf20Sopenharmony_ci if (error) 1988c2ecf20Sopenharmony_ci driver_remove_file(&usb_drv->drvwrap.driver, 1998c2ecf20Sopenharmony_ci &driver_attr_new_id); 2008c2ecf20Sopenharmony_ci } 2018c2ecf20Sopenharmony_ci } 2028c2ecf20Sopenharmony_ciexit: 2038c2ecf20Sopenharmony_ci return error; 2048c2ecf20Sopenharmony_ci} 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic void usb_remove_newid_files(struct usb_driver *usb_drv) 2078c2ecf20Sopenharmony_ci{ 2088c2ecf20Sopenharmony_ci if (usb_drv->no_dynamic_id) 2098c2ecf20Sopenharmony_ci return; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci if (usb_drv->probe != NULL) { 2128c2ecf20Sopenharmony_ci driver_remove_file(&usb_drv->drvwrap.driver, 2138c2ecf20Sopenharmony_ci &driver_attr_remove_id); 2148c2ecf20Sopenharmony_ci driver_remove_file(&usb_drv->drvwrap.driver, 2158c2ecf20Sopenharmony_ci &driver_attr_new_id); 2168c2ecf20Sopenharmony_ci } 2178c2ecf20Sopenharmony_ci} 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_cistatic void usb_free_dynids(struct usb_driver *usb_drv) 2208c2ecf20Sopenharmony_ci{ 2218c2ecf20Sopenharmony_ci struct usb_dynid *dynid, *n; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci spin_lock(&usb_drv->dynids.lock); 2248c2ecf20Sopenharmony_ci list_for_each_entry_safe(dynid, n, &usb_drv->dynids.list, node) { 2258c2ecf20Sopenharmony_ci list_del(&dynid->node); 2268c2ecf20Sopenharmony_ci kfree(dynid); 2278c2ecf20Sopenharmony_ci } 2288c2ecf20Sopenharmony_ci spin_unlock(&usb_drv->dynids.lock); 2298c2ecf20Sopenharmony_ci} 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_cistatic const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf, 2328c2ecf20Sopenharmony_ci struct usb_driver *drv) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci struct usb_dynid *dynid; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci spin_lock(&drv->dynids.lock); 2378c2ecf20Sopenharmony_ci list_for_each_entry(dynid, &drv->dynids.list, node) { 2388c2ecf20Sopenharmony_ci if (usb_match_one_id(intf, &dynid->id)) { 2398c2ecf20Sopenharmony_ci spin_unlock(&drv->dynids.lock); 2408c2ecf20Sopenharmony_ci return &dynid->id; 2418c2ecf20Sopenharmony_ci } 2428c2ecf20Sopenharmony_ci } 2438c2ecf20Sopenharmony_ci spin_unlock(&drv->dynids.lock); 2448c2ecf20Sopenharmony_ci return NULL; 2458c2ecf20Sopenharmony_ci} 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci/* called from driver core with dev locked */ 2498c2ecf20Sopenharmony_cistatic int usb_probe_device(struct device *dev) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci struct usb_device_driver *udriver = to_usb_device_driver(dev->driver); 2528c2ecf20Sopenharmony_ci struct usb_device *udev = to_usb_device(dev); 2538c2ecf20Sopenharmony_ci int error = 0; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci dev_dbg(dev, "%s\n", __func__); 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci /* TODO: Add real matching code */ 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci /* The device should always appear to be in use 2608c2ecf20Sopenharmony_ci * unless the driver supports autosuspend. 2618c2ecf20Sopenharmony_ci */ 2628c2ecf20Sopenharmony_ci if (!udriver->supports_autosuspend) 2638c2ecf20Sopenharmony_ci error = usb_autoresume_device(udev); 2648c2ecf20Sopenharmony_ci if (error) 2658c2ecf20Sopenharmony_ci return error; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci if (udriver->generic_subclass) 2688c2ecf20Sopenharmony_ci error = usb_generic_driver_probe(udev); 2698c2ecf20Sopenharmony_ci if (error) 2708c2ecf20Sopenharmony_ci return error; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci /* Probe the USB device with the driver in hand, but only 2738c2ecf20Sopenharmony_ci * defer to a generic driver in case the current USB 2748c2ecf20Sopenharmony_ci * device driver has an id_table or a match function; i.e., 2758c2ecf20Sopenharmony_ci * when the device driver was explicitly matched against 2768c2ecf20Sopenharmony_ci * a device. 2778c2ecf20Sopenharmony_ci * 2788c2ecf20Sopenharmony_ci * If the device driver does not have either of these, 2798c2ecf20Sopenharmony_ci * then we assume that it can bind to any device and is 2808c2ecf20Sopenharmony_ci * not truly a more specialized/non-generic driver, so a 2818c2ecf20Sopenharmony_ci * return value of -ENODEV should not force the device 2828c2ecf20Sopenharmony_ci * to be handled by the generic USB driver, as there 2838c2ecf20Sopenharmony_ci * can still be another, more specialized, device driver. 2848c2ecf20Sopenharmony_ci * 2858c2ecf20Sopenharmony_ci * This accommodates the usbip driver. 2868c2ecf20Sopenharmony_ci * 2878c2ecf20Sopenharmony_ci * TODO: What if, in the future, there are multiple 2888c2ecf20Sopenharmony_ci * specialized USB device drivers for a particular device? 2898c2ecf20Sopenharmony_ci * In such cases, there is a need to try all matching 2908c2ecf20Sopenharmony_ci * specialised device drivers prior to setting the 2918c2ecf20Sopenharmony_ci * use_generic_driver bit. 2928c2ecf20Sopenharmony_ci */ 2938c2ecf20Sopenharmony_ci error = udriver->probe(udev); 2948c2ecf20Sopenharmony_ci if (error == -ENODEV && udriver != &usb_generic_driver && 2958c2ecf20Sopenharmony_ci (udriver->id_table || udriver->match)) { 2968c2ecf20Sopenharmony_ci udev->use_generic_driver = 1; 2978c2ecf20Sopenharmony_ci return -EPROBE_DEFER; 2988c2ecf20Sopenharmony_ci } 2998c2ecf20Sopenharmony_ci return error; 3008c2ecf20Sopenharmony_ci} 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci/* called from driver core with dev locked */ 3038c2ecf20Sopenharmony_cistatic int usb_unbind_device(struct device *dev) 3048c2ecf20Sopenharmony_ci{ 3058c2ecf20Sopenharmony_ci struct usb_device *udev = to_usb_device(dev); 3068c2ecf20Sopenharmony_ci struct usb_device_driver *udriver = to_usb_device_driver(dev->driver); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci if (udriver->disconnect) 3098c2ecf20Sopenharmony_ci udriver->disconnect(udev); 3108c2ecf20Sopenharmony_ci if (udriver->generic_subclass) 3118c2ecf20Sopenharmony_ci usb_generic_driver_disconnect(udev); 3128c2ecf20Sopenharmony_ci if (!udriver->supports_autosuspend) 3138c2ecf20Sopenharmony_ci usb_autosuspend_device(udev); 3148c2ecf20Sopenharmony_ci return 0; 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci/* called from driver core with dev locked */ 3188c2ecf20Sopenharmony_cistatic int usb_probe_interface(struct device *dev) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci struct usb_driver *driver = to_usb_driver(dev->driver); 3218c2ecf20Sopenharmony_ci struct usb_interface *intf = to_usb_interface(dev); 3228c2ecf20Sopenharmony_ci struct usb_device *udev = interface_to_usbdev(intf); 3238c2ecf20Sopenharmony_ci const struct usb_device_id *id; 3248c2ecf20Sopenharmony_ci int error = -ENODEV; 3258c2ecf20Sopenharmony_ci int lpm_disable_error = -ENODEV; 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci dev_dbg(dev, "%s\n", __func__); 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci intf->needs_binding = 0; 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci if (usb_device_is_owned(udev)) 3328c2ecf20Sopenharmony_ci return error; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci if (udev->authorized == 0) { 3358c2ecf20Sopenharmony_ci dev_err(&intf->dev, "Device is not authorized for usage\n"); 3368c2ecf20Sopenharmony_ci return error; 3378c2ecf20Sopenharmony_ci } else if (intf->authorized == 0) { 3388c2ecf20Sopenharmony_ci dev_err(&intf->dev, "Interface %d is not authorized for usage\n", 3398c2ecf20Sopenharmony_ci intf->altsetting->desc.bInterfaceNumber); 3408c2ecf20Sopenharmony_ci return error; 3418c2ecf20Sopenharmony_ci } 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci id = usb_match_dynamic_id(intf, driver); 3448c2ecf20Sopenharmony_ci if (!id) 3458c2ecf20Sopenharmony_ci id = usb_match_id(intf, driver->id_table); 3468c2ecf20Sopenharmony_ci if (!id) 3478c2ecf20Sopenharmony_ci return error; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci dev_dbg(dev, "%s - got id\n", __func__); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci error = usb_autoresume_device(udev); 3528c2ecf20Sopenharmony_ci if (error) 3538c2ecf20Sopenharmony_ci return error; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci intf->condition = USB_INTERFACE_BINDING; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci /* Probed interfaces are initially active. They are 3588c2ecf20Sopenharmony_ci * runtime-PM-enabled only if the driver has autosuspend support. 3598c2ecf20Sopenharmony_ci * They are sensitive to their children's power states. 3608c2ecf20Sopenharmony_ci */ 3618c2ecf20Sopenharmony_ci pm_runtime_set_active(dev); 3628c2ecf20Sopenharmony_ci pm_suspend_ignore_children(dev, false); 3638c2ecf20Sopenharmony_ci if (driver->supports_autosuspend) 3648c2ecf20Sopenharmony_ci pm_runtime_enable(dev); 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci /* If the new driver doesn't allow hub-initiated LPM, and we can't 3678c2ecf20Sopenharmony_ci * disable hub-initiated LPM, then fail the probe. 3688c2ecf20Sopenharmony_ci * 3698c2ecf20Sopenharmony_ci * Otherwise, leaving LPM enabled should be harmless, because the 3708c2ecf20Sopenharmony_ci * endpoint intervals should remain the same, and the U1/U2 timeouts 3718c2ecf20Sopenharmony_ci * should remain the same. 3728c2ecf20Sopenharmony_ci * 3738c2ecf20Sopenharmony_ci * If we need to install alt setting 0 before probe, or another alt 3748c2ecf20Sopenharmony_ci * setting during probe, that should also be fine. usb_set_interface() 3758c2ecf20Sopenharmony_ci * will attempt to disable LPM, and fail if it can't disable it. 3768c2ecf20Sopenharmony_ci */ 3778c2ecf20Sopenharmony_ci if (driver->disable_hub_initiated_lpm) { 3788c2ecf20Sopenharmony_ci lpm_disable_error = usb_unlocked_disable_lpm(udev); 3798c2ecf20Sopenharmony_ci if (lpm_disable_error) { 3808c2ecf20Sopenharmony_ci dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n", 3818c2ecf20Sopenharmony_ci __func__, driver->name); 3828c2ecf20Sopenharmony_ci error = lpm_disable_error; 3838c2ecf20Sopenharmony_ci goto err; 3848c2ecf20Sopenharmony_ci } 3858c2ecf20Sopenharmony_ci } 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci /* Carry out a deferred switch to altsetting 0 */ 3888c2ecf20Sopenharmony_ci if (intf->needs_altsetting0) { 3898c2ecf20Sopenharmony_ci error = usb_set_interface(udev, intf->altsetting[0]. 3908c2ecf20Sopenharmony_ci desc.bInterfaceNumber, 0); 3918c2ecf20Sopenharmony_ci if (error < 0) 3928c2ecf20Sopenharmony_ci goto err; 3938c2ecf20Sopenharmony_ci intf->needs_altsetting0 = 0; 3948c2ecf20Sopenharmony_ci } 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci error = driver->probe(intf, id); 3978c2ecf20Sopenharmony_ci if (error) 3988c2ecf20Sopenharmony_ci goto err; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci intf->condition = USB_INTERFACE_BOUND; 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci /* If the LPM disable succeeded, balance the ref counts. */ 4038c2ecf20Sopenharmony_ci if (!lpm_disable_error) 4048c2ecf20Sopenharmony_ci usb_unlocked_enable_lpm(udev); 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci usb_autosuspend_device(udev); 4078c2ecf20Sopenharmony_ci return error; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci err: 4108c2ecf20Sopenharmony_ci usb_set_intfdata(intf, NULL); 4118c2ecf20Sopenharmony_ci intf->needs_remote_wakeup = 0; 4128c2ecf20Sopenharmony_ci intf->condition = USB_INTERFACE_UNBOUND; 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci /* If the LPM disable succeeded, balance the ref counts. */ 4158c2ecf20Sopenharmony_ci if (!lpm_disable_error) 4168c2ecf20Sopenharmony_ci usb_unlocked_enable_lpm(udev); 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci /* Unbound interfaces are always runtime-PM-disabled and -suspended */ 4198c2ecf20Sopenharmony_ci if (driver->supports_autosuspend) 4208c2ecf20Sopenharmony_ci pm_runtime_disable(dev); 4218c2ecf20Sopenharmony_ci pm_runtime_set_suspended(dev); 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci usb_autosuspend_device(udev); 4248c2ecf20Sopenharmony_ci return error; 4258c2ecf20Sopenharmony_ci} 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci/* called from driver core with dev locked */ 4288c2ecf20Sopenharmony_cistatic int usb_unbind_interface(struct device *dev) 4298c2ecf20Sopenharmony_ci{ 4308c2ecf20Sopenharmony_ci struct usb_driver *driver = to_usb_driver(dev->driver); 4318c2ecf20Sopenharmony_ci struct usb_interface *intf = to_usb_interface(dev); 4328c2ecf20Sopenharmony_ci struct usb_host_endpoint *ep, **eps = NULL; 4338c2ecf20Sopenharmony_ci struct usb_device *udev; 4348c2ecf20Sopenharmony_ci int i, j, error, r; 4358c2ecf20Sopenharmony_ci int lpm_disable_error = -ENODEV; 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci intf->condition = USB_INTERFACE_UNBINDING; 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci /* Autoresume for set_interface call below */ 4408c2ecf20Sopenharmony_ci udev = interface_to_usbdev(intf); 4418c2ecf20Sopenharmony_ci error = usb_autoresume_device(udev); 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci /* If hub-initiated LPM policy may change, attempt to disable LPM until 4448c2ecf20Sopenharmony_ci * the driver is unbound. If LPM isn't disabled, that's fine because it 4458c2ecf20Sopenharmony_ci * wouldn't be enabled unless all the bound interfaces supported 4468c2ecf20Sopenharmony_ci * hub-initiated LPM. 4478c2ecf20Sopenharmony_ci */ 4488c2ecf20Sopenharmony_ci if (driver->disable_hub_initiated_lpm) 4498c2ecf20Sopenharmony_ci lpm_disable_error = usb_unlocked_disable_lpm(udev); 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci /* 4528c2ecf20Sopenharmony_ci * Terminate all URBs for this interface unless the driver 4538c2ecf20Sopenharmony_ci * supports "soft" unbinding and the device is still present. 4548c2ecf20Sopenharmony_ci */ 4558c2ecf20Sopenharmony_ci if (!driver->soft_unbind || udev->state == USB_STATE_NOTATTACHED) 4568c2ecf20Sopenharmony_ci usb_disable_interface(udev, intf, false); 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_ci driver->disconnect(intf); 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci /* Free streams */ 4618c2ecf20Sopenharmony_ci for (i = 0, j = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { 4628c2ecf20Sopenharmony_ci ep = &intf->cur_altsetting->endpoint[i]; 4638c2ecf20Sopenharmony_ci if (ep->streams == 0) 4648c2ecf20Sopenharmony_ci continue; 4658c2ecf20Sopenharmony_ci if (j == 0) { 4668c2ecf20Sopenharmony_ci eps = kmalloc_array(USB_MAXENDPOINTS, sizeof(void *), 4678c2ecf20Sopenharmony_ci GFP_KERNEL); 4688c2ecf20Sopenharmony_ci if (!eps) 4698c2ecf20Sopenharmony_ci break; 4708c2ecf20Sopenharmony_ci } 4718c2ecf20Sopenharmony_ci eps[j++] = ep; 4728c2ecf20Sopenharmony_ci } 4738c2ecf20Sopenharmony_ci if (j) { 4748c2ecf20Sopenharmony_ci usb_free_streams(intf, eps, j, GFP_KERNEL); 4758c2ecf20Sopenharmony_ci kfree(eps); 4768c2ecf20Sopenharmony_ci } 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci /* Reset other interface state. 4798c2ecf20Sopenharmony_ci * We cannot do a Set-Interface if the device is suspended or 4808c2ecf20Sopenharmony_ci * if it is prepared for a system sleep (since installing a new 4818c2ecf20Sopenharmony_ci * altsetting means creating new endpoint device entries). 4828c2ecf20Sopenharmony_ci * When either of these happens, defer the Set-Interface. 4838c2ecf20Sopenharmony_ci */ 4848c2ecf20Sopenharmony_ci if (intf->cur_altsetting->desc.bAlternateSetting == 0) { 4858c2ecf20Sopenharmony_ci /* Already in altsetting 0 so skip Set-Interface. 4868c2ecf20Sopenharmony_ci * Just re-enable it without affecting the endpoint toggles. 4878c2ecf20Sopenharmony_ci */ 4888c2ecf20Sopenharmony_ci usb_enable_interface(udev, intf, false); 4898c2ecf20Sopenharmony_ci } else if (!error && !intf->dev.power.is_prepared) { 4908c2ecf20Sopenharmony_ci r = usb_set_interface(udev, intf->altsetting[0]. 4918c2ecf20Sopenharmony_ci desc.bInterfaceNumber, 0); 4928c2ecf20Sopenharmony_ci if (r < 0) 4938c2ecf20Sopenharmony_ci intf->needs_altsetting0 = 1; 4948c2ecf20Sopenharmony_ci } else { 4958c2ecf20Sopenharmony_ci intf->needs_altsetting0 = 1; 4968c2ecf20Sopenharmony_ci } 4978c2ecf20Sopenharmony_ci usb_set_intfdata(intf, NULL); 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci intf->condition = USB_INTERFACE_UNBOUND; 5008c2ecf20Sopenharmony_ci intf->needs_remote_wakeup = 0; 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci /* Attempt to re-enable USB3 LPM, if the disable succeeded. */ 5038c2ecf20Sopenharmony_ci if (!lpm_disable_error) 5048c2ecf20Sopenharmony_ci usb_unlocked_enable_lpm(udev); 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci /* Unbound interfaces are always runtime-PM-disabled and -suspended */ 5078c2ecf20Sopenharmony_ci if (driver->supports_autosuspend) 5088c2ecf20Sopenharmony_ci pm_runtime_disable(dev); 5098c2ecf20Sopenharmony_ci pm_runtime_set_suspended(dev); 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci if (!error) 5128c2ecf20Sopenharmony_ci usb_autosuspend_device(udev); 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci return 0; 5158c2ecf20Sopenharmony_ci} 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci/** 5188c2ecf20Sopenharmony_ci * usb_driver_claim_interface - bind a driver to an interface 5198c2ecf20Sopenharmony_ci * @driver: the driver to be bound 5208c2ecf20Sopenharmony_ci * @iface: the interface to which it will be bound; must be in the 5218c2ecf20Sopenharmony_ci * usb device's active configuration 5228c2ecf20Sopenharmony_ci * @priv: driver data associated with that interface 5238c2ecf20Sopenharmony_ci * 5248c2ecf20Sopenharmony_ci * This is used by usb device drivers that need to claim more than one 5258c2ecf20Sopenharmony_ci * interface on a device when probing (audio and acm are current examples). 5268c2ecf20Sopenharmony_ci * No device driver should directly modify internal usb_interface or 5278c2ecf20Sopenharmony_ci * usb_device structure members. 5288c2ecf20Sopenharmony_ci * 5298c2ecf20Sopenharmony_ci * Few drivers should need to use this routine, since the most natural 5308c2ecf20Sopenharmony_ci * way to bind to an interface is to return the private data from 5318c2ecf20Sopenharmony_ci * the driver's probe() method. 5328c2ecf20Sopenharmony_ci * 5338c2ecf20Sopenharmony_ci * Callers must own the device lock, so driver probe() entries don't need 5348c2ecf20Sopenharmony_ci * extra locking, but other call contexts may need to explicitly claim that 5358c2ecf20Sopenharmony_ci * lock. 5368c2ecf20Sopenharmony_ci * 5378c2ecf20Sopenharmony_ci * Return: 0 on success. 5388c2ecf20Sopenharmony_ci */ 5398c2ecf20Sopenharmony_ciint usb_driver_claim_interface(struct usb_driver *driver, 5408c2ecf20Sopenharmony_ci struct usb_interface *iface, void *priv) 5418c2ecf20Sopenharmony_ci{ 5428c2ecf20Sopenharmony_ci struct device *dev; 5438c2ecf20Sopenharmony_ci int retval = 0; 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci if (!iface) 5468c2ecf20Sopenharmony_ci return -ENODEV; 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ci dev = &iface->dev; 5498c2ecf20Sopenharmony_ci if (dev->driver) 5508c2ecf20Sopenharmony_ci return -EBUSY; 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_ci /* reject claim if interface is not authorized */ 5538c2ecf20Sopenharmony_ci if (!iface->authorized) 5548c2ecf20Sopenharmony_ci return -ENODEV; 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci dev->driver = &driver->drvwrap.driver; 5578c2ecf20Sopenharmony_ci usb_set_intfdata(iface, priv); 5588c2ecf20Sopenharmony_ci iface->needs_binding = 0; 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci iface->condition = USB_INTERFACE_BOUND; 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci /* Claimed interfaces are initially inactive (suspended) and 5638c2ecf20Sopenharmony_ci * runtime-PM-enabled, but only if the driver has autosuspend 5648c2ecf20Sopenharmony_ci * support. Otherwise they are marked active, to prevent the 5658c2ecf20Sopenharmony_ci * device from being autosuspended, but left disabled. In either 5668c2ecf20Sopenharmony_ci * case they are sensitive to their children's power states. 5678c2ecf20Sopenharmony_ci */ 5688c2ecf20Sopenharmony_ci pm_suspend_ignore_children(dev, false); 5698c2ecf20Sopenharmony_ci if (driver->supports_autosuspend) 5708c2ecf20Sopenharmony_ci pm_runtime_enable(dev); 5718c2ecf20Sopenharmony_ci else 5728c2ecf20Sopenharmony_ci pm_runtime_set_active(dev); 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci /* if interface was already added, bind now; else let 5758c2ecf20Sopenharmony_ci * the future device_add() bind it, bypassing probe() 5768c2ecf20Sopenharmony_ci */ 5778c2ecf20Sopenharmony_ci if (device_is_registered(dev)) 5788c2ecf20Sopenharmony_ci retval = device_bind_driver(dev); 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci if (retval) { 5818c2ecf20Sopenharmony_ci dev->driver = NULL; 5828c2ecf20Sopenharmony_ci usb_set_intfdata(iface, NULL); 5838c2ecf20Sopenharmony_ci iface->needs_remote_wakeup = 0; 5848c2ecf20Sopenharmony_ci iface->condition = USB_INTERFACE_UNBOUND; 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci /* 5878c2ecf20Sopenharmony_ci * Unbound interfaces are always runtime-PM-disabled 5888c2ecf20Sopenharmony_ci * and runtime-PM-suspended 5898c2ecf20Sopenharmony_ci */ 5908c2ecf20Sopenharmony_ci if (driver->supports_autosuspend) 5918c2ecf20Sopenharmony_ci pm_runtime_disable(dev); 5928c2ecf20Sopenharmony_ci pm_runtime_set_suspended(dev); 5938c2ecf20Sopenharmony_ci } 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci return retval; 5968c2ecf20Sopenharmony_ci} 5978c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_driver_claim_interface); 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci/** 6008c2ecf20Sopenharmony_ci * usb_driver_release_interface - unbind a driver from an interface 6018c2ecf20Sopenharmony_ci * @driver: the driver to be unbound 6028c2ecf20Sopenharmony_ci * @iface: the interface from which it will be unbound 6038c2ecf20Sopenharmony_ci * 6048c2ecf20Sopenharmony_ci * This can be used by drivers to release an interface without waiting 6058c2ecf20Sopenharmony_ci * for their disconnect() methods to be called. In typical cases this 6068c2ecf20Sopenharmony_ci * also causes the driver disconnect() method to be called. 6078c2ecf20Sopenharmony_ci * 6088c2ecf20Sopenharmony_ci * This call is synchronous, and may not be used in an interrupt context. 6098c2ecf20Sopenharmony_ci * Callers must own the device lock, so driver disconnect() entries don't 6108c2ecf20Sopenharmony_ci * need extra locking, but other call contexts may need to explicitly claim 6118c2ecf20Sopenharmony_ci * that lock. 6128c2ecf20Sopenharmony_ci */ 6138c2ecf20Sopenharmony_civoid usb_driver_release_interface(struct usb_driver *driver, 6148c2ecf20Sopenharmony_ci struct usb_interface *iface) 6158c2ecf20Sopenharmony_ci{ 6168c2ecf20Sopenharmony_ci struct device *dev = &iface->dev; 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci /* this should never happen, don't release something that's not ours */ 6198c2ecf20Sopenharmony_ci if (!dev->driver || dev->driver != &driver->drvwrap.driver) 6208c2ecf20Sopenharmony_ci return; 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci /* don't release from within disconnect() */ 6238c2ecf20Sopenharmony_ci if (iface->condition != USB_INTERFACE_BOUND) 6248c2ecf20Sopenharmony_ci return; 6258c2ecf20Sopenharmony_ci iface->condition = USB_INTERFACE_UNBINDING; 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci /* Release via the driver core only if the interface 6288c2ecf20Sopenharmony_ci * has already been registered 6298c2ecf20Sopenharmony_ci */ 6308c2ecf20Sopenharmony_ci if (device_is_registered(dev)) { 6318c2ecf20Sopenharmony_ci device_release_driver(dev); 6328c2ecf20Sopenharmony_ci } else { 6338c2ecf20Sopenharmony_ci device_lock(dev); 6348c2ecf20Sopenharmony_ci usb_unbind_interface(dev); 6358c2ecf20Sopenharmony_ci dev->driver = NULL; 6368c2ecf20Sopenharmony_ci device_unlock(dev); 6378c2ecf20Sopenharmony_ci } 6388c2ecf20Sopenharmony_ci} 6398c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_driver_release_interface); 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci/* returns 0 if no match, 1 if match */ 6428c2ecf20Sopenharmony_ciint usb_match_device(struct usb_device *dev, const struct usb_device_id *id) 6438c2ecf20Sopenharmony_ci{ 6448c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && 6458c2ecf20Sopenharmony_ci id->idVendor != le16_to_cpu(dev->descriptor.idVendor)) 6468c2ecf20Sopenharmony_ci return 0; 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && 6498c2ecf20Sopenharmony_ci id->idProduct != le16_to_cpu(dev->descriptor.idProduct)) 6508c2ecf20Sopenharmony_ci return 0; 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ci /* No need to test id->bcdDevice_lo != 0, since 0 is never 6538c2ecf20Sopenharmony_ci greater than any unsigned number. */ 6548c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && 6558c2ecf20Sopenharmony_ci (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice))) 6568c2ecf20Sopenharmony_ci return 0; 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && 6598c2ecf20Sopenharmony_ci (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice))) 6608c2ecf20Sopenharmony_ci return 0; 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && 6638c2ecf20Sopenharmony_ci (id->bDeviceClass != dev->descriptor.bDeviceClass)) 6648c2ecf20Sopenharmony_ci return 0; 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && 6678c2ecf20Sopenharmony_ci (id->bDeviceSubClass != dev->descriptor.bDeviceSubClass)) 6688c2ecf20Sopenharmony_ci return 0; 6698c2ecf20Sopenharmony_ci 6708c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && 6718c2ecf20Sopenharmony_ci (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) 6728c2ecf20Sopenharmony_ci return 0; 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci return 1; 6758c2ecf20Sopenharmony_ci} 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci/* returns 0 if no match, 1 if match */ 6788c2ecf20Sopenharmony_ciint usb_match_one_id_intf(struct usb_device *dev, 6798c2ecf20Sopenharmony_ci struct usb_host_interface *intf, 6808c2ecf20Sopenharmony_ci const struct usb_device_id *id) 6818c2ecf20Sopenharmony_ci{ 6828c2ecf20Sopenharmony_ci /* The interface class, subclass, protocol and number should never be 6838c2ecf20Sopenharmony_ci * checked for a match if the device class is Vendor Specific, 6848c2ecf20Sopenharmony_ci * unless the match record specifies the Vendor ID. */ 6858c2ecf20Sopenharmony_ci if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC && 6868c2ecf20Sopenharmony_ci !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && 6878c2ecf20Sopenharmony_ci (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS | 6888c2ecf20Sopenharmony_ci USB_DEVICE_ID_MATCH_INT_SUBCLASS | 6898c2ecf20Sopenharmony_ci USB_DEVICE_ID_MATCH_INT_PROTOCOL | 6908c2ecf20Sopenharmony_ci USB_DEVICE_ID_MATCH_INT_NUMBER))) 6918c2ecf20Sopenharmony_ci return 0; 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && 6948c2ecf20Sopenharmony_ci (id->bInterfaceClass != intf->desc.bInterfaceClass)) 6958c2ecf20Sopenharmony_ci return 0; 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && 6988c2ecf20Sopenharmony_ci (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass)) 6998c2ecf20Sopenharmony_ci return 0; 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && 7028c2ecf20Sopenharmony_ci (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) 7038c2ecf20Sopenharmony_ci return 0; 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) && 7068c2ecf20Sopenharmony_ci (id->bInterfaceNumber != intf->desc.bInterfaceNumber)) 7078c2ecf20Sopenharmony_ci return 0; 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci return 1; 7108c2ecf20Sopenharmony_ci} 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci/* returns 0 if no match, 1 if match */ 7138c2ecf20Sopenharmony_ciint usb_match_one_id(struct usb_interface *interface, 7148c2ecf20Sopenharmony_ci const struct usb_device_id *id) 7158c2ecf20Sopenharmony_ci{ 7168c2ecf20Sopenharmony_ci struct usb_host_interface *intf; 7178c2ecf20Sopenharmony_ci struct usb_device *dev; 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_ci /* proc_connectinfo in devio.c may call us with id == NULL. */ 7208c2ecf20Sopenharmony_ci if (id == NULL) 7218c2ecf20Sopenharmony_ci return 0; 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci intf = interface->cur_altsetting; 7248c2ecf20Sopenharmony_ci dev = interface_to_usbdev(interface); 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci if (!usb_match_device(dev, id)) 7278c2ecf20Sopenharmony_ci return 0; 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_ci return usb_match_one_id_intf(dev, intf, id); 7308c2ecf20Sopenharmony_ci} 7318c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_match_one_id); 7328c2ecf20Sopenharmony_ci 7338c2ecf20Sopenharmony_ci/** 7348c2ecf20Sopenharmony_ci * usb_match_id - find first usb_device_id matching device or interface 7358c2ecf20Sopenharmony_ci * @interface: the interface of interest 7368c2ecf20Sopenharmony_ci * @id: array of usb_device_id structures, terminated by zero entry 7378c2ecf20Sopenharmony_ci * 7388c2ecf20Sopenharmony_ci * usb_match_id searches an array of usb_device_id's and returns 7398c2ecf20Sopenharmony_ci * the first one matching the device or interface, or null. 7408c2ecf20Sopenharmony_ci * This is used when binding (or rebinding) a driver to an interface. 7418c2ecf20Sopenharmony_ci * Most USB device drivers will use this indirectly, through the usb core, 7428c2ecf20Sopenharmony_ci * but some layered driver frameworks use it directly. 7438c2ecf20Sopenharmony_ci * These device tables are exported with MODULE_DEVICE_TABLE, through 7448c2ecf20Sopenharmony_ci * modutils, to support the driver loading functionality of USB hotplugging. 7458c2ecf20Sopenharmony_ci * 7468c2ecf20Sopenharmony_ci * Return: The first matching usb_device_id, or %NULL. 7478c2ecf20Sopenharmony_ci * 7488c2ecf20Sopenharmony_ci * What Matches: 7498c2ecf20Sopenharmony_ci * 7508c2ecf20Sopenharmony_ci * The "match_flags" element in a usb_device_id controls which 7518c2ecf20Sopenharmony_ci * members are used. If the corresponding bit is set, the 7528c2ecf20Sopenharmony_ci * value in the device_id must match its corresponding member 7538c2ecf20Sopenharmony_ci * in the device or interface descriptor, or else the device_id 7548c2ecf20Sopenharmony_ci * does not match. 7558c2ecf20Sopenharmony_ci * 7568c2ecf20Sopenharmony_ci * "driver_info" is normally used only by device drivers, 7578c2ecf20Sopenharmony_ci * but you can create a wildcard "matches anything" usb_device_id 7588c2ecf20Sopenharmony_ci * as a driver's "modules.usbmap" entry if you provide an id with 7598c2ecf20Sopenharmony_ci * only a nonzero "driver_info" field. If you do this, the USB device 7608c2ecf20Sopenharmony_ci * driver's probe() routine should use additional intelligence to 7618c2ecf20Sopenharmony_ci * decide whether to bind to the specified interface. 7628c2ecf20Sopenharmony_ci * 7638c2ecf20Sopenharmony_ci * What Makes Good usb_device_id Tables: 7648c2ecf20Sopenharmony_ci * 7658c2ecf20Sopenharmony_ci * The match algorithm is very simple, so that intelligence in 7668c2ecf20Sopenharmony_ci * driver selection must come from smart driver id records. 7678c2ecf20Sopenharmony_ci * Unless you have good reasons to use another selection policy, 7688c2ecf20Sopenharmony_ci * provide match elements only in related groups, and order match 7698c2ecf20Sopenharmony_ci * specifiers from specific to general. Use the macros provided 7708c2ecf20Sopenharmony_ci * for that purpose if you can. 7718c2ecf20Sopenharmony_ci * 7728c2ecf20Sopenharmony_ci * The most specific match specifiers use device descriptor 7738c2ecf20Sopenharmony_ci * data. These are commonly used with product-specific matches; 7748c2ecf20Sopenharmony_ci * the USB_DEVICE macro lets you provide vendor and product IDs, 7758c2ecf20Sopenharmony_ci * and you can also match against ranges of product revisions. 7768c2ecf20Sopenharmony_ci * These are widely used for devices with application or vendor 7778c2ecf20Sopenharmony_ci * specific bDeviceClass values. 7788c2ecf20Sopenharmony_ci * 7798c2ecf20Sopenharmony_ci * Matches based on device class/subclass/protocol specifications 7808c2ecf20Sopenharmony_ci * are slightly more general; use the USB_DEVICE_INFO macro, or 7818c2ecf20Sopenharmony_ci * its siblings. These are used with single-function devices 7828c2ecf20Sopenharmony_ci * where bDeviceClass doesn't specify that each interface has 7838c2ecf20Sopenharmony_ci * its own class. 7848c2ecf20Sopenharmony_ci * 7858c2ecf20Sopenharmony_ci * Matches based on interface class/subclass/protocol are the 7868c2ecf20Sopenharmony_ci * most general; they let drivers bind to any interface on a 7878c2ecf20Sopenharmony_ci * multiple-function device. Use the USB_INTERFACE_INFO 7888c2ecf20Sopenharmony_ci * macro, or its siblings, to match class-per-interface style 7898c2ecf20Sopenharmony_ci * devices (as recorded in bInterfaceClass). 7908c2ecf20Sopenharmony_ci * 7918c2ecf20Sopenharmony_ci * Note that an entry created by USB_INTERFACE_INFO won't match 7928c2ecf20Sopenharmony_ci * any interface if the device class is set to Vendor-Specific. 7938c2ecf20Sopenharmony_ci * This is deliberate; according to the USB spec the meanings of 7948c2ecf20Sopenharmony_ci * the interface class/subclass/protocol for these devices are also 7958c2ecf20Sopenharmony_ci * vendor-specific, and hence matching against a standard product 7968c2ecf20Sopenharmony_ci * class wouldn't work anyway. If you really want to use an 7978c2ecf20Sopenharmony_ci * interface-based match for such a device, create a match record 7988c2ecf20Sopenharmony_ci * that also specifies the vendor ID. (Unforunately there isn't a 7998c2ecf20Sopenharmony_ci * standard macro for creating records like this.) 8008c2ecf20Sopenharmony_ci * 8018c2ecf20Sopenharmony_ci * Within those groups, remember that not all combinations are 8028c2ecf20Sopenharmony_ci * meaningful. For example, don't give a product version range 8038c2ecf20Sopenharmony_ci * without vendor and product IDs; or specify a protocol without 8048c2ecf20Sopenharmony_ci * its associated class and subclass. 8058c2ecf20Sopenharmony_ci */ 8068c2ecf20Sopenharmony_ciconst struct usb_device_id *usb_match_id(struct usb_interface *interface, 8078c2ecf20Sopenharmony_ci const struct usb_device_id *id) 8088c2ecf20Sopenharmony_ci{ 8098c2ecf20Sopenharmony_ci /* proc_connectinfo in devio.c may call us with id == NULL. */ 8108c2ecf20Sopenharmony_ci if (id == NULL) 8118c2ecf20Sopenharmony_ci return NULL; 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci /* It is important to check that id->driver_info is nonzero, 8148c2ecf20Sopenharmony_ci since an entry that is all zeroes except for a nonzero 8158c2ecf20Sopenharmony_ci id->driver_info is the way to create an entry that 8168c2ecf20Sopenharmony_ci indicates that the driver want to examine every 8178c2ecf20Sopenharmony_ci device and interface. */ 8188c2ecf20Sopenharmony_ci for (; id->idVendor || id->idProduct || id->bDeviceClass || 8198c2ecf20Sopenharmony_ci id->bInterfaceClass || id->driver_info; id++) { 8208c2ecf20Sopenharmony_ci if (usb_match_one_id(interface, id)) 8218c2ecf20Sopenharmony_ci return id; 8228c2ecf20Sopenharmony_ci } 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_ci return NULL; 8258c2ecf20Sopenharmony_ci} 8268c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_match_id); 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ciconst struct usb_device_id *usb_device_match_id(struct usb_device *udev, 8298c2ecf20Sopenharmony_ci const struct usb_device_id *id) 8308c2ecf20Sopenharmony_ci{ 8318c2ecf20Sopenharmony_ci if (!id) 8328c2ecf20Sopenharmony_ci return NULL; 8338c2ecf20Sopenharmony_ci 8348c2ecf20Sopenharmony_ci for (; id->idVendor || id->idProduct ; id++) { 8358c2ecf20Sopenharmony_ci if (usb_match_device(udev, id)) 8368c2ecf20Sopenharmony_ci return id; 8378c2ecf20Sopenharmony_ci } 8388c2ecf20Sopenharmony_ci 8398c2ecf20Sopenharmony_ci return NULL; 8408c2ecf20Sopenharmony_ci} 8418c2ecf20Sopenharmony_ci 8428c2ecf20Sopenharmony_cibool usb_driver_applicable(struct usb_device *udev, 8438c2ecf20Sopenharmony_ci struct usb_device_driver *udrv) 8448c2ecf20Sopenharmony_ci{ 8458c2ecf20Sopenharmony_ci if (udrv->id_table && udrv->match) 8468c2ecf20Sopenharmony_ci return usb_device_match_id(udev, udrv->id_table) != NULL && 8478c2ecf20Sopenharmony_ci udrv->match(udev); 8488c2ecf20Sopenharmony_ci 8498c2ecf20Sopenharmony_ci if (udrv->id_table) 8508c2ecf20Sopenharmony_ci return usb_device_match_id(udev, udrv->id_table) != NULL; 8518c2ecf20Sopenharmony_ci 8528c2ecf20Sopenharmony_ci if (udrv->match) 8538c2ecf20Sopenharmony_ci return udrv->match(udev); 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci return false; 8568c2ecf20Sopenharmony_ci} 8578c2ecf20Sopenharmony_ci 8588c2ecf20Sopenharmony_cistatic int usb_device_match(struct device *dev, struct device_driver *drv) 8598c2ecf20Sopenharmony_ci{ 8608c2ecf20Sopenharmony_ci /* devices and interfaces are handled separately */ 8618c2ecf20Sopenharmony_ci if (is_usb_device(dev)) { 8628c2ecf20Sopenharmony_ci struct usb_device *udev; 8638c2ecf20Sopenharmony_ci struct usb_device_driver *udrv; 8648c2ecf20Sopenharmony_ci 8658c2ecf20Sopenharmony_ci /* interface drivers never match devices */ 8668c2ecf20Sopenharmony_ci if (!is_usb_device_driver(drv)) 8678c2ecf20Sopenharmony_ci return 0; 8688c2ecf20Sopenharmony_ci 8698c2ecf20Sopenharmony_ci udev = to_usb_device(dev); 8708c2ecf20Sopenharmony_ci udrv = to_usb_device_driver(drv); 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ci /* If the device driver under consideration does not have a 8738c2ecf20Sopenharmony_ci * id_table or a match function, then let the driver's probe 8748c2ecf20Sopenharmony_ci * function decide. 8758c2ecf20Sopenharmony_ci */ 8768c2ecf20Sopenharmony_ci if (!udrv->id_table && !udrv->match) 8778c2ecf20Sopenharmony_ci return 1; 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ci return usb_driver_applicable(udev, udrv); 8808c2ecf20Sopenharmony_ci 8818c2ecf20Sopenharmony_ci } else if (is_usb_interface(dev)) { 8828c2ecf20Sopenharmony_ci struct usb_interface *intf; 8838c2ecf20Sopenharmony_ci struct usb_driver *usb_drv; 8848c2ecf20Sopenharmony_ci const struct usb_device_id *id; 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ci /* device drivers never match interfaces */ 8878c2ecf20Sopenharmony_ci if (is_usb_device_driver(drv)) 8888c2ecf20Sopenharmony_ci return 0; 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_ci intf = to_usb_interface(dev); 8918c2ecf20Sopenharmony_ci usb_drv = to_usb_driver(drv); 8928c2ecf20Sopenharmony_ci 8938c2ecf20Sopenharmony_ci id = usb_match_id(intf, usb_drv->id_table); 8948c2ecf20Sopenharmony_ci if (id) 8958c2ecf20Sopenharmony_ci return 1; 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_ci id = usb_match_dynamic_id(intf, usb_drv); 8988c2ecf20Sopenharmony_ci if (id) 8998c2ecf20Sopenharmony_ci return 1; 9008c2ecf20Sopenharmony_ci } 9018c2ecf20Sopenharmony_ci 9028c2ecf20Sopenharmony_ci return 0; 9038c2ecf20Sopenharmony_ci} 9048c2ecf20Sopenharmony_ci 9058c2ecf20Sopenharmony_cistatic int usb_uevent(struct device *dev, struct kobj_uevent_env *env) 9068c2ecf20Sopenharmony_ci{ 9078c2ecf20Sopenharmony_ci struct usb_device *usb_dev; 9088c2ecf20Sopenharmony_ci 9098c2ecf20Sopenharmony_ci if (is_usb_device(dev)) { 9108c2ecf20Sopenharmony_ci usb_dev = to_usb_device(dev); 9118c2ecf20Sopenharmony_ci } else if (is_usb_interface(dev)) { 9128c2ecf20Sopenharmony_ci struct usb_interface *intf = to_usb_interface(dev); 9138c2ecf20Sopenharmony_ci 9148c2ecf20Sopenharmony_ci usb_dev = interface_to_usbdev(intf); 9158c2ecf20Sopenharmony_ci } else { 9168c2ecf20Sopenharmony_ci return 0; 9178c2ecf20Sopenharmony_ci } 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci if (usb_dev->devnum < 0) { 9208c2ecf20Sopenharmony_ci /* driver is often null here; dev_dbg() would oops */ 9218c2ecf20Sopenharmony_ci pr_debug("usb %s: already deleted?\n", dev_name(dev)); 9228c2ecf20Sopenharmony_ci return -ENODEV; 9238c2ecf20Sopenharmony_ci } 9248c2ecf20Sopenharmony_ci if (!usb_dev->bus) { 9258c2ecf20Sopenharmony_ci pr_debug("usb %s: bus removed?\n", dev_name(dev)); 9268c2ecf20Sopenharmony_ci return -ENODEV; 9278c2ecf20Sopenharmony_ci } 9288c2ecf20Sopenharmony_ci 9298c2ecf20Sopenharmony_ci /* per-device configurations are common */ 9308c2ecf20Sopenharmony_ci if (add_uevent_var(env, "PRODUCT=%x/%x/%x", 9318c2ecf20Sopenharmony_ci le16_to_cpu(usb_dev->descriptor.idVendor), 9328c2ecf20Sopenharmony_ci le16_to_cpu(usb_dev->descriptor.idProduct), 9338c2ecf20Sopenharmony_ci le16_to_cpu(usb_dev->descriptor.bcdDevice))) 9348c2ecf20Sopenharmony_ci return -ENOMEM; 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci /* class-based driver binding models */ 9378c2ecf20Sopenharmony_ci if (add_uevent_var(env, "TYPE=%d/%d/%d", 9388c2ecf20Sopenharmony_ci usb_dev->descriptor.bDeviceClass, 9398c2ecf20Sopenharmony_ci usb_dev->descriptor.bDeviceSubClass, 9408c2ecf20Sopenharmony_ci usb_dev->descriptor.bDeviceProtocol)) 9418c2ecf20Sopenharmony_ci return -ENOMEM; 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci return 0; 9448c2ecf20Sopenharmony_ci} 9458c2ecf20Sopenharmony_ci 9468c2ecf20Sopenharmony_cistatic int __usb_bus_reprobe_drivers(struct device *dev, void *data) 9478c2ecf20Sopenharmony_ci{ 9488c2ecf20Sopenharmony_ci struct usb_device_driver *new_udriver = data; 9498c2ecf20Sopenharmony_ci struct usb_device *udev; 9508c2ecf20Sopenharmony_ci int ret; 9518c2ecf20Sopenharmony_ci 9528c2ecf20Sopenharmony_ci /* Don't reprobe if current driver isn't usb_generic_driver */ 9538c2ecf20Sopenharmony_ci if (dev->driver != &usb_generic_driver.drvwrap.driver) 9548c2ecf20Sopenharmony_ci return 0; 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_ci udev = to_usb_device(dev); 9578c2ecf20Sopenharmony_ci if (!usb_driver_applicable(udev, new_udriver)) 9588c2ecf20Sopenharmony_ci return 0; 9598c2ecf20Sopenharmony_ci 9608c2ecf20Sopenharmony_ci ret = device_reprobe(dev); 9618c2ecf20Sopenharmony_ci if (ret && ret != -EPROBE_DEFER) 9628c2ecf20Sopenharmony_ci dev_err(dev, "Failed to reprobe device (error %d)\n", ret); 9638c2ecf20Sopenharmony_ci 9648c2ecf20Sopenharmony_ci return 0; 9658c2ecf20Sopenharmony_ci} 9668c2ecf20Sopenharmony_ci 9678c2ecf20Sopenharmony_ci/** 9688c2ecf20Sopenharmony_ci * usb_register_device_driver - register a USB device (not interface) driver 9698c2ecf20Sopenharmony_ci * @new_udriver: USB operations for the device driver 9708c2ecf20Sopenharmony_ci * @owner: module owner of this driver. 9718c2ecf20Sopenharmony_ci * 9728c2ecf20Sopenharmony_ci * Registers a USB device driver with the USB core. The list of 9738c2ecf20Sopenharmony_ci * unattached devices will be rescanned whenever a new driver is 9748c2ecf20Sopenharmony_ci * added, allowing the new driver to attach to any recognized devices. 9758c2ecf20Sopenharmony_ci * 9768c2ecf20Sopenharmony_ci * Return: A negative error code on failure and 0 on success. 9778c2ecf20Sopenharmony_ci */ 9788c2ecf20Sopenharmony_ciint usb_register_device_driver(struct usb_device_driver *new_udriver, 9798c2ecf20Sopenharmony_ci struct module *owner) 9808c2ecf20Sopenharmony_ci{ 9818c2ecf20Sopenharmony_ci int retval = 0; 9828c2ecf20Sopenharmony_ci 9838c2ecf20Sopenharmony_ci if (usb_disabled()) 9848c2ecf20Sopenharmony_ci return -ENODEV; 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci new_udriver->drvwrap.for_devices = 1; 9878c2ecf20Sopenharmony_ci new_udriver->drvwrap.driver.name = new_udriver->name; 9888c2ecf20Sopenharmony_ci new_udriver->drvwrap.driver.bus = &usb_bus_type; 9898c2ecf20Sopenharmony_ci new_udriver->drvwrap.driver.probe = usb_probe_device; 9908c2ecf20Sopenharmony_ci new_udriver->drvwrap.driver.remove = usb_unbind_device; 9918c2ecf20Sopenharmony_ci new_udriver->drvwrap.driver.owner = owner; 9928c2ecf20Sopenharmony_ci new_udriver->drvwrap.driver.dev_groups = new_udriver->dev_groups; 9938c2ecf20Sopenharmony_ci 9948c2ecf20Sopenharmony_ci retval = driver_register(&new_udriver->drvwrap.driver); 9958c2ecf20Sopenharmony_ci 9968c2ecf20Sopenharmony_ci if (!retval) { 9978c2ecf20Sopenharmony_ci pr_info("%s: registered new device driver %s\n", 9988c2ecf20Sopenharmony_ci usbcore_name, new_udriver->name); 9998c2ecf20Sopenharmony_ci /* 10008c2ecf20Sopenharmony_ci * Check whether any device could be better served with 10018c2ecf20Sopenharmony_ci * this new driver 10028c2ecf20Sopenharmony_ci */ 10038c2ecf20Sopenharmony_ci bus_for_each_dev(&usb_bus_type, NULL, new_udriver, 10048c2ecf20Sopenharmony_ci __usb_bus_reprobe_drivers); 10058c2ecf20Sopenharmony_ci } else { 10068c2ecf20Sopenharmony_ci pr_err("%s: error %d registering device driver %s\n", 10078c2ecf20Sopenharmony_ci usbcore_name, retval, new_udriver->name); 10088c2ecf20Sopenharmony_ci } 10098c2ecf20Sopenharmony_ci 10108c2ecf20Sopenharmony_ci return retval; 10118c2ecf20Sopenharmony_ci} 10128c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_register_device_driver); 10138c2ecf20Sopenharmony_ci 10148c2ecf20Sopenharmony_ci/** 10158c2ecf20Sopenharmony_ci * usb_deregister_device_driver - unregister a USB device (not interface) driver 10168c2ecf20Sopenharmony_ci * @udriver: USB operations of the device driver to unregister 10178c2ecf20Sopenharmony_ci * Context: must be able to sleep 10188c2ecf20Sopenharmony_ci * 10198c2ecf20Sopenharmony_ci * Unlinks the specified driver from the internal USB driver list. 10208c2ecf20Sopenharmony_ci */ 10218c2ecf20Sopenharmony_civoid usb_deregister_device_driver(struct usb_device_driver *udriver) 10228c2ecf20Sopenharmony_ci{ 10238c2ecf20Sopenharmony_ci pr_info("%s: deregistering device driver %s\n", 10248c2ecf20Sopenharmony_ci usbcore_name, udriver->name); 10258c2ecf20Sopenharmony_ci 10268c2ecf20Sopenharmony_ci driver_unregister(&udriver->drvwrap.driver); 10278c2ecf20Sopenharmony_ci} 10288c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_deregister_device_driver); 10298c2ecf20Sopenharmony_ci 10308c2ecf20Sopenharmony_ci/** 10318c2ecf20Sopenharmony_ci * usb_register_driver - register a USB interface driver 10328c2ecf20Sopenharmony_ci * @new_driver: USB operations for the interface driver 10338c2ecf20Sopenharmony_ci * @owner: module owner of this driver. 10348c2ecf20Sopenharmony_ci * @mod_name: module name string 10358c2ecf20Sopenharmony_ci * 10368c2ecf20Sopenharmony_ci * Registers a USB interface driver with the USB core. The list of 10378c2ecf20Sopenharmony_ci * unattached interfaces will be rescanned whenever a new driver is 10388c2ecf20Sopenharmony_ci * added, allowing the new driver to attach to any recognized interfaces. 10398c2ecf20Sopenharmony_ci * 10408c2ecf20Sopenharmony_ci * Return: A negative error code on failure and 0 on success. 10418c2ecf20Sopenharmony_ci * 10428c2ecf20Sopenharmony_ci * NOTE: if you want your driver to use the USB major number, you must call 10438c2ecf20Sopenharmony_ci * usb_register_dev() to enable that functionality. This function no longer 10448c2ecf20Sopenharmony_ci * takes care of that. 10458c2ecf20Sopenharmony_ci */ 10468c2ecf20Sopenharmony_ciint usb_register_driver(struct usb_driver *new_driver, struct module *owner, 10478c2ecf20Sopenharmony_ci const char *mod_name) 10488c2ecf20Sopenharmony_ci{ 10498c2ecf20Sopenharmony_ci int retval = 0; 10508c2ecf20Sopenharmony_ci 10518c2ecf20Sopenharmony_ci if (usb_disabled()) 10528c2ecf20Sopenharmony_ci return -ENODEV; 10538c2ecf20Sopenharmony_ci 10548c2ecf20Sopenharmony_ci new_driver->drvwrap.for_devices = 0; 10558c2ecf20Sopenharmony_ci new_driver->drvwrap.driver.name = new_driver->name; 10568c2ecf20Sopenharmony_ci new_driver->drvwrap.driver.bus = &usb_bus_type; 10578c2ecf20Sopenharmony_ci new_driver->drvwrap.driver.probe = usb_probe_interface; 10588c2ecf20Sopenharmony_ci new_driver->drvwrap.driver.remove = usb_unbind_interface; 10598c2ecf20Sopenharmony_ci new_driver->drvwrap.driver.owner = owner; 10608c2ecf20Sopenharmony_ci new_driver->drvwrap.driver.mod_name = mod_name; 10618c2ecf20Sopenharmony_ci new_driver->drvwrap.driver.dev_groups = new_driver->dev_groups; 10628c2ecf20Sopenharmony_ci spin_lock_init(&new_driver->dynids.lock); 10638c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&new_driver->dynids.list); 10648c2ecf20Sopenharmony_ci 10658c2ecf20Sopenharmony_ci retval = driver_register(&new_driver->drvwrap.driver); 10668c2ecf20Sopenharmony_ci if (retval) 10678c2ecf20Sopenharmony_ci goto out; 10688c2ecf20Sopenharmony_ci 10698c2ecf20Sopenharmony_ci retval = usb_create_newid_files(new_driver); 10708c2ecf20Sopenharmony_ci if (retval) 10718c2ecf20Sopenharmony_ci goto out_newid; 10728c2ecf20Sopenharmony_ci 10738c2ecf20Sopenharmony_ci pr_info("%s: registered new interface driver %s\n", 10748c2ecf20Sopenharmony_ci usbcore_name, new_driver->name); 10758c2ecf20Sopenharmony_ci 10768c2ecf20Sopenharmony_ciout: 10778c2ecf20Sopenharmony_ci return retval; 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_ciout_newid: 10808c2ecf20Sopenharmony_ci driver_unregister(&new_driver->drvwrap.driver); 10818c2ecf20Sopenharmony_ci 10828c2ecf20Sopenharmony_ci pr_err("%s: error %d registering interface driver %s\n", 10838c2ecf20Sopenharmony_ci usbcore_name, retval, new_driver->name); 10848c2ecf20Sopenharmony_ci goto out; 10858c2ecf20Sopenharmony_ci} 10868c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_register_driver); 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_ci/** 10898c2ecf20Sopenharmony_ci * usb_deregister - unregister a USB interface driver 10908c2ecf20Sopenharmony_ci * @driver: USB operations of the interface driver to unregister 10918c2ecf20Sopenharmony_ci * Context: must be able to sleep 10928c2ecf20Sopenharmony_ci * 10938c2ecf20Sopenharmony_ci * Unlinks the specified driver from the internal USB driver list. 10948c2ecf20Sopenharmony_ci * 10958c2ecf20Sopenharmony_ci * NOTE: If you called usb_register_dev(), you still need to call 10968c2ecf20Sopenharmony_ci * usb_deregister_dev() to clean up your driver's allocated minor numbers, 10978c2ecf20Sopenharmony_ci * this * call will no longer do it for you. 10988c2ecf20Sopenharmony_ci */ 10998c2ecf20Sopenharmony_civoid usb_deregister(struct usb_driver *driver) 11008c2ecf20Sopenharmony_ci{ 11018c2ecf20Sopenharmony_ci pr_info("%s: deregistering interface driver %s\n", 11028c2ecf20Sopenharmony_ci usbcore_name, driver->name); 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci usb_remove_newid_files(driver); 11058c2ecf20Sopenharmony_ci driver_unregister(&driver->drvwrap.driver); 11068c2ecf20Sopenharmony_ci usb_free_dynids(driver); 11078c2ecf20Sopenharmony_ci} 11088c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_deregister); 11098c2ecf20Sopenharmony_ci 11108c2ecf20Sopenharmony_ci/* Forced unbinding of a USB interface driver, either because 11118c2ecf20Sopenharmony_ci * it doesn't support pre_reset/post_reset/reset_resume or 11128c2ecf20Sopenharmony_ci * because it doesn't support suspend/resume. 11138c2ecf20Sopenharmony_ci * 11148c2ecf20Sopenharmony_ci * The caller must hold @intf's device's lock, but not @intf's lock. 11158c2ecf20Sopenharmony_ci */ 11168c2ecf20Sopenharmony_civoid usb_forced_unbind_intf(struct usb_interface *intf) 11178c2ecf20Sopenharmony_ci{ 11188c2ecf20Sopenharmony_ci struct usb_driver *driver = to_usb_driver(intf->dev.driver); 11198c2ecf20Sopenharmony_ci 11208c2ecf20Sopenharmony_ci dev_dbg(&intf->dev, "forced unbind\n"); 11218c2ecf20Sopenharmony_ci usb_driver_release_interface(driver, intf); 11228c2ecf20Sopenharmony_ci 11238c2ecf20Sopenharmony_ci /* Mark the interface for later rebinding */ 11248c2ecf20Sopenharmony_ci intf->needs_binding = 1; 11258c2ecf20Sopenharmony_ci} 11268c2ecf20Sopenharmony_ci 11278c2ecf20Sopenharmony_ci/* 11288c2ecf20Sopenharmony_ci * Unbind drivers for @udev's marked interfaces. These interfaces have 11298c2ecf20Sopenharmony_ci * the needs_binding flag set, for example by usb_resume_interface(). 11308c2ecf20Sopenharmony_ci * 11318c2ecf20Sopenharmony_ci * The caller must hold @udev's device lock. 11328c2ecf20Sopenharmony_ci */ 11338c2ecf20Sopenharmony_cistatic void unbind_marked_interfaces(struct usb_device *udev) 11348c2ecf20Sopenharmony_ci{ 11358c2ecf20Sopenharmony_ci struct usb_host_config *config; 11368c2ecf20Sopenharmony_ci int i; 11378c2ecf20Sopenharmony_ci struct usb_interface *intf; 11388c2ecf20Sopenharmony_ci 11398c2ecf20Sopenharmony_ci config = udev->actconfig; 11408c2ecf20Sopenharmony_ci if (config) { 11418c2ecf20Sopenharmony_ci for (i = 0; i < config->desc.bNumInterfaces; ++i) { 11428c2ecf20Sopenharmony_ci intf = config->interface[i]; 11438c2ecf20Sopenharmony_ci if (intf->dev.driver && intf->needs_binding) 11448c2ecf20Sopenharmony_ci usb_forced_unbind_intf(intf); 11458c2ecf20Sopenharmony_ci } 11468c2ecf20Sopenharmony_ci } 11478c2ecf20Sopenharmony_ci} 11488c2ecf20Sopenharmony_ci 11498c2ecf20Sopenharmony_ci/* Delayed forced unbinding of a USB interface driver and scan 11508c2ecf20Sopenharmony_ci * for rebinding. 11518c2ecf20Sopenharmony_ci * 11528c2ecf20Sopenharmony_ci * The caller must hold @intf's device's lock, but not @intf's lock. 11538c2ecf20Sopenharmony_ci * 11548c2ecf20Sopenharmony_ci * Note: Rebinds will be skipped if a system sleep transition is in 11558c2ecf20Sopenharmony_ci * progress and the PM "complete" callback hasn't occurred yet. 11568c2ecf20Sopenharmony_ci */ 11578c2ecf20Sopenharmony_cistatic void usb_rebind_intf(struct usb_interface *intf) 11588c2ecf20Sopenharmony_ci{ 11598c2ecf20Sopenharmony_ci int rc; 11608c2ecf20Sopenharmony_ci 11618c2ecf20Sopenharmony_ci /* Delayed unbind of an existing driver */ 11628c2ecf20Sopenharmony_ci if (intf->dev.driver) 11638c2ecf20Sopenharmony_ci usb_forced_unbind_intf(intf); 11648c2ecf20Sopenharmony_ci 11658c2ecf20Sopenharmony_ci /* Try to rebind the interface */ 11668c2ecf20Sopenharmony_ci if (!intf->dev.power.is_prepared) { 11678c2ecf20Sopenharmony_ci intf->needs_binding = 0; 11688c2ecf20Sopenharmony_ci rc = device_attach(&intf->dev); 11698c2ecf20Sopenharmony_ci if (rc < 0 && rc != -EPROBE_DEFER) 11708c2ecf20Sopenharmony_ci dev_warn(&intf->dev, "rebind failed: %d\n", rc); 11718c2ecf20Sopenharmony_ci } 11728c2ecf20Sopenharmony_ci} 11738c2ecf20Sopenharmony_ci 11748c2ecf20Sopenharmony_ci/* 11758c2ecf20Sopenharmony_ci * Rebind drivers to @udev's marked interfaces. These interfaces have 11768c2ecf20Sopenharmony_ci * the needs_binding flag set. 11778c2ecf20Sopenharmony_ci * 11788c2ecf20Sopenharmony_ci * The caller must hold @udev's device lock. 11798c2ecf20Sopenharmony_ci */ 11808c2ecf20Sopenharmony_cistatic void rebind_marked_interfaces(struct usb_device *udev) 11818c2ecf20Sopenharmony_ci{ 11828c2ecf20Sopenharmony_ci struct usb_host_config *config; 11838c2ecf20Sopenharmony_ci int i; 11848c2ecf20Sopenharmony_ci struct usb_interface *intf; 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_ci config = udev->actconfig; 11878c2ecf20Sopenharmony_ci if (config) { 11888c2ecf20Sopenharmony_ci for (i = 0; i < config->desc.bNumInterfaces; ++i) { 11898c2ecf20Sopenharmony_ci intf = config->interface[i]; 11908c2ecf20Sopenharmony_ci if (intf->needs_binding) 11918c2ecf20Sopenharmony_ci usb_rebind_intf(intf); 11928c2ecf20Sopenharmony_ci } 11938c2ecf20Sopenharmony_ci } 11948c2ecf20Sopenharmony_ci} 11958c2ecf20Sopenharmony_ci 11968c2ecf20Sopenharmony_ci/* 11978c2ecf20Sopenharmony_ci * Unbind all of @udev's marked interfaces and then rebind all of them. 11988c2ecf20Sopenharmony_ci * This ordering is necessary because some drivers claim several interfaces 11998c2ecf20Sopenharmony_ci * when they are first probed. 12008c2ecf20Sopenharmony_ci * 12018c2ecf20Sopenharmony_ci * The caller must hold @udev's device lock. 12028c2ecf20Sopenharmony_ci */ 12038c2ecf20Sopenharmony_civoid usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev) 12048c2ecf20Sopenharmony_ci{ 12058c2ecf20Sopenharmony_ci unbind_marked_interfaces(udev); 12068c2ecf20Sopenharmony_ci rebind_marked_interfaces(udev); 12078c2ecf20Sopenharmony_ci} 12088c2ecf20Sopenharmony_ci 12098c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_ci/* Unbind drivers for @udev's interfaces that don't support suspend/resume 12128c2ecf20Sopenharmony_ci * There is no check for reset_resume here because it can be determined 12138c2ecf20Sopenharmony_ci * only during resume whether reset_resume is needed. 12148c2ecf20Sopenharmony_ci * 12158c2ecf20Sopenharmony_ci * The caller must hold @udev's device lock. 12168c2ecf20Sopenharmony_ci */ 12178c2ecf20Sopenharmony_cistatic void unbind_no_pm_drivers_interfaces(struct usb_device *udev) 12188c2ecf20Sopenharmony_ci{ 12198c2ecf20Sopenharmony_ci struct usb_host_config *config; 12208c2ecf20Sopenharmony_ci int i; 12218c2ecf20Sopenharmony_ci struct usb_interface *intf; 12228c2ecf20Sopenharmony_ci struct usb_driver *drv; 12238c2ecf20Sopenharmony_ci 12248c2ecf20Sopenharmony_ci config = udev->actconfig; 12258c2ecf20Sopenharmony_ci if (config) { 12268c2ecf20Sopenharmony_ci for (i = 0; i < config->desc.bNumInterfaces; ++i) { 12278c2ecf20Sopenharmony_ci intf = config->interface[i]; 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_ci if (intf->dev.driver) { 12308c2ecf20Sopenharmony_ci drv = to_usb_driver(intf->dev.driver); 12318c2ecf20Sopenharmony_ci if (!drv->suspend || !drv->resume) 12328c2ecf20Sopenharmony_ci usb_forced_unbind_intf(intf); 12338c2ecf20Sopenharmony_ci } 12348c2ecf20Sopenharmony_ci } 12358c2ecf20Sopenharmony_ci } 12368c2ecf20Sopenharmony_ci} 12378c2ecf20Sopenharmony_ci 12388c2ecf20Sopenharmony_cistatic int usb_suspend_device(struct usb_device *udev, pm_message_t msg) 12398c2ecf20Sopenharmony_ci{ 12408c2ecf20Sopenharmony_ci struct usb_device_driver *udriver; 12418c2ecf20Sopenharmony_ci int status = 0; 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ci if (udev->state == USB_STATE_NOTATTACHED || 12448c2ecf20Sopenharmony_ci udev->state == USB_STATE_SUSPENDED) 12458c2ecf20Sopenharmony_ci goto done; 12468c2ecf20Sopenharmony_ci 12478c2ecf20Sopenharmony_ci /* For devices that don't have a driver, we do a generic suspend. */ 12488c2ecf20Sopenharmony_ci if (udev->dev.driver) 12498c2ecf20Sopenharmony_ci udriver = to_usb_device_driver(udev->dev.driver); 12508c2ecf20Sopenharmony_ci else { 12518c2ecf20Sopenharmony_ci udev->do_remote_wakeup = 0; 12528c2ecf20Sopenharmony_ci udriver = &usb_generic_driver; 12538c2ecf20Sopenharmony_ci } 12548c2ecf20Sopenharmony_ci if (udriver->suspend) 12558c2ecf20Sopenharmony_ci status = udriver->suspend(udev, msg); 12568c2ecf20Sopenharmony_ci if (status == 0 && udriver->generic_subclass) 12578c2ecf20Sopenharmony_ci status = usb_generic_driver_suspend(udev, msg); 12588c2ecf20Sopenharmony_ci 12598c2ecf20Sopenharmony_ci done: 12608c2ecf20Sopenharmony_ci dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); 12618c2ecf20Sopenharmony_ci return status; 12628c2ecf20Sopenharmony_ci} 12638c2ecf20Sopenharmony_ci 12648c2ecf20Sopenharmony_cistatic int usb_resume_device(struct usb_device *udev, pm_message_t msg) 12658c2ecf20Sopenharmony_ci{ 12668c2ecf20Sopenharmony_ci struct usb_device_driver *udriver; 12678c2ecf20Sopenharmony_ci int status = 0; 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_ci if (udev->state == USB_STATE_NOTATTACHED) 12708c2ecf20Sopenharmony_ci goto done; 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_ci /* Can't resume it if it doesn't have a driver. */ 12738c2ecf20Sopenharmony_ci if (udev->dev.driver == NULL) { 12748c2ecf20Sopenharmony_ci status = -ENOTCONN; 12758c2ecf20Sopenharmony_ci goto done; 12768c2ecf20Sopenharmony_ci } 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ci /* Non-root devices on a full/low-speed bus must wait for their 12798c2ecf20Sopenharmony_ci * companion high-speed root hub, in case a handoff is needed. 12808c2ecf20Sopenharmony_ci */ 12818c2ecf20Sopenharmony_ci if (!PMSG_IS_AUTO(msg) && udev->parent && udev->bus->hs_companion) 12828c2ecf20Sopenharmony_ci device_pm_wait_for_dev(&udev->dev, 12838c2ecf20Sopenharmony_ci &udev->bus->hs_companion->root_hub->dev); 12848c2ecf20Sopenharmony_ci 12858c2ecf20Sopenharmony_ci if (udev->quirks & USB_QUIRK_RESET_RESUME) 12868c2ecf20Sopenharmony_ci udev->reset_resume = 1; 12878c2ecf20Sopenharmony_ci 12888c2ecf20Sopenharmony_ci udriver = to_usb_device_driver(udev->dev.driver); 12898c2ecf20Sopenharmony_ci if (udriver->generic_subclass) 12908c2ecf20Sopenharmony_ci status = usb_generic_driver_resume(udev, msg); 12918c2ecf20Sopenharmony_ci if (status == 0 && udriver->resume) 12928c2ecf20Sopenharmony_ci status = udriver->resume(udev, msg); 12938c2ecf20Sopenharmony_ci 12948c2ecf20Sopenharmony_ci done: 12958c2ecf20Sopenharmony_ci dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); 12968c2ecf20Sopenharmony_ci return status; 12978c2ecf20Sopenharmony_ci} 12988c2ecf20Sopenharmony_ci 12998c2ecf20Sopenharmony_cistatic int usb_suspend_interface(struct usb_device *udev, 13008c2ecf20Sopenharmony_ci struct usb_interface *intf, pm_message_t msg) 13018c2ecf20Sopenharmony_ci{ 13028c2ecf20Sopenharmony_ci struct usb_driver *driver; 13038c2ecf20Sopenharmony_ci int status = 0; 13048c2ecf20Sopenharmony_ci 13058c2ecf20Sopenharmony_ci if (udev->state == USB_STATE_NOTATTACHED || 13068c2ecf20Sopenharmony_ci intf->condition == USB_INTERFACE_UNBOUND) 13078c2ecf20Sopenharmony_ci goto done; 13088c2ecf20Sopenharmony_ci driver = to_usb_driver(intf->dev.driver); 13098c2ecf20Sopenharmony_ci 13108c2ecf20Sopenharmony_ci /* at this time we know the driver supports suspend */ 13118c2ecf20Sopenharmony_ci status = driver->suspend(intf, msg); 13128c2ecf20Sopenharmony_ci if (status && !PMSG_IS_AUTO(msg)) 13138c2ecf20Sopenharmony_ci dev_err(&intf->dev, "suspend error %d\n", status); 13148c2ecf20Sopenharmony_ci 13158c2ecf20Sopenharmony_ci done: 13168c2ecf20Sopenharmony_ci dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status); 13178c2ecf20Sopenharmony_ci return status; 13188c2ecf20Sopenharmony_ci} 13198c2ecf20Sopenharmony_ci 13208c2ecf20Sopenharmony_cistatic int usb_resume_interface(struct usb_device *udev, 13218c2ecf20Sopenharmony_ci struct usb_interface *intf, pm_message_t msg, int reset_resume) 13228c2ecf20Sopenharmony_ci{ 13238c2ecf20Sopenharmony_ci struct usb_driver *driver; 13248c2ecf20Sopenharmony_ci int status = 0; 13258c2ecf20Sopenharmony_ci 13268c2ecf20Sopenharmony_ci if (udev->state == USB_STATE_NOTATTACHED) 13278c2ecf20Sopenharmony_ci goto done; 13288c2ecf20Sopenharmony_ci 13298c2ecf20Sopenharmony_ci /* Don't let autoresume interfere with unbinding */ 13308c2ecf20Sopenharmony_ci if (intf->condition == USB_INTERFACE_UNBINDING) 13318c2ecf20Sopenharmony_ci goto done; 13328c2ecf20Sopenharmony_ci 13338c2ecf20Sopenharmony_ci /* Can't resume it if it doesn't have a driver. */ 13348c2ecf20Sopenharmony_ci if (intf->condition == USB_INTERFACE_UNBOUND) { 13358c2ecf20Sopenharmony_ci 13368c2ecf20Sopenharmony_ci /* Carry out a deferred switch to altsetting 0 */ 13378c2ecf20Sopenharmony_ci if (intf->needs_altsetting0 && !intf->dev.power.is_prepared) { 13388c2ecf20Sopenharmony_ci usb_set_interface(udev, intf->altsetting[0]. 13398c2ecf20Sopenharmony_ci desc.bInterfaceNumber, 0); 13408c2ecf20Sopenharmony_ci intf->needs_altsetting0 = 0; 13418c2ecf20Sopenharmony_ci } 13428c2ecf20Sopenharmony_ci goto done; 13438c2ecf20Sopenharmony_ci } 13448c2ecf20Sopenharmony_ci 13458c2ecf20Sopenharmony_ci /* Don't resume if the interface is marked for rebinding */ 13468c2ecf20Sopenharmony_ci if (intf->needs_binding) 13478c2ecf20Sopenharmony_ci goto done; 13488c2ecf20Sopenharmony_ci driver = to_usb_driver(intf->dev.driver); 13498c2ecf20Sopenharmony_ci 13508c2ecf20Sopenharmony_ci if (reset_resume) { 13518c2ecf20Sopenharmony_ci if (driver->reset_resume) { 13528c2ecf20Sopenharmony_ci status = driver->reset_resume(intf); 13538c2ecf20Sopenharmony_ci if (status) 13548c2ecf20Sopenharmony_ci dev_err(&intf->dev, "%s error %d\n", 13558c2ecf20Sopenharmony_ci "reset_resume", status); 13568c2ecf20Sopenharmony_ci } else { 13578c2ecf20Sopenharmony_ci intf->needs_binding = 1; 13588c2ecf20Sopenharmony_ci dev_dbg(&intf->dev, "no reset_resume for driver %s?\n", 13598c2ecf20Sopenharmony_ci driver->name); 13608c2ecf20Sopenharmony_ci } 13618c2ecf20Sopenharmony_ci } else { 13628c2ecf20Sopenharmony_ci status = driver->resume(intf); 13638c2ecf20Sopenharmony_ci if (status) 13648c2ecf20Sopenharmony_ci dev_err(&intf->dev, "resume error %d\n", status); 13658c2ecf20Sopenharmony_ci } 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_cidone: 13688c2ecf20Sopenharmony_ci dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status); 13698c2ecf20Sopenharmony_ci 13708c2ecf20Sopenharmony_ci /* Later we will unbind the driver and/or reprobe, if necessary */ 13718c2ecf20Sopenharmony_ci return status; 13728c2ecf20Sopenharmony_ci} 13738c2ecf20Sopenharmony_ci 13748c2ecf20Sopenharmony_ci/** 13758c2ecf20Sopenharmony_ci * usb_suspend_both - suspend a USB device and its interfaces 13768c2ecf20Sopenharmony_ci * @udev: the usb_device to suspend 13778c2ecf20Sopenharmony_ci * @msg: Power Management message describing this state transition 13788c2ecf20Sopenharmony_ci * 13798c2ecf20Sopenharmony_ci * This is the central routine for suspending USB devices. It calls the 13808c2ecf20Sopenharmony_ci * suspend methods for all the interface drivers in @udev and then calls 13818c2ecf20Sopenharmony_ci * the suspend method for @udev itself. When the routine is called in 13828c2ecf20Sopenharmony_ci * autosuspend, if an error occurs at any stage, all the interfaces 13838c2ecf20Sopenharmony_ci * which were suspended are resumed so that they remain in the same 13848c2ecf20Sopenharmony_ci * state as the device, but when called from system sleep, all error 13858c2ecf20Sopenharmony_ci * from suspend methods of interfaces and the non-root-hub device itself 13868c2ecf20Sopenharmony_ci * are simply ignored, so all suspended interfaces are only resumed 13878c2ecf20Sopenharmony_ci * to the device's state when @udev is root-hub and its suspend method 13888c2ecf20Sopenharmony_ci * returns failure. 13898c2ecf20Sopenharmony_ci * 13908c2ecf20Sopenharmony_ci * Autosuspend requests originating from a child device or an interface 13918c2ecf20Sopenharmony_ci * driver may be made without the protection of @udev's device lock, but 13928c2ecf20Sopenharmony_ci * all other suspend calls will hold the lock. Usbcore will insure that 13938c2ecf20Sopenharmony_ci * method calls do not arrive during bind, unbind, or reset operations. 13948c2ecf20Sopenharmony_ci * However drivers must be prepared to handle suspend calls arriving at 13958c2ecf20Sopenharmony_ci * unpredictable times. 13968c2ecf20Sopenharmony_ci * 13978c2ecf20Sopenharmony_ci * This routine can run only in process context. 13988c2ecf20Sopenharmony_ci * 13998c2ecf20Sopenharmony_ci * Return: 0 if the suspend succeeded. 14008c2ecf20Sopenharmony_ci */ 14018c2ecf20Sopenharmony_cistatic int usb_suspend_both(struct usb_device *udev, pm_message_t msg) 14028c2ecf20Sopenharmony_ci{ 14038c2ecf20Sopenharmony_ci int status = 0; 14048c2ecf20Sopenharmony_ci int i = 0, n = 0; 14058c2ecf20Sopenharmony_ci struct usb_interface *intf; 14068c2ecf20Sopenharmony_ci 14078c2ecf20Sopenharmony_ci if (udev->state == USB_STATE_NOTATTACHED || 14088c2ecf20Sopenharmony_ci udev->state == USB_STATE_SUSPENDED) 14098c2ecf20Sopenharmony_ci goto done; 14108c2ecf20Sopenharmony_ci 14118c2ecf20Sopenharmony_ci /* Suspend all the interfaces and then udev itself */ 14128c2ecf20Sopenharmony_ci if (udev->actconfig) { 14138c2ecf20Sopenharmony_ci n = udev->actconfig->desc.bNumInterfaces; 14148c2ecf20Sopenharmony_ci for (i = n - 1; i >= 0; --i) { 14158c2ecf20Sopenharmony_ci intf = udev->actconfig->interface[i]; 14168c2ecf20Sopenharmony_ci status = usb_suspend_interface(udev, intf, msg); 14178c2ecf20Sopenharmony_ci 14188c2ecf20Sopenharmony_ci /* Ignore errors during system sleep transitions */ 14198c2ecf20Sopenharmony_ci if (!PMSG_IS_AUTO(msg)) 14208c2ecf20Sopenharmony_ci status = 0; 14218c2ecf20Sopenharmony_ci if (status != 0) 14228c2ecf20Sopenharmony_ci break; 14238c2ecf20Sopenharmony_ci } 14248c2ecf20Sopenharmony_ci } 14258c2ecf20Sopenharmony_ci if (status == 0) { 14268c2ecf20Sopenharmony_ci status = usb_suspend_device(udev, msg); 14278c2ecf20Sopenharmony_ci 14288c2ecf20Sopenharmony_ci /* 14298c2ecf20Sopenharmony_ci * Ignore errors from non-root-hub devices during 14308c2ecf20Sopenharmony_ci * system sleep transitions. For the most part, 14318c2ecf20Sopenharmony_ci * these devices should go to low power anyway when 14328c2ecf20Sopenharmony_ci * the entire bus is suspended. 14338c2ecf20Sopenharmony_ci */ 14348c2ecf20Sopenharmony_ci if (udev->parent && !PMSG_IS_AUTO(msg)) 14358c2ecf20Sopenharmony_ci status = 0; 14368c2ecf20Sopenharmony_ci 14378c2ecf20Sopenharmony_ci /* 14388c2ecf20Sopenharmony_ci * If the device is inaccessible, don't try to resume 14398c2ecf20Sopenharmony_ci * suspended interfaces and just return the error. 14408c2ecf20Sopenharmony_ci */ 14418c2ecf20Sopenharmony_ci if (status && status != -EBUSY) { 14428c2ecf20Sopenharmony_ci int err; 14438c2ecf20Sopenharmony_ci u16 devstat; 14448c2ecf20Sopenharmony_ci 14458c2ecf20Sopenharmony_ci err = usb_get_std_status(udev, USB_RECIP_DEVICE, 0, 14468c2ecf20Sopenharmony_ci &devstat); 14478c2ecf20Sopenharmony_ci if (err) { 14488c2ecf20Sopenharmony_ci dev_err(&udev->dev, 14498c2ecf20Sopenharmony_ci "Failed to suspend device, error %d\n", 14508c2ecf20Sopenharmony_ci status); 14518c2ecf20Sopenharmony_ci goto done; 14528c2ecf20Sopenharmony_ci } 14538c2ecf20Sopenharmony_ci } 14548c2ecf20Sopenharmony_ci } 14558c2ecf20Sopenharmony_ci 14568c2ecf20Sopenharmony_ci /* If the suspend failed, resume interfaces that did get suspended */ 14578c2ecf20Sopenharmony_ci if (status != 0) { 14588c2ecf20Sopenharmony_ci if (udev->actconfig) { 14598c2ecf20Sopenharmony_ci msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME); 14608c2ecf20Sopenharmony_ci while (++i < n) { 14618c2ecf20Sopenharmony_ci intf = udev->actconfig->interface[i]; 14628c2ecf20Sopenharmony_ci usb_resume_interface(udev, intf, msg, 0); 14638c2ecf20Sopenharmony_ci } 14648c2ecf20Sopenharmony_ci } 14658c2ecf20Sopenharmony_ci 14668c2ecf20Sopenharmony_ci /* If the suspend succeeded then prevent any more URB submissions 14678c2ecf20Sopenharmony_ci * and flush any outstanding URBs. 14688c2ecf20Sopenharmony_ci */ 14698c2ecf20Sopenharmony_ci } else { 14708c2ecf20Sopenharmony_ci udev->can_submit = 0; 14718c2ecf20Sopenharmony_ci for (i = 0; i < 16; ++i) { 14728c2ecf20Sopenharmony_ci usb_hcd_flush_endpoint(udev, udev->ep_out[i]); 14738c2ecf20Sopenharmony_ci usb_hcd_flush_endpoint(udev, udev->ep_in[i]); 14748c2ecf20Sopenharmony_ci } 14758c2ecf20Sopenharmony_ci } 14768c2ecf20Sopenharmony_ci 14778c2ecf20Sopenharmony_ci done: 14788c2ecf20Sopenharmony_ci dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); 14798c2ecf20Sopenharmony_ci return status; 14808c2ecf20Sopenharmony_ci} 14818c2ecf20Sopenharmony_ci 14828c2ecf20Sopenharmony_ci/** 14838c2ecf20Sopenharmony_ci * usb_resume_both - resume a USB device and its interfaces 14848c2ecf20Sopenharmony_ci * @udev: the usb_device to resume 14858c2ecf20Sopenharmony_ci * @msg: Power Management message describing this state transition 14868c2ecf20Sopenharmony_ci * 14878c2ecf20Sopenharmony_ci * This is the central routine for resuming USB devices. It calls the 14888c2ecf20Sopenharmony_ci * the resume method for @udev and then calls the resume methods for all 14898c2ecf20Sopenharmony_ci * the interface drivers in @udev. 14908c2ecf20Sopenharmony_ci * 14918c2ecf20Sopenharmony_ci * Autoresume requests originating from a child device or an interface 14928c2ecf20Sopenharmony_ci * driver may be made without the protection of @udev's device lock, but 14938c2ecf20Sopenharmony_ci * all other resume calls will hold the lock. Usbcore will insure that 14948c2ecf20Sopenharmony_ci * method calls do not arrive during bind, unbind, or reset operations. 14958c2ecf20Sopenharmony_ci * However drivers must be prepared to handle resume calls arriving at 14968c2ecf20Sopenharmony_ci * unpredictable times. 14978c2ecf20Sopenharmony_ci * 14988c2ecf20Sopenharmony_ci * This routine can run only in process context. 14998c2ecf20Sopenharmony_ci * 15008c2ecf20Sopenharmony_ci * Return: 0 on success. 15018c2ecf20Sopenharmony_ci */ 15028c2ecf20Sopenharmony_cistatic int usb_resume_both(struct usb_device *udev, pm_message_t msg) 15038c2ecf20Sopenharmony_ci{ 15048c2ecf20Sopenharmony_ci int status = 0; 15058c2ecf20Sopenharmony_ci int i; 15068c2ecf20Sopenharmony_ci struct usb_interface *intf; 15078c2ecf20Sopenharmony_ci 15088c2ecf20Sopenharmony_ci if (udev->state == USB_STATE_NOTATTACHED) { 15098c2ecf20Sopenharmony_ci status = -ENODEV; 15108c2ecf20Sopenharmony_ci goto done; 15118c2ecf20Sopenharmony_ci } 15128c2ecf20Sopenharmony_ci udev->can_submit = 1; 15138c2ecf20Sopenharmony_ci 15148c2ecf20Sopenharmony_ci /* Resume the device */ 15158c2ecf20Sopenharmony_ci if (udev->state == USB_STATE_SUSPENDED || udev->reset_resume) 15168c2ecf20Sopenharmony_ci status = usb_resume_device(udev, msg); 15178c2ecf20Sopenharmony_ci 15188c2ecf20Sopenharmony_ci /* Resume the interfaces */ 15198c2ecf20Sopenharmony_ci if (status == 0 && udev->actconfig) { 15208c2ecf20Sopenharmony_ci for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { 15218c2ecf20Sopenharmony_ci intf = udev->actconfig->interface[i]; 15228c2ecf20Sopenharmony_ci usb_resume_interface(udev, intf, msg, 15238c2ecf20Sopenharmony_ci udev->reset_resume); 15248c2ecf20Sopenharmony_ci } 15258c2ecf20Sopenharmony_ci } 15268c2ecf20Sopenharmony_ci usb_mark_last_busy(udev); 15278c2ecf20Sopenharmony_ci 15288c2ecf20Sopenharmony_ci done: 15298c2ecf20Sopenharmony_ci dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); 15308c2ecf20Sopenharmony_ci if (!status) 15318c2ecf20Sopenharmony_ci udev->reset_resume = 0; 15328c2ecf20Sopenharmony_ci return status; 15338c2ecf20Sopenharmony_ci} 15348c2ecf20Sopenharmony_ci 15358c2ecf20Sopenharmony_cistatic void choose_wakeup(struct usb_device *udev, pm_message_t msg) 15368c2ecf20Sopenharmony_ci{ 15378c2ecf20Sopenharmony_ci int w; 15388c2ecf20Sopenharmony_ci 15398c2ecf20Sopenharmony_ci /* Remote wakeup is needed only when we actually go to sleep. 15408c2ecf20Sopenharmony_ci * For things like FREEZE and QUIESCE, if the device is already 15418c2ecf20Sopenharmony_ci * autosuspended then its current wakeup setting is okay. 15428c2ecf20Sopenharmony_ci */ 15438c2ecf20Sopenharmony_ci if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) { 15448c2ecf20Sopenharmony_ci if (udev->state != USB_STATE_SUSPENDED) 15458c2ecf20Sopenharmony_ci udev->do_remote_wakeup = 0; 15468c2ecf20Sopenharmony_ci return; 15478c2ecf20Sopenharmony_ci } 15488c2ecf20Sopenharmony_ci 15498c2ecf20Sopenharmony_ci /* Enable remote wakeup if it is allowed, even if no interface drivers 15508c2ecf20Sopenharmony_ci * actually want it. 15518c2ecf20Sopenharmony_ci */ 15528c2ecf20Sopenharmony_ci w = device_may_wakeup(&udev->dev); 15538c2ecf20Sopenharmony_ci 15548c2ecf20Sopenharmony_ci /* If the device is autosuspended with the wrong wakeup setting, 15558c2ecf20Sopenharmony_ci * autoresume now so the setting can be changed. 15568c2ecf20Sopenharmony_ci */ 15578c2ecf20Sopenharmony_ci if (udev->state == USB_STATE_SUSPENDED && w != udev->do_remote_wakeup) 15588c2ecf20Sopenharmony_ci pm_runtime_resume(&udev->dev); 15598c2ecf20Sopenharmony_ci udev->do_remote_wakeup = w; 15608c2ecf20Sopenharmony_ci} 15618c2ecf20Sopenharmony_ci 15628c2ecf20Sopenharmony_ci/* The device lock is held by the PM core */ 15638c2ecf20Sopenharmony_ciint usb_suspend(struct device *dev, pm_message_t msg) 15648c2ecf20Sopenharmony_ci{ 15658c2ecf20Sopenharmony_ci struct usb_device *udev = to_usb_device(dev); 15668c2ecf20Sopenharmony_ci int r; 15678c2ecf20Sopenharmony_ci 15688c2ecf20Sopenharmony_ci unbind_no_pm_drivers_interfaces(udev); 15698c2ecf20Sopenharmony_ci 15708c2ecf20Sopenharmony_ci /* From now on we are sure all drivers support suspend/resume 15718c2ecf20Sopenharmony_ci * but not necessarily reset_resume() 15728c2ecf20Sopenharmony_ci * so we may still need to unbind and rebind upon resume 15738c2ecf20Sopenharmony_ci */ 15748c2ecf20Sopenharmony_ci choose_wakeup(udev, msg); 15758c2ecf20Sopenharmony_ci r = usb_suspend_both(udev, msg); 15768c2ecf20Sopenharmony_ci if (r) 15778c2ecf20Sopenharmony_ci return r; 15788c2ecf20Sopenharmony_ci 15798c2ecf20Sopenharmony_ci if (udev->quirks & USB_QUIRK_DISCONNECT_SUSPEND) 15808c2ecf20Sopenharmony_ci usb_port_disable(udev); 15818c2ecf20Sopenharmony_ci 15828c2ecf20Sopenharmony_ci return 0; 15838c2ecf20Sopenharmony_ci} 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_ci/* The device lock is held by the PM core */ 15868c2ecf20Sopenharmony_ciint usb_resume_complete(struct device *dev) 15878c2ecf20Sopenharmony_ci{ 15888c2ecf20Sopenharmony_ci struct usb_device *udev = to_usb_device(dev); 15898c2ecf20Sopenharmony_ci 15908c2ecf20Sopenharmony_ci /* For PM complete calls, all we do is rebind interfaces 15918c2ecf20Sopenharmony_ci * whose needs_binding flag is set 15928c2ecf20Sopenharmony_ci */ 15938c2ecf20Sopenharmony_ci if (udev->state != USB_STATE_NOTATTACHED) 15948c2ecf20Sopenharmony_ci rebind_marked_interfaces(udev); 15958c2ecf20Sopenharmony_ci return 0; 15968c2ecf20Sopenharmony_ci} 15978c2ecf20Sopenharmony_ci 15988c2ecf20Sopenharmony_ci/* The device lock is held by the PM core */ 15998c2ecf20Sopenharmony_ciint usb_resume(struct device *dev, pm_message_t msg) 16008c2ecf20Sopenharmony_ci{ 16018c2ecf20Sopenharmony_ci struct usb_device *udev = to_usb_device(dev); 16028c2ecf20Sopenharmony_ci int status; 16038c2ecf20Sopenharmony_ci 16048c2ecf20Sopenharmony_ci /* For all calls, take the device back to full power and 16058c2ecf20Sopenharmony_ci * tell the PM core in case it was autosuspended previously. 16068c2ecf20Sopenharmony_ci * Unbind the interfaces that will need rebinding later, 16078c2ecf20Sopenharmony_ci * because they fail to support reset_resume. 16088c2ecf20Sopenharmony_ci * (This can't be done in usb_resume_interface() 16098c2ecf20Sopenharmony_ci * above because it doesn't own the right set of locks.) 16108c2ecf20Sopenharmony_ci */ 16118c2ecf20Sopenharmony_ci status = usb_resume_both(udev, msg); 16128c2ecf20Sopenharmony_ci if (status == 0) { 16138c2ecf20Sopenharmony_ci pm_runtime_disable(dev); 16148c2ecf20Sopenharmony_ci pm_runtime_set_active(dev); 16158c2ecf20Sopenharmony_ci pm_runtime_enable(dev); 16168c2ecf20Sopenharmony_ci unbind_marked_interfaces(udev); 16178c2ecf20Sopenharmony_ci } 16188c2ecf20Sopenharmony_ci 16198c2ecf20Sopenharmony_ci /* Avoid PM error messages for devices disconnected while suspended 16208c2ecf20Sopenharmony_ci * as we'll display regular disconnect messages just a bit later. 16218c2ecf20Sopenharmony_ci */ 16228c2ecf20Sopenharmony_ci if (status == -ENODEV || status == -ESHUTDOWN) 16238c2ecf20Sopenharmony_ci status = 0; 16248c2ecf20Sopenharmony_ci return status; 16258c2ecf20Sopenharmony_ci} 16268c2ecf20Sopenharmony_ci 16278c2ecf20Sopenharmony_ci/** 16288c2ecf20Sopenharmony_ci * usb_enable_autosuspend - allow a USB device to be autosuspended 16298c2ecf20Sopenharmony_ci * @udev: the USB device which may be autosuspended 16308c2ecf20Sopenharmony_ci * 16318c2ecf20Sopenharmony_ci * This routine allows @udev to be autosuspended. An autosuspend won't 16328c2ecf20Sopenharmony_ci * take place until the autosuspend_delay has elapsed and all the other 16338c2ecf20Sopenharmony_ci * necessary conditions are satisfied. 16348c2ecf20Sopenharmony_ci * 16358c2ecf20Sopenharmony_ci * The caller must hold @udev's device lock. 16368c2ecf20Sopenharmony_ci */ 16378c2ecf20Sopenharmony_civoid usb_enable_autosuspend(struct usb_device *udev) 16388c2ecf20Sopenharmony_ci{ 16398c2ecf20Sopenharmony_ci pm_runtime_allow(&udev->dev); 16408c2ecf20Sopenharmony_ci} 16418c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_enable_autosuspend); 16428c2ecf20Sopenharmony_ci 16438c2ecf20Sopenharmony_ci/** 16448c2ecf20Sopenharmony_ci * usb_disable_autosuspend - prevent a USB device from being autosuspended 16458c2ecf20Sopenharmony_ci * @udev: the USB device which may not be autosuspended 16468c2ecf20Sopenharmony_ci * 16478c2ecf20Sopenharmony_ci * This routine prevents @udev from being autosuspended and wakes it up 16488c2ecf20Sopenharmony_ci * if it is already autosuspended. 16498c2ecf20Sopenharmony_ci * 16508c2ecf20Sopenharmony_ci * The caller must hold @udev's device lock. 16518c2ecf20Sopenharmony_ci */ 16528c2ecf20Sopenharmony_civoid usb_disable_autosuspend(struct usb_device *udev) 16538c2ecf20Sopenharmony_ci{ 16548c2ecf20Sopenharmony_ci pm_runtime_forbid(&udev->dev); 16558c2ecf20Sopenharmony_ci} 16568c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_disable_autosuspend); 16578c2ecf20Sopenharmony_ci 16588c2ecf20Sopenharmony_ci/** 16598c2ecf20Sopenharmony_ci * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces 16608c2ecf20Sopenharmony_ci * @udev: the usb_device to autosuspend 16618c2ecf20Sopenharmony_ci * 16628c2ecf20Sopenharmony_ci * This routine should be called when a core subsystem is finished using 16638c2ecf20Sopenharmony_ci * @udev and wants to allow it to autosuspend. Examples would be when 16648c2ecf20Sopenharmony_ci * @udev's device file in usbfs is closed or after a configuration change. 16658c2ecf20Sopenharmony_ci * 16668c2ecf20Sopenharmony_ci * @udev's usage counter is decremented; if it drops to 0 and all the 16678c2ecf20Sopenharmony_ci * interfaces are inactive then a delayed autosuspend will be attempted. 16688c2ecf20Sopenharmony_ci * The attempt may fail (see autosuspend_check()). 16698c2ecf20Sopenharmony_ci * 16708c2ecf20Sopenharmony_ci * The caller must hold @udev's device lock. 16718c2ecf20Sopenharmony_ci * 16728c2ecf20Sopenharmony_ci * This routine can run only in process context. 16738c2ecf20Sopenharmony_ci */ 16748c2ecf20Sopenharmony_civoid usb_autosuspend_device(struct usb_device *udev) 16758c2ecf20Sopenharmony_ci{ 16768c2ecf20Sopenharmony_ci int status; 16778c2ecf20Sopenharmony_ci 16788c2ecf20Sopenharmony_ci usb_mark_last_busy(udev); 16798c2ecf20Sopenharmony_ci status = pm_runtime_put_sync_autosuspend(&udev->dev); 16808c2ecf20Sopenharmony_ci dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", 16818c2ecf20Sopenharmony_ci __func__, atomic_read(&udev->dev.power.usage_count), 16828c2ecf20Sopenharmony_ci status); 16838c2ecf20Sopenharmony_ci} 16848c2ecf20Sopenharmony_ci 16858c2ecf20Sopenharmony_ci/** 16868c2ecf20Sopenharmony_ci * usb_autoresume_device - immediately autoresume a USB device and its interfaces 16878c2ecf20Sopenharmony_ci * @udev: the usb_device to autoresume 16888c2ecf20Sopenharmony_ci * 16898c2ecf20Sopenharmony_ci * This routine should be called when a core subsystem wants to use @udev 16908c2ecf20Sopenharmony_ci * and needs to guarantee that it is not suspended. No autosuspend will 16918c2ecf20Sopenharmony_ci * occur until usb_autosuspend_device() is called. (Note that this will 16928c2ecf20Sopenharmony_ci * not prevent suspend events originating in the PM core.) Examples would 16938c2ecf20Sopenharmony_ci * be when @udev's device file in usbfs is opened or when a remote-wakeup 16948c2ecf20Sopenharmony_ci * request is received. 16958c2ecf20Sopenharmony_ci * 16968c2ecf20Sopenharmony_ci * @udev's usage counter is incremented to prevent subsequent autosuspends. 16978c2ecf20Sopenharmony_ci * However if the autoresume fails then the usage counter is re-decremented. 16988c2ecf20Sopenharmony_ci * 16998c2ecf20Sopenharmony_ci * The caller must hold @udev's device lock. 17008c2ecf20Sopenharmony_ci * 17018c2ecf20Sopenharmony_ci * This routine can run only in process context. 17028c2ecf20Sopenharmony_ci * 17038c2ecf20Sopenharmony_ci * Return: 0 on success. A negative error code otherwise. 17048c2ecf20Sopenharmony_ci */ 17058c2ecf20Sopenharmony_ciint usb_autoresume_device(struct usb_device *udev) 17068c2ecf20Sopenharmony_ci{ 17078c2ecf20Sopenharmony_ci int status; 17088c2ecf20Sopenharmony_ci 17098c2ecf20Sopenharmony_ci status = pm_runtime_get_sync(&udev->dev); 17108c2ecf20Sopenharmony_ci if (status < 0) 17118c2ecf20Sopenharmony_ci pm_runtime_put_sync(&udev->dev); 17128c2ecf20Sopenharmony_ci dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", 17138c2ecf20Sopenharmony_ci __func__, atomic_read(&udev->dev.power.usage_count), 17148c2ecf20Sopenharmony_ci status); 17158c2ecf20Sopenharmony_ci if (status > 0) 17168c2ecf20Sopenharmony_ci status = 0; 17178c2ecf20Sopenharmony_ci return status; 17188c2ecf20Sopenharmony_ci} 17198c2ecf20Sopenharmony_ci 17208c2ecf20Sopenharmony_ci/** 17218c2ecf20Sopenharmony_ci * usb_autopm_put_interface - decrement a USB interface's PM-usage counter 17228c2ecf20Sopenharmony_ci * @intf: the usb_interface whose counter should be decremented 17238c2ecf20Sopenharmony_ci * 17248c2ecf20Sopenharmony_ci * This routine should be called by an interface driver when it is 17258c2ecf20Sopenharmony_ci * finished using @intf and wants to allow it to autosuspend. A typical 17268c2ecf20Sopenharmony_ci * example would be a character-device driver when its device file is 17278c2ecf20Sopenharmony_ci * closed. 17288c2ecf20Sopenharmony_ci * 17298c2ecf20Sopenharmony_ci * The routine decrements @intf's usage counter. When the counter reaches 17308c2ecf20Sopenharmony_ci * 0, a delayed autosuspend request for @intf's device is attempted. The 17318c2ecf20Sopenharmony_ci * attempt may fail (see autosuspend_check()). 17328c2ecf20Sopenharmony_ci * 17338c2ecf20Sopenharmony_ci * This routine can run only in process context. 17348c2ecf20Sopenharmony_ci */ 17358c2ecf20Sopenharmony_civoid usb_autopm_put_interface(struct usb_interface *intf) 17368c2ecf20Sopenharmony_ci{ 17378c2ecf20Sopenharmony_ci struct usb_device *udev = interface_to_usbdev(intf); 17388c2ecf20Sopenharmony_ci int status; 17398c2ecf20Sopenharmony_ci 17408c2ecf20Sopenharmony_ci usb_mark_last_busy(udev); 17418c2ecf20Sopenharmony_ci status = pm_runtime_put_sync(&intf->dev); 17428c2ecf20Sopenharmony_ci dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", 17438c2ecf20Sopenharmony_ci __func__, atomic_read(&intf->dev.power.usage_count), 17448c2ecf20Sopenharmony_ci status); 17458c2ecf20Sopenharmony_ci} 17468c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_autopm_put_interface); 17478c2ecf20Sopenharmony_ci 17488c2ecf20Sopenharmony_ci/** 17498c2ecf20Sopenharmony_ci * usb_autopm_put_interface_async - decrement a USB interface's PM-usage counter 17508c2ecf20Sopenharmony_ci * @intf: the usb_interface whose counter should be decremented 17518c2ecf20Sopenharmony_ci * 17528c2ecf20Sopenharmony_ci * This routine does much the same thing as usb_autopm_put_interface(): 17538c2ecf20Sopenharmony_ci * It decrements @intf's usage counter and schedules a delayed 17548c2ecf20Sopenharmony_ci * autosuspend request if the counter is <= 0. The difference is that it 17558c2ecf20Sopenharmony_ci * does not perform any synchronization; callers should hold a private 17568c2ecf20Sopenharmony_ci * lock and handle all synchronization issues themselves. 17578c2ecf20Sopenharmony_ci * 17588c2ecf20Sopenharmony_ci * Typically a driver would call this routine during an URB's completion 17598c2ecf20Sopenharmony_ci * handler, if no more URBs were pending. 17608c2ecf20Sopenharmony_ci * 17618c2ecf20Sopenharmony_ci * This routine can run in atomic context. 17628c2ecf20Sopenharmony_ci */ 17638c2ecf20Sopenharmony_civoid usb_autopm_put_interface_async(struct usb_interface *intf) 17648c2ecf20Sopenharmony_ci{ 17658c2ecf20Sopenharmony_ci struct usb_device *udev = interface_to_usbdev(intf); 17668c2ecf20Sopenharmony_ci int status; 17678c2ecf20Sopenharmony_ci 17688c2ecf20Sopenharmony_ci usb_mark_last_busy(udev); 17698c2ecf20Sopenharmony_ci status = pm_runtime_put(&intf->dev); 17708c2ecf20Sopenharmony_ci dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", 17718c2ecf20Sopenharmony_ci __func__, atomic_read(&intf->dev.power.usage_count), 17728c2ecf20Sopenharmony_ci status); 17738c2ecf20Sopenharmony_ci} 17748c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_autopm_put_interface_async); 17758c2ecf20Sopenharmony_ci 17768c2ecf20Sopenharmony_ci/** 17778c2ecf20Sopenharmony_ci * usb_autopm_put_interface_no_suspend - decrement a USB interface's PM-usage counter 17788c2ecf20Sopenharmony_ci * @intf: the usb_interface whose counter should be decremented 17798c2ecf20Sopenharmony_ci * 17808c2ecf20Sopenharmony_ci * This routine decrements @intf's usage counter but does not carry out an 17818c2ecf20Sopenharmony_ci * autosuspend. 17828c2ecf20Sopenharmony_ci * 17838c2ecf20Sopenharmony_ci * This routine can run in atomic context. 17848c2ecf20Sopenharmony_ci */ 17858c2ecf20Sopenharmony_civoid usb_autopm_put_interface_no_suspend(struct usb_interface *intf) 17868c2ecf20Sopenharmony_ci{ 17878c2ecf20Sopenharmony_ci struct usb_device *udev = interface_to_usbdev(intf); 17888c2ecf20Sopenharmony_ci 17898c2ecf20Sopenharmony_ci usb_mark_last_busy(udev); 17908c2ecf20Sopenharmony_ci pm_runtime_put_noidle(&intf->dev); 17918c2ecf20Sopenharmony_ci} 17928c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_autopm_put_interface_no_suspend); 17938c2ecf20Sopenharmony_ci 17948c2ecf20Sopenharmony_ci/** 17958c2ecf20Sopenharmony_ci * usb_autopm_get_interface - increment a USB interface's PM-usage counter 17968c2ecf20Sopenharmony_ci * @intf: the usb_interface whose counter should be incremented 17978c2ecf20Sopenharmony_ci * 17988c2ecf20Sopenharmony_ci * This routine should be called by an interface driver when it wants to 17998c2ecf20Sopenharmony_ci * use @intf and needs to guarantee that it is not suspended. In addition, 18008c2ecf20Sopenharmony_ci * the routine prevents @intf from being autosuspended subsequently. (Note 18018c2ecf20Sopenharmony_ci * that this will not prevent suspend events originating in the PM core.) 18028c2ecf20Sopenharmony_ci * This prevention will persist until usb_autopm_put_interface() is called 18038c2ecf20Sopenharmony_ci * or @intf is unbound. A typical example would be a character-device 18048c2ecf20Sopenharmony_ci * driver when its device file is opened. 18058c2ecf20Sopenharmony_ci * 18068c2ecf20Sopenharmony_ci * @intf's usage counter is incremented to prevent subsequent autosuspends. 18078c2ecf20Sopenharmony_ci * However if the autoresume fails then the counter is re-decremented. 18088c2ecf20Sopenharmony_ci * 18098c2ecf20Sopenharmony_ci * This routine can run only in process context. 18108c2ecf20Sopenharmony_ci * 18118c2ecf20Sopenharmony_ci * Return: 0 on success. 18128c2ecf20Sopenharmony_ci */ 18138c2ecf20Sopenharmony_ciint usb_autopm_get_interface(struct usb_interface *intf) 18148c2ecf20Sopenharmony_ci{ 18158c2ecf20Sopenharmony_ci int status; 18168c2ecf20Sopenharmony_ci 18178c2ecf20Sopenharmony_ci status = pm_runtime_get_sync(&intf->dev); 18188c2ecf20Sopenharmony_ci if (status < 0) 18198c2ecf20Sopenharmony_ci pm_runtime_put_sync(&intf->dev); 18208c2ecf20Sopenharmony_ci dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", 18218c2ecf20Sopenharmony_ci __func__, atomic_read(&intf->dev.power.usage_count), 18228c2ecf20Sopenharmony_ci status); 18238c2ecf20Sopenharmony_ci if (status > 0) 18248c2ecf20Sopenharmony_ci status = 0; 18258c2ecf20Sopenharmony_ci return status; 18268c2ecf20Sopenharmony_ci} 18278c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_autopm_get_interface); 18288c2ecf20Sopenharmony_ci 18298c2ecf20Sopenharmony_ci/** 18308c2ecf20Sopenharmony_ci * usb_autopm_get_interface_async - increment a USB interface's PM-usage counter 18318c2ecf20Sopenharmony_ci * @intf: the usb_interface whose counter should be incremented 18328c2ecf20Sopenharmony_ci * 18338c2ecf20Sopenharmony_ci * This routine does much the same thing as 18348c2ecf20Sopenharmony_ci * usb_autopm_get_interface(): It increments @intf's usage counter and 18358c2ecf20Sopenharmony_ci * queues an autoresume request if the device is suspended. The 18368c2ecf20Sopenharmony_ci * differences are that it does not perform any synchronization (callers 18378c2ecf20Sopenharmony_ci * should hold a private lock and handle all synchronization issues 18388c2ecf20Sopenharmony_ci * themselves), and it does not autoresume the device directly (it only 18398c2ecf20Sopenharmony_ci * queues a request). After a successful call, the device may not yet be 18408c2ecf20Sopenharmony_ci * resumed. 18418c2ecf20Sopenharmony_ci * 18428c2ecf20Sopenharmony_ci * This routine can run in atomic context. 18438c2ecf20Sopenharmony_ci * 18448c2ecf20Sopenharmony_ci * Return: 0 on success. A negative error code otherwise. 18458c2ecf20Sopenharmony_ci */ 18468c2ecf20Sopenharmony_ciint usb_autopm_get_interface_async(struct usb_interface *intf) 18478c2ecf20Sopenharmony_ci{ 18488c2ecf20Sopenharmony_ci int status; 18498c2ecf20Sopenharmony_ci 18508c2ecf20Sopenharmony_ci status = pm_runtime_get(&intf->dev); 18518c2ecf20Sopenharmony_ci if (status < 0 && status != -EINPROGRESS) 18528c2ecf20Sopenharmony_ci pm_runtime_put_noidle(&intf->dev); 18538c2ecf20Sopenharmony_ci dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", 18548c2ecf20Sopenharmony_ci __func__, atomic_read(&intf->dev.power.usage_count), 18558c2ecf20Sopenharmony_ci status); 18568c2ecf20Sopenharmony_ci if (status > 0 || status == -EINPROGRESS) 18578c2ecf20Sopenharmony_ci status = 0; 18588c2ecf20Sopenharmony_ci return status; 18598c2ecf20Sopenharmony_ci} 18608c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_autopm_get_interface_async); 18618c2ecf20Sopenharmony_ci 18628c2ecf20Sopenharmony_ci/** 18638c2ecf20Sopenharmony_ci * usb_autopm_get_interface_no_resume - increment a USB interface's PM-usage counter 18648c2ecf20Sopenharmony_ci * @intf: the usb_interface whose counter should be incremented 18658c2ecf20Sopenharmony_ci * 18668c2ecf20Sopenharmony_ci * This routine increments @intf's usage counter but does not carry out an 18678c2ecf20Sopenharmony_ci * autoresume. 18688c2ecf20Sopenharmony_ci * 18698c2ecf20Sopenharmony_ci * This routine can run in atomic context. 18708c2ecf20Sopenharmony_ci */ 18718c2ecf20Sopenharmony_civoid usb_autopm_get_interface_no_resume(struct usb_interface *intf) 18728c2ecf20Sopenharmony_ci{ 18738c2ecf20Sopenharmony_ci struct usb_device *udev = interface_to_usbdev(intf); 18748c2ecf20Sopenharmony_ci 18758c2ecf20Sopenharmony_ci usb_mark_last_busy(udev); 18768c2ecf20Sopenharmony_ci pm_runtime_get_noresume(&intf->dev); 18778c2ecf20Sopenharmony_ci} 18788c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_autopm_get_interface_no_resume); 18798c2ecf20Sopenharmony_ci 18808c2ecf20Sopenharmony_ci/* Internal routine to check whether we may autosuspend a device. */ 18818c2ecf20Sopenharmony_cistatic int autosuspend_check(struct usb_device *udev) 18828c2ecf20Sopenharmony_ci{ 18838c2ecf20Sopenharmony_ci int w, i; 18848c2ecf20Sopenharmony_ci struct usb_interface *intf; 18858c2ecf20Sopenharmony_ci 18868c2ecf20Sopenharmony_ci if (udev->state == USB_STATE_NOTATTACHED) 18878c2ecf20Sopenharmony_ci return -ENODEV; 18888c2ecf20Sopenharmony_ci 18898c2ecf20Sopenharmony_ci /* Fail if autosuspend is disabled, or any interfaces are in use, or 18908c2ecf20Sopenharmony_ci * any interface drivers require remote wakeup but it isn't available. 18918c2ecf20Sopenharmony_ci */ 18928c2ecf20Sopenharmony_ci w = 0; 18938c2ecf20Sopenharmony_ci if (udev->actconfig) { 18948c2ecf20Sopenharmony_ci for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { 18958c2ecf20Sopenharmony_ci intf = udev->actconfig->interface[i]; 18968c2ecf20Sopenharmony_ci 18978c2ecf20Sopenharmony_ci /* We don't need to check interfaces that are 18988c2ecf20Sopenharmony_ci * disabled for runtime PM. Either they are unbound 18998c2ecf20Sopenharmony_ci * or else their drivers don't support autosuspend 19008c2ecf20Sopenharmony_ci * and so they are permanently active. 19018c2ecf20Sopenharmony_ci */ 19028c2ecf20Sopenharmony_ci if (intf->dev.power.disable_depth) 19038c2ecf20Sopenharmony_ci continue; 19048c2ecf20Sopenharmony_ci if (atomic_read(&intf->dev.power.usage_count) > 0) 19058c2ecf20Sopenharmony_ci return -EBUSY; 19068c2ecf20Sopenharmony_ci w |= intf->needs_remote_wakeup; 19078c2ecf20Sopenharmony_ci 19088c2ecf20Sopenharmony_ci /* Don't allow autosuspend if the device will need 19098c2ecf20Sopenharmony_ci * a reset-resume and any of its interface drivers 19108c2ecf20Sopenharmony_ci * doesn't include support or needs remote wakeup. 19118c2ecf20Sopenharmony_ci */ 19128c2ecf20Sopenharmony_ci if (udev->quirks & USB_QUIRK_RESET_RESUME) { 19138c2ecf20Sopenharmony_ci struct usb_driver *driver; 19148c2ecf20Sopenharmony_ci 19158c2ecf20Sopenharmony_ci driver = to_usb_driver(intf->dev.driver); 19168c2ecf20Sopenharmony_ci if (!driver->reset_resume || 19178c2ecf20Sopenharmony_ci intf->needs_remote_wakeup) 19188c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 19198c2ecf20Sopenharmony_ci } 19208c2ecf20Sopenharmony_ci } 19218c2ecf20Sopenharmony_ci } 19228c2ecf20Sopenharmony_ci if (w && !device_can_wakeup(&udev->dev)) { 19238c2ecf20Sopenharmony_ci dev_dbg(&udev->dev, "remote wakeup needed for autosuspend\n"); 19248c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 19258c2ecf20Sopenharmony_ci } 19268c2ecf20Sopenharmony_ci 19278c2ecf20Sopenharmony_ci /* 19288c2ecf20Sopenharmony_ci * If the device is a direct child of the root hub and the HCD 19298c2ecf20Sopenharmony_ci * doesn't handle wakeup requests, don't allow autosuspend when 19308c2ecf20Sopenharmony_ci * wakeup is needed. 19318c2ecf20Sopenharmony_ci */ 19328c2ecf20Sopenharmony_ci if (w && udev->parent == udev->bus->root_hub && 19338c2ecf20Sopenharmony_ci bus_to_hcd(udev->bus)->cant_recv_wakeups) { 19348c2ecf20Sopenharmony_ci dev_dbg(&udev->dev, "HCD doesn't handle wakeup requests\n"); 19358c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 19368c2ecf20Sopenharmony_ci } 19378c2ecf20Sopenharmony_ci 19388c2ecf20Sopenharmony_ci udev->do_remote_wakeup = w; 19398c2ecf20Sopenharmony_ci return 0; 19408c2ecf20Sopenharmony_ci} 19418c2ecf20Sopenharmony_ci 19428c2ecf20Sopenharmony_ciint usb_runtime_suspend(struct device *dev) 19438c2ecf20Sopenharmony_ci{ 19448c2ecf20Sopenharmony_ci struct usb_device *udev = to_usb_device(dev); 19458c2ecf20Sopenharmony_ci int status; 19468c2ecf20Sopenharmony_ci 19478c2ecf20Sopenharmony_ci /* A USB device can be suspended if it passes the various autosuspend 19488c2ecf20Sopenharmony_ci * checks. Runtime suspend for a USB device means suspending all the 19498c2ecf20Sopenharmony_ci * interfaces and then the device itself. 19508c2ecf20Sopenharmony_ci */ 19518c2ecf20Sopenharmony_ci if (autosuspend_check(udev) != 0) 19528c2ecf20Sopenharmony_ci return -EAGAIN; 19538c2ecf20Sopenharmony_ci 19548c2ecf20Sopenharmony_ci status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); 19558c2ecf20Sopenharmony_ci 19568c2ecf20Sopenharmony_ci /* Allow a retry if autosuspend failed temporarily */ 19578c2ecf20Sopenharmony_ci if (status == -EAGAIN || status == -EBUSY) 19588c2ecf20Sopenharmony_ci usb_mark_last_busy(udev); 19598c2ecf20Sopenharmony_ci 19608c2ecf20Sopenharmony_ci /* 19618c2ecf20Sopenharmony_ci * The PM core reacts badly unless the return code is 0, 19628c2ecf20Sopenharmony_ci * -EAGAIN, or -EBUSY, so always return -EBUSY on an error 19638c2ecf20Sopenharmony_ci * (except for root hubs, because they don't suspend through 19648c2ecf20Sopenharmony_ci * an upstream port like other USB devices). 19658c2ecf20Sopenharmony_ci */ 19668c2ecf20Sopenharmony_ci if (status != 0 && udev->parent) 19678c2ecf20Sopenharmony_ci return -EBUSY; 19688c2ecf20Sopenharmony_ci return status; 19698c2ecf20Sopenharmony_ci} 19708c2ecf20Sopenharmony_ci 19718c2ecf20Sopenharmony_ciint usb_runtime_resume(struct device *dev) 19728c2ecf20Sopenharmony_ci{ 19738c2ecf20Sopenharmony_ci struct usb_device *udev = to_usb_device(dev); 19748c2ecf20Sopenharmony_ci int status; 19758c2ecf20Sopenharmony_ci 19768c2ecf20Sopenharmony_ci /* Runtime resume for a USB device means resuming both the device 19778c2ecf20Sopenharmony_ci * and all its interfaces. 19788c2ecf20Sopenharmony_ci */ 19798c2ecf20Sopenharmony_ci status = usb_resume_both(udev, PMSG_AUTO_RESUME); 19808c2ecf20Sopenharmony_ci return status; 19818c2ecf20Sopenharmony_ci} 19828c2ecf20Sopenharmony_ci 19838c2ecf20Sopenharmony_ciint usb_runtime_idle(struct device *dev) 19848c2ecf20Sopenharmony_ci{ 19858c2ecf20Sopenharmony_ci struct usb_device *udev = to_usb_device(dev); 19868c2ecf20Sopenharmony_ci 19878c2ecf20Sopenharmony_ci /* An idle USB device can be suspended if it passes the various 19888c2ecf20Sopenharmony_ci * autosuspend checks. 19898c2ecf20Sopenharmony_ci */ 19908c2ecf20Sopenharmony_ci if (autosuspend_check(udev) == 0) 19918c2ecf20Sopenharmony_ci pm_runtime_autosuspend(dev); 19928c2ecf20Sopenharmony_ci /* Tell the core not to suspend it, though. */ 19938c2ecf20Sopenharmony_ci return -EBUSY; 19948c2ecf20Sopenharmony_ci} 19958c2ecf20Sopenharmony_ci 19968c2ecf20Sopenharmony_cistatic int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) 19978c2ecf20Sopenharmony_ci{ 19988c2ecf20Sopenharmony_ci struct usb_hcd *hcd = bus_to_hcd(udev->bus); 19998c2ecf20Sopenharmony_ci int ret = -EPERM; 20008c2ecf20Sopenharmony_ci 20018c2ecf20Sopenharmony_ci if (hcd->driver->set_usb2_hw_lpm) { 20028c2ecf20Sopenharmony_ci ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable); 20038c2ecf20Sopenharmony_ci if (!ret) 20048c2ecf20Sopenharmony_ci udev->usb2_hw_lpm_enabled = enable; 20058c2ecf20Sopenharmony_ci } 20068c2ecf20Sopenharmony_ci 20078c2ecf20Sopenharmony_ci return ret; 20088c2ecf20Sopenharmony_ci} 20098c2ecf20Sopenharmony_ci 20108c2ecf20Sopenharmony_ciint usb_enable_usb2_hardware_lpm(struct usb_device *udev) 20118c2ecf20Sopenharmony_ci{ 20128c2ecf20Sopenharmony_ci if (!udev->usb2_hw_lpm_capable || 20138c2ecf20Sopenharmony_ci !udev->usb2_hw_lpm_allowed || 20148c2ecf20Sopenharmony_ci udev->usb2_hw_lpm_enabled) 20158c2ecf20Sopenharmony_ci return 0; 20168c2ecf20Sopenharmony_ci 20178c2ecf20Sopenharmony_ci return usb_set_usb2_hardware_lpm(udev, 1); 20188c2ecf20Sopenharmony_ci} 20198c2ecf20Sopenharmony_ci 20208c2ecf20Sopenharmony_ciint usb_disable_usb2_hardware_lpm(struct usb_device *udev) 20218c2ecf20Sopenharmony_ci{ 20228c2ecf20Sopenharmony_ci if (!udev->usb2_hw_lpm_enabled) 20238c2ecf20Sopenharmony_ci return 0; 20248c2ecf20Sopenharmony_ci 20258c2ecf20Sopenharmony_ci return usb_set_usb2_hardware_lpm(udev, 0); 20268c2ecf20Sopenharmony_ci} 20278c2ecf20Sopenharmony_ci 20288c2ecf20Sopenharmony_ci#endif /* CONFIG_PM */ 20298c2ecf20Sopenharmony_ci 20308c2ecf20Sopenharmony_cistruct bus_type usb_bus_type = { 20318c2ecf20Sopenharmony_ci .name = "usb", 20328c2ecf20Sopenharmony_ci .match = usb_device_match, 20338c2ecf20Sopenharmony_ci .uevent = usb_uevent, 20348c2ecf20Sopenharmony_ci .need_parent_lock = true, 20358c2ecf20Sopenharmony_ci}; 2036