summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/hcd.c51
-rw-r--r--drivers/usb/core/usb.c33
2 files changed, 57 insertions, 27 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 86f39e44f98a..3b6e3e25f59e 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -373,13 +373,19 @@ static const u8 ss_rh_config_descriptor[] = {
* -1 is authorized for all devices except wireless (old behaviour)
* 0 is unauthorized for all devices
* 1 is authorized for all devices
+ * 2 is authorized for internal devices
*/
-static int authorized_default = -1;
+#define USB_AUTHORIZE_WIRED -1
+#define USB_AUTHORIZE_NONE 0
+#define USB_AUTHORIZE_ALL 1
+#define USB_AUTHORIZE_INTERNAL 2
+
+static int authorized_default = USB_AUTHORIZE_WIRED;
module_param(authorized_default, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(authorized_default,
"Default USB device authorization: 0 is not authorized, 1 is "
- "authorized, -1 is authorized except for wireless USB (default, "
- "old behaviour");
+ "authorized, 2 is authorized for internal devices, -1 is "
+ "authorized except for wireless USB (default, old behaviour");
/*-------------------------------------------------------------------------*/
/**
@@ -884,7 +890,7 @@ static ssize_t authorized_default_show(struct device *dev,
struct usb_hcd *hcd;
hcd = bus_to_hcd(usb_bus);
- return snprintf(buf, PAGE_SIZE, "%u\n", !!HCD_DEV_AUTHORIZED(hcd));
+ return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy);
}
static ssize_t authorized_default_store(struct device *dev,
@@ -900,11 +906,8 @@ static ssize_t authorized_default_store(struct device *dev,
hcd = bus_to_hcd(usb_bus);
result = sscanf(buf, "%u\n", &val);
if (result == 1) {
- if (val)
- set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
- else
- clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
-
+ hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ?
+ val : USB_DEVICE_AUTHORIZE_ALL;
result = size;
} else {
result = -EINVAL;
@@ -2748,18 +2751,26 @@ 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) {
- 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);
+ switch (authorized_default) {
+ case USB_AUTHORIZE_NONE:
+ hcd->dev_policy = USB_DEVICE_AUTHORIZE_NONE;
+ break;
+
+ case USB_AUTHORIZE_ALL:
+ hcd->dev_policy = USB_DEVICE_AUTHORIZE_ALL;
+ break;
+
+ case USB_AUTHORIZE_INTERNAL:
+ hcd->dev_policy = USB_DEVICE_AUTHORIZE_INTERNAL;
+ break;
+
+ case USB_AUTHORIZE_WIRED:
+ default:
+ hcd->dev_policy = hcd->wireless ?
+ USB_DEVICE_AUTHORIZE_NONE : USB_DEVICE_AUTHORIZE_ALL;
+ break;
}
+
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
/* per default all interfaces are authorized */
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 4ebfbd737905..9b5852e313f5 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -46,8 +46,7 @@
#include <linux/mm.h>
#include <linux/dma-mapping.h>
-#include "usb.h"
-
+#include "hub.h"
const char *usbcore_name = "usbcore";
@@ -536,6 +535,27 @@ static unsigned usb_bus_is_wusb(struct usb_bus *bus)
return hcd->wireless;
}
+static bool usb_dev_authorized(struct usb_device *dev, struct usb_hcd *hcd)
+{
+ struct usb_hub *hub;
+
+ if (!dev->parent)
+ return true; /* Root hub always ok [and always wired] */
+
+ switch (hcd->dev_policy) {
+ case USB_DEVICE_AUTHORIZE_NONE:
+ default:
+ return false;
+
+ case USB_DEVICE_AUTHORIZE_ALL:
+ return true;
+
+ case USB_DEVICE_AUTHORIZE_INTERNAL:
+ hub = usb_hub_to_struct_hub(dev->parent);
+ return hub->ports[dev->portnum - 1]->connect_type ==
+ USB_PORT_CONNECT_TYPE_HARD_WIRED;
+ }
+}
/**
* usb_alloc_dev - usb device constructor (usbcore-internal)
@@ -663,12 +683,11 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
dev->connect_time = jiffies;
dev->active_duration = -jiffies;
#endif
- if (root_hub) /* Root hub always ok [and always wired] */
- dev->authorized = 1;
- else {
- dev->authorized = !!HCD_DEV_AUTHORIZED(usb_hcd);
+
+ dev->authorized = usb_dev_authorized(dev, usb_hcd);
+ if (!root_hub)
dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0;
- }
+
return dev;
}
EXPORT_SYMBOL_GPL(usb_alloc_dev);