162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * drivers/usb/core/usb.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * (C) Copyright Linus Torvalds 1999 662306a36Sopenharmony_ci * (C) Copyright Johannes Erdfelt 1999-2001 762306a36Sopenharmony_ci * (C) Copyright Andreas Gal 1999 862306a36Sopenharmony_ci * (C) Copyright Gregory P. Smith 1999 962306a36Sopenharmony_ci * (C) Copyright Deti Fliegl 1999 (new USB architecture) 1062306a36Sopenharmony_ci * (C) Copyright Randy Dunlap 2000 1162306a36Sopenharmony_ci * (C) Copyright David Brownell 2000-2004 1262306a36Sopenharmony_ci * (C) Copyright Yggdrasil Computing, Inc. 2000 1362306a36Sopenharmony_ci * (usb_device_id matching changes by Adam J. Richter) 1462306a36Sopenharmony_ci * (C) Copyright Greg Kroah-Hartman 2002-2003 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * Released under the GPLv2 only. 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci * NOTE! This is not actually a driver at all, rather this is 1962306a36Sopenharmony_ci * just a collection of helper routines that implement the 2062306a36Sopenharmony_ci * generic USB things that the real drivers can use.. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * Think of this as a "USB library" rather than anything else, 2362306a36Sopenharmony_ci * with no callbacks. Callbacks are evil. 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include <linux/module.h> 2762306a36Sopenharmony_ci#include <linux/moduleparam.h> 2862306a36Sopenharmony_ci#include <linux/of.h> 2962306a36Sopenharmony_ci#include <linux/string.h> 3062306a36Sopenharmony_ci#include <linux/bitops.h> 3162306a36Sopenharmony_ci#include <linux/slab.h> 3262306a36Sopenharmony_ci#include <linux/kmod.h> 3362306a36Sopenharmony_ci#include <linux/init.h> 3462306a36Sopenharmony_ci#include <linux/spinlock.h> 3562306a36Sopenharmony_ci#include <linux/errno.h> 3662306a36Sopenharmony_ci#include <linux/usb.h> 3762306a36Sopenharmony_ci#include <linux/usb/hcd.h> 3862306a36Sopenharmony_ci#include <linux/mutex.h> 3962306a36Sopenharmony_ci#include <linux/workqueue.h> 4062306a36Sopenharmony_ci#include <linux/debugfs.h> 4162306a36Sopenharmony_ci#include <linux/usb/of.h> 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#include <asm/io.h> 4462306a36Sopenharmony_ci#include <linux/scatterlist.h> 4562306a36Sopenharmony_ci#include <linux/mm.h> 4662306a36Sopenharmony_ci#include <linux/dma-mapping.h> 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#include "hub.h" 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ciconst char *usbcore_name = "usbcore"; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic bool nousb; /* Disable USB when built into kernel image */ 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cimodule_param(nousb, bool, 0444); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* 5762306a36Sopenharmony_ci * for external read access to <nousb> 5862306a36Sopenharmony_ci */ 5962306a36Sopenharmony_ciint usb_disabled(void) 6062306a36Sopenharmony_ci{ 6162306a36Sopenharmony_ci return nousb; 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_disabled); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#ifdef CONFIG_PM 6662306a36Sopenharmony_ci/* Default delay value, in seconds */ 6762306a36Sopenharmony_cistatic int usb_autosuspend_delay = CONFIG_USB_AUTOSUSPEND_DELAY; 6862306a36Sopenharmony_cimodule_param_named(autosuspend, usb_autosuspend_delay, int, 0644); 6962306a36Sopenharmony_ciMODULE_PARM_DESC(autosuspend, "default autosuspend delay"); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci#else 7262306a36Sopenharmony_ci#define usb_autosuspend_delay 0 7362306a36Sopenharmony_ci#endif 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic bool match_endpoint(struct usb_endpoint_descriptor *epd, 7662306a36Sopenharmony_ci struct usb_endpoint_descriptor **bulk_in, 7762306a36Sopenharmony_ci struct usb_endpoint_descriptor **bulk_out, 7862306a36Sopenharmony_ci struct usb_endpoint_descriptor **int_in, 7962306a36Sopenharmony_ci struct usb_endpoint_descriptor **int_out) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci switch (usb_endpoint_type(epd)) { 8262306a36Sopenharmony_ci case USB_ENDPOINT_XFER_BULK: 8362306a36Sopenharmony_ci if (usb_endpoint_dir_in(epd)) { 8462306a36Sopenharmony_ci if (bulk_in && !*bulk_in) { 8562306a36Sopenharmony_ci *bulk_in = epd; 8662306a36Sopenharmony_ci break; 8762306a36Sopenharmony_ci } 8862306a36Sopenharmony_ci } else { 8962306a36Sopenharmony_ci if (bulk_out && !*bulk_out) { 9062306a36Sopenharmony_ci *bulk_out = epd; 9162306a36Sopenharmony_ci break; 9262306a36Sopenharmony_ci } 9362306a36Sopenharmony_ci } 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci return false; 9662306a36Sopenharmony_ci case USB_ENDPOINT_XFER_INT: 9762306a36Sopenharmony_ci if (usb_endpoint_dir_in(epd)) { 9862306a36Sopenharmony_ci if (int_in && !*int_in) { 9962306a36Sopenharmony_ci *int_in = epd; 10062306a36Sopenharmony_ci break; 10162306a36Sopenharmony_ci } 10262306a36Sopenharmony_ci } else { 10362306a36Sopenharmony_ci if (int_out && !*int_out) { 10462306a36Sopenharmony_ci *int_out = epd; 10562306a36Sopenharmony_ci break; 10662306a36Sopenharmony_ci } 10762306a36Sopenharmony_ci } 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci return false; 11062306a36Sopenharmony_ci default: 11162306a36Sopenharmony_ci return false; 11262306a36Sopenharmony_ci } 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci return (!bulk_in || *bulk_in) && (!bulk_out || *bulk_out) && 11562306a36Sopenharmony_ci (!int_in || *int_in) && (!int_out || *int_out); 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci/** 11962306a36Sopenharmony_ci * usb_find_common_endpoints() -- look up common endpoint descriptors 12062306a36Sopenharmony_ci * @alt: alternate setting to search 12162306a36Sopenharmony_ci * @bulk_in: pointer to descriptor pointer, or NULL 12262306a36Sopenharmony_ci * @bulk_out: pointer to descriptor pointer, or NULL 12362306a36Sopenharmony_ci * @int_in: pointer to descriptor pointer, or NULL 12462306a36Sopenharmony_ci * @int_out: pointer to descriptor pointer, or NULL 12562306a36Sopenharmony_ci * 12662306a36Sopenharmony_ci * Search the alternate setting's endpoint descriptors for the first bulk-in, 12762306a36Sopenharmony_ci * bulk-out, interrupt-in and interrupt-out endpoints and return them in the 12862306a36Sopenharmony_ci * provided pointers (unless they are NULL). 12962306a36Sopenharmony_ci * 13062306a36Sopenharmony_ci * If a requested endpoint is not found, the corresponding pointer is set to 13162306a36Sopenharmony_ci * NULL. 13262306a36Sopenharmony_ci * 13362306a36Sopenharmony_ci * Return: Zero if all requested descriptors were found, or -ENXIO otherwise. 13462306a36Sopenharmony_ci */ 13562306a36Sopenharmony_ciint usb_find_common_endpoints(struct usb_host_interface *alt, 13662306a36Sopenharmony_ci struct usb_endpoint_descriptor **bulk_in, 13762306a36Sopenharmony_ci struct usb_endpoint_descriptor **bulk_out, 13862306a36Sopenharmony_ci struct usb_endpoint_descriptor **int_in, 13962306a36Sopenharmony_ci struct usb_endpoint_descriptor **int_out) 14062306a36Sopenharmony_ci{ 14162306a36Sopenharmony_ci struct usb_endpoint_descriptor *epd; 14262306a36Sopenharmony_ci int i; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci if (bulk_in) 14562306a36Sopenharmony_ci *bulk_in = NULL; 14662306a36Sopenharmony_ci if (bulk_out) 14762306a36Sopenharmony_ci *bulk_out = NULL; 14862306a36Sopenharmony_ci if (int_in) 14962306a36Sopenharmony_ci *int_in = NULL; 15062306a36Sopenharmony_ci if (int_out) 15162306a36Sopenharmony_ci *int_out = NULL; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci for (i = 0; i < alt->desc.bNumEndpoints; ++i) { 15462306a36Sopenharmony_ci epd = &alt->endpoint[i].desc; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci if (match_endpoint(epd, bulk_in, bulk_out, int_in, int_out)) 15762306a36Sopenharmony_ci return 0; 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci return -ENXIO; 16162306a36Sopenharmony_ci} 16262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_find_common_endpoints); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci/** 16562306a36Sopenharmony_ci * usb_find_common_endpoints_reverse() -- look up common endpoint descriptors 16662306a36Sopenharmony_ci * @alt: alternate setting to search 16762306a36Sopenharmony_ci * @bulk_in: pointer to descriptor pointer, or NULL 16862306a36Sopenharmony_ci * @bulk_out: pointer to descriptor pointer, or NULL 16962306a36Sopenharmony_ci * @int_in: pointer to descriptor pointer, or NULL 17062306a36Sopenharmony_ci * @int_out: pointer to descriptor pointer, or NULL 17162306a36Sopenharmony_ci * 17262306a36Sopenharmony_ci * Search the alternate setting's endpoint descriptors for the last bulk-in, 17362306a36Sopenharmony_ci * bulk-out, interrupt-in and interrupt-out endpoints and return them in the 17462306a36Sopenharmony_ci * provided pointers (unless they are NULL). 17562306a36Sopenharmony_ci * 17662306a36Sopenharmony_ci * If a requested endpoint is not found, the corresponding pointer is set to 17762306a36Sopenharmony_ci * NULL. 17862306a36Sopenharmony_ci * 17962306a36Sopenharmony_ci * Return: Zero if all requested descriptors were found, or -ENXIO otherwise. 18062306a36Sopenharmony_ci */ 18162306a36Sopenharmony_ciint usb_find_common_endpoints_reverse(struct usb_host_interface *alt, 18262306a36Sopenharmony_ci struct usb_endpoint_descriptor **bulk_in, 18362306a36Sopenharmony_ci struct usb_endpoint_descriptor **bulk_out, 18462306a36Sopenharmony_ci struct usb_endpoint_descriptor **int_in, 18562306a36Sopenharmony_ci struct usb_endpoint_descriptor **int_out) 18662306a36Sopenharmony_ci{ 18762306a36Sopenharmony_ci struct usb_endpoint_descriptor *epd; 18862306a36Sopenharmony_ci int i; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci if (bulk_in) 19162306a36Sopenharmony_ci *bulk_in = NULL; 19262306a36Sopenharmony_ci if (bulk_out) 19362306a36Sopenharmony_ci *bulk_out = NULL; 19462306a36Sopenharmony_ci if (int_in) 19562306a36Sopenharmony_ci *int_in = NULL; 19662306a36Sopenharmony_ci if (int_out) 19762306a36Sopenharmony_ci *int_out = NULL; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci for (i = alt->desc.bNumEndpoints - 1; i >= 0; --i) { 20062306a36Sopenharmony_ci epd = &alt->endpoint[i].desc; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci if (match_endpoint(epd, bulk_in, bulk_out, int_in, int_out)) 20362306a36Sopenharmony_ci return 0; 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci return -ENXIO; 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_find_common_endpoints_reverse); 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci/** 21162306a36Sopenharmony_ci * usb_find_endpoint() - Given an endpoint address, search for the endpoint's 21262306a36Sopenharmony_ci * usb_host_endpoint structure in an interface's current altsetting. 21362306a36Sopenharmony_ci * @intf: the interface whose current altsetting should be searched 21462306a36Sopenharmony_ci * @ep_addr: the endpoint address (number and direction) to find 21562306a36Sopenharmony_ci * 21662306a36Sopenharmony_ci * Search the altsetting's list of endpoints for one with the specified address. 21762306a36Sopenharmony_ci * 21862306a36Sopenharmony_ci * Return: Pointer to the usb_host_endpoint if found, %NULL otherwise. 21962306a36Sopenharmony_ci */ 22062306a36Sopenharmony_cistatic const struct usb_host_endpoint *usb_find_endpoint( 22162306a36Sopenharmony_ci const struct usb_interface *intf, unsigned int ep_addr) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci int n; 22462306a36Sopenharmony_ci const struct usb_host_endpoint *ep; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci n = intf->cur_altsetting->desc.bNumEndpoints; 22762306a36Sopenharmony_ci ep = intf->cur_altsetting->endpoint; 22862306a36Sopenharmony_ci for (; n > 0; (--n, ++ep)) { 22962306a36Sopenharmony_ci if (ep->desc.bEndpointAddress == ep_addr) 23062306a36Sopenharmony_ci return ep; 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci return NULL; 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci/** 23662306a36Sopenharmony_ci * usb_check_bulk_endpoints - Check whether an interface's current altsetting 23762306a36Sopenharmony_ci * contains a set of bulk endpoints with the given addresses. 23862306a36Sopenharmony_ci * @intf: the interface whose current altsetting should be searched 23962306a36Sopenharmony_ci * @ep_addrs: 0-terminated array of the endpoint addresses (number and 24062306a36Sopenharmony_ci * direction) to look for 24162306a36Sopenharmony_ci * 24262306a36Sopenharmony_ci * Search for endpoints with the specified addresses and check their types. 24362306a36Sopenharmony_ci * 24462306a36Sopenharmony_ci * Return: %true if all the endpoints are found and are bulk, %false otherwise. 24562306a36Sopenharmony_ci */ 24662306a36Sopenharmony_cibool usb_check_bulk_endpoints( 24762306a36Sopenharmony_ci const struct usb_interface *intf, const u8 *ep_addrs) 24862306a36Sopenharmony_ci{ 24962306a36Sopenharmony_ci const struct usb_host_endpoint *ep; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci for (; *ep_addrs; ++ep_addrs) { 25262306a36Sopenharmony_ci ep = usb_find_endpoint(intf, *ep_addrs); 25362306a36Sopenharmony_ci if (!ep || !usb_endpoint_xfer_bulk(&ep->desc)) 25462306a36Sopenharmony_ci return false; 25562306a36Sopenharmony_ci } 25662306a36Sopenharmony_ci return true; 25762306a36Sopenharmony_ci} 25862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_check_bulk_endpoints); 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci/** 26162306a36Sopenharmony_ci * usb_check_int_endpoints - Check whether an interface's current altsetting 26262306a36Sopenharmony_ci * contains a set of interrupt endpoints with the given addresses. 26362306a36Sopenharmony_ci * @intf: the interface whose current altsetting should be searched 26462306a36Sopenharmony_ci * @ep_addrs: 0-terminated array of the endpoint addresses (number and 26562306a36Sopenharmony_ci * direction) to look for 26662306a36Sopenharmony_ci * 26762306a36Sopenharmony_ci * Search for endpoints with the specified addresses and check their types. 26862306a36Sopenharmony_ci * 26962306a36Sopenharmony_ci * Return: %true if all the endpoints are found and are interrupt, 27062306a36Sopenharmony_ci * %false otherwise. 27162306a36Sopenharmony_ci */ 27262306a36Sopenharmony_cibool usb_check_int_endpoints( 27362306a36Sopenharmony_ci const struct usb_interface *intf, const u8 *ep_addrs) 27462306a36Sopenharmony_ci{ 27562306a36Sopenharmony_ci const struct usb_host_endpoint *ep; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci for (; *ep_addrs; ++ep_addrs) { 27862306a36Sopenharmony_ci ep = usb_find_endpoint(intf, *ep_addrs); 27962306a36Sopenharmony_ci if (!ep || !usb_endpoint_xfer_int(&ep->desc)) 28062306a36Sopenharmony_ci return false; 28162306a36Sopenharmony_ci } 28262306a36Sopenharmony_ci return true; 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_check_int_endpoints); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci/** 28762306a36Sopenharmony_ci * usb_find_alt_setting() - Given a configuration, find the alternate setting 28862306a36Sopenharmony_ci * for the given interface. 28962306a36Sopenharmony_ci * @config: the configuration to search (not necessarily the current config). 29062306a36Sopenharmony_ci * @iface_num: interface number to search in 29162306a36Sopenharmony_ci * @alt_num: alternate interface setting number to search for. 29262306a36Sopenharmony_ci * 29362306a36Sopenharmony_ci * Search the configuration's interface cache for the given alt setting. 29462306a36Sopenharmony_ci * 29562306a36Sopenharmony_ci * Return: The alternate setting, if found. %NULL otherwise. 29662306a36Sopenharmony_ci */ 29762306a36Sopenharmony_cistruct usb_host_interface *usb_find_alt_setting( 29862306a36Sopenharmony_ci struct usb_host_config *config, 29962306a36Sopenharmony_ci unsigned int iface_num, 30062306a36Sopenharmony_ci unsigned int alt_num) 30162306a36Sopenharmony_ci{ 30262306a36Sopenharmony_ci struct usb_interface_cache *intf_cache = NULL; 30362306a36Sopenharmony_ci int i; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci if (!config) 30662306a36Sopenharmony_ci return NULL; 30762306a36Sopenharmony_ci for (i = 0; i < config->desc.bNumInterfaces; i++) { 30862306a36Sopenharmony_ci if (config->intf_cache[i]->altsetting[0].desc.bInterfaceNumber 30962306a36Sopenharmony_ci == iface_num) { 31062306a36Sopenharmony_ci intf_cache = config->intf_cache[i]; 31162306a36Sopenharmony_ci break; 31262306a36Sopenharmony_ci } 31362306a36Sopenharmony_ci } 31462306a36Sopenharmony_ci if (!intf_cache) 31562306a36Sopenharmony_ci return NULL; 31662306a36Sopenharmony_ci for (i = 0; i < intf_cache->num_altsetting; i++) 31762306a36Sopenharmony_ci if (intf_cache->altsetting[i].desc.bAlternateSetting == alt_num) 31862306a36Sopenharmony_ci return &intf_cache->altsetting[i]; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci printk(KERN_DEBUG "Did not find alt setting %u for intf %u, " 32162306a36Sopenharmony_ci "config %u\n", alt_num, iface_num, 32262306a36Sopenharmony_ci config->desc.bConfigurationValue); 32362306a36Sopenharmony_ci return NULL; 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_find_alt_setting); 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci/** 32862306a36Sopenharmony_ci * usb_ifnum_to_if - get the interface object with a given interface number 32962306a36Sopenharmony_ci * @dev: the device whose current configuration is considered 33062306a36Sopenharmony_ci * @ifnum: the desired interface 33162306a36Sopenharmony_ci * 33262306a36Sopenharmony_ci * This walks the device descriptor for the currently active configuration 33362306a36Sopenharmony_ci * to find the interface object with the particular interface number. 33462306a36Sopenharmony_ci * 33562306a36Sopenharmony_ci * Note that configuration descriptors are not required to assign interface 33662306a36Sopenharmony_ci * numbers sequentially, so that it would be incorrect to assume that 33762306a36Sopenharmony_ci * the first interface in that descriptor corresponds to interface zero. 33862306a36Sopenharmony_ci * This routine helps device drivers avoid such mistakes. 33962306a36Sopenharmony_ci * However, you should make sure that you do the right thing with any 34062306a36Sopenharmony_ci * alternate settings available for this interfaces. 34162306a36Sopenharmony_ci * 34262306a36Sopenharmony_ci * Don't call this function unless you are bound to one of the interfaces 34362306a36Sopenharmony_ci * on this device or you have locked the device! 34462306a36Sopenharmony_ci * 34562306a36Sopenharmony_ci * Return: A pointer to the interface that has @ifnum as interface number, 34662306a36Sopenharmony_ci * if found. %NULL otherwise. 34762306a36Sopenharmony_ci */ 34862306a36Sopenharmony_cistruct usb_interface *usb_ifnum_to_if(const struct usb_device *dev, 34962306a36Sopenharmony_ci unsigned ifnum) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci struct usb_host_config *config = dev->actconfig; 35262306a36Sopenharmony_ci int i; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci if (!config) 35562306a36Sopenharmony_ci return NULL; 35662306a36Sopenharmony_ci for (i = 0; i < config->desc.bNumInterfaces; i++) 35762306a36Sopenharmony_ci if (config->interface[i]->altsetting[0] 35862306a36Sopenharmony_ci .desc.bInterfaceNumber == ifnum) 35962306a36Sopenharmony_ci return config->interface[i]; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci return NULL; 36262306a36Sopenharmony_ci} 36362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_ifnum_to_if); 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci/** 36662306a36Sopenharmony_ci * usb_altnum_to_altsetting - get the altsetting structure with a given alternate setting number. 36762306a36Sopenharmony_ci * @intf: the interface containing the altsetting in question 36862306a36Sopenharmony_ci * @altnum: the desired alternate setting number 36962306a36Sopenharmony_ci * 37062306a36Sopenharmony_ci * This searches the altsetting array of the specified interface for 37162306a36Sopenharmony_ci * an entry with the correct bAlternateSetting value. 37262306a36Sopenharmony_ci * 37362306a36Sopenharmony_ci * Note that altsettings need not be stored sequentially by number, so 37462306a36Sopenharmony_ci * it would be incorrect to assume that the first altsetting entry in 37562306a36Sopenharmony_ci * the array corresponds to altsetting zero. This routine helps device 37662306a36Sopenharmony_ci * drivers avoid such mistakes. 37762306a36Sopenharmony_ci * 37862306a36Sopenharmony_ci * Don't call this function unless you are bound to the intf interface 37962306a36Sopenharmony_ci * or you have locked the device! 38062306a36Sopenharmony_ci * 38162306a36Sopenharmony_ci * Return: A pointer to the entry of the altsetting array of @intf that 38262306a36Sopenharmony_ci * has @altnum as the alternate setting number. %NULL if not found. 38362306a36Sopenharmony_ci */ 38462306a36Sopenharmony_cistruct usb_host_interface *usb_altnum_to_altsetting( 38562306a36Sopenharmony_ci const struct usb_interface *intf, 38662306a36Sopenharmony_ci unsigned int altnum) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci int i; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci for (i = 0; i < intf->num_altsetting; i++) { 39162306a36Sopenharmony_ci if (intf->altsetting[i].desc.bAlternateSetting == altnum) 39262306a36Sopenharmony_ci return &intf->altsetting[i]; 39362306a36Sopenharmony_ci } 39462306a36Sopenharmony_ci return NULL; 39562306a36Sopenharmony_ci} 39662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_altnum_to_altsetting); 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_cistruct find_interface_arg { 39962306a36Sopenharmony_ci int minor; 40062306a36Sopenharmony_ci struct device_driver *drv; 40162306a36Sopenharmony_ci}; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_cistatic int __find_interface(struct device *dev, const void *data) 40462306a36Sopenharmony_ci{ 40562306a36Sopenharmony_ci const struct find_interface_arg *arg = data; 40662306a36Sopenharmony_ci struct usb_interface *intf; 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci if (!is_usb_interface(dev)) 40962306a36Sopenharmony_ci return 0; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci if (dev->driver != arg->drv) 41262306a36Sopenharmony_ci return 0; 41362306a36Sopenharmony_ci intf = to_usb_interface(dev); 41462306a36Sopenharmony_ci return intf->minor == arg->minor; 41562306a36Sopenharmony_ci} 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci/** 41862306a36Sopenharmony_ci * usb_find_interface - find usb_interface pointer for driver and device 41962306a36Sopenharmony_ci * @drv: the driver whose current configuration is considered 42062306a36Sopenharmony_ci * @minor: the minor number of the desired device 42162306a36Sopenharmony_ci * 42262306a36Sopenharmony_ci * This walks the bus device list and returns a pointer to the interface 42362306a36Sopenharmony_ci * with the matching minor and driver. Note, this only works for devices 42462306a36Sopenharmony_ci * that share the USB major number. 42562306a36Sopenharmony_ci * 42662306a36Sopenharmony_ci * Return: A pointer to the interface with the matching major and @minor. 42762306a36Sopenharmony_ci */ 42862306a36Sopenharmony_cistruct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) 42962306a36Sopenharmony_ci{ 43062306a36Sopenharmony_ci struct find_interface_arg argb; 43162306a36Sopenharmony_ci struct device *dev; 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci argb.minor = minor; 43462306a36Sopenharmony_ci argb.drv = &drv->drvwrap.driver; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci dev = bus_find_device(&usb_bus_type, NULL, &argb, __find_interface); 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci /* Drop reference count from bus_find_device */ 43962306a36Sopenharmony_ci put_device(dev); 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci return dev ? to_usb_interface(dev) : NULL; 44262306a36Sopenharmony_ci} 44362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_find_interface); 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_cistruct each_dev_arg { 44662306a36Sopenharmony_ci void *data; 44762306a36Sopenharmony_ci int (*fn)(struct usb_device *, void *); 44862306a36Sopenharmony_ci}; 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_cistatic int __each_dev(struct device *dev, void *data) 45162306a36Sopenharmony_ci{ 45262306a36Sopenharmony_ci struct each_dev_arg *arg = (struct each_dev_arg *)data; 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci /* There are struct usb_interface on the same bus, filter them out */ 45562306a36Sopenharmony_ci if (!is_usb_device(dev)) 45662306a36Sopenharmony_ci return 0; 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci return arg->fn(to_usb_device(dev), arg->data); 45962306a36Sopenharmony_ci} 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci/** 46262306a36Sopenharmony_ci * usb_for_each_dev - iterate over all USB devices in the system 46362306a36Sopenharmony_ci * @data: data pointer that will be handed to the callback function 46462306a36Sopenharmony_ci * @fn: callback function to be called for each USB device 46562306a36Sopenharmony_ci * 46662306a36Sopenharmony_ci * Iterate over all USB devices and call @fn for each, passing it @data. If it 46762306a36Sopenharmony_ci * returns anything other than 0, we break the iteration prematurely and return 46862306a36Sopenharmony_ci * that value. 46962306a36Sopenharmony_ci */ 47062306a36Sopenharmony_ciint usb_for_each_dev(void *data, int (*fn)(struct usb_device *, void *)) 47162306a36Sopenharmony_ci{ 47262306a36Sopenharmony_ci struct each_dev_arg arg = {data, fn}; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci return bus_for_each_dev(&usb_bus_type, NULL, &arg, __each_dev); 47562306a36Sopenharmony_ci} 47662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_for_each_dev); 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci/** 47962306a36Sopenharmony_ci * usb_release_dev - free a usb device structure when all users of it are finished. 48062306a36Sopenharmony_ci * @dev: device that's been disconnected 48162306a36Sopenharmony_ci * 48262306a36Sopenharmony_ci * Will be called only by the device core when all users of this usb device are 48362306a36Sopenharmony_ci * done. 48462306a36Sopenharmony_ci */ 48562306a36Sopenharmony_cistatic void usb_release_dev(struct device *dev) 48662306a36Sopenharmony_ci{ 48762306a36Sopenharmony_ci struct usb_device *udev; 48862306a36Sopenharmony_ci struct usb_hcd *hcd; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci udev = to_usb_device(dev); 49162306a36Sopenharmony_ci hcd = bus_to_hcd(udev->bus); 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci usb_destroy_configuration(udev); 49462306a36Sopenharmony_ci usb_release_bos_descriptor(udev); 49562306a36Sopenharmony_ci of_node_put(dev->of_node); 49662306a36Sopenharmony_ci usb_put_hcd(hcd); 49762306a36Sopenharmony_ci kfree(udev->product); 49862306a36Sopenharmony_ci kfree(udev->manufacturer); 49962306a36Sopenharmony_ci kfree(udev->serial); 50062306a36Sopenharmony_ci kfree(udev); 50162306a36Sopenharmony_ci} 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_cistatic int usb_dev_uevent(const struct device *dev, struct kobj_uevent_env *env) 50462306a36Sopenharmony_ci{ 50562306a36Sopenharmony_ci const struct usb_device *usb_dev; 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ci usb_dev = to_usb_device(dev); 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci if (add_uevent_var(env, "BUSNUM=%03d", usb_dev->bus->busnum)) 51062306a36Sopenharmony_ci return -ENOMEM; 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci if (add_uevent_var(env, "DEVNUM=%03d", usb_dev->devnum)) 51362306a36Sopenharmony_ci return -ENOMEM; 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci return 0; 51662306a36Sopenharmony_ci} 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci#ifdef CONFIG_PM 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci/* USB device Power-Management thunks. 52162306a36Sopenharmony_ci * There's no need to distinguish here between quiescing a USB device 52262306a36Sopenharmony_ci * and powering it down; the generic_suspend() routine takes care of 52362306a36Sopenharmony_ci * it by skipping the usb_port_suspend() call for a quiesce. And for 52462306a36Sopenharmony_ci * USB interfaces there's no difference at all. 52562306a36Sopenharmony_ci */ 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_cistatic int usb_dev_prepare(struct device *dev) 52862306a36Sopenharmony_ci{ 52962306a36Sopenharmony_ci return 0; /* Implement eventually? */ 53062306a36Sopenharmony_ci} 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_cistatic void usb_dev_complete(struct device *dev) 53362306a36Sopenharmony_ci{ 53462306a36Sopenharmony_ci /* Currently used only for rebinding interfaces */ 53562306a36Sopenharmony_ci usb_resume_complete(dev); 53662306a36Sopenharmony_ci} 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_cistatic int usb_dev_suspend(struct device *dev) 53962306a36Sopenharmony_ci{ 54062306a36Sopenharmony_ci return usb_suspend(dev, PMSG_SUSPEND); 54162306a36Sopenharmony_ci} 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_cistatic int usb_dev_resume(struct device *dev) 54462306a36Sopenharmony_ci{ 54562306a36Sopenharmony_ci return usb_resume(dev, PMSG_RESUME); 54662306a36Sopenharmony_ci} 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_cistatic int usb_dev_freeze(struct device *dev) 54962306a36Sopenharmony_ci{ 55062306a36Sopenharmony_ci return usb_suspend(dev, PMSG_FREEZE); 55162306a36Sopenharmony_ci} 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_cistatic int usb_dev_thaw(struct device *dev) 55462306a36Sopenharmony_ci{ 55562306a36Sopenharmony_ci return usb_resume(dev, PMSG_THAW); 55662306a36Sopenharmony_ci} 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_cistatic int usb_dev_poweroff(struct device *dev) 55962306a36Sopenharmony_ci{ 56062306a36Sopenharmony_ci return usb_suspend(dev, PMSG_HIBERNATE); 56162306a36Sopenharmony_ci} 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_cistatic int usb_dev_restore(struct device *dev) 56462306a36Sopenharmony_ci{ 56562306a36Sopenharmony_ci return usb_resume(dev, PMSG_RESTORE); 56662306a36Sopenharmony_ci} 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_cistatic const struct dev_pm_ops usb_device_pm_ops = { 56962306a36Sopenharmony_ci .prepare = usb_dev_prepare, 57062306a36Sopenharmony_ci .complete = usb_dev_complete, 57162306a36Sopenharmony_ci .suspend = usb_dev_suspend, 57262306a36Sopenharmony_ci .resume = usb_dev_resume, 57362306a36Sopenharmony_ci .freeze = usb_dev_freeze, 57462306a36Sopenharmony_ci .thaw = usb_dev_thaw, 57562306a36Sopenharmony_ci .poweroff = usb_dev_poweroff, 57662306a36Sopenharmony_ci .restore = usb_dev_restore, 57762306a36Sopenharmony_ci .runtime_suspend = usb_runtime_suspend, 57862306a36Sopenharmony_ci .runtime_resume = usb_runtime_resume, 57962306a36Sopenharmony_ci .runtime_idle = usb_runtime_idle, 58062306a36Sopenharmony_ci}; 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci#endif /* CONFIG_PM */ 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_cistatic char *usb_devnode(const struct device *dev, 58662306a36Sopenharmony_ci umode_t *mode, kuid_t *uid, kgid_t *gid) 58762306a36Sopenharmony_ci{ 58862306a36Sopenharmony_ci const struct usb_device *usb_dev; 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci usb_dev = to_usb_device(dev); 59162306a36Sopenharmony_ci return kasprintf(GFP_KERNEL, "bus/usb/%03d/%03d", 59262306a36Sopenharmony_ci usb_dev->bus->busnum, usb_dev->devnum); 59362306a36Sopenharmony_ci} 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_cistruct device_type usb_device_type = { 59662306a36Sopenharmony_ci .name = "usb_device", 59762306a36Sopenharmony_ci .release = usb_release_dev, 59862306a36Sopenharmony_ci .uevent = usb_dev_uevent, 59962306a36Sopenharmony_ci .devnode = usb_devnode, 60062306a36Sopenharmony_ci#ifdef CONFIG_PM 60162306a36Sopenharmony_ci .pm = &usb_device_pm_ops, 60262306a36Sopenharmony_ci#endif 60362306a36Sopenharmony_ci}; 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_cistatic bool usb_dev_authorized(struct usb_device *dev, struct usb_hcd *hcd) 60662306a36Sopenharmony_ci{ 60762306a36Sopenharmony_ci struct usb_hub *hub; 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci if (!dev->parent) 61062306a36Sopenharmony_ci return true; /* Root hub always ok [and always wired] */ 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci switch (hcd->dev_policy) { 61362306a36Sopenharmony_ci case USB_DEVICE_AUTHORIZE_NONE: 61462306a36Sopenharmony_ci default: 61562306a36Sopenharmony_ci return false; 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci case USB_DEVICE_AUTHORIZE_ALL: 61862306a36Sopenharmony_ci return true; 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci case USB_DEVICE_AUTHORIZE_INTERNAL: 62162306a36Sopenharmony_ci hub = usb_hub_to_struct_hub(dev->parent); 62262306a36Sopenharmony_ci return hub->ports[dev->portnum - 1]->connect_type == 62362306a36Sopenharmony_ci USB_PORT_CONNECT_TYPE_HARD_WIRED; 62462306a36Sopenharmony_ci } 62562306a36Sopenharmony_ci} 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci/** 62862306a36Sopenharmony_ci * usb_alloc_dev - usb device constructor (usbcore-internal) 62962306a36Sopenharmony_ci * @parent: hub to which device is connected; null to allocate a root hub 63062306a36Sopenharmony_ci * @bus: bus used to access the device 63162306a36Sopenharmony_ci * @port1: one-based index of port; ignored for root hubs 63262306a36Sopenharmony_ci * 63362306a36Sopenharmony_ci * Context: task context, might sleep. 63462306a36Sopenharmony_ci * 63562306a36Sopenharmony_ci * Only hub drivers (including virtual root hub drivers for host 63662306a36Sopenharmony_ci * controllers) should ever call this. 63762306a36Sopenharmony_ci * 63862306a36Sopenharmony_ci * This call may not be used in a non-sleeping context. 63962306a36Sopenharmony_ci * 64062306a36Sopenharmony_ci * Return: On success, a pointer to the allocated usb device. %NULL on 64162306a36Sopenharmony_ci * failure. 64262306a36Sopenharmony_ci */ 64362306a36Sopenharmony_cistruct usb_device *usb_alloc_dev(struct usb_device *parent, 64462306a36Sopenharmony_ci struct usb_bus *bus, unsigned port1) 64562306a36Sopenharmony_ci{ 64662306a36Sopenharmony_ci struct usb_device *dev; 64762306a36Sopenharmony_ci struct usb_hcd *usb_hcd = bus_to_hcd(bus); 64862306a36Sopenharmony_ci unsigned raw_port = port1; 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci dev = kzalloc(sizeof(*dev), GFP_KERNEL); 65162306a36Sopenharmony_ci if (!dev) 65262306a36Sopenharmony_ci return NULL; 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci if (!usb_get_hcd(usb_hcd)) { 65562306a36Sopenharmony_ci kfree(dev); 65662306a36Sopenharmony_ci return NULL; 65762306a36Sopenharmony_ci } 65862306a36Sopenharmony_ci /* Root hubs aren't true devices, so don't allocate HCD resources */ 65962306a36Sopenharmony_ci if (usb_hcd->driver->alloc_dev && parent && 66062306a36Sopenharmony_ci !usb_hcd->driver->alloc_dev(usb_hcd, dev)) { 66162306a36Sopenharmony_ci usb_put_hcd(bus_to_hcd(bus)); 66262306a36Sopenharmony_ci kfree(dev); 66362306a36Sopenharmony_ci return NULL; 66462306a36Sopenharmony_ci } 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci device_initialize(&dev->dev); 66762306a36Sopenharmony_ci dev->dev.bus = &usb_bus_type; 66862306a36Sopenharmony_ci dev->dev.type = &usb_device_type; 66962306a36Sopenharmony_ci dev->dev.groups = usb_device_groups; 67062306a36Sopenharmony_ci set_dev_node(&dev->dev, dev_to_node(bus->sysdev)); 67162306a36Sopenharmony_ci dev->state = USB_STATE_ATTACHED; 67262306a36Sopenharmony_ci dev->lpm_disable_count = 1; 67362306a36Sopenharmony_ci atomic_set(&dev->urbnum, 0); 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci INIT_LIST_HEAD(&dev->ep0.urb_list); 67662306a36Sopenharmony_ci dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; 67762306a36Sopenharmony_ci dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; 67862306a36Sopenharmony_ci /* ep0 maxpacket comes later, from device descriptor */ 67962306a36Sopenharmony_ci usb_enable_endpoint(dev, &dev->ep0, false); 68062306a36Sopenharmony_ci dev->can_submit = 1; 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci /* Save readable and stable topology id, distinguishing devices 68362306a36Sopenharmony_ci * by location for diagnostics, tools, driver model, etc. The 68462306a36Sopenharmony_ci * string is a path along hub ports, from the root. Each device's 68562306a36Sopenharmony_ci * dev->devpath will be stable until USB is re-cabled, and hubs 68662306a36Sopenharmony_ci * are often labeled with these port numbers. The name isn't 68762306a36Sopenharmony_ci * as stable: bus->busnum changes easily from modprobe order, 68862306a36Sopenharmony_ci * cardbus or pci hotplugging, and so on. 68962306a36Sopenharmony_ci */ 69062306a36Sopenharmony_ci if (unlikely(!parent)) { 69162306a36Sopenharmony_ci dev->devpath[0] = '0'; 69262306a36Sopenharmony_ci dev->route = 0; 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci dev->dev.parent = bus->controller; 69562306a36Sopenharmony_ci device_set_of_node_from_dev(&dev->dev, bus->sysdev); 69662306a36Sopenharmony_ci dev_set_name(&dev->dev, "usb%d", bus->busnum); 69762306a36Sopenharmony_ci } else { 69862306a36Sopenharmony_ci /* match any labeling on the hubs; it's one-based */ 69962306a36Sopenharmony_ci if (parent->devpath[0] == '0') { 70062306a36Sopenharmony_ci snprintf(dev->devpath, sizeof dev->devpath, 70162306a36Sopenharmony_ci "%d", port1); 70262306a36Sopenharmony_ci /* Root ports are not counted in route string */ 70362306a36Sopenharmony_ci dev->route = 0; 70462306a36Sopenharmony_ci } else { 70562306a36Sopenharmony_ci snprintf(dev->devpath, sizeof dev->devpath, 70662306a36Sopenharmony_ci "%s.%d", parent->devpath, port1); 70762306a36Sopenharmony_ci /* Route string assumes hubs have less than 16 ports */ 70862306a36Sopenharmony_ci if (port1 < 15) 70962306a36Sopenharmony_ci dev->route = parent->route + 71062306a36Sopenharmony_ci (port1 << ((parent->level - 1)*4)); 71162306a36Sopenharmony_ci else 71262306a36Sopenharmony_ci dev->route = parent->route + 71362306a36Sopenharmony_ci (15 << ((parent->level - 1)*4)); 71462306a36Sopenharmony_ci } 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci dev->dev.parent = &parent->dev; 71762306a36Sopenharmony_ci dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath); 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_ci if (!parent->parent) { 72062306a36Sopenharmony_ci /* device under root hub's port */ 72162306a36Sopenharmony_ci raw_port = usb_hcd_find_raw_port_number(usb_hcd, 72262306a36Sopenharmony_ci port1); 72362306a36Sopenharmony_ci } 72462306a36Sopenharmony_ci dev->dev.of_node = usb_of_get_device_node(parent, raw_port); 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci /* hub driver sets up TT records */ 72762306a36Sopenharmony_ci } 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci dev->portnum = port1; 73062306a36Sopenharmony_ci dev->bus = bus; 73162306a36Sopenharmony_ci dev->parent = parent; 73262306a36Sopenharmony_ci INIT_LIST_HEAD(&dev->filelist); 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci#ifdef CONFIG_PM 73562306a36Sopenharmony_ci pm_runtime_set_autosuspend_delay(&dev->dev, 73662306a36Sopenharmony_ci usb_autosuspend_delay * 1000); 73762306a36Sopenharmony_ci dev->connect_time = jiffies; 73862306a36Sopenharmony_ci dev->active_duration = -jiffies; 73962306a36Sopenharmony_ci#endif 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci dev->authorized = usb_dev_authorized(dev, usb_hcd); 74262306a36Sopenharmony_ci return dev; 74362306a36Sopenharmony_ci} 74462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_alloc_dev); 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci/** 74762306a36Sopenharmony_ci * usb_get_dev - increments the reference count of the usb device structure 74862306a36Sopenharmony_ci * @dev: the device being referenced 74962306a36Sopenharmony_ci * 75062306a36Sopenharmony_ci * Each live reference to a device should be refcounted. 75162306a36Sopenharmony_ci * 75262306a36Sopenharmony_ci * Drivers for USB interfaces should normally record such references in 75362306a36Sopenharmony_ci * their probe() methods, when they bind to an interface, and release 75462306a36Sopenharmony_ci * them by calling usb_put_dev(), in their disconnect() methods. 75562306a36Sopenharmony_ci * However, if a driver does not access the usb_device structure after 75662306a36Sopenharmony_ci * its disconnect() method returns then refcounting is not necessary, 75762306a36Sopenharmony_ci * because the USB core guarantees that a usb_device will not be 75862306a36Sopenharmony_ci * deallocated until after all of its interface drivers have been unbound. 75962306a36Sopenharmony_ci * 76062306a36Sopenharmony_ci * Return: A pointer to the device with the incremented reference counter. 76162306a36Sopenharmony_ci */ 76262306a36Sopenharmony_cistruct usb_device *usb_get_dev(struct usb_device *dev) 76362306a36Sopenharmony_ci{ 76462306a36Sopenharmony_ci if (dev) 76562306a36Sopenharmony_ci get_device(&dev->dev); 76662306a36Sopenharmony_ci return dev; 76762306a36Sopenharmony_ci} 76862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_get_dev); 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_ci/** 77162306a36Sopenharmony_ci * usb_put_dev - release a use of the usb device structure 77262306a36Sopenharmony_ci * @dev: device that's been disconnected 77362306a36Sopenharmony_ci * 77462306a36Sopenharmony_ci * Must be called when a user of a device is finished with it. When the last 77562306a36Sopenharmony_ci * user of the device calls this function, the memory of the device is freed. 77662306a36Sopenharmony_ci */ 77762306a36Sopenharmony_civoid usb_put_dev(struct usb_device *dev) 77862306a36Sopenharmony_ci{ 77962306a36Sopenharmony_ci if (dev) 78062306a36Sopenharmony_ci put_device(&dev->dev); 78162306a36Sopenharmony_ci} 78262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_put_dev); 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_ci/** 78562306a36Sopenharmony_ci * usb_get_intf - increments the reference count of the usb interface structure 78662306a36Sopenharmony_ci * @intf: the interface being referenced 78762306a36Sopenharmony_ci * 78862306a36Sopenharmony_ci * Each live reference to a interface must be refcounted. 78962306a36Sopenharmony_ci * 79062306a36Sopenharmony_ci * Drivers for USB interfaces should normally record such references in 79162306a36Sopenharmony_ci * their probe() methods, when they bind to an interface, and release 79262306a36Sopenharmony_ci * them by calling usb_put_intf(), in their disconnect() methods. 79362306a36Sopenharmony_ci * However, if a driver does not access the usb_interface structure after 79462306a36Sopenharmony_ci * its disconnect() method returns then refcounting is not necessary, 79562306a36Sopenharmony_ci * because the USB core guarantees that a usb_interface will not be 79662306a36Sopenharmony_ci * deallocated until after its driver has been unbound. 79762306a36Sopenharmony_ci * 79862306a36Sopenharmony_ci * Return: A pointer to the interface with the incremented reference counter. 79962306a36Sopenharmony_ci */ 80062306a36Sopenharmony_cistruct usb_interface *usb_get_intf(struct usb_interface *intf) 80162306a36Sopenharmony_ci{ 80262306a36Sopenharmony_ci if (intf) 80362306a36Sopenharmony_ci get_device(&intf->dev); 80462306a36Sopenharmony_ci return intf; 80562306a36Sopenharmony_ci} 80662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_get_intf); 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_ci/** 80962306a36Sopenharmony_ci * usb_put_intf - release a use of the usb interface structure 81062306a36Sopenharmony_ci * @intf: interface that's been decremented 81162306a36Sopenharmony_ci * 81262306a36Sopenharmony_ci * Must be called when a user of an interface is finished with it. When the 81362306a36Sopenharmony_ci * last user of the interface calls this function, the memory of the interface 81462306a36Sopenharmony_ci * is freed. 81562306a36Sopenharmony_ci */ 81662306a36Sopenharmony_civoid usb_put_intf(struct usb_interface *intf) 81762306a36Sopenharmony_ci{ 81862306a36Sopenharmony_ci if (intf) 81962306a36Sopenharmony_ci put_device(&intf->dev); 82062306a36Sopenharmony_ci} 82162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_put_intf); 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_ci/** 82462306a36Sopenharmony_ci * usb_intf_get_dma_device - acquire a reference on the usb interface's DMA endpoint 82562306a36Sopenharmony_ci * @intf: the usb interface 82662306a36Sopenharmony_ci * 82762306a36Sopenharmony_ci * While a USB device cannot perform DMA operations by itself, many USB 82862306a36Sopenharmony_ci * controllers can. A call to usb_intf_get_dma_device() returns the DMA endpoint 82962306a36Sopenharmony_ci * for the given USB interface, if any. The returned device structure must be 83062306a36Sopenharmony_ci * released with put_device(). 83162306a36Sopenharmony_ci * 83262306a36Sopenharmony_ci * See also usb_get_dma_device(). 83362306a36Sopenharmony_ci * 83462306a36Sopenharmony_ci * Returns: A reference to the usb interface's DMA endpoint; or NULL if none 83562306a36Sopenharmony_ci * exists. 83662306a36Sopenharmony_ci */ 83762306a36Sopenharmony_cistruct device *usb_intf_get_dma_device(struct usb_interface *intf) 83862306a36Sopenharmony_ci{ 83962306a36Sopenharmony_ci struct usb_device *udev = interface_to_usbdev(intf); 84062306a36Sopenharmony_ci struct device *dmadev; 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci if (!udev->bus) 84362306a36Sopenharmony_ci return NULL; 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci dmadev = get_device(udev->bus->sysdev); 84662306a36Sopenharmony_ci if (!dmadev || !dmadev->dma_mask) { 84762306a36Sopenharmony_ci put_device(dmadev); 84862306a36Sopenharmony_ci return NULL; 84962306a36Sopenharmony_ci } 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_ci return dmadev; 85262306a36Sopenharmony_ci} 85362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_intf_get_dma_device); 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci/* USB device locking 85662306a36Sopenharmony_ci * 85762306a36Sopenharmony_ci * USB devices and interfaces are locked using the semaphore in their 85862306a36Sopenharmony_ci * embedded struct device. The hub driver guarantees that whenever a 85962306a36Sopenharmony_ci * device is connected or disconnected, drivers are called with the 86062306a36Sopenharmony_ci * USB device locked as well as their particular interface. 86162306a36Sopenharmony_ci * 86262306a36Sopenharmony_ci * Complications arise when several devices are to be locked at the same 86362306a36Sopenharmony_ci * time. Only hub-aware drivers that are part of usbcore ever have to 86462306a36Sopenharmony_ci * do this; nobody else needs to worry about it. The rule for locking 86562306a36Sopenharmony_ci * is simple: 86662306a36Sopenharmony_ci * 86762306a36Sopenharmony_ci * When locking both a device and its parent, always lock the 86862306a36Sopenharmony_ci * parent first. 86962306a36Sopenharmony_ci */ 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci/** 87262306a36Sopenharmony_ci * usb_lock_device_for_reset - cautiously acquire the lock for a usb device structure 87362306a36Sopenharmony_ci * @udev: device that's being locked 87462306a36Sopenharmony_ci * @iface: interface bound to the driver making the request (optional) 87562306a36Sopenharmony_ci * 87662306a36Sopenharmony_ci * Attempts to acquire the device lock, but fails if the device is 87762306a36Sopenharmony_ci * NOTATTACHED or SUSPENDED, or if iface is specified and the interface 87862306a36Sopenharmony_ci * is neither BINDING nor BOUND. Rather than sleeping to wait for the 87962306a36Sopenharmony_ci * lock, the routine polls repeatedly. This is to prevent deadlock with 88062306a36Sopenharmony_ci * disconnect; in some drivers (such as usb-storage) the disconnect() 88162306a36Sopenharmony_ci * or suspend() method will block waiting for a device reset to complete. 88262306a36Sopenharmony_ci * 88362306a36Sopenharmony_ci * Return: A negative error code for failure, otherwise 0. 88462306a36Sopenharmony_ci */ 88562306a36Sopenharmony_ciint usb_lock_device_for_reset(struct usb_device *udev, 88662306a36Sopenharmony_ci const struct usb_interface *iface) 88762306a36Sopenharmony_ci{ 88862306a36Sopenharmony_ci unsigned long jiffies_expire = jiffies + HZ; 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ci if (udev->state == USB_STATE_NOTATTACHED) 89162306a36Sopenharmony_ci return -ENODEV; 89262306a36Sopenharmony_ci if (udev->state == USB_STATE_SUSPENDED) 89362306a36Sopenharmony_ci return -EHOSTUNREACH; 89462306a36Sopenharmony_ci if (iface && (iface->condition == USB_INTERFACE_UNBINDING || 89562306a36Sopenharmony_ci iface->condition == USB_INTERFACE_UNBOUND)) 89662306a36Sopenharmony_ci return -EINTR; 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci while (!usb_trylock_device(udev)) { 89962306a36Sopenharmony_ci 90062306a36Sopenharmony_ci /* If we can't acquire the lock after waiting one second, 90162306a36Sopenharmony_ci * we're probably deadlocked */ 90262306a36Sopenharmony_ci if (time_after(jiffies, jiffies_expire)) 90362306a36Sopenharmony_ci return -EBUSY; 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_ci msleep(15); 90662306a36Sopenharmony_ci if (udev->state == USB_STATE_NOTATTACHED) 90762306a36Sopenharmony_ci return -ENODEV; 90862306a36Sopenharmony_ci if (udev->state == USB_STATE_SUSPENDED) 90962306a36Sopenharmony_ci return -EHOSTUNREACH; 91062306a36Sopenharmony_ci if (iface && (iface->condition == USB_INTERFACE_UNBINDING || 91162306a36Sopenharmony_ci iface->condition == USB_INTERFACE_UNBOUND)) 91262306a36Sopenharmony_ci return -EINTR; 91362306a36Sopenharmony_ci } 91462306a36Sopenharmony_ci return 0; 91562306a36Sopenharmony_ci} 91662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_lock_device_for_reset); 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci/** 91962306a36Sopenharmony_ci * usb_get_current_frame_number - return current bus frame number 92062306a36Sopenharmony_ci * @dev: the device whose bus is being queried 92162306a36Sopenharmony_ci * 92262306a36Sopenharmony_ci * Return: The current frame number for the USB host controller used 92362306a36Sopenharmony_ci * with the given USB device. This can be used when scheduling 92462306a36Sopenharmony_ci * isochronous requests. 92562306a36Sopenharmony_ci * 92662306a36Sopenharmony_ci * Note: Different kinds of host controller have different "scheduling 92762306a36Sopenharmony_ci * horizons". While one type might support scheduling only 32 frames 92862306a36Sopenharmony_ci * into the future, others could support scheduling up to 1024 frames 92962306a36Sopenharmony_ci * into the future. 93062306a36Sopenharmony_ci * 93162306a36Sopenharmony_ci */ 93262306a36Sopenharmony_ciint usb_get_current_frame_number(struct usb_device *dev) 93362306a36Sopenharmony_ci{ 93462306a36Sopenharmony_ci return usb_hcd_get_frame_number(dev); 93562306a36Sopenharmony_ci} 93662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_get_current_frame_number); 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci/*-------------------------------------------------------------------*/ 93962306a36Sopenharmony_ci/* 94062306a36Sopenharmony_ci * __usb_get_extra_descriptor() finds a descriptor of specific type in the 94162306a36Sopenharmony_ci * extra field of the interface and endpoint descriptor structs. 94262306a36Sopenharmony_ci */ 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_ciint __usb_get_extra_descriptor(char *buffer, unsigned size, 94562306a36Sopenharmony_ci unsigned char type, void **ptr, size_t minsize) 94662306a36Sopenharmony_ci{ 94762306a36Sopenharmony_ci struct usb_descriptor_header *header; 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci while (size >= sizeof(struct usb_descriptor_header)) { 95062306a36Sopenharmony_ci header = (struct usb_descriptor_header *)buffer; 95162306a36Sopenharmony_ci 95262306a36Sopenharmony_ci if (header->bLength < 2 || header->bLength > size) { 95362306a36Sopenharmony_ci printk(KERN_ERR 95462306a36Sopenharmony_ci "%s: bogus descriptor, type %d length %d\n", 95562306a36Sopenharmony_ci usbcore_name, 95662306a36Sopenharmony_ci header->bDescriptorType, 95762306a36Sopenharmony_ci header->bLength); 95862306a36Sopenharmony_ci return -1; 95962306a36Sopenharmony_ci } 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci if (header->bDescriptorType == type && header->bLength >= minsize) { 96262306a36Sopenharmony_ci *ptr = header; 96362306a36Sopenharmony_ci return 0; 96462306a36Sopenharmony_ci } 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_ci buffer += header->bLength; 96762306a36Sopenharmony_ci size -= header->bLength; 96862306a36Sopenharmony_ci } 96962306a36Sopenharmony_ci return -1; 97062306a36Sopenharmony_ci} 97162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__usb_get_extra_descriptor); 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci/** 97462306a36Sopenharmony_ci * usb_alloc_coherent - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP 97562306a36Sopenharmony_ci * @dev: device the buffer will be used with 97662306a36Sopenharmony_ci * @size: requested buffer size 97762306a36Sopenharmony_ci * @mem_flags: affect whether allocation may block 97862306a36Sopenharmony_ci * @dma: used to return DMA address of buffer 97962306a36Sopenharmony_ci * 98062306a36Sopenharmony_ci * Return: Either null (indicating no buffer could be allocated), or the 98162306a36Sopenharmony_ci * cpu-space pointer to a buffer that may be used to perform DMA to the 98262306a36Sopenharmony_ci * specified device. Such cpu-space buffers are returned along with the DMA 98362306a36Sopenharmony_ci * address (through the pointer provided). 98462306a36Sopenharmony_ci * 98562306a36Sopenharmony_ci * Note: 98662306a36Sopenharmony_ci * These buffers are used with URB_NO_xxx_DMA_MAP set in urb->transfer_flags 98762306a36Sopenharmony_ci * to avoid behaviors like using "DMA bounce buffers", or thrashing IOMMU 98862306a36Sopenharmony_ci * hardware during URB completion/resubmit. The implementation varies between 98962306a36Sopenharmony_ci * platforms, depending on details of how DMA will work to this device. 99062306a36Sopenharmony_ci * Using these buffers also eliminates cacheline sharing problems on 99162306a36Sopenharmony_ci * architectures where CPU caches are not DMA-coherent. On systems without 99262306a36Sopenharmony_ci * bus-snooping caches, these buffers are uncached. 99362306a36Sopenharmony_ci * 99462306a36Sopenharmony_ci * When the buffer is no longer used, free it with usb_free_coherent(). 99562306a36Sopenharmony_ci */ 99662306a36Sopenharmony_civoid *usb_alloc_coherent(struct usb_device *dev, size_t size, gfp_t mem_flags, 99762306a36Sopenharmony_ci dma_addr_t *dma) 99862306a36Sopenharmony_ci{ 99962306a36Sopenharmony_ci if (!dev || !dev->bus) 100062306a36Sopenharmony_ci return NULL; 100162306a36Sopenharmony_ci return hcd_buffer_alloc(dev->bus, size, mem_flags, dma); 100262306a36Sopenharmony_ci} 100362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_alloc_coherent); 100462306a36Sopenharmony_ci 100562306a36Sopenharmony_ci/** 100662306a36Sopenharmony_ci * usb_free_coherent - free memory allocated with usb_alloc_coherent() 100762306a36Sopenharmony_ci * @dev: device the buffer was used with 100862306a36Sopenharmony_ci * @size: requested buffer size 100962306a36Sopenharmony_ci * @addr: CPU address of buffer 101062306a36Sopenharmony_ci * @dma: DMA address of buffer 101162306a36Sopenharmony_ci * 101262306a36Sopenharmony_ci * This reclaims an I/O buffer, letting it be reused. The memory must have 101362306a36Sopenharmony_ci * been allocated using usb_alloc_coherent(), and the parameters must match 101462306a36Sopenharmony_ci * those provided in that allocation request. 101562306a36Sopenharmony_ci */ 101662306a36Sopenharmony_civoid usb_free_coherent(struct usb_device *dev, size_t size, void *addr, 101762306a36Sopenharmony_ci dma_addr_t dma) 101862306a36Sopenharmony_ci{ 101962306a36Sopenharmony_ci if (!dev || !dev->bus) 102062306a36Sopenharmony_ci return; 102162306a36Sopenharmony_ci if (!addr) 102262306a36Sopenharmony_ci return; 102362306a36Sopenharmony_ci hcd_buffer_free(dev->bus, size, addr, dma); 102462306a36Sopenharmony_ci} 102562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(usb_free_coherent); 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci/* 102862306a36Sopenharmony_ci * Notifications of device and interface registration 102962306a36Sopenharmony_ci */ 103062306a36Sopenharmony_cistatic int usb_bus_notify(struct notifier_block *nb, unsigned long action, 103162306a36Sopenharmony_ci void *data) 103262306a36Sopenharmony_ci{ 103362306a36Sopenharmony_ci struct device *dev = data; 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_ci switch (action) { 103662306a36Sopenharmony_ci case BUS_NOTIFY_ADD_DEVICE: 103762306a36Sopenharmony_ci if (dev->type == &usb_device_type) 103862306a36Sopenharmony_ci (void) usb_create_sysfs_dev_files(to_usb_device(dev)); 103962306a36Sopenharmony_ci else if (dev->type == &usb_if_device_type) 104062306a36Sopenharmony_ci usb_create_sysfs_intf_files(to_usb_interface(dev)); 104162306a36Sopenharmony_ci break; 104262306a36Sopenharmony_ci 104362306a36Sopenharmony_ci case BUS_NOTIFY_DEL_DEVICE: 104462306a36Sopenharmony_ci if (dev->type == &usb_device_type) 104562306a36Sopenharmony_ci usb_remove_sysfs_dev_files(to_usb_device(dev)); 104662306a36Sopenharmony_ci else if (dev->type == &usb_if_device_type) 104762306a36Sopenharmony_ci usb_remove_sysfs_intf_files(to_usb_interface(dev)); 104862306a36Sopenharmony_ci break; 104962306a36Sopenharmony_ci } 105062306a36Sopenharmony_ci return 0; 105162306a36Sopenharmony_ci} 105262306a36Sopenharmony_ci 105362306a36Sopenharmony_cistatic struct notifier_block usb_bus_nb = { 105462306a36Sopenharmony_ci .notifier_call = usb_bus_notify, 105562306a36Sopenharmony_ci}; 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_cistatic void usb_debugfs_init(void) 105862306a36Sopenharmony_ci{ 105962306a36Sopenharmony_ci debugfs_create_file("devices", 0444, usb_debug_root, NULL, 106062306a36Sopenharmony_ci &usbfs_devices_fops); 106162306a36Sopenharmony_ci} 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_cistatic void usb_debugfs_cleanup(void) 106462306a36Sopenharmony_ci{ 106562306a36Sopenharmony_ci debugfs_lookup_and_remove("devices", usb_debug_root); 106662306a36Sopenharmony_ci} 106762306a36Sopenharmony_ci 106862306a36Sopenharmony_ci/* 106962306a36Sopenharmony_ci * Init 107062306a36Sopenharmony_ci */ 107162306a36Sopenharmony_cistatic int __init usb_init(void) 107262306a36Sopenharmony_ci{ 107362306a36Sopenharmony_ci int retval; 107462306a36Sopenharmony_ci if (usb_disabled()) { 107562306a36Sopenharmony_ci pr_info("%s: USB support disabled\n", usbcore_name); 107662306a36Sopenharmony_ci return 0; 107762306a36Sopenharmony_ci } 107862306a36Sopenharmony_ci usb_init_pool_max(); 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_ci usb_debugfs_init(); 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci usb_acpi_register(); 108362306a36Sopenharmony_ci retval = bus_register(&usb_bus_type); 108462306a36Sopenharmony_ci if (retval) 108562306a36Sopenharmony_ci goto bus_register_failed; 108662306a36Sopenharmony_ci retval = bus_register_notifier(&usb_bus_type, &usb_bus_nb); 108762306a36Sopenharmony_ci if (retval) 108862306a36Sopenharmony_ci goto bus_notifier_failed; 108962306a36Sopenharmony_ci retval = usb_major_init(); 109062306a36Sopenharmony_ci if (retval) 109162306a36Sopenharmony_ci goto major_init_failed; 109262306a36Sopenharmony_ci retval = class_register(&usbmisc_class); 109362306a36Sopenharmony_ci if (retval) 109462306a36Sopenharmony_ci goto class_register_failed; 109562306a36Sopenharmony_ci retval = usb_register(&usbfs_driver); 109662306a36Sopenharmony_ci if (retval) 109762306a36Sopenharmony_ci goto driver_register_failed; 109862306a36Sopenharmony_ci retval = usb_devio_init(); 109962306a36Sopenharmony_ci if (retval) 110062306a36Sopenharmony_ci goto usb_devio_init_failed; 110162306a36Sopenharmony_ci retval = usb_hub_init(); 110262306a36Sopenharmony_ci if (retval) 110362306a36Sopenharmony_ci goto hub_init_failed; 110462306a36Sopenharmony_ci retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE); 110562306a36Sopenharmony_ci if (!retval) 110662306a36Sopenharmony_ci goto out; 110762306a36Sopenharmony_ci 110862306a36Sopenharmony_ci usb_hub_cleanup(); 110962306a36Sopenharmony_cihub_init_failed: 111062306a36Sopenharmony_ci usb_devio_cleanup(); 111162306a36Sopenharmony_ciusb_devio_init_failed: 111262306a36Sopenharmony_ci usb_deregister(&usbfs_driver); 111362306a36Sopenharmony_cidriver_register_failed: 111462306a36Sopenharmony_ci class_unregister(&usbmisc_class); 111562306a36Sopenharmony_ciclass_register_failed: 111662306a36Sopenharmony_ci usb_major_cleanup(); 111762306a36Sopenharmony_cimajor_init_failed: 111862306a36Sopenharmony_ci bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); 111962306a36Sopenharmony_cibus_notifier_failed: 112062306a36Sopenharmony_ci bus_unregister(&usb_bus_type); 112162306a36Sopenharmony_cibus_register_failed: 112262306a36Sopenharmony_ci usb_acpi_unregister(); 112362306a36Sopenharmony_ci usb_debugfs_cleanup(); 112462306a36Sopenharmony_ciout: 112562306a36Sopenharmony_ci return retval; 112662306a36Sopenharmony_ci} 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci/* 112962306a36Sopenharmony_ci * Cleanup 113062306a36Sopenharmony_ci */ 113162306a36Sopenharmony_cistatic void __exit usb_exit(void) 113262306a36Sopenharmony_ci{ 113362306a36Sopenharmony_ci /* This will matter if shutdown/reboot does exitcalls. */ 113462306a36Sopenharmony_ci if (usb_disabled()) 113562306a36Sopenharmony_ci return; 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci usb_release_quirk_list(); 113862306a36Sopenharmony_ci usb_deregister_device_driver(&usb_generic_driver); 113962306a36Sopenharmony_ci usb_major_cleanup(); 114062306a36Sopenharmony_ci usb_deregister(&usbfs_driver); 114162306a36Sopenharmony_ci usb_devio_cleanup(); 114262306a36Sopenharmony_ci usb_hub_cleanup(); 114362306a36Sopenharmony_ci class_unregister(&usbmisc_class); 114462306a36Sopenharmony_ci bus_unregister_notifier(&usb_bus_type, &usb_bus_nb); 114562306a36Sopenharmony_ci bus_unregister(&usb_bus_type); 114662306a36Sopenharmony_ci usb_acpi_unregister(); 114762306a36Sopenharmony_ci usb_debugfs_cleanup(); 114862306a36Sopenharmony_ci idr_destroy(&usb_bus_idr); 114962306a36Sopenharmony_ci} 115062306a36Sopenharmony_ci 115162306a36Sopenharmony_cisubsys_initcall(usb_init); 115262306a36Sopenharmony_cimodule_exit(usb_exit); 115362306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 1154