diff options
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r-- | drivers/usb/core/hcd.c | 110 |
1 files changed, 86 insertions, 24 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 4d64e5c499e1..1c102d60cd9f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -131,7 +131,7 @@ static inline int is_root_hub(struct usb_device *udev) /* usb 3.0 root hub device descriptor */ static const u8 usb3_rh_dev_descriptor[18] = { 0x12, /* __u8 bLength; */ - 0x01, /* __u8 bDescriptorType; Device */ + USB_DT_DEVICE, /* __u8 bDescriptorType; Device */ 0x00, 0x03, /* __le16 bcdUSB; v3.0 */ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ @@ -152,7 +152,7 @@ static const u8 usb3_rh_dev_descriptor[18] = { /* usb 2.5 (wireless USB 1.0) root hub device descriptor */ static const u8 usb25_rh_dev_descriptor[18] = { 0x12, /* __u8 bLength; */ - 0x01, /* __u8 bDescriptorType; Device */ + USB_DT_DEVICE, /* __u8 bDescriptorType; Device */ 0x50, 0x02, /* __le16 bcdUSB; v2.5 */ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ @@ -173,7 +173,7 @@ static const u8 usb25_rh_dev_descriptor[18] = { /* usb 2.0 root hub device descriptor */ static const u8 usb2_rh_dev_descriptor[18] = { 0x12, /* __u8 bLength; */ - 0x01, /* __u8 bDescriptorType; Device */ + USB_DT_DEVICE, /* __u8 bDescriptorType; Device */ 0x00, 0x02, /* __le16 bcdUSB; v2.0 */ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ @@ -196,7 +196,7 @@ static const u8 usb2_rh_dev_descriptor[18] = { /* usb 1.1 root hub device descriptor */ static const u8 usb11_rh_dev_descriptor[18] = { 0x12, /* __u8 bLength; */ - 0x01, /* __u8 bDescriptorType; Device */ + USB_DT_DEVICE, /* __u8 bDescriptorType; Device */ 0x10, 0x01, /* __le16 bcdUSB; v1.1 */ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ @@ -223,7 +223,7 @@ static const u8 fs_rh_config_descriptor[] = { /* one configuration */ 0x09, /* __u8 bLength; */ - 0x02, /* __u8 bDescriptorType; Configuration */ + USB_DT_CONFIG, /* __u8 bDescriptorType; Configuration */ 0x19, 0x00, /* __le16 wTotalLength; */ 0x01, /* __u8 bNumInterfaces; (1) */ 0x01, /* __u8 bConfigurationValue; */ @@ -248,7 +248,7 @@ static const u8 fs_rh_config_descriptor[] = { /* one interface */ 0x09, /* __u8 if_bLength; */ - 0x04, /* __u8 if_bDescriptorType; Interface */ + USB_DT_INTERFACE, /* __u8 if_bDescriptorType; Interface */ 0x00, /* __u8 if_bInterfaceNumber; */ 0x00, /* __u8 if_bAlternateSetting; */ 0x01, /* __u8 if_bNumEndpoints; */ @@ -259,7 +259,7 @@ static const u8 fs_rh_config_descriptor[] = { /* one endpoint (status change endpoint) */ 0x07, /* __u8 ep_bLength; */ - 0x05, /* __u8 ep_bDescriptorType; Endpoint */ + USB_DT_ENDPOINT, /* __u8 ep_bDescriptorType; Endpoint */ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 0x03, /* __u8 ep_bmAttributes; Interrupt */ 0x02, 0x00, /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ @@ -270,7 +270,7 @@ static const u8 hs_rh_config_descriptor[] = { /* one configuration */ 0x09, /* __u8 bLength; */ - 0x02, /* __u8 bDescriptorType; Configuration */ + USB_DT_CONFIG, /* __u8 bDescriptorType; Configuration */ 0x19, 0x00, /* __le16 wTotalLength; */ 0x01, /* __u8 bNumInterfaces; (1) */ 0x01, /* __u8 bConfigurationValue; */ @@ -295,7 +295,7 @@ static const u8 hs_rh_config_descriptor[] = { /* one interface */ 0x09, /* __u8 if_bLength; */ - 0x04, /* __u8 if_bDescriptorType; Interface */ + USB_DT_INTERFACE, /* __u8 if_bDescriptorType; Interface */ 0x00, /* __u8 if_bInterfaceNumber; */ 0x00, /* __u8 if_bAlternateSetting; */ 0x01, /* __u8 if_bNumEndpoints; */ @@ -306,7 +306,7 @@ static const u8 hs_rh_config_descriptor[] = { /* one endpoint (status change endpoint) */ 0x07, /* __u8 ep_bLength; */ - 0x05, /* __u8 ep_bDescriptorType; Endpoint */ + USB_DT_ENDPOINT, /* __u8 ep_bDescriptorType; Endpoint */ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 0x03, /* __u8 ep_bmAttributes; Interrupt */ /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) @@ -318,7 +318,7 @@ static const u8 hs_rh_config_descriptor[] = { static const u8 ss_rh_config_descriptor[] = { /* one configuration */ 0x09, /* __u8 bLength; */ - 0x02, /* __u8 bDescriptorType; Configuration */ + USB_DT_CONFIG, /* __u8 bDescriptorType; Configuration */ 0x1f, 0x00, /* __le16 wTotalLength; */ 0x01, /* __u8 bNumInterfaces; (1) */ 0x01, /* __u8 bConfigurationValue; */ @@ -332,7 +332,7 @@ static const u8 ss_rh_config_descriptor[] = { /* one interface */ 0x09, /* __u8 if_bLength; */ - 0x04, /* __u8 if_bDescriptorType; Interface */ + USB_DT_INTERFACE, /* __u8 if_bDescriptorType; Interface */ 0x00, /* __u8 if_bInterfaceNumber; */ 0x00, /* __u8 if_bAlternateSetting; */ 0x01, /* __u8 if_bNumEndpoints; */ @@ -343,7 +343,7 @@ static const u8 ss_rh_config_descriptor[] = { /* one endpoint (status change endpoint) */ 0x07, /* __u8 ep_bLength; */ - 0x05, /* __u8 ep_bDescriptorType; Endpoint */ + USB_DT_ENDPOINT, /* __u8 ep_bDescriptorType; Endpoint */ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 0x03, /* __u8 ep_bmAttributes; Interrupt */ /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) @@ -353,7 +353,8 @@ static const u8 ss_rh_config_descriptor[] = { /* one SuperSpeed endpoint companion descriptor */ 0x06, /* __u8 ss_bLength */ - 0x30, /* __u8 ss_bDescriptorType; SuperSpeed EP Companion */ + USB_DT_SS_ENDPOINT_COMP, /* __u8 ss_bDescriptorType; SuperSpeed EP */ + /* Companion */ 0x00, /* __u8 ss_bMaxBurst; allows 1 TX between ACKs */ 0x00, /* __u8 ss_bmAttributes; 1 packet per service interval */ 0x02, 0x00 /* __le16 ss_wBytesPerInterval; 15 bits for max 15 ports */ @@ -555,6 +556,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) switch (wValue & 0xff00) { case USB_DT_DEVICE << 8: switch (hcd->speed) { + case HCD_USB31: case HCD_USB3: bufp = usb3_rh_dev_descriptor; break; @@ -576,6 +578,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) break; case USB_DT_CONFIG << 8: switch (hcd->speed) { + case HCD_USB31: case HCD_USB3: bufp = ss_rh_config_descriptor; len = sizeof ss_rh_config_descriptor; @@ -854,10 +857,10 @@ static ssize_t authorized_default_show(struct device *dev, { struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev->bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); - return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default); + hcd = bus_to_hcd(usb_bus); + return snprintf(buf, PAGE_SIZE, "%u\n", !!HCD_DEV_AUTHORIZED(hcd)); } static ssize_t authorized_default_store(struct device *dev, @@ -868,12 +871,16 @@ static ssize_t authorized_default_store(struct device *dev, unsigned val; struct usb_device *rh_usb_dev = to_usb_device(dev); struct usb_bus *usb_bus = rh_usb_dev->bus; - struct usb_hcd *usb_hcd; + struct usb_hcd *hcd; - usb_hcd = bus_to_hcd(usb_bus); + hcd = bus_to_hcd(usb_bus); result = sscanf(buf, "%u\n", &val); if (result == 1) { - usb_hcd->authorized_default = val ? 1 : 0; + if (val) + set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); + result = size; } else { result = -EINVAL; @@ -882,9 +889,53 @@ static ssize_t authorized_default_store(struct device *dev, } static DEVICE_ATTR_RW(authorized_default); +/* + * interface_authorized_default_show - show default authorization status + * for USB interfaces + * + * note: interface_authorized_default is the default value + * for initializing the authorized attribute of interfaces + */ +static ssize_t interface_authorized_default_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_device *usb_dev = to_usb_device(dev); + struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus); + + return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd)); +} + +/* + * interface_authorized_default_store - store default authorization status + * for USB interfaces + * + * note: interface_authorized_default is the default value + * for initializing the authorized attribute of interfaces + */ +static ssize_t interface_authorized_default_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_device *usb_dev = to_usb_device(dev); + struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus); + int rc = count; + bool val; + + if (strtobool(buf, &val) != 0) + return -EINVAL; + + if (val) + set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags); + else + clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags); + + return rc; +} +static DEVICE_ATTR_RW(interface_authorized_default); + /* Group all the USB bus attributes */ static struct attribute *usb_bus_attrs[] = { &dev_attr_authorized_default.attr, + &dev_attr_interface_authorized_default.attr, NULL, }; @@ -2676,12 +2727,22 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_info(hcd->self.controller, "%s\n", hcd->product_desc); /* Keep old behaviour if authorized_default is not in [0, 1]. */ - if (authorized_default < 0 || authorized_default > 1) - hcd->authorized_default = hcd->wireless ? 0 : 1; - else - hcd->authorized_default = authorized_default; + if (authorized_default < 0 || authorized_default > 1) { + if (hcd->wireless) + clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); + else + set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); + } else { + if (authorized_default) + set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); + else + clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags); + } set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + /* per default all interfaces are authorized */ + set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags); + /* HC is in reset state, but accessible. Now do the one-time init, * bottom up so that hcds can customize the root hubs before hub_wq * starts talking to them. (Note, bus id is assigned early too.) @@ -2717,6 +2778,7 @@ int usb_add_hcd(struct usb_hcd *hcd, rhdev->speed = USB_SPEED_WIRELESS; break; case HCD_USB3: + case HCD_USB31: rhdev->speed = USB_SPEED_SUPER; break; default: |