summaryrefslogtreecommitdiff
path: root/drivers/usb/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/buffer.c10
-rw-r--r--drivers/usb/core/devio.c2
-rw-r--r--drivers/usb/core/file.c10
-rw-r--r--drivers/usb/core/hcd.c127
-rw-r--r--drivers/usb/core/message.c4
-rw-r--r--drivers/usb/core/sysfs.c121
-rw-r--r--drivers/usb/core/usb.h5
7 files changed, 138 insertions, 141 deletions
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 1359b78a624e..6cf22c27f2d2 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -66,9 +66,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
char name[16];
int i, size;
- if (!IS_ENABLED(CONFIG_HAS_DMA) ||
- (!is_device_dma_capable(hcd->self.sysdev) &&
- !hcd->localmem_pool))
+ if (hcd->localmem_pool || !hcd_uses_dma(hcd))
return 0;
for (i = 0; i < HCD_BUFFER_POOLS; i++) {
@@ -129,8 +127,7 @@ void *hcd_buffer_alloc(
return gen_pool_dma_alloc(hcd->localmem_pool, size, dma);
/* some USB hosts just use PIO */
- if (!IS_ENABLED(CONFIG_HAS_DMA) ||
- !is_device_dma_capable(bus->sysdev)) {
+ if (!hcd_uses_dma(hcd)) {
*dma = ~(dma_addr_t) 0;
return kmalloc(size, mem_flags);
}
@@ -160,8 +157,7 @@ void hcd_buffer_free(
return;
}
- if (!IS_ENABLED(CONFIG_HAS_DMA) ||
- !is_device_dma_capable(bus->sysdev)) {
+ if (!hcd_uses_dma(hcd)) {
kfree(addr);
return;
}
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index b265ab5405f9..9063ede411ae 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1812,8 +1812,6 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
return 0;
error:
- if (as && as->usbm)
- dec_usb_memory_use_count(as->usbm, &as->usbm->urb_use_count);
kfree(isopkt);
kfree(dr);
if (as)
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 65de6f73b672..558890ada0e5 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -193,9 +193,10 @@ int usb_register_dev(struct usb_interface *intf,
intf->minor = minor;
break;
}
- up_write(&minor_rwsem);
- if (intf->minor < 0)
+ if (intf->minor < 0) {
+ up_write(&minor_rwsem);
return -EXFULL;
+ }
/* create a usb class device for this usb interface */
snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
@@ -203,12 +204,11 @@ int usb_register_dev(struct usb_interface *intf,
MKDEV(USB_MAJOR, minor), class_driver,
"%s", kbasename(name));
if (IS_ERR(intf->usb_dev)) {
- down_write(&minor_rwsem);
usb_minors[minor] = NULL;
intf->minor = -1;
- up_write(&minor_rwsem);
retval = PTR_ERR(intf->usb_dev);
}
+ up_write(&minor_rwsem);
return retval;
}
EXPORT_SYMBOL_GPL(usb_register_dev);
@@ -234,12 +234,12 @@ void usb_deregister_dev(struct usb_interface *intf,
return;
dev_dbg(&intf->dev, "removing %d minor\n", intf->minor);
+ device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
down_write(&minor_rwsem);
usb_minors[intf->minor] = NULL;
up_write(&minor_rwsem);
- device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
intf->usb_dev = NULL;
intf->minor = -1;
destroy_usb_class();
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 9320787ac2e6..8592c0344fe8 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -103,11 +103,6 @@ static DEFINE_SPINLOCK(hcd_urb_unlink_lock);
/* wait queue for synchronous unlinks */
DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue);
-static inline int is_root_hub(struct usb_device *udev)
-{
- return (udev->parent == NULL);
-}
-
/*-------------------------------------------------------------------------*/
/*
@@ -880,101 +875,6 @@ static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
}
-
-/*
- * Show & store the current value of authorized_default
- */
-static ssize_t authorized_default_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_device *rh_usb_dev = to_usb_device(dev);
- struct usb_bus *usb_bus = rh_usb_dev->bus;
- struct usb_hcd *hcd;
-
- hcd = bus_to_hcd(usb_bus);
- return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy);
-}
-
-static ssize_t authorized_default_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
-{
- ssize_t result;
- unsigned val;
- struct usb_device *rh_usb_dev = to_usb_device(dev);
- struct usb_bus *usb_bus = rh_usb_dev->bus;
- struct usb_hcd *hcd;
-
- hcd = bus_to_hcd(usb_bus);
- result = sscanf(buf, "%u\n", &val);
- if (result == 1) {
- hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ?
- val : USB_DEVICE_AUTHORIZE_ALL;
- result = size;
- } else {
- result = -EINVAL;
- }
- return result;
-}
-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,
-};
-
-static const struct attribute_group usb_bus_attr_group = {
- .name = NULL, /* we want them in the same directory */
- .attrs = usb_bus_attrs,
-};
-
-
-
/*-------------------------------------------------------------------------*/
/**
@@ -1512,7 +1412,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
if (usb_endpoint_xfer_control(&urb->ep->desc)) {
if (hcd->self.uses_pio_for_control)
return ret;
- if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
+ if (hcd_uses_dma(hcd)) {
if (is_vmalloc_addr(urb->setup_packet)) {
WARN_ONCE(1, "setup packet is not dma capable\n");
return -EAGAIN;
@@ -1546,7 +1446,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
if (urb->transfer_buffer_length != 0
&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
- if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
+ if (hcd_uses_dma(hcd)) {
if (urb->num_sgs) {
int n;
@@ -2894,32 +2794,11 @@ int usb_add_hcd(struct usb_hcd *hcd,
if (retval != 0)
goto err_register_root_hub;
- retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);
- if (retval < 0) {
- printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n",
- retval);
- goto error_create_attr_group;
- }
if (hcd->uses_new_polling && HCD_POLL_RH(hcd))
usb_hcd_poll_rh_status(hcd);
return retval;
-error_create_attr_group:
- clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
- if (HC_IS_RUNNING(hcd->state))
- hcd->state = HC_STATE_QUIESCING;
- spin_lock_irq(&hcd_root_hub_lock);
- hcd->rh_registered = 0;
- spin_unlock_irq(&hcd_root_hub_lock);
-
-#ifdef CONFIG_PM
- cancel_work_sync(&hcd->wakeup_work);
-#endif
- cancel_work_sync(&hcd->died_work);
- mutex_lock(&usb_bus_idr_lock);
- usb_disconnect(&rhdev); /* Sets rhdev to NULL */
- mutex_unlock(&usb_bus_idr_lock);
err_register_root_hub:
hcd->rh_pollable = 0;
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
@@ -2963,8 +2842,6 @@ void usb_remove_hcd(struct usb_hcd *hcd)
dev_info(hcd->self.controller, "remove, state %x\n", hcd->state);
usb_get_dev(rhdev);
- sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group);
-
clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
if (HC_IS_RUNNING (hcd->state))
hcd->state = HC_STATE_QUIESCING;
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index e844bb7b5676..5adf489428aa 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -2218,14 +2218,14 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr,
(struct usb_cdc_dmm_desc *)buffer;
break;
case USB_CDC_MDLM_TYPE:
- if (elength < sizeof(struct usb_cdc_mdlm_desc *))
+ if (elength < sizeof(struct usb_cdc_mdlm_desc))
goto next_desc;
if (desc)
return -EINVAL;
desc = (struct usb_cdc_mdlm_desc *)buffer;
break;
case USB_CDC_MDLM_DETAIL_TYPE:
- if (elength < sizeof(struct usb_cdc_mdlm_detail_desc *))
+ if (elength < sizeof(struct usb_cdc_mdlm_detail_desc))
goto next_desc;
if (detail)
return -EINVAL;
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 7e88fdfe3cf5..f19694e69f5c 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/usb.h>
+#include <linux/usb/hcd.h>
#include <linux/usb/quirks.h>
#include <linux/of.h>
#include "usb.h"
@@ -922,6 +923,116 @@ static struct bin_attribute dev_bin_attr_descriptors = {
.size = 18 + 65535, /* dev descr + max-size raw descriptor */
};
+/*
+ * Show & store the current value of authorized_default
+ */
+static ssize_t authorized_default_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_device *rh_usb_dev = to_usb_device(dev);
+ struct usb_bus *usb_bus = rh_usb_dev->bus;
+ struct usb_hcd *hcd;
+
+ hcd = bus_to_hcd(usb_bus);
+ return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy);
+}
+
+static ssize_t authorized_default_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ ssize_t result;
+ unsigned int val;
+ struct usb_device *rh_usb_dev = to_usb_device(dev);
+ struct usb_bus *usb_bus = rh_usb_dev->bus;
+ struct usb_hcd *hcd;
+
+ hcd = bus_to_hcd(usb_bus);
+ result = sscanf(buf, "%u\n", &val);
+ if (result == 1) {
+ hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ?
+ val : USB_DEVICE_AUTHORIZE_ALL;
+ result = size;
+ } else {
+ result = -EINVAL;
+ }
+ return result;
+}
+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,
+};
+
+static const struct attribute_group usb_bus_attr_group = {
+ .name = NULL, /* we want them in the same directory */
+ .attrs = usb_bus_attrs,
+};
+
+
+static int add_default_authorized_attributes(struct device *dev)
+{
+ int rc = 0;
+
+ if (is_usb_device(dev))
+ rc = sysfs_create_group(&dev->kobj, &usb_bus_attr_group);
+
+ return rc;
+}
+
+static void remove_default_authorized_attributes(struct device *dev)
+{
+ if (is_usb_device(dev)) {
+ sysfs_remove_group(&dev->kobj, &usb_bus_attr_group);
+ }
+}
+
int usb_create_sysfs_dev_files(struct usb_device *udev)
{
struct device *dev = &udev->dev;
@@ -938,7 +1049,14 @@ int usb_create_sysfs_dev_files(struct usb_device *udev)
retval = add_power_attributes(dev);
if (retval)
goto error;
+
+ if (is_root_hub(udev)) {
+ retval = add_default_authorized_attributes(dev);
+ if (retval)
+ goto error;
+ }
return retval;
+
error:
usb_remove_sysfs_dev_files(udev);
return retval;
@@ -948,6 +1066,9 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev)
{
struct device *dev = &udev->dev;
+ if (is_root_hub(udev))
+ remove_default_authorized_attributes(dev);
+
remove_power_attributes(dev);
remove_persist_attributes(dev);
device_remove_bin_file(dev, &dev_bin_attr_descriptors);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index bd8d01f85a13..0c9fde5ad052 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -153,6 +153,11 @@ static inline int is_usb_port(const struct device *dev)
return dev->type == &usb_port_device_type;
}
+static inline int is_root_hub(struct usb_device *udev)
+{
+ return (udev->parent == NULL);
+}
+
/* Do the same for device drivers and interface drivers. */
static inline int is_usb_device_driver(struct device_driver *drv)