hcd.c revision f150fa1afbf69a87f54752579ff2bb769aad88b3
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) Copyright Linus Torvalds 1999 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) Copyright Johannes Erdfelt 1999-2001 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) Copyright Andreas Gal 1999 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) Copyright Gregory P. Smith 1999 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) Copyright Deti Fliegl 1999 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) Copyright Randy Dunlap 2000 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) Copyright David Brownell 2000-2002 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify it 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * under the terms of the GNU General Public License as published by the 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Free Software Foundation; either version 2 of the License, or (at your 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * option) any later version. 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, but 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for more details. 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software Foundation, 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/version.h> 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/completion.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/utsname.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/device.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/dma-mapping.h> 354186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de Ven#include <linux/mutex.h> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/byteorder.h> 38b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm#include <asm/unaligned.h> 3964a21d025d3a979a8715f2ec7acabca7b5406c8aAleksey Gorelov#include <linux/platform_device.h> 406b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern#include <linux/workqueue.h> 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/usb.h> 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "usb.h" 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hcd.h" 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hub.h" 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * USB Host Controller Driver framework 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Plugs into usbcore (usb_bus) and lets HCDs share code, minimizing 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HCD-specific behaviors/bugs. 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This does error checks, tracks devices and urbs, and delegates to a 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "hc_driver" only for code (and data) that really needs to know about 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hardware differences. That includes root hub registers, i/o queues, 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and so on ... but as little else as possible. 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Shared code includes most of the "root hub" code (these are emulated, 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * though each HC's hardware works differently) and PCI glue, plus request 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * tracking overhead. The HCD code should only block on spinlocks or on 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hardware handshaking; blocking on software events (such as other kernel 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * threads releasing resources, or completing actions) is all generic. 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Happens the USB 2.0 spec says this would be invisible inside the "USBD", 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and includes mostly a "HCDI" (HCD Interface) along with some APIs used 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * only by the hub driver ... and that neither should be seen or used by 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb client device drivers. 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Contributors of ideas or unattributed patches include: David Brownell, 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Roman Weissgaerber, Rory Bolt, Greg Kroah-Hartman, ... 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HISTORY: 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2002-02-21 Pull in most of the usb_bus support from usb.c; some 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * associated cleanup. "usb_hcd" still != "usb_bus". 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2001-12-12 Initial patch version for Linux 2.5.1 kernel. 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 849beeee6584b9aa4f9192055512411484a2a624dfAlan Stern/* Keep track of which host controller drivers are loaded */ 859beeee6584b9aa4f9192055512411484a2a624dfAlan Sternunsigned long usb_hcds_loaded; 869beeee6584b9aa4f9192055512411484a2a624dfAlan SternEXPORT_SYMBOL_GPL(usb_hcds_loaded); 879beeee6584b9aa4f9192055512411484a2a624dfAlan Stern 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* host controllers we manage */ 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsLIST_HEAD (usb_bus_list); 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL (usb_bus_list); 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* used when allocating bus numbers */ 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define USB_MAXBUS 64 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct usb_busmap { 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long busmap [USB_MAXBUS / (8*sizeof (unsigned long))]; 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct usb_busmap busmap; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* used when updating list of hcds */ 1004186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de VenDEFINE_MUTEX(usb_bus_list_lock); /* exported only for usbfs */ 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL (usb_bus_list_lock); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* used for controlling access to virtual root hubs */ 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEFINE_SPINLOCK(hcd_root_hub_lock); 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 106809a58b896ba07e771adc76a47c83e4ca1969da8Alan Stern/* used when updating an endpoint's URB list */ 107809a58b896ba07e771adc76a47c83e4ca1969da8Alan Sternstatic DEFINE_SPINLOCK(hcd_urb_list_lock); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 109cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern/* used to protect against unlinking URBs after the device is gone */ 110cde217a556ec552d28ac9e136c5a94684a69ae94Alan Sternstatic DEFINE_SPINLOCK(hcd_urb_unlink_lock); 111cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* wait queue for synchronous unlinks */ 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsDECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 115809a58b896ba07e771adc76a47c83e4ca1969da8Alan Sternstatic inline int is_root_hub(struct usb_device *udev) 116809a58b896ba07e771adc76a47c83e4ca1969da8Alan Stern{ 117809a58b896ba07e771adc76a47c83e4ca1969da8Alan Stern return (udev->parent == NULL); 118809a58b896ba07e771adc76a47c83e4ca1969da8Alan Stern} 119809a58b896ba07e771adc76a47c83e4ca1969da8Alan Stern 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sharable chunks of root hub code. 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define KERNEL_REL ((LINUX_VERSION_CODE >> 16) & 0x0ff) 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define KERNEL_VER ((LINUX_VERSION_CODE >> 8) & 0x0ff) 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* usb 2.0 root hub device descriptor */ 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 usb2_rh_dev_descriptor [18] = { 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x12, /* __u8 bLength; */ 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01, /* __u8 bDescriptorType; Device */ 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, 0x02, /* __le16 bcdUSB; v2.0 */ 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 bDeviceSubClass; */ 1397329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern 0x00, /* __u8 bDeviceProtocol; [ usb 2.0 no TT ] */ 14016f16d117c1eb99451e4c73c87546eef05c66790Alan Stern 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 142667d691ed7a70c9a9fde5b6bd663a5f38326e026Greg Kroah-Hartman 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ 143667d691ed7a70c9a9fde5b6bd663a5f38326e026Greg Kroah-Hartman 0x02, 0x00, /* __le16 idProduct; device 0x0002 */ 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x03, /* __u8 iManufacturer; */ 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x02, /* __u8 iProduct; */ 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01, /* __u8 iSerialNumber; */ 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01 /* __u8 bNumConfigurations; */ 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* no usb 2.0 root hub "device qualifier" descriptor: one speed only */ 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* usb 1.1 root hub device descriptor */ 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 usb11_rh_dev_descriptor [18] = { 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x12, /* __u8 bLength; */ 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01, /* __u8 bDescriptorType; Device */ 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x10, 0x01, /* __le16 bcdUSB; v1.1 */ 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 bDeviceSubClass; */ 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */ 16316f16d117c1eb99451e4c73c87546eef05c66790Alan Stern 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 165667d691ed7a70c9a9fde5b6bd663a5f38326e026Greg Kroah-Hartman 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ 166667d691ed7a70c9a9fde5b6bd663a5f38326e026Greg Kroah-Hartman 0x01, 0x00, /* __le16 idProduct; device 0x0001 */ 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x03, /* __u8 iManufacturer; */ 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x02, /* __u8 iProduct; */ 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01, /* __u8 iSerialNumber; */ 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01 /* __u8 bNumConfigurations; */ 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Configuration descriptors for our root hubs */ 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 fs_rh_config_descriptor [] = { 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* one configuration */ 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x09, /* __u8 bLength; */ 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x02, /* __u8 bDescriptorType; Configuration */ 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x19, 0x00, /* __le16 wTotalLength; */ 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01, /* __u8 bNumInterfaces; (1) */ 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01, /* __u8 bConfigurationValue; */ 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 iConfiguration; */ 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xc0, /* __u8 bmAttributes; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Bit 7: must be set, 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6: Self-powered, 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5: Remote wakeup, 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4..0: resvd */ 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 MaxPower; */ 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* USB 1.1: 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * USB 2.0, single TT organization (mandatory): 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * one interface, protocol 0 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * USB 2.0, multiple TT organization (optional): 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * two interfaces, protocols 1 (like single TT) 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and 2 (multiple TT mode) ... config is 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sometimes settable 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOT IMPLEMENTED 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* one interface */ 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x09, /* __u8 if_bLength; */ 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x04, /* __u8 if_bDescriptorType; Interface */ 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 if_bInterfaceNumber; */ 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 if_bAlternateSetting; */ 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01, /* __u8 if_bNumEndpoints; */ 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 if_bInterfaceSubClass; */ 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 if_iInterface; */ 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* one endpoint (status change endpoint) */ 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x07, /* __u8 ep_bLength; */ 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x03, /* __u8 ep_bmAttributes; Interrupt */ 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x02, 0x00, /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xff /* __u8 ep_bInterval; (255ms -- usb 2.0 spec) */ 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 hs_rh_config_descriptor [] = { 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* one configuration */ 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x09, /* __u8 bLength; */ 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x02, /* __u8 bDescriptorType; Configuration */ 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x19, 0x00, /* __le16 wTotalLength; */ 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01, /* __u8 bNumInterfaces; (1) */ 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01, /* __u8 bConfigurationValue; */ 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 iConfiguration; */ 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0xc0, /* __u8 bmAttributes; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Bit 7: must be set, 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6: Self-powered, 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5: Remote wakeup, 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4..0: resvd */ 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 MaxPower; */ 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* USB 1.1: 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * USB 2.0, single TT organization (mandatory): 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * one interface, protocol 0 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * USB 2.0, multiple TT organization (optional): 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * two interfaces, protocols 1 (like single TT) 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and 2 (multiple TT mode) ... config is 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sometimes settable 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOT IMPLEMENTED 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* one interface */ 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x09, /* __u8 if_bLength; */ 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x04, /* __u8 if_bDescriptorType; Interface */ 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 if_bInterfaceNumber; */ 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 if_bAlternateSetting; */ 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x01, /* __u8 if_bNumEndpoints; */ 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 if_bInterfaceSubClass; */ 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, /* __u8 if_iInterface; */ 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* one endpoint (status change endpoint) */ 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x07, /* __u8 ep_bLength; */ 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x03, /* __u8 ep_bmAttributes; Interrupt */ 27088fafff9d73c0a506c0b08e7cd637c89d8b604e1inaky@linux.intel.com /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) 27188fafff9d73c0a506c0b08e7cd637c89d8b604e1inaky@linux.intel.com * see hub.c:hub_configure() for details. */ 27288fafff9d73c0a506c0b08e7cd637c89d8b604e1inaky@linux.intel.com (USB_MAXCHILDREN + 1 + 7) / 8, 0x00, 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * helper routine for returning string descriptors in UTF-16LE 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * input can actually be ISO-8859-1; ASCII is its 7-bit subset 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ascii2utf (char *s, u8 *utf, int utfmax) 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval; 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *utf++ = *s++; 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *utf++ = 0; 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (utfmax > 0) { 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *utf = *s; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++retval; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * rh_string - provides manufacturer, product and serial strings for root hub 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @id: the string ID number (1: serial number, 2: product, 3: vendor) 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @hcd: the host controller for this root hub 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @data: return packet in UTF-16 LE 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @len: length of the return packet 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Produces either a manufacturer, product or serial number string for the 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * virtual root hub device. 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int rh_string ( 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int id, 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct usb_hcd *hcd, 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *data, 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds) { 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char buf [100]; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // language ids 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (id == 0) { 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] = 4; buf[1] = 3; /* 4 bytes string data */ 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */ 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = min (len, 4); 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy (data, buf, len); 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return len; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // serial number 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (id == 1) { 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strlcpy (buf, hcd->self.bus_name, sizeof buf); 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // product description 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (id == 2) { 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strlcpy (buf, hcd->product_desc, sizeof buf); 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // id 3 == vendor description 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (id == 3) { 33396b644bdec977b97a45133e5b4466ba47a7a5e65Serge E. Hallyn snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname, 33496b644bdec977b97a45133e5b4466ba47a7a5e65Serge E. Hallyn init_utsname()->release, hcd->driver->description); 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // unsupported IDs --> "protocol stall" 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPIPE; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (len) { /* All cases fall through */ 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 2 + ascii2utf (buf, data + 2, len - 2); 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data [1] = 3; /* type == string */ 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data [0] = 2 * (strlen (buf) + 1); 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; /* Compiler wants a statement here */ 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return len; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Root hub control transfers execute synchronously */ 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int rh_call_control (struct usb_hcd *hcd, struct urb *urb) 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct usb_ctrlrequest *cmd; 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 typeReq, wValue, wIndex, wLength; 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *ubuf = urb->transfer_buffer; 36054bee6e1b455573658972510a76119f279db32b7Mikael Pettersson u8 tbuf [sizeof (struct usb_hub_descriptor)] 36154bee6e1b455573658972510a76119f279db32b7Mikael Pettersson __attribute__((aligned(4))); 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const u8 *bufp = tbuf; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len = 0; 364e9df41c5c5899259541dc928872cad4d07b82076Alan Stern int status; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n; 3667329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern u8 patch_wakeup = 0; 3677329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern u8 patch_protocol = 0; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3699439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern might_sleep(); 3709439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern 371e9df41c5c5899259541dc928872cad4d07b82076Alan Stern spin_lock_irq(&hcd_root_hub_lock); 372e9df41c5c5899259541dc928872cad4d07b82076Alan Stern status = usb_hcd_link_urb_to_ep(hcd, urb); 373e9df41c5c5899259541dc928872cad4d07b82076Alan Stern spin_unlock_irq(&hcd_root_hub_lock); 374e9df41c5c5899259541dc928872cad4d07b82076Alan Stern if (status) 375e9df41c5c5899259541dc928872cad4d07b82076Alan Stern return status; 376b0d9efba3ec53468984aecef8eeaf079089f2e5aAlan Stern urb->hcpriv = hcd; /* Indicate it's queued */ 377e9df41c5c5899259541dc928872cad4d07b82076Alan Stern 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = (struct usb_ctrlrequest *) urb->setup_packet; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds typeReq = (cmd->bRequestType << 8) | cmd->bRequest; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wValue = le16_to_cpu (cmd->wValue); 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wIndex = le16_to_cpu (cmd->wIndex); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wLength = le16_to_cpu (cmd->wLength); 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wLength > urb->transfer_buffer_length) 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds urb->actual_length = 0; 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (typeReq) { 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* DEVICE REQUESTS */ 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 392fb669cc01ed778c4926f395e44a9b61644597d38David Brownell /* The root hub's remote wakeup enable bit is implemented using 393fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * driver model wakeup flags. If this system supports wakeup 394fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * through USB, userspace may change the default "allow wakeup" 395fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * policy through sysfs or these calls. 396fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * 397fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * Most root hubs support wakeup from downstream devices, for 398fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * runtime power management (disabling USB clocks and reducing 399fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * VBUS power usage). However, not all of them do so; silicon, 400fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * board, and BIOS bugs here are not uncommon, so these can't 401fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * be treated quite like external hubs. 402fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * 403fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * Likewise, not all root hubs will pass wakeup events upstream, 404fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * to wake up the whole system. So don't assume root hub and 405fb669cc01ed778c4926f395e44a9b61644597d38David Brownell * controller capabilities are identical. 406fb669cc01ed778c4926f395e44a9b61644597d38David Brownell */ 407fb669cc01ed778c4926f395e44a9b61644597d38David Brownell 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DeviceRequest | USB_REQ_GET_STATUS: 409fb669cc01ed778c4926f395e44a9b61644597d38David Brownell tbuf [0] = (device_may_wakeup(&hcd->self.root_hub->dev) 410fb669cc01ed778c4926f395e44a9b61644597d38David Brownell << USB_DEVICE_REMOTE_WAKEUP) 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | (1 << USB_DEVICE_SELF_POWERED); 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tbuf [1] = 0; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 2; 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wValue == USB_DEVICE_REMOTE_WAKEUP) 417fb669cc01ed778c4926f395e44a9b61644597d38David Brownell device_set_wakeup_enable(&hcd->self.root_hub->dev, 0); 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error; 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DeviceOutRequest | USB_REQ_SET_FEATURE: 422fb669cc01ed778c4926f395e44a9b61644597d38David Brownell if (device_can_wakeup(&hcd->self.root_hub->dev) 423fb669cc01ed778c4926f395e44a9b61644597d38David Brownell && wValue == USB_DEVICE_REMOTE_WAKEUP) 424fb669cc01ed778c4926f395e44a9b61644597d38David Brownell device_set_wakeup_enable(&hcd->self.root_hub->dev, 1); 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error; 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DeviceRequest | USB_REQ_GET_CONFIGURATION: 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tbuf [0] = 1; 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 1; 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FALLTHROUGH */ 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DeviceRequest | USB_REQ_GET_DESCRIPTOR: 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (wValue & 0xff00) { 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case USB_DT_DEVICE << 8: 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hcd->driver->flags & HCD_USB2) 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bufp = usb2_rh_dev_descriptor; 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (hcd->driver->flags & HCD_USB11) 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bufp = usb11_rh_dev_descriptor; 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error; 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 18; 4447329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern if (hcd->has_tt) 4457329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern patch_protocol = 1; 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case USB_DT_CONFIG << 8: 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hcd->driver->flags & HCD_USB2) { 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bufp = hs_rh_config_descriptor; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = sizeof hs_rh_config_descriptor; 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bufp = fs_rh_config_descriptor; 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = sizeof fs_rh_config_descriptor; 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 455fb669cc01ed778c4926f395e44a9b61644597d38David Brownell if (device_can_wakeup(&hcd->self.root_hub->dev)) 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds patch_wakeup = 1; 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case USB_DT_STRING << 8: 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = rh_string (wValue & 0xff, hcd, ubuf, wLength); 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (n < 0) 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error; 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds urb->actual_length = n; 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error; 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DeviceRequest | USB_REQ_GET_INTERFACE: 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tbuf [0] = 0; 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 1; 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FALLTHROUGH */ 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DeviceOutRequest | USB_REQ_SET_INTERFACE: 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DeviceOutRequest | USB_REQ_SET_ADDRESS: 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // wValue == urb->dev->devaddr 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_dbg (hcd->self.controller, "root hub device address %d\n", 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wValue); 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* INTERFACE REQUESTS (no defined feature/status flags) */ 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* ENDPOINT REQUESTS */ 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EndpointRequest | USB_REQ_GET_STATUS: 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // ENDPOINT_HALT flag 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tbuf [0] = 0; 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tbuf [1] = 0; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 2; 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FALLTHROUGH */ 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EndpointOutRequest | USB_REQ_CLEAR_FEATURE: 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EndpointOutRequest | USB_REQ_SET_FEATURE: 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_dbg (hcd->self.controller, "no endpoint features yet\n"); 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* CLASS REQUESTS (and errors) */ 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* non-generic request */ 499b13296c6617f22e8c0174a7af32780617db0e680David Brownell switch (typeReq) { 500b13296c6617f22e8c0174a7af32780617db0e680David Brownell case GetHubStatus: 501b13296c6617f22e8c0174a7af32780617db0e680David Brownell case GetPortStatus: 502b13296c6617f22e8c0174a7af32780617db0e680David Brownell len = 4; 503b13296c6617f22e8c0174a7af32780617db0e680David Brownell break; 504b13296c6617f22e8c0174a7af32780617db0e680David Brownell case GetHubDescriptor: 505b13296c6617f22e8c0174a7af32780617db0e680David Brownell len = sizeof (struct usb_hub_descriptor); 506b13296c6617f22e8c0174a7af32780617db0e680David Brownell break; 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 508b13296c6617f22e8c0174a7af32780617db0e680David Brownell status = hcd->driver->hub_control (hcd, 509b13296c6617f22e8c0174a7af32780617db0e680David Brownell typeReq, wValue, wIndex, 510b13296c6617f22e8c0174a7af32780617db0e680David Brownell tbuf, wLength); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldserror: 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* "protocol stall" on error */ 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = -EPIPE; 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status) { 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 0; 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status != -EPIPE) { 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_dbg (hcd->self.controller, 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CTRL: TypeReq=0x%x val=0x%x " 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "idx=0x%x len=%d ==> %d\n", 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds typeReq, wValue, wIndex, 524b13296c6617f22e8c0174a7af32780617db0e680David Brownell wLength, status); 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len) { 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (urb->transfer_buffer_length < len) 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = urb->transfer_buffer_length; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds urb->actual_length = len; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // always USB_DIR_IN, toward host 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy (ubuf, bufp, len); 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* report whether RH hardware supports remote wakeup */ 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (patch_wakeup && 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len > offsetof (struct usb_config_descriptor, 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bmAttributes)) 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((struct usb_config_descriptor *)ubuf)->bmAttributes 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds |= USB_CONFIG_ATT_WAKEUP; 5407329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern 5417329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern /* report whether RH hardware has an integrated TT */ 5427329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern if (patch_protocol && 5437329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern len > offsetof(struct usb_device_descriptor, 5447329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern bDeviceProtocol)) 5457329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern ((struct usb_device_descriptor *) ubuf)-> 5467329e211b987a493cbcfca0e98c60eb108ab42dfAlan Stern bDeviceProtocol = 1; 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* any errors get returned through the urb completion */ 5509439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_lock_irq(&hcd_root_hub_lock); 551e9df41c5c5899259541dc928872cad4d07b82076Alan Stern usb_hcd_unlink_urb_from_ep(hcd, urb); 5529439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern 5539439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern /* This peculiar use of spinlocks echoes what real HC drivers do. 5549439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern * Avoiding calls to local_irq_disable/enable makes the code 5559439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern * RT-friendly. 5569439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern */ 5579439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_unlock(&hcd_root_hub_lock); 5584a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Stern usb_hcd_giveback_urb(hcd, urb, status); 5599439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_lock(&hcd_root_hub_lock); 5609439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern 5619439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_unlock_irq(&hcd_root_hub_lock); 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 568d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern * Root Hub interrupt transfers are polled using a timer if the 569d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern * driver requests it; otherwise the driver is responsible for 570d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern * calling usb_hcd_poll_rh_status() when an event occurs. 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 572d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern * Completions are called in_interrupt(), but they may or may not 573d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern * be in_irq(). 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 575d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Sternvoid usb_hcd_poll_rh_status(struct usb_hcd *hcd) 576d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern{ 577d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern struct urb *urb; 578d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern int length; 579d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern unsigned long flags; 580d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern char buffer[4]; /* Any root hubs with > 31 ports? */ 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5821b42ae6d4355328dc4406b6f0188adcf8c566435Alan Stern if (unlikely(!hcd->rh_registered)) 5831b42ae6d4355328dc4406b6f0188adcf8c566435Alan Stern return; 584d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern if (!hcd->uses_new_polling && !hcd->status_urb) 585d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern return; 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 587d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern length = hcd->driver->hub_status_data(hcd, buffer); 588d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern if (length > 0) { 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 590d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern /* try to complete the status urb */ 5919439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_lock_irqsave(&hcd_root_hub_lock, flags); 592d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern urb = hcd->status_urb; 593d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern if (urb) { 594e9df41c5c5899259541dc928872cad4d07b82076Alan Stern hcd->poll_pending = 0; 595e9df41c5c5899259541dc928872cad4d07b82076Alan Stern hcd->status_urb = NULL; 596e9df41c5c5899259541dc928872cad4d07b82076Alan Stern urb->actual_length = length; 597e9df41c5c5899259541dc928872cad4d07b82076Alan Stern memcpy(urb->transfer_buffer, buffer, length); 5989439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern 599e9df41c5c5899259541dc928872cad4d07b82076Alan Stern usb_hcd_unlink_urb_from_ep(hcd, urb); 6009439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_unlock(&hcd_root_hub_lock); 6014a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Stern usb_hcd_giveback_urb(hcd, urb, 0); 6029439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_lock(&hcd_root_hub_lock); 603e9df41c5c5899259541dc928872cad4d07b82076Alan Stern } else { 604d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern length = 0; 605d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern hcd->poll_pending = 1; 606e9df41c5c5899259541dc928872cad4d07b82076Alan Stern } 6079439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_unlock_irqrestore(&hcd_root_hub_lock, flags); 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 610d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern /* The USB 2.0 spec says 256 ms. This is close enough and won't 61101cd08192040eab30f837f061ca07f43cf15f4a1Arjan van de Ven * exceed that limit if HZ is 100. The math is more clunky than 61201cd08192040eab30f837f061ca07f43cf15f4a1Arjan van de Ven * maybe expected, this is to make sure that all timers for USB devices 61301cd08192040eab30f837f061ca07f43cf15f4a1Arjan van de Ven * fire at the same time to give the CPU a break inbetween */ 614d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern if (hcd->uses_new_polling ? hcd->poll_rh : 615d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern (length == 0 && hcd->status_urb != NULL)) 61601cd08192040eab30f837f061ca07f43cf15f4a1Arjan van de Ven mod_timer (&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)); 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 618d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan SternEXPORT_SYMBOL_GPL(usb_hcd_poll_rh_status); 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* timer callback */ 621d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Sternstatic void rh_timer_func (unsigned long _hcd) 622d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern{ 623d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern usb_hcd_poll_rh_status((struct usb_hcd *) _hcd); 624d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern} 625d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern 626d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern/*-------------------------------------------------------------------------*/ 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 628d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Sternstatic int rh_queue_status (struct usb_hcd *hcd, struct urb *urb) 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 630d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern int retval; 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 632d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern int len = 1 + (urb->dev->maxchild / 8); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 634d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern spin_lock_irqsave (&hcd_root_hub_lock, flags); 635e9df41c5c5899259541dc928872cad4d07b82076Alan Stern if (hcd->status_urb || urb->transfer_buffer_length < len) { 636d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern dev_dbg (hcd->self.controller, "not queuing rh status urb\n"); 637d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern retval = -EINVAL; 638e9df41c5c5899259541dc928872cad4d07b82076Alan Stern goto done; 639e9df41c5c5899259541dc928872cad4d07b82076Alan Stern } 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 641e9df41c5c5899259541dc928872cad4d07b82076Alan Stern retval = usb_hcd_link_urb_to_ep(hcd, urb); 642e9df41c5c5899259541dc928872cad4d07b82076Alan Stern if (retval) 643e9df41c5c5899259541dc928872cad4d07b82076Alan Stern goto done; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 645e9df41c5c5899259541dc928872cad4d07b82076Alan Stern hcd->status_urb = urb; 646e9df41c5c5899259541dc928872cad4d07b82076Alan Stern urb->hcpriv = hcd; /* indicate it's queued */ 647e9df41c5c5899259541dc928872cad4d07b82076Alan Stern if (!hcd->uses_new_polling) 648e9df41c5c5899259541dc928872cad4d07b82076Alan Stern mod_timer(&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)); 649e9df41c5c5899259541dc928872cad4d07b82076Alan Stern 650e9df41c5c5899259541dc928872cad4d07b82076Alan Stern /* If a status change has already occurred, report it ASAP */ 651e9df41c5c5899259541dc928872cad4d07b82076Alan Stern else if (hcd->poll_pending) 652e9df41c5c5899259541dc928872cad4d07b82076Alan Stern mod_timer(&hcd->rh_timer, jiffies); 653e9df41c5c5899259541dc928872cad4d07b82076Alan Stern retval = 0; 654e9df41c5c5899259541dc928872cad4d07b82076Alan Stern done: 655d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern spin_unlock_irqrestore (&hcd_root_hub_lock, flags); 656d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern return retval; 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb) 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6615e60a16139c2a48b9876b0ff910671eee5fb32ecAlan Stern if (usb_endpoint_xfer_int(&urb->ep->desc)) 662d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern return rh_queue_status (hcd, urb); 6635e60a16139c2a48b9876b0ff910671eee5fb32ecAlan Stern if (usb_endpoint_xfer_control(&urb->ep->desc)) 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rh_call_control (hcd, urb); 665d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern return -EINVAL; 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 670455b25fb209c8241e2163b491228b28667d82c1cAlan Stern/* Unlinks of root-hub control URBs are legal, but they don't do anything 671455b25fb209c8241e2163b491228b28667d82c1cAlan Stern * since these URBs always execute synchronously. 672d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern */ 673e9df41c5c5899259541dc928872cad4d07b82076Alan Sternstatic int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 675455b25fb209c8241e2163b491228b28667d82c1cAlan Stern unsigned long flags; 676e9df41c5c5899259541dc928872cad4d07b82076Alan Stern int rc; 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6789439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_lock_irqsave(&hcd_root_hub_lock, flags); 679e9df41c5c5899259541dc928872cad4d07b82076Alan Stern rc = usb_hcd_check_unlink_urb(hcd, urb, status); 680e9df41c5c5899259541dc928872cad4d07b82076Alan Stern if (rc) 681e9df41c5c5899259541dc928872cad4d07b82076Alan Stern goto done; 682e9df41c5c5899259541dc928872cad4d07b82076Alan Stern 6835e60a16139c2a48b9876b0ff910671eee5fb32ecAlan Stern if (usb_endpoint_num(&urb->ep->desc) == 0) { /* Control URB */ 684455b25fb209c8241e2163b491228b28667d82c1cAlan Stern ; /* Do nothing */ 685d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern 686d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern } else { /* Status URB */ 687d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern if (!hcd->uses_new_polling) 688455b25fb209c8241e2163b491228b28667d82c1cAlan Stern del_timer (&hcd->rh_timer); 689d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern if (urb == hcd->status_urb) { 690d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern hcd->status_urb = NULL; 691e9df41c5c5899259541dc928872cad4d07b82076Alan Stern usb_hcd_unlink_urb_from_ep(hcd, urb); 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6939439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_unlock(&hcd_root_hub_lock); 6944a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Stern usb_hcd_giveback_urb(hcd, urb, status); 6959439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_lock(&hcd_root_hub_lock); 6969439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern } 6979439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern } 698e9df41c5c5899259541dc928872cad4d07b82076Alan Stern done: 6999439eb94b5c374d5b02699f8897fc43aa3603701Alan Stern spin_unlock_irqrestore(&hcd_root_hub_lock, flags); 700e9df41c5c5899259541dc928872cad4d07b82076Alan Stern return rc; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7035234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7045234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7055234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez/* 7065234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez * Show & store the current value of authorized_default 7075234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez */ 7085234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalezstatic ssize_t usb_host_authorized_default_show(struct device *dev, 7095234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez struct device_attribute *attr, 7105234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez char *buf) 7115234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez{ 7125234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez struct usb_device *rh_usb_dev = to_usb_device(dev); 7135234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez struct usb_bus *usb_bus = rh_usb_dev->bus; 7145234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez struct usb_hcd *usb_hcd; 7155234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7165234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez if (usb_bus == NULL) /* FIXME: not sure if this case is possible */ 7175234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez return -ENODEV; 7185234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez usb_hcd = bus_to_hcd(usb_bus); 7195234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default); 7205234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez} 7215234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7225234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalezstatic ssize_t usb_host_authorized_default_store(struct device *dev, 7235234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez struct device_attribute *attr, 7245234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez const char *buf, size_t size) 7255234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez{ 7265234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez ssize_t result; 7275234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez unsigned val; 7285234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez struct usb_device *rh_usb_dev = to_usb_device(dev); 7295234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez struct usb_bus *usb_bus = rh_usb_dev->bus; 7305234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez struct usb_hcd *usb_hcd; 7315234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7325234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez if (usb_bus == NULL) /* FIXME: not sure if this case is possible */ 7335234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez return -ENODEV; 7345234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez usb_hcd = bus_to_hcd(usb_bus); 7355234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez result = sscanf(buf, "%u\n", &val); 7365234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez if (result == 1) { 7375234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez usb_hcd->authorized_default = val? 1 : 0; 7385234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez result = size; 7395234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez } 7405234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez else 7415234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez result = -EINVAL; 7425234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez return result; 7435234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez} 7445234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7455234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalezstatic DEVICE_ATTR(authorized_default, 0644, 7465234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez usb_host_authorized_default_show, 7475234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez usb_host_authorized_default_store); 7485234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7495234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7505234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez/* Group all the USB bus attributes */ 7515234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalezstatic struct attribute *usb_bus_attrs[] = { 7525234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez &dev_attr_authorized_default.attr, 7535234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez NULL, 7545234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez}; 7555234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7565234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalezstatic struct attribute_group usb_bus_attr_group = { 7575234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez .name = NULL, /* we want them in the same directory */ 7585234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez .attrs = usb_bus_attrs, 7595234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez}; 7605234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7615234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7625234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7658561b10f6e7ef0a085709ffc844f74130a067abeGreg Kroah-Hartmanstatic struct class *usb_host_class; 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint usb_host_init(void) 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7698561b10f6e7ef0a085709ffc844f74130a067abeGreg Kroah-Hartman int retval = 0; 7708561b10f6e7ef0a085709ffc844f74130a067abeGreg Kroah-Hartman 7718561b10f6e7ef0a085709ffc844f74130a067abeGreg Kroah-Hartman usb_host_class = class_create(THIS_MODULE, "usb_host"); 7728561b10f6e7ef0a085709ffc844f74130a067abeGreg Kroah-Hartman if (IS_ERR(usb_host_class)) 7738561b10f6e7ef0a085709ffc844f74130a067abeGreg Kroah-Hartman retval = PTR_ERR(usb_host_class); 7748561b10f6e7ef0a085709ffc844f74130a067abeGreg Kroah-Hartman return retval; 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid usb_host_cleanup(void) 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7798561b10f6e7ef0a085709ffc844f74130a067abeGreg Kroah-Hartman class_destroy(usb_host_class); 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_bus_init - shared initialization code 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @bus: the bus structure being initialized 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This code is used to initialize a usb_bus structure, memory for which is 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * separately managed. 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void usb_bus_init (struct usb_bus *bus) 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset (&bus->devmap, 0, sizeof(struct usb_devmap)); 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bus->devnum_next = 1; 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bus->root_hub = NULL; 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bus->busnum = -1; 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bus->bandwidth_allocated = 0; 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bus->bandwidth_int_reqs = 0; 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bus->bandwidth_isoc_reqs = 0; 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds INIT_LIST_HEAD (&bus->bus_list); 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_register_bus - registers the USB host controller with the usb core 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @bus: pointer to the bus to register 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: !in_interrupt() 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Assigns a bus number, and links the controller into usbcore data 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * structures so that it can be seen by scanning the bus list. 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int usb_register_bus(struct usb_bus *bus) 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 816eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez int result = -E2BIG; 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int busnum; 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8194186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de Ven mutex_lock(&usb_bus_list_lock); 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); 821eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez if (busnum >= USB_MAXBUS) { 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk (KERN_ERR "%s: too many buses\n", usbcore_name); 823eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez goto error_find_busnum; 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 825eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez set_bit (busnum, busmap.busmap); 826eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez bus->busnum = busnum; 8275a3201b2809a9f7bcda8413c445483f5b5e490a3Tony Jones 828b0b090e5792fa228b5c825fcc5e1b7b0da7abec9Greg Kroah-Hartman bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0), 829b0b090e5792fa228b5c825fcc5e1b7b0da7abec9Greg Kroah-Hartman bus, "usb_host%d", busnum); 8305a3201b2809a9f7bcda8413c445483f5b5e490a3Tony Jones result = PTR_ERR(bus->dev); 8315a3201b2809a9f7bcda8413c445483f5b5e490a3Tony Jones if (IS_ERR(bus->dev)) 832eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez goto error_create_class_dev; 8338561b10f6e7ef0a085709ffc844f74130a067abeGreg Kroah-Hartman 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Add it to the local list of buses */ 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds list_add (&bus->bus_list, &usb_bus_list); 8364186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de Ven mutex_unlock(&usb_bus_list_lock); 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8383099e75a7ccc3c5b0a4cf988a76d9c4a7fa5e91aGreg Kroah-Hartman usb_notify_add_bus(bus); 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 840eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez dev_info (bus->controller, "new USB bus registered, assigned bus " 841eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez "number %d\n", bus->busnum); 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 843eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez 844eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalezerror_create_class_dev: 845eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez clear_bit(busnum, busmap.busmap); 846eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalezerror_find_busnum: 847eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez mutex_unlock(&usb_bus_list_lock); 848eb579f5811ddbc052c8d6b3bba38dd4e5148cf7bInaky Perez-Gonzalez return result; 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_deregister_bus - deregisters the USB host controller 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @bus: pointer to the bus to deregister 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: !in_interrupt() 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Recycles the bus number, and unlinks the controller from usbcore data 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * structures so that it won't be seen by scanning the bus list. 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void usb_deregister_bus (struct usb_bus *bus) 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_info (bus->controller, "USB bus %d deregistered\n", bus->busnum); 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE: make sure that all the devices are removed by the 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * controller code, as well as having it call this when cleaning 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * itself up 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8684186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de Ven mutex_lock(&usb_bus_list_lock); 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds list_del (&bus->bus_list); 8704186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de Ven mutex_unlock(&usb_bus_list_lock); 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8723099e75a7ccc3c5b0a4cf988a76d9c4a7fa5e91aGreg Kroah-Hartman usb_notify_remove_bus(bus); 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_bit (bus->busnum, busmap.busmap); 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8765a3201b2809a9f7bcda8413c445483f5b5e490a3Tony Jones device_unregister(bus->dev); 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 8808ec8d20b21f00a36343ca0ebd6c6be9421724a1eAlan Stern * register_root_hub - called by usb_add_hcd() to register a root hub 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @hcd: host controller for this root hub 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8838ec8d20b21f00a36343ca0ebd6c6be9421724a1eAlan Stern * This function registers the root hub with the USB subsystem. It sets up 884b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell * the device properly in the device tree and then calls usb_new_device() 885b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell * to register the usb device. It also assigns the root hub's USB address 886b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell * (always 1). 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 888b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownellstatic int register_root_hub(struct usb_hcd *hcd) 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct device *parent_dev = hcd->self.controller; 891b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell struct usb_device *usb_dev = hcd->self.root_hub; 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const int devnum = 1; 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval; 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_dev->devnum = devnum; 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_dev->bus->devnum_next = devnum + 1; 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset (&usb_dev->bus->devmap.devicemap, 0, 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof usb_dev->bus->devmap.devicemap); 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_bit (devnum, usb_dev->bus->devmap.devicemap); 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_set_device_state(usb_dev, USB_STATE_ADDRESS); 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9024186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de Ven mutex_lock(&usb_bus_list_lock); 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval != sizeof usb_dev->descriptor) { 9074186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de Ven mutex_unlock(&usb_bus_list_lock); 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_dbg (parent_dev, "can't read %s device descriptor %d\n", 9097071a3ce0ca058ad2a9e3e8c33f30fb0bce62005Kay Sievers dev_name(&usb_dev->dev), retval); 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (retval < 0) ? retval : -EMSGSIZE; 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = usb_new_device (usb_dev); 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval) { 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_err (parent_dev, "can't register root hub for %s, %d\n", 9167071a3ce0ca058ad2a9e3e8c33f30fb0bce62005Kay Sievers dev_name(&usb_dev->dev), retval); 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9184186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de Ven mutex_unlock(&usb_bus_list_lock); 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval == 0) { 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irq (&hcd_root_hub_lock); 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->rh_registered = 1; 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irq (&hcd_root_hub_lock); 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Did the HC die before the root hub was registered? */ 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hcd->state == HC_STATE_HALT) 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_hc_died (hcd); /* This time clean up */ 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_calc_bus_time - approximate periodic transaction time in nanoseconds 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @speed: from dev->speed; USB_SPEED_{LOW,FULL,HIGH} 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @is_input: true iff the transaction sends data to the host 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @isoc: true for isochronous transactions, false for interrupt ones 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @bytecount: how many bytes in the transaction. 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns approximate bus time in nanoseconds for a periodic transaction. 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * See USB 2.0 spec section 5.11.3; only periodic transfers need to be 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scheduled in software, this function is only used for such scheduling. 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslong usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount) 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long tmp; 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (speed) { 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case USB_SPEED_LOW: /* INTR only */ 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (is_input) { 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L; 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp); 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L; 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp); 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case USB_SPEED_FULL: /* ISOC or INTR */ 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (isoc) { 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L; 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (((is_input) ? 7268L : 6265L) + BW_HOST_DELAY + tmp); 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L; 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (9107L + BW_HOST_DELAY + tmp); 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case USB_SPEED_HIGH: /* ISOC or INTR */ 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // FIXME adjust for input vs output 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (isoc) 971498f78e6fcf558d0dec31f5648f43426ae16433fDan Streetman tmp = HS_NSECS_ISO (bytecount); 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 973498f78e6fcf558d0dec31f5648f43426ae16433fDan Streetman tmp = HS_NSECS (bytecount); 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return tmp; 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr_debug ("%s: bogus device speed!\n", usbcore_name); 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 980782e70c6fc2290a0395850e8e02583b8b62264d8Greg Kroah-HartmanEXPORT_SYMBOL_GPL(usb_calc_bus_time); 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Generic HC operations. 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 991e9df41c5c5899259541dc928872cad4d07b82076Alan Stern/** 992e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * usb_hcd_link_urb_to_ep - add an URB to its endpoint queue 993e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * @hcd: host controller to which @urb was submitted 994e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * @urb: URB being submitted 995e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * 996e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * Host controller drivers should call this routine in their enqueue() 997e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * method. The HCD's private spinlock must be held and interrupts must 998e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * be disabled. The actions carried out here are required for URB 999e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * submission, as well as for endpoint shutdown and for usb_kill_urb. 1000e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * 1001e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * Returns 0 for no error, otherwise a negative error code (in which case 1002e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * the enqueue() method must fail). If no error occurs but enqueue() fails 1003e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * anyway, it must call usb_hcd_unlink_urb_from_ep() before releasing 1004e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * the private spinlock and returning. 1005e9df41c5c5899259541dc928872cad4d07b82076Alan Stern */ 1006e9df41c5c5899259541dc928872cad4d07b82076Alan Sternint usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb) 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10089a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern int rc = 0; 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1010e9df41c5c5899259541dc928872cad4d07b82076Alan Stern spin_lock(&hcd_urb_list_lock); 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10129a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern /* Check that the URB isn't being killed */ 10139a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern if (unlikely(urb->reject)) { 10149a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern rc = -EPERM; 10159a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern goto done; 10169f6a93f7bbb6d73ca0e43c000f3bbf521cd4f782Pete Zaitcev } 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10189a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern if (unlikely(!urb->ep->enabled)) { 10199a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern rc = -ENOENT; 10209a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern goto done; 10219a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern } 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10236840d2555afd66290be7a39b400b5e66a840b82dAlan Stern if (unlikely(!urb->dev->can_submit)) { 10246840d2555afd66290be7a39b400b5e66a840b82dAlan Stern rc = -EHOSTUNREACH; 10256840d2555afd66290be7a39b400b5e66a840b82dAlan Stern goto done; 10266840d2555afd66290be7a39b400b5e66a840b82dAlan Stern } 10276840d2555afd66290be7a39b400b5e66a840b82dAlan Stern 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 10299a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * Check the host controller's state and add the URB to the 10309a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * endpoint's queue. 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10329a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern switch (hcd->state) { 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case HC_STATE_RUNNING: 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case HC_STATE_RESUMING: 1035eb23105462304fd35571fd0cab1de7aec79a9ec5Alan Stern urb->unlinked = 0; 10369a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern list_add_tail(&urb->urb_list, &urb->ep->urb_list); 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 10399a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern rc = -ESHUTDOWN; 10409a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern goto done; 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10429a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern done: 1043e9df41c5c5899259541dc928872cad4d07b82076Alan Stern spin_unlock(&hcd_urb_list_lock); 10449a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern return rc; 10459a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern} 1046e9df41c5c5899259541dc928872cad4d07b82076Alan SternEXPORT_SYMBOL_GPL(usb_hcd_link_urb_to_ep); 10479a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern 1048e9df41c5c5899259541dc928872cad4d07b82076Alan Stern/** 1049e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * usb_hcd_check_unlink_urb - check whether an URB may be unlinked 1050e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * @hcd: host controller to which @urb was submitted 1051e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * @urb: URB being checked for unlinkability 1052e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * @status: error code to store in @urb if the unlink succeeds 1053e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * 1054e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * Host controller drivers should call this routine in their dequeue() 1055e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * method. The HCD's private spinlock must be held and interrupts must 1056e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * be disabled. The actions carried out here are required for making 1057e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * sure than an unlink is valid. 1058e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * 1059e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * Returns 0 for no error, otherwise a negative error code (in which case 1060e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * the dequeue() method must fail). The possible error codes are: 1061e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * 1062e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * -EIDRM: @urb was not submitted or has already completed. 1063e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * The completion function may not have been called yet. 1064e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * 1065e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * -EBUSY: @urb has already been unlinked. 1066e9df41c5c5899259541dc928872cad4d07b82076Alan Stern */ 1067e9df41c5c5899259541dc928872cad4d07b82076Alan Sternint usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, 10689a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern int status) 10699a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern{ 10709a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern struct list_head *tmp; 10719a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern 10729a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern /* insist the urb is still queued */ 10739a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern list_for_each(tmp, &urb->ep->urb_list) { 10749a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern if (tmp == &urb->urb_list) 10759a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern break; 10769a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern } 1077e9df41c5c5899259541dc928872cad4d07b82076Alan Stern if (tmp != &urb->urb_list) 1078e9df41c5c5899259541dc928872cad4d07b82076Alan Stern return -EIDRM; 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10809a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern /* Any status except -EINPROGRESS means something already started to 10819a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * unlink this URB from the hardware. So there's no more work to do. 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1083eb23105462304fd35571fd0cab1de7aec79a9ec5Alan Stern if (urb->unlinked) 1084e9df41c5c5899259541dc928872cad4d07b82076Alan Stern return -EBUSY; 1085eb23105462304fd35571fd0cab1de7aec79a9ec5Alan Stern urb->unlinked = status; 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10879a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern /* IRQ setup can easily be broken so that USB controllers 10889a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * never get completion IRQs ... maybe even the ones we need to 10899a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * finish unlinking the initial failed usb_set_address() 10909a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * or device descriptor fetch. 10919a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern */ 10929a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) && 10939a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern !is_root_hub(urb->dev)) { 10949a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern dev_warn(hcd->self.controller, "Unlink after no-IRQ? " 10959a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern "Controller is probably using the wrong IRQ.\n"); 10969a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); 10979a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern } 10989a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern 1099e9df41c5c5899259541dc928872cad4d07b82076Alan Stern return 0; 11009a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern} 1101e9df41c5c5899259541dc928872cad4d07b82076Alan SternEXPORT_SYMBOL_GPL(usb_hcd_check_unlink_urb); 11029a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern 1103e9df41c5c5899259541dc928872cad4d07b82076Alan Stern/** 1104e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * usb_hcd_unlink_urb_from_ep - remove an URB from its endpoint queue 1105e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * @hcd: host controller to which @urb was submitted 1106e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * @urb: URB being unlinked 1107e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * 1108e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * Host controller drivers should call this routine before calling 1109e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * usb_hcd_giveback_urb(). The HCD's private spinlock must be held and 1110e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * interrupts must be disabled. The actions carried out here are required 1111e9df41c5c5899259541dc928872cad4d07b82076Alan Stern * for URB completion. 1112e9df41c5c5899259541dc928872cad4d07b82076Alan Stern */ 1113e9df41c5c5899259541dc928872cad4d07b82076Alan Sternvoid usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb) 11149a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern{ 11159a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern /* clear all state linking urb to this dev (and hcd) */ 1116e9df41c5c5899259541dc928872cad4d07b82076Alan Stern spin_lock(&hcd_urb_list_lock); 11179a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern list_del_init(&urb->urb_list); 1118e9df41c5c5899259541dc928872cad4d07b82076Alan Stern spin_unlock(&hcd_urb_list_lock); 11199a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern} 1120e9df41c5c5899259541dc928872cad4d07b82076Alan SternEXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep); 11219a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern 1122b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm/* 1123b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * Some usb host controllers can only perform dma using a small SRAM area. 1124b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * The usb core itself is however optimized for host controllers that can dma 1125b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * using regular system memory - like pci devices doing bus mastering. 1126b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * 1127b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * To support host controllers with limited dma capabilites we provide dma 1128b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * bounce buffers. This feature can be enabled using the HCD_LOCAL_MEM flag. 1129b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * For this to work properly the host controller code must first use the 1130b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * function dma_declare_coherent_memory() to point out which memory area 1131b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * that should be used for dma allocations. 1132b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * 1133b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * The HCD_LOCAL_MEM flag then tells the usb code to allocate all data for 1134b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * dma using dma_alloc_coherent() which in turn allocates from the memory 1135b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * area pointed out with dma_declare_coherent_memory(). 1136b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * 1137b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * So, to summarize... 1138b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * 1139b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * - We need "local" memory, canonical example being 1140b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * a small SRAM on a discrete controller being the 1141b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * only memory that the controller can read ... 1142b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * (a) "normal" kernel memory is no good, and 1143b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * (b) there's not enough to share 1144b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * 1145b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * - The only *portable* hook for such stuff in the 1146b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * DMA framework is dma_declare_coherent_memory() 1147b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * 1148b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * - So we use that, even though the primary requirement 1149b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * is that the memory be "local" (hence addressible 1150b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * by that device), not "coherent". 1151b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * 1152b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm */ 1153b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1154b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Dammstatic int hcd_alloc_coherent(struct usb_bus *bus, 1155b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm gfp_t mem_flags, dma_addr_t *dma_handle, 1156b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm void **vaddr_handle, size_t size, 1157b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm enum dma_data_direction dir) 1158b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm{ 1159b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm unsigned char *vaddr; 1160b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1161b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm vaddr = hcd_buffer_alloc(bus, size + sizeof(vaddr), 1162b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm mem_flags, dma_handle); 1163b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (!vaddr) 1164b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm return -ENOMEM; 1165b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1166b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm /* 1167b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * Store the virtual address of the buffer at the end 1168b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * of the allocated dma buffer. The size of the buffer 1169b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * may be uneven so use unaligned functions instead 1170b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * of just rounding up. It makes sense to optimize for 1171b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * memory footprint over access speed since the amount 1172b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm * of memory available for dma may be limited. 1173b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm */ 1174b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm put_unaligned((unsigned long)*vaddr_handle, 1175b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm (unsigned long *)(vaddr + size)); 1176b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1177b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (dir == DMA_TO_DEVICE) 1178b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm memcpy(vaddr, *vaddr_handle, size); 1179b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1180b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm *vaddr_handle = vaddr; 1181b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm return 0; 1182b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm} 1183b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1184b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Dammstatic void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle, 1185b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm void **vaddr_handle, size_t size, 1186b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm enum dma_data_direction dir) 1187b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm{ 1188b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm unsigned char *vaddr = *vaddr_handle; 1189b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1190b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm vaddr = (void *)get_unaligned((unsigned long *)(vaddr + size)); 1191b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1192b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (dir == DMA_FROM_DEVICE) 1193b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm memcpy(vaddr, *vaddr_handle, size); 1194b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1195b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm hcd_buffer_free(bus, size + sizeof(vaddr), *vaddr_handle, *dma_handle); 1196b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1197b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm *vaddr_handle = vaddr; 1198b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm *dma_handle = 0; 1199b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm} 1200b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1201b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Dammstatic int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, 1202b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm gfp_t mem_flags) 12039a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern{ 1204b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm enum dma_data_direction dir; 1205b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm int ret = 0; 1206b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 12079a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern /* Map the URB's buffers for DMA access. 12089a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * Lower level HCD code should use *_dma exclusively, 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unless it uses pio or talks to another transport. 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1211b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (is_root_hub(urb->dev)) 1212b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm return 0; 1213b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1214b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (usb_endpoint_xfer_control(&urb->ep->desc) 1215b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { 1216b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (hcd->self.uses_dma) 1217b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm urb->setup_dma = dma_map_single( 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->self.controller, 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds urb->setup_packet, 1220b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm sizeof(struct usb_ctrlrequest), 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DMA_TO_DEVICE); 1222b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm else if (hcd->driver->flags & HCD_LOCAL_MEM) 1223b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm ret = hcd_alloc_coherent( 1224b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm urb->dev->bus, mem_flags, 1225b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm &urb->setup_dma, 1226b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm (void **)&urb->setup_packet, 1227b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm sizeof(struct usb_ctrlrequest), 1228b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm DMA_TO_DEVICE); 1229b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm } 1230b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1231b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; 1232b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (ret == 0 && urb->transfer_buffer_length != 0 1233b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { 1234b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (hcd->self.uses_dma) 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds urb->transfer_dma = dma_map_single ( 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->self.controller, 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds urb->transfer_buffer, 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds urb->transfer_buffer_length, 1239b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm dir); 1240b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm else if (hcd->driver->flags & HCD_LOCAL_MEM) { 1241b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm ret = hcd_alloc_coherent( 1242b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm urb->dev->bus, mem_flags, 1243b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm &urb->transfer_dma, 1244b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm &urb->transfer_buffer, 1245b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm urb->transfer_buffer_length, 1246b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm dir); 1247b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1248b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (ret && usb_endpoint_xfer_control(&urb->ep->desc) 1249b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) 1250b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm hcd_free_coherent(urb->dev->bus, 1251b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm &urb->setup_dma, 1252b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm (void **)&urb->setup_packet, 1253b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm sizeof(struct usb_ctrlrequest), 1254b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm DMA_TO_DEVICE); 1255b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm } 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1257b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm return ret; 12589a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern} 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12609a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Sternstatic void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) 12619a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern{ 1262b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm enum dma_data_direction dir; 1263b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1264b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (is_root_hub(urb->dev)) 1265b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm return; 1266b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1267b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (usb_endpoint_xfer_control(&urb->ep->desc) 1268b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { 1269b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (hcd->self.uses_dma) 12709a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern dma_unmap_single(hcd->self.controller, urb->setup_dma, 12719a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern sizeof(struct usb_ctrlrequest), 12729a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern DMA_TO_DEVICE); 1273b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm else if (hcd->driver->flags & HCD_LOCAL_MEM) 1274b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm hcd_free_coherent(urb->dev->bus, &urb->setup_dma, 1275b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm (void **)&urb->setup_packet, 1276b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm sizeof(struct usb_ctrlrequest), 1277b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm DMA_TO_DEVICE); 1278b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm } 1279b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1280b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; 1281b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (urb->transfer_buffer_length != 0 1282b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { 1283b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (hcd->self.uses_dma) 12849a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern dma_unmap_single(hcd->self.controller, 12859a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern urb->transfer_dma, 12869a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern urb->transfer_buffer_length, 1287b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm dir); 1288b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm else if (hcd->driver->flags & HCD_LOCAL_MEM) 1289b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm hcd_free_coherent(urb->dev->bus, &urb->transfer_dma, 1290b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm &urb->transfer_buffer, 1291b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm urb->transfer_buffer_length, 1292b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm dir); 12939a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern } 12949a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern} 12959a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern 12969a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern/*-------------------------------------------------------------------------*/ 12979a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern 12989a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern/* may be called in any context with a valid urb->dev usecount 12999a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * caller surrenders "ownership" of urb 13009a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * expects usb_submit_urb() to have sanity checked and conditioned all 13019a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * inputs in the urb 13029a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern */ 13039a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Sternint usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) 13049a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern{ 13059a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern int status; 13069a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); 13079a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern 13089a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern /* increment urb's reference count as part of giving it to the HCD 13099a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * (which will control it). HCD guarantees that it either returns 13109a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * an error or calls giveback(), but not both. 13119a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern */ 13129a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern usb_get_urb(urb); 13139a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern atomic_inc(&urb->use_count); 13144d59d8a11383ebf0e0260ee481a4e766959fd7d9Sarah Sharp atomic_inc(&urb->dev->urbnum); 13159a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern usbmon_urb_submit(&hcd->self, urb); 13169a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern 13179a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern /* NOTE requirements on root-hub callers (usbfs and the hub 13189a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * driver, for now): URBs' urb->transfer_buffer must be 13199a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * valid and usb_buffer_{sync,unmap}() not be needed, since 13209a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * they could clobber root hub response data. Also, control 13219a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * URBs must be submitted in process context with interrupts 13229a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern * enabled. 13239a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern */ 1324b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm status = map_urb_for_dma(hcd, urb, mem_flags); 1325b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm if (unlikely(status)) { 1326b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm usbmon_urb_submit_error(&hcd->self, urb, status); 1327b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm goto error; 1328b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm } 1329b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm 1330e9df41c5c5899259541dc928872cad4d07b82076Alan Stern if (is_root_hub(urb->dev)) 1331e9df41c5c5899259541dc928872cad4d07b82076Alan Stern status = rh_urb_enqueue(hcd, urb); 1332e9df41c5c5899259541dc928872cad4d07b82076Alan Stern else 1333e9df41c5c5899259541dc928872cad4d07b82076Alan Stern status = hcd->driver->urb_enqueue(hcd, urb, mem_flags); 13349a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern 13359a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern if (unlikely(status)) { 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usbmon_urb_submit_error(&hcd->self, urb, status); 13379a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern unmap_urb_for_dma(hcd, urb); 1338b3476675320eda83cf061a686cdc80b76f2bfdc4Magnus Damm error: 1339b0d9efba3ec53468984aecef8eeaf079089f2e5aAlan Stern urb->hcpriv = NULL; 13409a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern INIT_LIST_HEAD(&urb->urb_list); 13419a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern atomic_dec(&urb->use_count); 13424d59d8a11383ebf0e0260ee481a4e766959fd7d9Sarah Sharp atomic_dec(&urb->dev->urbnum); 13439a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern if (urb->reject) 13449a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern wake_up(&usb_kill_urb_queue); 13459a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern usb_put_urb(urb); 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return status; 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 13511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this makes the hcd giveback() the urb more quickly, by kicking it 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * off hardware queues (which may take a while) and returning it as 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * soon as practical. we've already set up the urb's return status, 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but we can't know if the callback completed already. 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1357e9df41c5c5899259541dc928872cad4d07b82076Alan Sternstatic int unlink1(struct usb_hcd *hcd, struct urb *urb, int status) 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int value; 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1361809a58b896ba07e771adc76a47c83e4ca1969da8Alan Stern if (is_root_hub(urb->dev)) 1362e9df41c5c5899259541dc928872cad4d07b82076Alan Stern value = usb_rh_urb_dequeue(hcd, urb, status); 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* The only reason an HCD might fail this call is if 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it has not yet fully queued the urb to begin with. 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Such failures should be harmless. */ 1368e9df41c5c5899259541dc928872cad4d07b82076Alan Stern value = hcd->driver->urb_dequeue(hcd, urb, status); 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return value; 13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * called in any context 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * caller guarantees urb won't be recycled till both unlink() 13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and the urb's completion function return 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1379a6d2bb9ff919b4685bd684620ec7a1ffa8bf2349Alan Sternint usb_hcd_unlink_urb (struct urb *urb, int status) 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13819a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern struct usb_hcd *hcd; 1382cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern int retval = -EIDRM; 1383cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern unsigned long flags; 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1385cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern /* Prevent the device and bus from going away while 1386cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern * the unlink is carried out. If they are already gone 1387cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern * then urb->use_count must be 0, since disconnected 1388cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern * devices can't have any active URBs. 1389cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern */ 1390cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern spin_lock_irqsave(&hcd_urb_unlink_lock, flags); 1391cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern if (atomic_read(&urb->use_count) > 0) { 1392cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern retval = 0; 1393cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern usb_get_dev(urb->dev); 1394cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern } 1395cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern spin_unlock_irqrestore(&hcd_urb_unlink_lock, flags); 1396cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern if (retval == 0) { 1397cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern hcd = bus_to_hcd(urb->dev->bus); 1398cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern retval = unlink1(hcd, urb, status); 1399cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern usb_put_dev(urb->dev); 1400cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern } 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval == 0) 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -EINPROGRESS; 1404e9df41c5c5899259541dc928872cad4d07b82076Alan Stern else if (retval != -EIDRM && retval != -EBUSY) 14059a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern dev_dbg(&urb->dev->dev, "hcd_unlink_urb %p fail %d\n", 14069a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern urb, retval); 14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141232aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern/** 141332aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern * usb_hcd_giveback_urb - return URB from HCD to device driver 141432aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern * @hcd: host controller returning the URB 141532aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern * @urb: urb being returned to the USB device driver. 14164a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Stern * @status: completion status code for the URB. 141732aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern * Context: in_interrupt() 141832aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern * 141932aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern * This hands the URB from HCD to its USB device driver, using its 142032aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern * completion function. The HCD has freed all per-urb resources 142132aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern * (and is done using urb->hcpriv). It also released all HCD locks; 142232aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern * the device driver won't cause problems if it frees, modifies, 142332aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern * or resubmits this URB. 1424eb23105462304fd35571fd0cab1de7aec79a9ec5Alan Stern * 14254a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Stern * If @urb was unlinked, the value of @status will be overridden by 1426eb23105462304fd35571fd0cab1de7aec79a9ec5Alan Stern * @urb->unlinked. Erroneous short transfers are detected in case 1427eb23105462304fd35571fd0cab1de7aec79a9ec5Alan Stern * the HCD hasn't checked for them. 142832aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern */ 14294a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Sternvoid usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) 143032aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern{ 1431b0d9efba3ec53468984aecef8eeaf079089f2e5aAlan Stern urb->hcpriv = NULL; 1432eb23105462304fd35571fd0cab1de7aec79a9ec5Alan Stern if (unlikely(urb->unlinked)) 14334a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Stern status = urb->unlinked; 1434eb23105462304fd35571fd0cab1de7aec79a9ec5Alan Stern else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && 1435b0d9efba3ec53468984aecef8eeaf079089f2e5aAlan Stern urb->actual_length < urb->transfer_buffer_length && 14364a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Stern !status)) 14374a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Stern status = -EREMOTEIO; 143832aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern 14391f5a3d0f34fd5719081c6b8f3dbbcbe328d4da31Alan Stern unmap_urb_for_dma(hcd, urb); 14404a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Stern usbmon_urb_complete(&hcd->self, urb, status); 14411f5a3d0f34fd5719081c6b8f3dbbcbe328d4da31Alan Stern usb_unanchor_urb(urb); 14421f5a3d0f34fd5719081c6b8f3dbbcbe328d4da31Alan Stern 144332aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern /* pass ownership to the completion handler */ 14444a00027dcb088bf90fa8fb14a7e8ba3506d78f22Alan Stern urb->status = status; 144532aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern urb->complete (urb); 144632aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern atomic_dec (&urb->use_count); 144732aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern if (unlikely (urb->reject)) 144832aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern wake_up (&usb_kill_urb_queue); 144932aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern usb_put_urb (urb); 145032aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern} 1451782e70c6fc2290a0395850e8e02583b8b62264d8Greg Kroah-HartmanEXPORT_SYMBOL_GPL(usb_hcd_giveback_urb); 145232aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern 145332aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern/*-------------------------------------------------------------------------*/ 145432aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern 145595cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern/* Cancel all URBs pending on this endpoint and wait for the endpoint's 145695cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern * queue to drain completely. The caller must first insure that no more 145795cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern * URBs can be submitted for this endpoint. 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 145995cf82f99cfbd697c15572c444bd4f54f19745b0Alan Sternvoid usb_hcd_flush_endpoint(struct usb_device *udev, 1460a6d2bb9ff919b4685bd684620ec7a1ffa8bf2349Alan Stern struct usb_host_endpoint *ep) 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct usb_hcd *hcd; 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct urb *urb; 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 146595cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern if (!ep) 146695cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern return; 14679a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern might_sleep(); 14681720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern hcd = bus_to_hcd(udev->bus); 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 147095cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern /* No more submits can occur */ 14719a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern spin_lock_irq(&hcd_urb_list_lock); 1472ddc1fd6ac1f3ad3275e19451fb07d2eff249161cAlan Sternrescan: 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds list_for_each_entry (urb, &ep->urb_list, urb_list) { 14745e60a16139c2a48b9876b0ff910671eee5fb32ecAlan Stern int is_in; 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1476eb23105462304fd35571fd0cab1de7aec79a9ec5Alan Stern if (urb->unlinked) 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_get_urb (urb); 14795e60a16139c2a48b9876b0ff910671eee5fb32ecAlan Stern is_in = usb_urb_dir_in(urb); 1480809a58b896ba07e771adc76a47c83e4ca1969da8Alan Stern spin_unlock(&hcd_urb_list_lock); 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1482e9df41c5c5899259541dc928872cad4d07b82076Alan Stern /* kick hcd */ 1483e9df41c5c5899259541dc928872cad4d07b82076Alan Stern unlink1(hcd, urb, -ESHUTDOWN); 1484e9df41c5c5899259541dc928872cad4d07b82076Alan Stern dev_dbg (hcd->self.controller, 1485e9df41c5c5899259541dc928872cad4d07b82076Alan Stern "shutdown urb %p ep%d%s%s\n", 1486e9df41c5c5899259541dc928872cad4d07b82076Alan Stern urb, usb_endpoint_num(&ep->desc), 1487e9df41c5c5899259541dc928872cad4d07b82076Alan Stern is_in ? "in" : "out", 1488e9df41c5c5899259541dc928872cad4d07b82076Alan Stern ({ char *s; 1489e9df41c5c5899259541dc928872cad4d07b82076Alan Stern 1490e9df41c5c5899259541dc928872cad4d07b82076Alan Stern switch (usb_endpoint_type(&ep->desc)) { 1491e9df41c5c5899259541dc928872cad4d07b82076Alan Stern case USB_ENDPOINT_XFER_CONTROL: 1492e9df41c5c5899259541dc928872cad4d07b82076Alan Stern s = ""; break; 1493e9df41c5c5899259541dc928872cad4d07b82076Alan Stern case USB_ENDPOINT_XFER_BULK: 1494e9df41c5c5899259541dc928872cad4d07b82076Alan Stern s = "-bulk"; break; 1495e9df41c5c5899259541dc928872cad4d07b82076Alan Stern case USB_ENDPOINT_XFER_INT: 1496e9df41c5c5899259541dc928872cad4d07b82076Alan Stern s = "-intr"; break; 1497e9df41c5c5899259541dc928872cad4d07b82076Alan Stern default: 1498e9df41c5c5899259541dc928872cad4d07b82076Alan Stern s = "-iso"; break; 1499e9df41c5c5899259541dc928872cad4d07b82076Alan Stern }; 1500e9df41c5c5899259541dc928872cad4d07b82076Alan Stern s; 1501e9df41c5c5899259541dc928872cad4d07b82076Alan Stern })); 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_put_urb (urb); 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* list contents may have changed */ 1505ddc1fd6ac1f3ad3275e19451fb07d2eff249161cAlan Stern spin_lock(&hcd_urb_list_lock); 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto rescan; 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15089a9bf406df3ce238089d14f4cb41157ca56d8ad3Alan Stern spin_unlock_irq(&hcd_urb_list_lock); 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 151095cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern /* Wait until the endpoint queue is completely empty */ 1511455b25fb209c8241e2163b491228b28667d82c1cAlan Stern while (!list_empty (&ep->urb_list)) { 1512809a58b896ba07e771adc76a47c83e4ca1969da8Alan Stern spin_lock_irq(&hcd_urb_list_lock); 1513455b25fb209c8241e2163b491228b28667d82c1cAlan Stern 1514455b25fb209c8241e2163b491228b28667d82c1cAlan Stern /* The list may have changed while we acquired the spinlock */ 1515455b25fb209c8241e2163b491228b28667d82c1cAlan Stern urb = NULL; 1516455b25fb209c8241e2163b491228b28667d82c1cAlan Stern if (!list_empty (&ep->urb_list)) { 1517455b25fb209c8241e2163b491228b28667d82c1cAlan Stern urb = list_entry (ep->urb_list.prev, struct urb, 1518455b25fb209c8241e2163b491228b28667d82c1cAlan Stern urb_list); 1519455b25fb209c8241e2163b491228b28667d82c1cAlan Stern usb_get_urb (urb); 1520455b25fb209c8241e2163b491228b28667d82c1cAlan Stern } 1521809a58b896ba07e771adc76a47c83e4ca1969da8Alan Stern spin_unlock_irq(&hcd_urb_list_lock); 1522455b25fb209c8241e2163b491228b28667d82c1cAlan Stern 1523455b25fb209c8241e2163b491228b28667d82c1cAlan Stern if (urb) { 1524455b25fb209c8241e2163b491228b28667d82c1cAlan Stern usb_kill_urb (urb); 1525455b25fb209c8241e2163b491228b28667d82c1cAlan Stern usb_put_urb (urb); 1526455b25fb209c8241e2163b491228b28667d82c1cAlan Stern } 1527455b25fb209c8241e2163b491228b28667d82c1cAlan Stern } 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 153095cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern/* Disables the endpoint: synchronizes with the hcd to make sure all 153195cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern * endpoint state is gone from hardware. usb_hcd_flush_endpoint() must 153295cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern * have been called previously. Use for set_configuration, set_interface, 153395cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern * driver removal, physical disconnect. 153495cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern * 153595cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern * example: a qh stored in ep->hcpriv, holding state related to endpoint 153695cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern * type, maxpacket size, toggle, halt status, and scheduling. 153795cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern */ 153895cf82f99cfbd697c15572c444bd4f54f19745b0Alan Sternvoid usb_hcd_disable_endpoint(struct usb_device *udev, 153995cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern struct usb_host_endpoint *ep) 154095cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern{ 154195cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern struct usb_hcd *hcd; 154295cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern 154395cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern might_sleep(); 154495cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern hcd = bus_to_hcd(udev->bus); 154595cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern if (hcd->driver->endpoint_disable) 154695cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern hcd->driver->endpoint_disable(hcd, ep); 154795cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern} 154895cf82f99cfbd697c15572c444bd4f54f19745b0Alan Stern 1549cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern/* Protect against drivers that try to unlink URBs after the device 1550cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern * is gone, by waiting until all unlinks for @udev are finished. 1551cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern * Since we don't currently track URBs by device, simply wait until 1552cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern * nothing is running in the locked region of usb_hcd_unlink_urb(). 1553cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern */ 1554cde217a556ec552d28ac9e136c5a94684a69ae94Alan Sternvoid usb_hcd_synchronize_unlinks(struct usb_device *udev) 1555cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern{ 1556cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern spin_lock_irq(&hcd_urb_unlink_lock); 1557cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern spin_unlock_irq(&hcd_urb_unlink_lock); 1558cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern} 1559cde217a556ec552d28ac9e136c5a94684a69ae94Alan Stern 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 156232aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern/* called in any context */ 156332aca5600526189dd876e6c92b64fd88cf052c8dAlan Sternint usb_hcd_get_frame_number (struct usb_device *udev) 156432aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern{ 156532aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern struct usb_hcd *hcd = bus_to_hcd(udev->bus); 156632aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern 156732aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern if (!HC_IS_RUNNING (hcd->state)) 156832aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern return -ESHUTDOWN; 156932aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern return hcd->driver->get_frame_number (hcd); 157032aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern} 157132aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern 157232aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern/*-------------------------------------------------------------------------*/ 157332aca5600526189dd876e6c92b64fd88cf052c8dAlan Stern 15749293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell#ifdef CONFIG_PM 15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1576686314cfbdac21c9019c0e04487b5d940db62406Alan Sternint hcd_bus_suspend(struct usb_device *rhdev) 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1578686314cfbdac21c9019c0e04487b5d940db62406Alan Stern struct usb_hcd *hcd = container_of(rhdev->bus, struct usb_hcd, self); 1579686314cfbdac21c9019c0e04487b5d940db62406Alan Stern int status; 1580686314cfbdac21c9019c0e04487b5d940db62406Alan Stern int old_state = hcd->state; 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1582686314cfbdac21c9019c0e04487b5d940db62406Alan Stern dev_dbg(&rhdev->dev, "bus %s%s\n", 1583686314cfbdac21c9019c0e04487b5d940db62406Alan Stern rhdev->auto_pm ? "auto-" : "", "suspend"); 1584686314cfbdac21c9019c0e04487b5d940db62406Alan Stern if (!hcd->driver->bus_suspend) { 1585686314cfbdac21c9019c0e04487b5d940db62406Alan Stern status = -ENOENT; 1586686314cfbdac21c9019c0e04487b5d940db62406Alan Stern } else { 1587686314cfbdac21c9019c0e04487b5d940db62406Alan Stern hcd->state = HC_STATE_QUIESCING; 1588686314cfbdac21c9019c0e04487b5d940db62406Alan Stern status = hcd->driver->bus_suspend(hcd); 1589686314cfbdac21c9019c0e04487b5d940db62406Alan Stern } 1590686314cfbdac21c9019c0e04487b5d940db62406Alan Stern if (status == 0) { 1591686314cfbdac21c9019c0e04487b5d940db62406Alan Stern usb_set_device_state(rhdev, USB_STATE_SUSPENDED); 15929293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell hcd->state = HC_STATE_SUSPENDED; 1593686314cfbdac21c9019c0e04487b5d940db62406Alan Stern } else { 1594686314cfbdac21c9019c0e04487b5d940db62406Alan Stern hcd->state = old_state; 1595686314cfbdac21c9019c0e04487b5d940db62406Alan Stern dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", 15969293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell "suspend", status); 1597686314cfbdac21c9019c0e04487b5d940db62406Alan Stern } 15989293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell return status; 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1601686314cfbdac21c9019c0e04487b5d940db62406Alan Sternint hcd_bus_resume(struct usb_device *rhdev) 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1603686314cfbdac21c9019c0e04487b5d940db62406Alan Stern struct usb_hcd *hcd = container_of(rhdev->bus, struct usb_hcd, self); 1604686314cfbdac21c9019c0e04487b5d940db62406Alan Stern int status; 1605cfa59dab27d1b282886e7772a8f9548236883892Alan Stern int old_state = hcd->state; 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1607686314cfbdac21c9019c0e04487b5d940db62406Alan Stern dev_dbg(&rhdev->dev, "usb %s%s\n", 1608686314cfbdac21c9019c0e04487b5d940db62406Alan Stern rhdev->auto_pm ? "auto-" : "", "resume"); 16090c0382e32d46f606951010b202382be14d180a17Alan Stern if (!hcd->driver->bus_resume) 16109293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell return -ENOENT; 1611979d5199fee9e80290ddeb532e5993bd15506712David Brownell if (hcd->state == HC_STATE_RUNNING) 1612979d5199fee9e80290ddeb532e5993bd15506712David Brownell return 0; 1613686314cfbdac21c9019c0e04487b5d940db62406Alan Stern 16149293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell hcd->state = HC_STATE_RESUMING; 1615686314cfbdac21c9019c0e04487b5d940db62406Alan Stern status = hcd->driver->bus_resume(hcd); 1616686314cfbdac21c9019c0e04487b5d940db62406Alan Stern if (status == 0) { 1617686314cfbdac21c9019c0e04487b5d940db62406Alan Stern /* TRSMRCY = 10 msec */ 1618686314cfbdac21c9019c0e04487b5d940db62406Alan Stern msleep(10); 1619686314cfbdac21c9019c0e04487b5d940db62406Alan Stern usb_set_device_state(rhdev, rhdev->actconfig 1620686314cfbdac21c9019c0e04487b5d940db62406Alan Stern ? USB_STATE_CONFIGURED 1621686314cfbdac21c9019c0e04487b5d940db62406Alan Stern : USB_STATE_ADDRESS); 16229293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell hcd->state = HC_STATE_RUNNING; 1623686314cfbdac21c9019c0e04487b5d940db62406Alan Stern } else { 1624cfa59dab27d1b282886e7772a8f9548236883892Alan Stern hcd->state = old_state; 1625686314cfbdac21c9019c0e04487b5d940db62406Alan Stern dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", 16269293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell "resume", status); 1627cfa59dab27d1b282886e7772a8f9548236883892Alan Stern if (status != -ESHUTDOWN) 1628cfa59dab27d1b282886e7772a8f9548236883892Alan Stern usb_hc_died(hcd); 16299293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell } 16309293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell return status; 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16336b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern/* Workqueue routine for root-hub remote wakeup */ 16346b157c9bf3bace6eeb4a973da63923ef24995cceAlan Sternstatic void hcd_resume_work(struct work_struct *work) 16356b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern{ 16366b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern struct usb_hcd *hcd = container_of(work, struct usb_hcd, wakeup_work); 16376b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern struct usb_device *udev = hcd->self.root_hub; 16386b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern 16396b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern usb_lock_device(udev); 16401941044aa9632aa8debbb94a3c8a5ed0ebddade8Alan Stern usb_mark_last_busy(udev); 16416b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern usb_external_resume_device(udev); 16426b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern usb_unlock_device(udev); 16436b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern} 16446b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern 16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_hcd_resume_root_hub - called by HCD to resume its root hub 16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @hcd: host controller for this root hub 16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The USB host controller calls this function when its root hub is 16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * suspended (with the remote wakeup feature enabled) and a remote 16516b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern * wakeup request is received. The routine submits a workqueue request 16526b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern * to resume the root hub (that is, manage its downstream ports again). 16531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 16541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid usb_hcd_resume_root_hub (struct usb_hcd *hcd) 16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave (&hcd_root_hub_lock, flags); 16591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hcd->rh_registered) 16606b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern queue_work(ksuspend_usb_wq, &hcd->wakeup_work); 16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore (&hcd_root_hub_lock, flags); 16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16639293677af3dace2645dec0d0808efa02d36bf47bDavid BrownellEXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); 16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_USB_OTG 16701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_bus_start_enum - start immediate enumeration (for OTG) 16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @bus: the bus (must use hcd framework) 16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @port_num: 1-based number of port; usually bus->otg_port 16751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: in_interrupt() 16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Starts enumeration, with an immediate reset followed later by 16781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * khubd identifying and possibly configuring the device. 16791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is needed by OTG controller drivers, where it helps meet 16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HNP protocol timing requirements for starting a port reset. 16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 16821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint usb_bus_start_enum(struct usb_bus *bus, unsigned port_num) 16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct usb_hcd *hcd; 16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int status = -EOPNOTSUPP; 16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* NOTE: since HNP can't start by grabbing the bus's address0_sem, 16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * boards with root hubs hooked up to internal devices (instead of 16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * just the OTG port) may need more attention to resetting... 16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd = container_of (bus, struct usb_hcd, self); 16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (port_num && hcd->driver->start_port_reset) 16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = hcd->driver->start_port_reset(hcd, port_num); 16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* run khubd shortly after (first) root port reset finishes; 16961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it may issue others, until at least 50 msecs have passed. 16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status == 0) 16991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(10)); 17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return status; 17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1702782e70c6fc2290a0395850e8e02583b8b62264d8Greg Kroah-HartmanEXPORT_SYMBOL_GPL(usb_bus_start_enum); 17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_hcd_irq - hook IRQs to HCD framework (bus glue) 17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @irq: the IRQ being raised 17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @__hcd: pointer to the HCD whose IRQ is being signaled 17121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 17131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the controller isn't HALTed, calls the driver's irq handler. 17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Checks whether the controller is now dead. 17151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 17167d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsirqreturn_t usb_hcd_irq (int irq, void *__hcd) 17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct usb_hcd *hcd = __hcd; 1719de85422b94ddb23c021126815ea49414047c13dcStefan Becker unsigned long flags; 1720de85422b94ddb23c021126815ea49414047c13dcStefan Becker irqreturn_t rc; 17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1722de85422b94ddb23c021126815ea49414047c13dcStefan Becker /* IRQF_DISABLED doesn't work correctly with shared IRQs 1723de85422b94ddb23c021126815ea49414047c13dcStefan Becker * when the first handler doesn't use it. So let's just 1724de85422b94ddb23c021126815ea49414047c13dcStefan Becker * assume it's never used. 1725de85422b94ddb23c021126815ea49414047c13dcStefan Becker */ 1726de85422b94ddb23c021126815ea49414047c13dcStefan Becker local_irq_save(flags); 17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1728de85422b94ddb23c021126815ea49414047c13dcStefan Becker if (unlikely(hcd->state == HC_STATE_HALT || 1729de85422b94ddb23c021126815ea49414047c13dcStefan Becker !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) { 1730de85422b94ddb23c021126815ea49414047c13dcStefan Becker rc = IRQ_NONE; 1731de85422b94ddb23c021126815ea49414047c13dcStefan Becker } else if (hcd->driver->irq(hcd) == IRQ_NONE) { 1732de85422b94ddb23c021126815ea49414047c13dcStefan Becker rc = IRQ_NONE; 1733de85422b94ddb23c021126815ea49414047c13dcStefan Becker } else { 1734de85422b94ddb23c021126815ea49414047c13dcStefan Becker set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); 17358de98402652c01839ae321be6cb3054cf5735d83Benjamin Herrenschmidt 1736de85422b94ddb23c021126815ea49414047c13dcStefan Becker if (unlikely(hcd->state == HC_STATE_HALT)) 1737de85422b94ddb23c021126815ea49414047c13dcStefan Becker usb_hc_died(hcd); 1738de85422b94ddb23c021126815ea49414047c13dcStefan Becker rc = IRQ_HANDLED; 1739de85422b94ddb23c021126815ea49414047c13dcStefan Becker } 1740de85422b94ddb23c021126815ea49414047c13dcStefan Becker 1741de85422b94ddb23c021126815ea49414047c13dcStefan Becker local_irq_restore(flags); 1742de85422b94ddb23c021126815ea49414047c13dcStefan Becker return rc; 17431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 17461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 17481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_hc_died - report abnormal shutdown of a host controller (bus glue) 17491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @hcd: pointer to the HCD representing the controller 17501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is called by bus glue to report a USB host controller that died 17521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * while operations may still have been pending. It's called automatically 17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * by the PCI glue, so only glue for non-PCI busses should need to call it. 17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid usb_hc_died (struct usb_hcd *hcd) 17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_err (hcd->self.controller, "HC died; cleaning up\n"); 17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave (&hcd_root_hub_lock, flags); 17621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hcd->rh_registered) { 1763d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern hcd->poll_rh = 0; 17641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* make khubd clean up old urbs and devices */ 17661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_set_device_state (hcd->self.root_hub, 17671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds USB_STATE_NOTATTACHED); 17681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_kick_khubd (hcd->self.root_hub); 17691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore (&hcd_root_hub_lock, flags); 17711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL (usb_hc_died); 17731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 17751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 17771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_create_hcd - create and initialize an HCD structure 17781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @driver: HC driver that will use this hcd 17791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: device for this HC, stored in hcd->self.controller 17801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @bus_name: value to store in hcd->self.bus_name 17811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: !in_interrupt() 17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Allocate a struct usb_hcd, with extra space at the end for the 17841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HC driver's private data. Initialize the generic members of the 17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hcd structure. 17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 17871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If memory is unavailable, returns NULL. 17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct usb_hcd *usb_create_hcd (const struct hc_driver *driver, 17901b26da1510c02a2dac33c0ea48904256dcec4617Greg Kroah-Hartman struct device *dev, const char *bus_name) 17911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct usb_hcd *hcd; 17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17947b842b6e3704f4b9606ff8a4ffe03579d9addf5ePekka Enberg hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL); 17951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!hcd) { 17961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_dbg (dev, "hcd alloc failed\n"); 17971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 17981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_set_drvdata(dev, hcd); 18001720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern kref_init(&hcd->kref); 18011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_bus_init(&hcd->self); 18031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->self.controller = dev; 18041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->self.bus_name = bus_name; 1805dd990f16a39d4e615c0b70a0ab50b79b32bfb16dAlan Stern hcd->self.uses_dma = (dev->dma_mask != NULL); 18061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_timer(&hcd->rh_timer); 1808d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern hcd->rh_timer.function = rh_timer_func; 1809d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern hcd->rh_timer.data = (unsigned long) hcd; 18106b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern#ifdef CONFIG_PM 18116b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern INIT_WORK(&hcd->wakeup_work, hcd_resume_work); 18126b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern#endif 18131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->driver = driver; 18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->product_desc = (driver->product_desc) ? driver->product_desc : 18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "USB Host Controller"; 18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return hcd; 18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1819782e70c6fc2290a0395850e8e02583b8b62264d8Greg Kroah-HartmanEXPORT_SYMBOL_GPL(usb_create_hcd); 18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18211720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Sternstatic void hcd_release (struct kref *kref) 18221720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern{ 18231720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref); 18241720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern 18251720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern kfree(hcd); 18261720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern} 18271720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern 18281720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Sternstruct usb_hcd *usb_get_hcd (struct usb_hcd *hcd) 18291720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern{ 18301720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern if (hcd) 18311720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern kref_get (&hcd->kref); 18321720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern return hcd; 18331720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern} 1834782e70c6fc2290a0395850e8e02583b8b62264d8Greg Kroah-HartmanEXPORT_SYMBOL_GPL(usb_get_hcd); 18351720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern 18361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid usb_put_hcd (struct usb_hcd *hcd) 18371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18381720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern if (hcd) 18391720058343fa43a1a25bfad9e62ea06e7e9743b6Alan Stern kref_put (&hcd->kref, hcd_release); 18401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1841782e70c6fc2290a0395850e8e02583b8b62264d8Greg Kroah-HartmanEXPORT_SYMBOL_GPL(usb_put_hcd); 18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_add_hcd - finish generic HCD structure initialization and register 18451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @hcd: the usb_hcd structure to initialize 18461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @irqnum: Interrupt line to allocate 18471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @irqflags: Interrupt type flags 18481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Finish the remaining parts of generic HCD initialization: allocate the 18501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * buffers of consistent memory, register the bus, request the IRQ line, 18511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and call the driver's reset() and start() routines. 18521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 18531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint usb_add_hcd(struct usb_hcd *hcd, 18541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int irqnum, unsigned long irqflags) 18551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18568ec8d20b21f00a36343ca0ebd6c6be9421724a1eAlan Stern int retval; 18578ec8d20b21f00a36343ca0ebd6c6be9421724a1eAlan Stern struct usb_device *rhdev; 18581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_info(hcd->self.controller, "%s\n", hcd->product_desc); 18601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18615234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez hcd->authorized_default = hcd->wireless? 0 : 1; 18628de98402652c01839ae321be6cb3054cf5735d83Benjamin Herrenschmidt set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 18638de98402652c01839ae321be6cb3054cf5735d83Benjamin Herrenschmidt 1864b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell /* HC is in reset state, but accessible. Now do the one-time init, 1865b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell * bottom up so that hcds can customize the root hubs before khubd 1866b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell * starts talking to them. (Note, bus id is assigned early too.) 1867b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell */ 18681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((retval = hcd_buffer_create(hcd)) != 0) { 18691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_dbg(hcd->self.controller, "pool alloc failed\n"); 18701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 18711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((retval = usb_register_bus(&hcd->self)) < 0) 18748ec8d20b21f00a36343ca0ebd6c6be9421724a1eAlan Stern goto err_register_bus; 18751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1876b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) { 1877b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell dev_err(hcd->self.controller, "unable to allocate root hub\n"); 1878b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell retval = -ENOMEM; 1879b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell goto err_allocate_root_hub; 1880b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell } 1881b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : 1882b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell USB_SPEED_FULL; 1883b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell hcd->self.root_hub = rhdev; 1884b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell 1885db4cefaaea4c6d67cdaebfd315abc791c5c9d22fDavid Brownell /* wakeup flag init defaults to "everything works" for root hubs, 1886db4cefaaea4c6d67cdaebfd315abc791c5c9d22fDavid Brownell * but drivers can override it in reset() if needed, along with 1887db4cefaaea4c6d67cdaebfd315abc791c5c9d22fDavid Brownell * recording the overall controller's system wakeup capability. 1888db4cefaaea4c6d67cdaebfd315abc791c5c9d22fDavid Brownell */ 1889db4cefaaea4c6d67cdaebfd315abc791c5c9d22fDavid Brownell device_init_wakeup(&rhdev->dev, 1); 1890db4cefaaea4c6d67cdaebfd315abc791c5c9d22fDavid Brownell 1891b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell /* "reset" is misnamed; its role is now one-time init. the controller 1892b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell * should already have been reset (and boot firmware kicked off etc). 1893b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell */ 1894b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) { 1895b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell dev_err(hcd->self.controller, "can't setup\n"); 1896b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell goto err_hcd_driver_setup; 1897b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell } 1898b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell 1899fb669cc01ed778c4926f395e44a9b61644597d38David Brownell /* NOTE: root hub and controller capabilities may not be the same */ 1900fb669cc01ed778c4926f395e44a9b61644597d38David Brownell if (device_can_wakeup(hcd->self.controller) 1901fb669cc01ed778c4926f395e44a9b61644597d38David Brownell && device_can_wakeup(&hcd->self.root_hub->dev)) 1902b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); 1903b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell 1904b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell /* enable irqs just before we start the controller */ 19051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hcd->driver->irq) { 1906de85422b94ddb23c021126815ea49414047c13dcStefan Becker 1907de85422b94ddb23c021126815ea49414047c13dcStefan Becker /* IRQF_DISABLED doesn't work as advertised when used together 1908de85422b94ddb23c021126815ea49414047c13dcStefan Becker * with IRQF_SHARED. As usb_hcd_irq() will always disable 1909de85422b94ddb23c021126815ea49414047c13dcStefan Becker * interrupts we can remove it here. 1910de85422b94ddb23c021126815ea49414047c13dcStefan Becker */ 191183a798207361cc26385187b2e71efa2b5d75de7fGeoff Levand if (irqflags & IRQF_SHARED) 191283a798207361cc26385187b2e71efa2b5d75de7fGeoff Levand irqflags &= ~IRQF_DISABLED; 1913de85422b94ddb23c021126815ea49414047c13dcStefan Becker 19141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", 19151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->driver->description, hcd->self.busnum); 19161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags, 19171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->irq_descr, hcd)) != 0) { 19181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_err(hcd->self.controller, 1919c6387a48cf5958e43c201fc27a158c328927531aDavid S. Miller "request interrupt %d failed\n", irqnum); 19208ec8d20b21f00a36343ca0ebd6c6be9421724a1eAlan Stern goto err_request_irq; 19211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->irq = irqnum; 1923c6387a48cf5958e43c201fc27a158c328927531aDavid S. Miller dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum, 19241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (hcd->driver->flags & HCD_MEMORY) ? 19251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "io mem" : "io base", 19261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (unsigned long long)hcd->rsrc_start); 19271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 19281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->irq = -1; 19291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hcd->rsrc_start) 19301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_info(hcd->self.controller, "%s 0x%08llx\n", 19311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (hcd->driver->flags & HCD_MEMORY) ? 19321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "io mem" : "io base", 19331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (unsigned long long)hcd->rsrc_start); 19341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((retval = hcd->driver->start(hcd)) < 0) { 19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_err(hcd->self.controller, "startup error %d\n", retval); 19388ec8d20b21f00a36343ca0ebd6c6be9421724a1eAlan Stern goto err_hcd_driver_start; 19391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1941b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell /* starting here, usbcore will pay attention to this root hub */ 194255c527187c9d78f840b284d596a0b298bc1493afAlan Stern rhdev->bus_mA = min(500u, hcd->power_budget); 1943b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell if ((retval = register_root_hub(hcd)) != 0) 19448ec8d20b21f00a36343ca0ebd6c6be9421724a1eAlan Stern goto err_register_root_hub; 19458ec8d20b21f00a36343ca0ebd6c6be9421724a1eAlan Stern 19465234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group); 19475234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez if (retval < 0) { 19485234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n", 19495234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez retval); 19505234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez goto error_create_attr_group; 19515234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez } 1952d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern if (hcd->uses_new_polling && hcd->poll_rh) 1953d5926ae7a827bdd06b588ffbc56fd4525cd9214aAlan Stern usb_hcd_poll_rh_status(hcd); 19541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 19551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19565234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalezerror_create_attr_group: 19575234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez mutex_lock(&usb_bus_list_lock); 19585234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez usb_disconnect(&hcd->self.root_hub); 19595234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez mutex_unlock(&usb_bus_list_lock); 1960b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownellerr_register_root_hub: 19618ec8d20b21f00a36343ca0ebd6c6be9421724a1eAlan Stern hcd->driver->stop(hcd); 1962b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownellerr_hcd_driver_start: 19631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hcd->irq >= 0) 19641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(irqnum, hcd); 1965b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownellerr_request_irq: 1966b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownellerr_hcd_driver_setup: 1967b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell hcd->self.root_hub = NULL; 1968b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownell usb_put_dev(rhdev); 1969b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownellerr_allocate_root_hub: 19701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_deregister_bus(&hcd->self); 1971b1e8f0a6a8805c971857cd10a65cf8caa4c1a672David Brownellerr_register_bus: 19721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd_buffer_destroy(hcd); 19731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 19741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1975782e70c6fc2290a0395850e8e02583b8b62264d8Greg Kroah-HartmanEXPORT_SYMBOL_GPL(usb_add_hcd); 19761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 19781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * usb_remove_hcd - shutdown processing for generic HCDs 19791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @hcd: the usb_hcd structure to remove 19801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: !in_interrupt() 19811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Disconnects the root hub, then reverses the effects of usb_add_hcd(), 19831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * invoking the HCD's stop() method. 19841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 19851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid usb_remove_hcd(struct usb_hcd *hcd) 19861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 19871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_info(hcd->self.controller, "remove, state %x\n", hcd->state); 19881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (HC_IS_RUNNING (hcd->state)) 19901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->state = HC_STATE_QUIESCING; 19911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_dbg(hcd->self.controller, "roothub graceful disconnect\n"); 19931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irq (&hcd_root_hub_lock); 19941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->rh_registered = 0; 19951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irq (&hcd_root_hub_lock); 19969ad3d6ccf5eee285e233dbaf186369b8d477a666Alan Stern 19976b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern#ifdef CONFIG_PM 1998d5d4db704b962773c03ee3beb3258b6450611e66Alan Stern cancel_work_sync(&hcd->wakeup_work); 19996b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern#endif 20006b157c9bf3bace6eeb4a973da63923ef24995cceAlan Stern 20015234ce1b02ae2574098ebe9839dcf241076a9367Inaky Perez-Gonzalez sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group); 20024186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de Ven mutex_lock(&usb_bus_list_lock); 20031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_disconnect(&hcd->self.root_hub); 20044186ecf8ad16dd05759a09594de6a87e48759ba6Arjan van de Ven mutex_unlock(&usb_bus_list_lock); 20051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->driver->stop(hcd); 20071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd->state = HC_STATE_HALT; 20081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20091b42ae6d4355328dc4406b6f0188adcf8c566435Alan Stern hcd->poll_rh = 0; 20101b42ae6d4355328dc4406b6f0188adcf8c566435Alan Stern del_timer_sync(&hcd->rh_timer); 20111b42ae6d4355328dc4406b6f0188adcf8c566435Alan Stern 20121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hcd->irq >= 0) 20131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(hcd->irq, hcd); 20141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usb_deregister_bus(&hcd->self); 20151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hcd_buffer_destroy(hcd); 20161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2017782e70c6fc2290a0395850e8e02583b8b62264d8Greg Kroah-HartmanEXPORT_SYMBOL_GPL(usb_remove_hcd); 20181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 201964a21d025d3a979a8715f2ec7acabca7b5406c8aAleksey Gorelovvoid 202064a21d025d3a979a8715f2ec7acabca7b5406c8aAleksey Gorelovusb_hcd_platform_shutdown(struct platform_device* dev) 202164a21d025d3a979a8715f2ec7acabca7b5406c8aAleksey Gorelov{ 202264a21d025d3a979a8715f2ec7acabca7b5406c8aAleksey Gorelov struct usb_hcd *hcd = platform_get_drvdata(dev); 202364a21d025d3a979a8715f2ec7acabca7b5406c8aAleksey Gorelov 202464a21d025d3a979a8715f2ec7acabca7b5406c8aAleksey Gorelov if (hcd->driver->shutdown) 202564a21d025d3a979a8715f2ec7acabca7b5406c8aAleksey Gorelov hcd->driver->shutdown(hcd); 202664a21d025d3a979a8715f2ec7acabca7b5406c8aAleksey Gorelov} 2027782e70c6fc2290a0395850e8e02583b8b62264d8Greg Kroah-HartmanEXPORT_SYMBOL_GPL(usb_hcd_platform_shutdown); 202864a21d025d3a979a8715f2ec7acabca7b5406c8aAleksey Gorelov 20291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*-------------------------------------------------------------------------*/ 20301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2031f150fa1afbf69a87f54752579ff2bb769aad88b3Pete Zaitcev#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) 20321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct usb_mon_operations *mon_ops; 20341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 20361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The registration is unlocked. 20371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We do it this way because we do not want to lock in hot paths. 20381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Notice that the code is minimally error-proof. Because usbmon needs 20401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * symbols from usbcore, usbcore gets referenced and cannot be unloaded first. 20411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 20421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint usb_mon_register (struct usb_mon_operations *ops) 20441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 20451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mon_ops) 20471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EBUSY; 20481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mon_ops = ops; 20501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 20511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 20521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 20531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL (usb_mon_register); 20541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid usb_mon_deregister (void) 20561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 20571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mon_ops == NULL) { 20591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "USB: monitor was not registered\n"); 20601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 20611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 20621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mon_ops = NULL; 20631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 20641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 20651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL_GPL (usb_mon_deregister); 20661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2067f150fa1afbf69a87f54752579ff2bb769aad88b3Pete Zaitcev#endif /* CONFIG_USB_MON || CONFIG_USB_MON_MODULE */ 2068