diff options
Diffstat (limited to 'drivers/usb/core')
| -rw-r--r-- | drivers/usb/core/config.c | 2 | ||||
| -rw-r--r-- | drivers/usb/core/devices.c | 7 | ||||
| -rw-r--r-- | drivers/usb/core/devio.c | 15 | ||||
| -rw-r--r-- | drivers/usb/core/driver.c | 12 | ||||
| -rw-r--r-- | drivers/usb/core/hub.c | 17 |
5 files changed, 33 insertions, 20 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 346a2faa9bb8..0e79b7f8a73d 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -151,7 +151,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, usb_endpoint_xfer_int(&ep->desc)) && desc->bmAttributes != 0) { dev_notice(ddev, "%s endpoint with bmAttributes = %d in config %d interface %d altsetting %d ep 0x%X: setting to zero\n", - usb_endpoint_xfer_control(&ep->desc) ? "Control" : "Bulk", + usb_endpoint_xfer_control(&ep->desc) ? "Control" : "Interrupt", desc->bmAttributes, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bmAttributes = 0; diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index a247da73f34d..6f0354aba38b 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -37,6 +37,7 @@ */ #include <linux/fs.h> +#include <linux/slab.h> #include <linux/mm.h> #include <linux/gfp.h> #include <linux/usb.h> @@ -408,7 +409,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, return 0; /* allocate 2^1 pages = 8K (on i386); * should be more than enough for one device */ - pages_start = (char *)__get_free_pages(GFP_NOIO, 1); + pages_start = kmalloc(PAGE_SIZE << 1, GFP_NOIO); if (!pages_start) return -ENOMEM; @@ -479,7 +480,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, if (length > *nbytes) length = *nbytes; if (copy_to_user(*buffer, pages_start + *skip_bytes, length)) { - free_pages((unsigned long)pages_start, 1); + kfree(pages_start); return -EFAULT; } *nbytes -= length; @@ -490,7 +491,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, } else *skip_bytes -= length; - free_pages((unsigned long)pages_start, 1); + kfree(pages_start); /* Now look at all of this device's children. */ usb_hub_for_each_child(usbdev, chix, childdev) { diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e191934623c7..101cb9425480 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1113,7 +1113,6 @@ static int usbdev_release(struct inode *inode, struct file *file) if (!ps->suspend_allowed) usb_autosuspend_device(dev); usb_unlock_device(dev); - usb_put_dev(dev); put_pid(ps->disc_pid); put_cred(ps->cred); @@ -1122,6 +1121,7 @@ static int usbdev_release(struct inode *inode, struct file *file) free_async(as); as = async_getcompleted(ps); } + usb_put_dev(dev); kfree(ps); return 0; @@ -2329,6 +2329,13 @@ static int proc_ioctl(struct usb_dev_state *ps, struct usbdevfs_ioctl *ctl) if (!connected(ps)) return -ENODEV; + if (ps->dev->state != USB_STATE_CONFIGURED) + return -EHOSTUNREACH; + + intf = usb_ifnum_to_if(ps->dev, ctl->ifno); + if (!intf) + return -EINVAL; + /* alloc buffer */ size = _IOC_SIZE(ctl->ioctl_code); if (size > 0) { @@ -2345,11 +2352,7 @@ static int proc_ioctl(struct usb_dev_state *ps, struct usbdevfs_ioctl *ctl) } } - if (ps->dev->state != USB_STATE_CONFIGURED) - retval = -EHOSTUNREACH; - else if (!(intf = usb_ifnum_to_if(ps->dev, ctl->ifno))) - retval = -EINVAL; - else switch (ctl->ioctl_code) { + switch (ctl->ioctl_code) { /* disconnect kernel driver from interface */ case USBDEVFS_DISCONNECT: diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index f63004417058..7f33fe5ba03b 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -228,14 +228,16 @@ static void usb_free_dynids(struct usb_driver *usb_drv) } static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf, - const struct usb_driver *drv) + const struct usb_driver *drv, + struct usb_device_id *id_copy) { struct usb_dynid *dynid; guard(mutex)(&usb_dynids_lock); list_for_each_entry(dynid, &drv->dynids.list, node) { if (usb_match_one_id(intf, &dynid->id)) { - return &dynid->id; + *id_copy = dynid->id; + return id_copy; } } return NULL; @@ -321,6 +323,7 @@ static int usb_probe_interface(struct device *dev) struct usb_interface *intf = to_usb_interface(dev); struct usb_device *udev = interface_to_usbdev(intf); const struct usb_device_id *id; + struct usb_device_id id_copy; int error = -ENODEV; int lpm_disable_error = -ENODEV; @@ -340,7 +343,7 @@ static int usb_probe_interface(struct device *dev) return error; } - id = usb_match_dynamic_id(intf, driver); + id = usb_match_dynamic_id(intf, driver, &id_copy); if (!id) id = usb_match_id(intf, driver->id_table); if (!id) @@ -892,6 +895,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv) struct usb_interface *intf; const struct usb_driver *usb_drv; const struct usb_device_id *id; + struct usb_device_id id_copy; /* device drivers never match interfaces */ if (is_usb_device_driver(drv)) @@ -904,7 +908,7 @@ static int usb_device_match(struct device *dev, const struct device_driver *drv) if (id) return 1; - id = usb_match_dynamic_id(intf, usb_drv); + id = usb_match_dynamic_id(intf, usb_drv, &id_copy); if (id) return 1; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d92bf887739d..3345b3298daf 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -623,11 +623,11 @@ static int hub_ext_port_status(struct usb_hub *hub, int port1, int type, mutex_lock(&hub->status_mutex); ret = get_port_status(hub->hdev, port1, &hub->status->port, type, len); if (ret < len) { - if (ret != -ENODEV) - dev_err(hub->intfdev, - "%s failed (err = %d)\n", __func__, ret); if (ret >= 0) ret = -EIO; + if (ret != -ENODEV) + dev_dbg(hub->intfdev, + "get_port_status failed: err = %d\n", ret); } else { *status = le16_to_cpu(hub->status->port.wPortStatus); *change = le16_to_cpu(hub->status->port.wPortChange); @@ -753,10 +753,12 @@ void usb_wakeup_notification(struct usb_device *hdev, { struct usb_hub *hub; struct usb_port *port_dev; + unsigned long flags; if (!hdev) return; + spin_lock_irqsave(&device_state_lock, flags); hub = usb_hub_to_struct_hub(hdev); if (hub) { port_dev = hub->ports[portnum - 1]; @@ -766,6 +768,7 @@ void usb_wakeup_notification(struct usb_device *hdev, set_bit(portnum, hub->wakeup_bits); kick_hub_wq(hub); } + spin_unlock_irqrestore(&device_state_lock, flags); } EXPORT_SYMBOL_GPL(usb_wakeup_notification); @@ -991,10 +994,12 @@ static int hub_hub_status(struct usb_hub *hub, mutex_lock(&hub->status_mutex); ret = get_hub_status(hub->hdev, &hub->status->hub); - if (ret < 0) { + if (ret < (int)sizeof(hub->status->hub)) { + if (ret >= 0) + ret = -EIO; if (ret != -ENODEV) - dev_err(hub->intfdev, - "%s failed (err = %d)\n", __func__, ret); + dev_dbg(hub->intfdev, + "get_hub_status failed: err = %d\n", ret); } else { *status = le16_to_cpu(hub->status->hub.wHubStatus); *change = le16_to_cpu(hub->status->hub.wHubChange); |
