Commit bf3bd966 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-5.1-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are some small USB fixes for a bunch of warnings/errors that the
  syzbot has been finding with it's new-found ability to stress-test the
  USB layer.

  All of these are tiny, but fix real issues, and are marked for stable
  as well. All of these have had lots of testing in linux-next as well"

* tag 'usb-5.1-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  USB: w1 ds2490: Fix bug caused by improper use of altsetting array
  USB: yurex: Fix protection fault after device removal
  usb: usbip: fix isoc packet num validation in get_pipe
  USB: core: Fix bug caused by duplicate interface PM usage counter
  USB: dummy-hcd: Fix failure to give back unlinked URBs
  USB: core: Fix unterminated string returned by usb_string()
parents fea27bc7 c114944d
...@@ -370,11 +370,15 @@ autosuspend the interface's device. When the usage counter is = 0 ...@@ -370,11 +370,15 @@ autosuspend the interface's device. When the usage counter is = 0
then the interface is considered to be idle, and the kernel may then the interface is considered to be idle, and the kernel may
autosuspend the device. autosuspend the device.
Drivers need not be concerned about balancing changes to the usage Drivers must be careful to balance their overall changes to the usage
counter; the USB core will undo any remaining "get"s when a driver counter. Unbalanced "get"s will remain in effect when a driver is
is unbound from its interface. As a corollary, drivers must not call unbound from its interface, preventing the device from going into
any of the ``usb_autopm_*`` functions after their ``disconnect`` runtime suspend should the interface be bound to a driver again. On
routine has returned. the other hand, drivers are allowed to achieve this balance by calling
the ``usb_autopm_*`` functions even after their ``disconnect`` routine
has returned -- say from within a work-queue routine -- provided they
retain an active reference to the interface (via ``usb_get_intf`` and
``usb_put_intf``).
Drivers using the async routines are responsible for their own Drivers using the async routines are responsible for their own
synchronization and mutual exclusion. synchronization and mutual exclusion.
......
...@@ -473,11 +473,6 @@ static int usb_unbind_interface(struct device *dev) ...@@ -473,11 +473,6 @@ static int usb_unbind_interface(struct device *dev)
pm_runtime_disable(dev); pm_runtime_disable(dev);
pm_runtime_set_suspended(dev); pm_runtime_set_suspended(dev);
/* Undo any residual pm_autopm_get_interface_* calls */
for (r = atomic_read(&intf->pm_usage_cnt); r > 0; --r)
usb_autopm_put_interface_no_suspend(intf);
atomic_set(&intf->pm_usage_cnt, 0);
if (!error) if (!error)
usb_autosuspend_device(udev); usb_autosuspend_device(udev);
...@@ -1633,7 +1628,6 @@ void usb_autopm_put_interface(struct usb_interface *intf) ...@@ -1633,7 +1628,6 @@ void usb_autopm_put_interface(struct usb_interface *intf)
int status; int status;
usb_mark_last_busy(udev); usb_mark_last_busy(udev);
atomic_dec(&intf->pm_usage_cnt);
status = pm_runtime_put_sync(&intf->dev); status = pm_runtime_put_sync(&intf->dev);
dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
__func__, atomic_read(&intf->dev.power.usage_count), __func__, atomic_read(&intf->dev.power.usage_count),
...@@ -1662,7 +1656,6 @@ void usb_autopm_put_interface_async(struct usb_interface *intf) ...@@ -1662,7 +1656,6 @@ void usb_autopm_put_interface_async(struct usb_interface *intf)
int status; int status;
usb_mark_last_busy(udev); usb_mark_last_busy(udev);
atomic_dec(&intf->pm_usage_cnt);
status = pm_runtime_put(&intf->dev); status = pm_runtime_put(&intf->dev);
dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
__func__, atomic_read(&intf->dev.power.usage_count), __func__, atomic_read(&intf->dev.power.usage_count),
...@@ -1684,7 +1677,6 @@ void usb_autopm_put_interface_no_suspend(struct usb_interface *intf) ...@@ -1684,7 +1677,6 @@ void usb_autopm_put_interface_no_suspend(struct usb_interface *intf)
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
usb_mark_last_busy(udev); usb_mark_last_busy(udev);
atomic_dec(&intf->pm_usage_cnt);
pm_runtime_put_noidle(&intf->dev); pm_runtime_put_noidle(&intf->dev);
} }
EXPORT_SYMBOL_GPL(usb_autopm_put_interface_no_suspend); EXPORT_SYMBOL_GPL(usb_autopm_put_interface_no_suspend);
...@@ -1715,8 +1707,6 @@ int usb_autopm_get_interface(struct usb_interface *intf) ...@@ -1715,8 +1707,6 @@ int usb_autopm_get_interface(struct usb_interface *intf)
status = pm_runtime_get_sync(&intf->dev); status = pm_runtime_get_sync(&intf->dev);
if (status < 0) if (status < 0)
pm_runtime_put_sync(&intf->dev); pm_runtime_put_sync(&intf->dev);
else
atomic_inc(&intf->pm_usage_cnt);
dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
__func__, atomic_read(&intf->dev.power.usage_count), __func__, atomic_read(&intf->dev.power.usage_count),
status); status);
...@@ -1750,8 +1740,6 @@ int usb_autopm_get_interface_async(struct usb_interface *intf) ...@@ -1750,8 +1740,6 @@ int usb_autopm_get_interface_async(struct usb_interface *intf)
status = pm_runtime_get(&intf->dev); status = pm_runtime_get(&intf->dev);
if (status < 0 && status != -EINPROGRESS) if (status < 0 && status != -EINPROGRESS)
pm_runtime_put_noidle(&intf->dev); pm_runtime_put_noidle(&intf->dev);
else
atomic_inc(&intf->pm_usage_cnt);
dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
__func__, atomic_read(&intf->dev.power.usage_count), __func__, atomic_read(&intf->dev.power.usage_count),
status); status);
...@@ -1775,7 +1763,6 @@ void usb_autopm_get_interface_no_resume(struct usb_interface *intf) ...@@ -1775,7 +1763,6 @@ void usb_autopm_get_interface_no_resume(struct usb_interface *intf)
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
usb_mark_last_busy(udev); usb_mark_last_busy(udev);
atomic_inc(&intf->pm_usage_cnt);
pm_runtime_get_noresume(&intf->dev); pm_runtime_get_noresume(&intf->dev);
} }
EXPORT_SYMBOL_GPL(usb_autopm_get_interface_no_resume); EXPORT_SYMBOL_GPL(usb_autopm_get_interface_no_resume);
......
...@@ -820,9 +820,11 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) ...@@ -820,9 +820,11 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
if (dev->state == USB_STATE_SUSPENDED) if (dev->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH; return -EHOSTUNREACH;
if (size <= 0 || !buf || !index) if (size <= 0 || !buf)
return -EINVAL; return -EINVAL;
buf[0] = 0; buf[0] = 0;
if (index <= 0 || index >= 256)
return -EINVAL;
tbuf = kmalloc(256, GFP_NOIO); tbuf = kmalloc(256, GFP_NOIO);
if (!tbuf) if (!tbuf)
return -ENOMEM; return -ENOMEM;
......
...@@ -979,8 +979,18 @@ static int dummy_udc_start(struct usb_gadget *g, ...@@ -979,8 +979,18 @@ static int dummy_udc_start(struct usb_gadget *g,
struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g);
struct dummy *dum = dum_hcd->dum; struct dummy *dum = dum_hcd->dum;
if (driver->max_speed == USB_SPEED_UNKNOWN) switch (g->speed) {
/* All the speeds we support */
case USB_SPEED_LOW:
case USB_SPEED_FULL:
case USB_SPEED_HIGH:
case USB_SPEED_SUPER:
break;
default:
dev_err(dummy_dev(dum_hcd), "Unsupported driver max speed %d\n",
driver->max_speed);
return -EINVAL; return -EINVAL;
}
/* /*
* SLAVE side init ... the layer above hardware, which * SLAVE side init ... the layer above hardware, which
...@@ -1784,9 +1794,10 @@ static void dummy_timer(struct timer_list *t) ...@@ -1784,9 +1794,10 @@ static void dummy_timer(struct timer_list *t)
/* Bus speed is 500000 bytes/ms, so use a little less */ /* Bus speed is 500000 bytes/ms, so use a little less */
total = 490000; total = 490000;
break; break;
default: default: /* Can't happen */
dev_err(dummy_dev(dum_hcd), "bogus device speed\n"); dev_err(dummy_dev(dum_hcd), "bogus device speed\n");
return; total = 0;
break;
} }
/* FIXME if HZ != 1000 this will probably misbehave ... */ /* FIXME if HZ != 1000 this will probably misbehave ... */
...@@ -1828,7 +1839,7 @@ static void dummy_timer(struct timer_list *t) ...@@ -1828,7 +1839,7 @@ static void dummy_timer(struct timer_list *t)
/* Used up this frame's bandwidth? */ /* Used up this frame's bandwidth? */
if (total <= 0) if (total <= 0)
break; continue;
/* find the gadget's ep for this request (if configured) */ /* find the gadget's ep for this request (if configured) */
address = usb_pipeendpoint (urb->pipe); address = usb_pipeendpoint (urb->pipe);
......
...@@ -314,6 +314,7 @@ static void yurex_disconnect(struct usb_interface *interface) ...@@ -314,6 +314,7 @@ static void yurex_disconnect(struct usb_interface *interface)
usb_deregister_dev(interface, &yurex_class); usb_deregister_dev(interface, &yurex_class);
/* prevent more I/O from starting */ /* prevent more I/O from starting */
usb_poison_urb(dev->urb);
mutex_lock(&dev->io_mutex); mutex_lock(&dev->io_mutex);
dev->interface = NULL; dev->interface = NULL;
mutex_unlock(&dev->io_mutex); mutex_unlock(&dev->io_mutex);
......
...@@ -763,18 +763,16 @@ static void rts51x_suspend_timer_fn(struct timer_list *t) ...@@ -763,18 +763,16 @@ static void rts51x_suspend_timer_fn(struct timer_list *t)
break; break;
case RTS51X_STAT_IDLE: case RTS51X_STAT_IDLE:
case RTS51X_STAT_SS: case RTS51X_STAT_SS:
usb_stor_dbg(us, "RTS51X_STAT_SS, intf->pm_usage_cnt:%d, power.usage:%d\n", usb_stor_dbg(us, "RTS51X_STAT_SS, power.usage:%d\n",
atomic_read(&us->pusb_intf->pm_usage_cnt),
atomic_read(&us->pusb_intf->dev.power.usage_count)); atomic_read(&us->pusb_intf->dev.power.usage_count));
if (atomic_read(&us->pusb_intf->pm_usage_cnt) > 0) { if (atomic_read(&us->pusb_intf->dev.power.usage_count) > 0) {
usb_stor_dbg(us, "Ready to enter SS state\n"); usb_stor_dbg(us, "Ready to enter SS state\n");
rts51x_set_stat(chip, RTS51X_STAT_SS); rts51x_set_stat(chip, RTS51X_STAT_SS);
/* ignore mass storage interface's children */ /* ignore mass storage interface's children */
pm_suspend_ignore_children(&us->pusb_intf->dev, true); pm_suspend_ignore_children(&us->pusb_intf->dev, true);
usb_autopm_put_interface_async(us->pusb_intf); usb_autopm_put_interface_async(us->pusb_intf);
usb_stor_dbg(us, "RTS51X_STAT_SS 01, intf->pm_usage_cnt:%d, power.usage:%d\n", usb_stor_dbg(us, "RTS51X_STAT_SS 01, power.usage:%d\n",
atomic_read(&us->pusb_intf->pm_usage_cnt),
atomic_read(&us->pusb_intf->dev.power.usage_count)); atomic_read(&us->pusb_intf->dev.power.usage_count));
} }
break; break;
...@@ -807,11 +805,10 @@ static void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) ...@@ -807,11 +805,10 @@ static void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
int ret; int ret;
if (working_scsi(srb)) { if (working_scsi(srb)) {
usb_stor_dbg(us, "working scsi, intf->pm_usage_cnt:%d, power.usage:%d\n", usb_stor_dbg(us, "working scsi, power.usage:%d\n",
atomic_read(&us->pusb_intf->pm_usage_cnt),
atomic_read(&us->pusb_intf->dev.power.usage_count)); atomic_read(&us->pusb_intf->dev.power.usage_count));
if (atomic_read(&us->pusb_intf->pm_usage_cnt) <= 0) { if (atomic_read(&us->pusb_intf->dev.power.usage_count) <= 0) {
ret = usb_autopm_get_interface(us->pusb_intf); ret = usb_autopm_get_interface(us->pusb_intf);
usb_stor_dbg(us, "working scsi, ret=%d\n", ret); usb_stor_dbg(us, "working scsi, ret=%d\n", ret);
} }
......
...@@ -361,16 +361,10 @@ static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu) ...@@ -361,16 +361,10 @@ static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu)
} }
if (usb_endpoint_xfer_isoc(epd)) { if (usb_endpoint_xfer_isoc(epd)) {
/* validate packet size and number of packets */ /* validate number of packets */
unsigned int maxp, packets, bytes;
maxp = usb_endpoint_maxp(epd);
maxp *= usb_endpoint_maxp_mult(epd);
bytes = pdu->u.cmd_submit.transfer_buffer_length;
packets = DIV_ROUND_UP(bytes, maxp);
if (pdu->u.cmd_submit.number_of_packets < 0 || if (pdu->u.cmd_submit.number_of_packets < 0 ||
pdu->u.cmd_submit.number_of_packets > packets) { pdu->u.cmd_submit.number_of_packets >
USBIP_MAX_ISO_PACKETS) {
dev_err(&sdev->udev->dev, dev_err(&sdev->udev->dev,
"CMD_SUBMIT: isoc invalid num packets %d\n", "CMD_SUBMIT: isoc invalid num packets %d\n",
pdu->u.cmd_submit.number_of_packets); pdu->u.cmd_submit.number_of_packets);
......
...@@ -121,6 +121,13 @@ extern struct device_attribute dev_attr_usbip_debug; ...@@ -121,6 +121,13 @@ extern struct device_attribute dev_attr_usbip_debug;
#define USBIP_DIR_OUT 0x00 #define USBIP_DIR_OUT 0x00
#define USBIP_DIR_IN 0x01 #define USBIP_DIR_IN 0x01
/*
* Arbitrary limit for the maximum number of isochronous packets in an URB,
* compare for example the uhci_submit_isochronous function in
* drivers/usb/host/uhci-q.c
*/
#define USBIP_MAX_ISO_PACKETS 1024
/** /**
* struct usbip_header_basic - data pertinent to every request * struct usbip_header_basic - data pertinent to every request
* @command: the usbip request type * @command: the usbip request type
......
...@@ -1016,15 +1016,15 @@ static int ds_probe(struct usb_interface *intf, ...@@ -1016,15 +1016,15 @@ static int ds_probe(struct usb_interface *intf,
/* alternative 3, 1ms interrupt (greatly speeds search), 64 byte bulk */ /* alternative 3, 1ms interrupt (greatly speeds search), 64 byte bulk */
alt = 3; alt = 3;
err = usb_set_interface(dev->udev, err = usb_set_interface(dev->udev,
intf->altsetting[alt].desc.bInterfaceNumber, alt); intf->cur_altsetting->desc.bInterfaceNumber, alt);
if (err) { if (err) {
dev_err(&dev->udev->dev, "Failed to set alternative setting %d " dev_err(&dev->udev->dev, "Failed to set alternative setting %d "
"for %d interface: err=%d.\n", alt, "for %d interface: err=%d.\n", alt,
intf->altsetting[alt].desc.bInterfaceNumber, err); intf->cur_altsetting->desc.bInterfaceNumber, err);
goto err_out_clear; goto err_out_clear;
} }
iface_desc = &intf->altsetting[alt]; iface_desc = intf->cur_altsetting;
if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {
pr_info("Num endpoints=%d. It is not DS9490R.\n", pr_info("Num endpoints=%d. It is not DS9490R.\n",
iface_desc->desc.bNumEndpoints); iface_desc->desc.bNumEndpoints);
......
...@@ -200,7 +200,6 @@ usb_find_last_int_out_endpoint(struct usb_host_interface *alt, ...@@ -200,7 +200,6 @@ usb_find_last_int_out_endpoint(struct usb_host_interface *alt,
* @dev: driver model's view of this device * @dev: driver model's view of this device
* @usb_dev: if an interface is bound to the USB major, this will point * @usb_dev: if an interface is bound to the USB major, this will point
* to the sysfs representation for that device. * to the sysfs representation for that device.
* @pm_usage_cnt: PM usage counter for this interface
* @reset_ws: Used for scheduling resets from atomic context. * @reset_ws: Used for scheduling resets from atomic context.
* @resetting_device: USB core reset the device, so use alt setting 0 as * @resetting_device: USB core reset the device, so use alt setting 0 as
* current; needs bandwidth alloc after reset. * current; needs bandwidth alloc after reset.
...@@ -257,7 +256,6 @@ struct usb_interface { ...@@ -257,7 +256,6 @@ struct usb_interface {
struct device dev; /* interface specific device info */ struct device dev; /* interface specific device info */
struct device *usb_dev; struct device *usb_dev;
atomic_t pm_usage_cnt; /* usage counter for autosuspend */
struct work_struct reset_ws; /* for resets in atomic context */ struct work_struct reset_ws; /* for resets in atomic context */
}; };
#define to_usb_interface(d) container_of(d, struct usb_interface, dev) #define to_usb_interface(d) container_of(d, struct usb_interface, dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment