diff options
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r-- | drivers/usb/core/hcd.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index eb212178826..875e2476c1f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -679,6 +679,66 @@ static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | |||
679 | return 0; | 679 | return 0; |
680 | } | 680 | } |
681 | 681 | ||
682 | |||
683 | |||
684 | /* | ||
685 | * Show & store the current value of authorized_default | ||
686 | */ | ||
687 | static ssize_t usb_host_authorized_default_show(struct device *dev, | ||
688 | struct device_attribute *attr, | ||
689 | char *buf) | ||
690 | { | ||
691 | struct usb_device *rh_usb_dev = to_usb_device(dev); | ||
692 | struct usb_bus *usb_bus = rh_usb_dev->bus; | ||
693 | struct usb_hcd *usb_hcd; | ||
694 | |||
695 | if (usb_bus == NULL) /* FIXME: not sure if this case is possible */ | ||
696 | return -ENODEV; | ||
697 | usb_hcd = bus_to_hcd(usb_bus); | ||
698 | return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default); | ||
699 | } | ||
700 | |||
701 | static ssize_t usb_host_authorized_default_store(struct device *dev, | ||
702 | struct device_attribute *attr, | ||
703 | const char *buf, size_t size) | ||
704 | { | ||
705 | ssize_t result; | ||
706 | unsigned val; | ||
707 | struct usb_device *rh_usb_dev = to_usb_device(dev); | ||
708 | struct usb_bus *usb_bus = rh_usb_dev->bus; | ||
709 | struct usb_hcd *usb_hcd; | ||
710 | |||
711 | if (usb_bus == NULL) /* FIXME: not sure if this case is possible */ | ||
712 | return -ENODEV; | ||
713 | usb_hcd = bus_to_hcd(usb_bus); | ||
714 | result = sscanf(buf, "%u\n", &val); | ||
715 | if (result == 1) { | ||
716 | usb_hcd->authorized_default = val? 1 : 0; | ||
717 | result = size; | ||
718 | } | ||
719 | else | ||
720 | result = -EINVAL; | ||
721 | return result; | ||
722 | } | ||
723 | |||
724 | static DEVICE_ATTR(authorized_default, 0644, | ||
725 | usb_host_authorized_default_show, | ||
726 | usb_host_authorized_default_store); | ||
727 | |||
728 | |||
729 | /* Group all the USB bus attributes */ | ||
730 | static struct attribute *usb_bus_attrs[] = { | ||
731 | &dev_attr_authorized_default.attr, | ||
732 | NULL, | ||
733 | }; | ||
734 | |||
735 | static struct attribute_group usb_bus_attr_group = { | ||
736 | .name = NULL, /* we want them in the same directory */ | ||
737 | .attrs = usb_bus_attrs, | ||
738 | }; | ||
739 | |||
740 | |||
741 | |||
682 | /*-------------------------------------------------------------------------*/ | 742 | /*-------------------------------------------------------------------------*/ |
683 | 743 | ||
684 | static struct class *usb_host_class; | 744 | static struct class *usb_host_class; |
@@ -1542,7 +1602,6 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, | |||
1542 | hcd->driver = driver; | 1602 | hcd->driver = driver; |
1543 | hcd->product_desc = (driver->product_desc) ? driver->product_desc : | 1603 | hcd->product_desc = (driver->product_desc) ? driver->product_desc : |
1544 | "USB Host Controller"; | 1604 | "USB Host Controller"; |
1545 | |||
1546 | return hcd; | 1605 | return hcd; |
1547 | } | 1606 | } |
1548 | EXPORT_SYMBOL (usb_create_hcd); | 1607 | EXPORT_SYMBOL (usb_create_hcd); |
@@ -1587,6 +1646,7 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1587 | 1646 | ||
1588 | dev_info(hcd->self.controller, "%s\n", hcd->product_desc); | 1647 | dev_info(hcd->self.controller, "%s\n", hcd->product_desc); |
1589 | 1648 | ||
1649 | hcd->authorized_default = hcd->wireless? 0 : 1; | ||
1590 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 1650 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
1591 | 1651 | ||
1592 | /* HC is in reset state, but accessible. Now do the one-time init, | 1652 | /* HC is in reset state, but accessible. Now do the one-time init, |
@@ -1663,10 +1723,20 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1663 | if ((retval = register_root_hub(hcd)) != 0) | 1723 | if ((retval = register_root_hub(hcd)) != 0) |
1664 | goto err_register_root_hub; | 1724 | goto err_register_root_hub; |
1665 | 1725 | ||
1726 | retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group); | ||
1727 | if (retval < 0) { | ||
1728 | printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n", | ||
1729 | retval); | ||
1730 | goto error_create_attr_group; | ||
1731 | } | ||
1666 | if (hcd->uses_new_polling && hcd->poll_rh) | 1732 | if (hcd->uses_new_polling && hcd->poll_rh) |
1667 | usb_hcd_poll_rh_status(hcd); | 1733 | usb_hcd_poll_rh_status(hcd); |
1668 | return retval; | 1734 | return retval; |
1669 | 1735 | ||
1736 | error_create_attr_group: | ||
1737 | mutex_lock(&usb_bus_list_lock); | ||
1738 | usb_disconnect(&hcd->self.root_hub); | ||
1739 | mutex_unlock(&usb_bus_list_lock); | ||
1670 | err_register_root_hub: | 1740 | err_register_root_hub: |
1671 | hcd->driver->stop(hcd); | 1741 | hcd->driver->stop(hcd); |
1672 | err_hcd_driver_start: | 1742 | err_hcd_driver_start: |
@@ -1708,6 +1778,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
1708 | cancel_work_sync(&hcd->wakeup_work); | 1778 | cancel_work_sync(&hcd->wakeup_work); |
1709 | #endif | 1779 | #endif |
1710 | 1780 | ||
1781 | sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group); | ||
1711 | mutex_lock(&usb_bus_list_lock); | 1782 | mutex_lock(&usb_bus_list_lock); |
1712 | usb_disconnect(&hcd->self.root_hub); | 1783 | usb_disconnect(&hcd->self.root_hub); |
1713 | mutex_unlock(&usb_bus_list_lock); | 1784 | mutex_unlock(&usb_bus_list_lock); |