Merge tag 'usb-5.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 31 May 2019 15:16:31 +0000 (08:16 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 31 May 2019 15:16:31 +0000 (08:16 -0700)
Pull USB fixes from Greg KH:
 "Here are some tiny USB fixes for a number of reported issues for
  5.2-rc3.

  Nothing huge here, just a small collection of xhci and other driver
  bugs that syzbot has been finding in some drivers. There is also a
  usbip fix and a fix for the usbip fix in here :)

  All have been in linux-next with no reported issues"

* tag 'usb-5.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usbip: usbip_host: fix stub_dev lock context imbalance regression
  media: smsusb: better handle optional alignment
  xhci: Use %zu for printing size_t type
  xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic()
  xhci: Fix immediate data transfer if buffer is already DMA mapped
  usb: xhci: avoid null pointer deref when bos field is NULL
  usb: xhci: Fix a potential null pointer dereference in xhci_debugfs_create_endpoint()
  xhci: update bounce buffer with correct sg num
  media: usb: siano: Fix false-positive "uninitialized variable" warning
  USB: rio500: update Documentation
  USB: rio500: simplify locking
  USB: rio500: fix memory leak in close after disconnect
  USB: rio500: refuse more than one device at a time
  usbip: usbip_host: fix BUG: sleeping function called from invalid context
  USB: sisusbvga: fix oops in error path of sisusb_probe
  USB: Add LPM quirk for Surface Dock GigE adapter
  media: usb: siano: Fix general protection fault in smsusb
  usb: mtu3: fix up undefined reference to usb_debug_root
  USB: Fix slab-out-of-bounds write in usb_get_bos_descriptor

12 files changed:
Documentation/usb/rio.txt
drivers/media/usb/siano/smsusb.c
drivers/usb/core/config.c
drivers/usb/core/quirks.c
drivers/usb/host/xhci-debugfs.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/rio500.c
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/mtu3/mtu3_debugfs.c
drivers/usb/usbip/stub_dev.c

index ca9adcf..ea73475 100644 (file)
@@ -76,70 +76,30 @@ Additional Information and userspace tools
 Requirements
 ============
 
-A host with a USB port.  Ideally, either a UHCI (Intel) or OHCI
-(Compaq and others) hardware port should work.
+A host with a USB port running a Linux kernel with RIO 500 support enabled.
 
-A Linux development kernel (2.3.x) with USB support enabled or a
-backported version to linux-2.2.x.  See http://www.linux-usb.org for
-more information on accomplishing this.
+The driver is a module called rio500, which should be automatically loaded
+as you plug in your device. If that fails you can manually load it with
 
-A Linux kernel with RIO 500 support enabled.
+  modprobe rio500
 
-'lspci' which is only needed to determine the type of USB hardware
-available in your machine.
-
-Configuration
-
-Using `lspci -v`, determine the type of USB hardware available.
-
-  If you see something like::
-
-    USB Controller: ......
-    Flags: .....
-    I/O ports at ....
-
-  Then you have a UHCI based controller.
-
-  If you see something like::
-
-     USB Controller: .....
-     Flags: ....
-     Memory at .....
-
-  Then you have a OHCI based controller.
-
-Using `make menuconfig` or your preferred method for configuring the
-kernel, select 'Support for USB', 'OHCI/UHCI' depending on your
-hardware (determined from the steps above), 'USB Diamond Rio500 support', and
-'Preliminary USB device filesystem'.  Compile and install the modules
-(you may need to execute `depmod -a` to update the module
-dependencies).
-
-Add a device for the USB rio500::
+Udev should automatically create a device node as soon as plug in your device.
+If that fails, you can manually add a device for the USB rio500::
 
   mknod /dev/usb/rio500 c 180 64
 
-Set appropriate permissions for /dev/usb/rio500 (don't forget about
-group and world permissions).  Both read and write permissions are
+In that case, set appropriate permissions for /dev/usb/rio500 (don't forget
+about group and world permissions).  Both read and write permissions are
 required for proper operation.
 
-Load the appropriate modules (if compiled as modules):
-
-  OHCI::
-
-    modprobe usbcore
-    modprobe usb-ohci
-    modprobe rio500
-
-  UHCI::
-
-    modprobe usbcore
-    modprobe usb-uhci  (or uhci)
-    modprobe rio500
-
 That's it.  The Rio500 Utils at: http://rio500.sourceforge.net should
 be able to access the rio500.
 
+Limits
+======
+
+You can use only a single rio500 device at a time with your computer.
+
 Bugs
 ====
 
index e13d77b..9ba3a2a 100644 (file)
@@ -389,6 +389,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
        struct smsusb_device_t *dev;
        void *mdev;
        int i, rc;
+       int align = 0;
 
        /* create device object */
        dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
@@ -400,6 +401,24 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
        dev->udev = interface_to_usbdev(intf);
        dev->state = SMSUSB_DISCONNECTED;
 
+       for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+               struct usb_endpoint_descriptor *desc =
+                               &intf->cur_altsetting->endpoint[i].desc;
+
+               if (desc->bEndpointAddress & USB_DIR_IN) {
+                       dev->in_ep = desc->bEndpointAddress;
+                       align = usb_endpoint_maxp(desc) - sizeof(struct sms_msg_hdr);
+               } else {
+                       dev->out_ep = desc->bEndpointAddress;
+               }
+       }
+
+       pr_debug("in_ep = %02x, out_ep = %02x\n", dev->in_ep, dev->out_ep);
+       if (!dev->in_ep || !dev->out_ep || align < 0) {  /* Missing endpoints? */
+               smsusb_term_device(intf);
+               return -ENODEV;
+       }
+
        params.device_type = sms_get_board(board_id)->type;
 
        switch (params.device_type) {
@@ -414,24 +433,12 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
                /* fall-thru */
        default:
                dev->buffer_size = USB2_BUFFER_SIZE;
-               dev->response_alignment =
-                   le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) -
-                   sizeof(struct sms_msg_hdr);
+               dev->response_alignment = align;
 
                params.flags |= SMS_DEVICE_FAMILY2;
                break;
        }
 
-       for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
-               if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN)
-                       dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
-               else
-                       dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
-       }
-
-       pr_debug("in_ep = %02x, out_ep = %02x\n",
-               dev->in_ep, dev->out_ep);
-
        params.device = &dev->udev->dev;
        params.usb_device = dev->udev;
        params.buffer_size = dev->buffer_size;
index 20ff036..9d6cb70 100644 (file)
@@ -932,8 +932,8 @@ int usb_get_bos_descriptor(struct usb_device *dev)
 
        /* Get BOS descriptor */
        ret = usb_get_descriptor(dev, USB_DT_BOS, 0, bos, USB_DT_BOS_SIZE);
-       if (ret < USB_DT_BOS_SIZE) {
-               dev_err(ddev, "unable to get BOS descriptor\n");
+       if (ret < USB_DT_BOS_SIZE || bos->bLength < USB_DT_BOS_SIZE) {
+               dev_err(ddev, "unable to get BOS descriptor or descriptor too short\n");
                if (ret >= 0)
                        ret = -ENOMSG;
                kfree(bos);
index 8bc35d5..6082b00 100644 (file)
@@ -209,6 +209,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* Microsoft LifeCam-VX700 v2.0 */
        { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Microsoft Surface Dock Ethernet (RTL8153 GigE) */
+       { USB_DEVICE(0x045e, 0x07c6), .driver_info = USB_QUIRK_NO_LPM },
+
        /* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */
        { USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME },
 
index cadc013..7ba6afc 100644 (file)
@@ -440,6 +440,9 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci,
        struct xhci_ep_priv     *epriv;
        struct xhci_slot_priv   *spriv = dev->debugfs_private;
 
+       if (!spriv)
+               return;
+
        if (spriv->eps[ep_index])
                return;
 
index fed3385..feffceb 100644 (file)
@@ -656,6 +656,7 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci,
        struct device *dev = xhci_to_hcd(xhci)->self.controller;
        struct xhci_segment *seg = td->bounce_seg;
        struct urb *urb = td->urb;
+       size_t len;
 
        if (!ring || !seg || !urb)
                return;
@@ -666,11 +667,14 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci,
                return;
        }
 
-       /* for in tranfers we need to copy the data from bounce to sg */
-       sg_pcopy_from_buffer(urb->sg, urb->num_mapped_sgs, seg->bounce_buf,
-                            seg->bounce_len, seg->bounce_offs);
        dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len,
                         DMA_FROM_DEVICE);
+       /* for in tranfers we need to copy the data from bounce to sg */
+       len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf,
+                            seg->bounce_len, seg->bounce_offs);
+       if (len != seg->bounce_len)
+               xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n",
+                               len, seg->bounce_len);
        seg->bounce_len = 0;
        seg->bounce_offs = 0;
 }
@@ -3127,6 +3131,7 @@ static int xhci_align_td(struct xhci_hcd *xhci, struct urb *urb, u32 enqd_len,
        unsigned int unalign;
        unsigned int max_pkt;
        u32 new_buff_len;
+       size_t len;
 
        max_pkt = usb_endpoint_maxp(&urb->ep->desc);
        unalign = (enqd_len + *trb_buff_len) % max_pkt;
@@ -3157,8 +3162,12 @@ static int xhci_align_td(struct xhci_hcd *xhci, struct urb *urb, u32 enqd_len,
 
        /* create a max max_pkt sized bounce buffer pointed to by last trb */
        if (usb_urb_dir_out(urb)) {
-               sg_pcopy_to_buffer(urb->sg, urb->num_mapped_sgs,
+               len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
                                   seg->bounce_buf, new_buff_len, enqd_len);
+               if (len != seg->bounce_len)
+                       xhci_warn(xhci,
+                               "WARN Wrong bounce buffer write length: %zu != %d\n",
+                               len, seg->bounce_len);
                seg->bounce_dma = dma_map_single(dev, seg->bounce_buf,
                                                 max_pkt, DMA_TO_DEVICE);
        } else {
@@ -3423,11 +3432,14 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
        if (urb->transfer_buffer_length > 0) {
                u32 length_field, remainder;
+               u64 addr;
 
                if (xhci_urb_suitable_for_idt(urb)) {
-                       memcpy(&urb->transfer_dma, urb->transfer_buffer,
+                       memcpy(&addr, urb->transfer_buffer,
                               urb->transfer_buffer_length);
                        field |= TRB_IDT;
+               } else {
+                       addr = (u64) urb->transfer_dma;
                }
 
                remainder = xhci_td_remainder(xhci, 0,
@@ -3440,8 +3452,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                if (setup->bRequestType & USB_DIR_IN)
                        field |= TRB_DIR_IN;
                queue_trb(xhci, ep_ring, true,
-                               lower_32_bits(urb->transfer_dma),
-                               upper_32_bits(urb->transfer_dma),
+                               lower_32_bits(addr),
+                               upper_32_bits(addr),
                                length_field,
                                field | ep_ring->cycle_state);
        }
index a9bb796..20db378 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/iopoll.h>
 #include <linux/irq.h>
 #include <linux/log2.h>
 #include <linux/module.h>
@@ -52,7 +53,6 @@ static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
        return false;
 }
 
-/* TODO: copied from ehci-hcd.c - can this be refactored? */
 /*
  * xhci_handshake - spin reading hc until handshake completes or fails
  * @ptr: address of hc register to be read
@@ -69,18 +69,16 @@ static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
 int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
 {
        u32     result;
+       int     ret;
 
-       do {
-               result = readl(ptr);
-               if (result == ~(u32)0)          /* card removed */
-                       return -ENODEV;
-               result &= mask;
-               if (result == done)
-                       return 0;
-               udelay(1);
-               usec--;
-       } while (usec > 0);
-       return -ETIMEDOUT;
+       ret = readl_poll_timeout_atomic(ptr, result,
+                                       (result & mask) == done ||
+                                       result == U32_MAX,
+                                       1, usec);
+       if (result == U32_MAX)          /* card removed */
+               return -ENODEV;
+
+       return ret;
 }
 
 /*
@@ -4320,7 +4318,6 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
        pm_addr = ports[port_num]->addr + PORTPMSC;
        pm_val = readl(pm_addr);
        hlpm_addr = ports[port_num]->addr + PORTHLPMC;
-       field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
 
        xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
                        enable ? "enable" : "disable", port_num + 1);
@@ -4332,6 +4329,7 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
                         * default one which works with mixed HIRD and BESL
                         * systems. See XHCI_DEFAULT_BESL definition in xhci.h
                         */
+                       field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
                        if ((field & USB_BESL_SUPPORT) &&
                            (field & USB_BESL_BASELINE_VALID))
                                hird = USB_GET_BESL_BASELINE(field);
index a450a99..7f8b950 100644 (file)
@@ -2160,7 +2160,8 @@ static inline bool xhci_urb_suitable_for_idt(struct urb *urb)
 {
        if (!usb_endpoint_xfer_isoc(&urb->ep->desc) && usb_urb_dir_out(urb) &&
            usb_endpoint_maxp(&urb->ep->desc) >= TRB_IDT_MAX_SIZE &&
-           urb->transfer_buffer_length <= TRB_IDT_MAX_SIZE)
+           urb->transfer_buffer_length <= TRB_IDT_MAX_SIZE &&
+           !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
                return true;
 
        return false;
index 7b9adeb..27e9c78 100644 (file)
@@ -51,7 +51,6 @@ struct rio_usb_data {
         char *obuf, *ibuf;              /* transfer buffers */
         char bulk_in_ep, bulk_out_ep;   /* Endpoint assignments */
         wait_queue_head_t wait_q;       /* for timeouts */
-       struct mutex lock;          /* general race avoidance */
 };
 
 static DEFINE_MUTEX(rio500_mutex);
@@ -63,10 +62,8 @@ static int open_rio(struct inode *inode, struct file *file)
 
        /* against disconnect() */
        mutex_lock(&rio500_mutex);
-       mutex_lock(&(rio->lock));
 
        if (rio->isopen || !rio->present) {
-               mutex_unlock(&(rio->lock));
                mutex_unlock(&rio500_mutex);
                return -EBUSY;
        }
@@ -74,7 +71,6 @@ static int open_rio(struct inode *inode, struct file *file)
 
        init_waitqueue_head(&rio->wait_q);
 
-       mutex_unlock(&(rio->lock));
 
        dev_info(&rio->rio_dev->dev, "Rio opened.\n");
        mutex_unlock(&rio500_mutex);
@@ -86,9 +82,20 @@ static int close_rio(struct inode *inode, struct file *file)
 {
        struct rio_usb_data *rio = &rio_instance;
 
-       rio->isopen = 0;
+       /* against disconnect() */
+       mutex_lock(&rio500_mutex);
 
-       dev_info(&rio->rio_dev->dev, "Rio closed.\n");
+       rio->isopen = 0;
+       if (!rio->present) {
+               /* cleanup has been delayed */
+               kfree(rio->ibuf);
+               kfree(rio->obuf);
+               rio->ibuf = NULL;
+               rio->obuf = NULL;
+       } else {
+               dev_info(&rio->rio_dev->dev, "Rio closed.\n");
+       }
+       mutex_unlock(&rio500_mutex);
        return 0;
 }
 
@@ -102,7 +109,7 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
        int retries;
        int retval=0;
 
-       mutex_lock(&(rio->lock));
+       mutex_lock(&rio500_mutex);
         /* Sanity check to make sure rio is connected, powered, etc */
         if (rio->present == 0 || rio->rio_dev == NULL) {
                retval = -ENODEV;
@@ -246,7 +253,7 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
 
 
 err_out:
-       mutex_unlock(&(rio->lock));
+       mutex_unlock(&rio500_mutex);
        return retval;
 }
 
@@ -266,12 +273,12 @@ write_rio(struct file *file, const char __user *buffer,
        int errn = 0;
        int intr;
 
-       intr = mutex_lock_interruptible(&(rio->lock));
+       intr = mutex_lock_interruptible(&rio500_mutex);
        if (intr)
                return -EINTR;
         /* Sanity check to make sure rio is connected, powered, etc */
         if (rio->present == 0 || rio->rio_dev == NULL) {
-               mutex_unlock(&(rio->lock));
+               mutex_unlock(&rio500_mutex);
                return -ENODEV;
        }
 
@@ -294,7 +301,7 @@ write_rio(struct file *file, const char __user *buffer,
                                goto error;
                        }
                        if (signal_pending(current)) {
-                               mutex_unlock(&(rio->lock));
+                               mutex_unlock(&rio500_mutex);
                                return bytes_written ? bytes_written : -EINTR;
                        }
 
@@ -332,12 +339,12 @@ write_rio(struct file *file, const char __user *buffer,
                buffer += copy_size;
        } while (count > 0);
 
-       mutex_unlock(&(rio->lock));
+       mutex_unlock(&rio500_mutex);
 
        return bytes_written ? bytes_written : -EIO;
 
 error:
-       mutex_unlock(&(rio->lock));
+       mutex_unlock(&rio500_mutex);
        return errn;
 }
 
@@ -354,12 +361,12 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
        char *ibuf;
        int intr;
 
-       intr = mutex_lock_interruptible(&(rio->lock));
+       intr = mutex_lock_interruptible(&rio500_mutex);
        if (intr)
                return -EINTR;
        /* Sanity check to make sure rio is connected, powered, etc */
         if (rio->present == 0 || rio->rio_dev == NULL) {
-               mutex_unlock(&(rio->lock));
+               mutex_unlock(&rio500_mutex);
                return -ENODEV;
        }
 
@@ -370,11 +377,11 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
 
        while (count > 0) {
                if (signal_pending(current)) {
-                       mutex_unlock(&(rio->lock));
+                       mutex_unlock(&rio500_mutex);
                        return read_count ? read_count : -EINTR;
                }
                if (!rio->rio_dev) {
-                       mutex_unlock(&(rio->lock));
+                       mutex_unlock(&rio500_mutex);
                        return -ENODEV;
                }
                this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
@@ -392,7 +399,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
                        count = this_read = partial;
                } else if (result == -ETIMEDOUT || result == 15) {      /* FIXME: 15 ??? */
                        if (!maxretry--) {
-                               mutex_unlock(&(rio->lock));
+                               mutex_unlock(&rio500_mutex);
                                dev_err(&rio->rio_dev->dev,
                                        "read_rio: maxretry timeout\n");
                                return -ETIME;
@@ -402,19 +409,19 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
                        finish_wait(&rio->wait_q, &wait);
                        continue;
                } else if (result != -EREMOTEIO) {
-                       mutex_unlock(&(rio->lock));
+                       mutex_unlock(&rio500_mutex);
                        dev_err(&rio->rio_dev->dev,
                                "Read Whoops - result:%d partial:%u this_read:%u\n",
                                result, partial, this_read);
                        return -EIO;
                } else {
-                       mutex_unlock(&(rio->lock));
+                       mutex_unlock(&rio500_mutex);
                        return (0);
                }
 
                if (this_read) {
                        if (copy_to_user(buffer, ibuf, this_read)) {
-                               mutex_unlock(&(rio->lock));
+                               mutex_unlock(&rio500_mutex);
                                return -EFAULT;
                        }
                        count -= this_read;
@@ -422,7 +429,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
                        buffer += this_read;
                }
        }
-       mutex_unlock(&(rio->lock));
+       mutex_unlock(&rio500_mutex);
        return read_count;
 }
 
@@ -447,15 +454,23 @@ static int probe_rio(struct usb_interface *intf,
 {
        struct usb_device *dev = interface_to_usbdev(intf);
        struct rio_usb_data *rio = &rio_instance;
-       int retval;
+       int retval = 0;
 
-       dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
+       mutex_lock(&rio500_mutex);
+       if (rio->present) {
+               dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum);
+               retval = -EBUSY;
+               goto bail_out;
+       } else {
+               dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
+       }
 
        retval = usb_register_dev(intf, &usb_rio_class);
        if (retval) {
                dev_err(&dev->dev,
                        "Not able to get a minor for this device.\n");
-               return -ENOMEM;
+               retval = -ENOMEM;
+               goto bail_out;
        }
 
        rio->rio_dev = dev;
@@ -464,7 +479,8 @@ static int probe_rio(struct usb_interface *intf,
                dev_err(&dev->dev,
                        "probe_rio: Not enough memory for the output buffer\n");
                usb_deregister_dev(intf, &usb_rio_class);
-               return -ENOMEM;
+               retval = -ENOMEM;
+               goto bail_out;
        }
        dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf);
 
@@ -473,16 +489,17 @@ static int probe_rio(struct usb_interface *intf,
                        "probe_rio: Not enough memory for the input buffer\n");
                usb_deregister_dev(intf, &usb_rio_class);
                kfree(rio->obuf);
-               return -ENOMEM;
+               retval = -ENOMEM;
+               goto bail_out;
        }
        dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf);
 
-       mutex_init(&(rio->lock));
-
        usb_set_intfdata (intf, rio);
        rio->present = 1;
+bail_out:
+       mutex_unlock(&rio500_mutex);
 
-       return 0;
+       return retval;
 }
 
 static void disconnect_rio(struct usb_interface *intf)
@@ -494,12 +511,10 @@ static void disconnect_rio(struct usb_interface *intf)
        if (rio) {
                usb_deregister_dev(intf, &usb_rio_class);
 
-               mutex_lock(&(rio->lock));
                if (rio->isopen) {
                        rio->isopen = 0;
                        /* better let it finish - the release will do whats needed */
                        rio->rio_dev = NULL;
-                       mutex_unlock(&(rio->lock));
                        mutex_unlock(&rio500_mutex);
                        return;
                }
@@ -509,7 +524,6 @@ static void disconnect_rio(struct usb_interface *intf)
                dev_info(&intf->dev, "USB Rio disconnected.\n");
 
                rio->present = 0;
-               mutex_unlock(&(rio->lock));
        }
        mutex_unlock(&rio500_mutex);
 }
index 9560fde..ea06f1f 100644 (file)
@@ -3029,6 +3029,13 @@ static int sisusb_probe(struct usb_interface *intf,
 
        mutex_init(&(sisusb->lock));
 
+       sisusb->sisusb_dev = dev;
+       sisusb->vrambase   = SISUSB_PCI_MEMBASE;
+       sisusb->mmiobase   = SISUSB_PCI_MMIOBASE;
+       sisusb->mmiosize   = SISUSB_PCI_MMIOSIZE;
+       sisusb->ioportbase = SISUSB_PCI_IOPORTBASE;
+       /* Everything else is zero */
+
        /* Register device */
        retval = usb_register_dev(intf, &usb_sisusb_class);
        if (retval) {
@@ -3039,13 +3046,7 @@ static int sisusb_probe(struct usb_interface *intf,
                goto error_1;
        }
 
-       sisusb->sisusb_dev = dev;
-       sisusb->minor      = intf->minor;
-       sisusb->vrambase   = SISUSB_PCI_MEMBASE;
-       sisusb->mmiobase   = SISUSB_PCI_MMIOBASE;
-       sisusb->mmiosize   = SISUSB_PCI_MMIOSIZE;
-       sisusb->ioportbase = SISUSB_PCI_IOPORTBASE;
-       /* Everything else is zero */
+       sisusb->minor = intf->minor;
 
        /* Allocate buffers */
        sisusb->ibufsize = SISUSB_IBUF_SIZE;
index 62c57dd..b7c86cc 100644 (file)
@@ -528,8 +528,7 @@ void ssusb_dr_debugfs_init(struct ssusb_mtk *ssusb)
 
 void ssusb_debugfs_create_root(struct ssusb_mtk *ssusb)
 {
-       ssusb->dbgfs_root =
-               debugfs_create_dir(dev_name(ssusb->dev), usb_debug_root);
+       ssusb->dbgfs_root = debugfs_create_dir(dev_name(ssusb->dev), NULL);
 }
 
 void ssusb_debugfs_remove_root(struct ssusb_mtk *ssusb)
index c0d6ff1..7931e6c 100644 (file)
@@ -301,9 +301,17 @@ static int stub_probe(struct usb_device *udev)
        const char *udev_busid = dev_name(&udev->dev);
        struct bus_id_priv *busid_priv;
        int rc = 0;
+       char save_status;
 
        dev_dbg(&udev->dev, "Enter probe\n");
 
+       /* Not sure if this is our device. Allocate here to avoid
+        * calling alloc while holding busid_table lock.
+        */
+       sdev = stub_device_alloc(udev);
+       if (!sdev)
+               return -ENOMEM;
+
        /* check we should claim or not by busid_table */
        busid_priv = get_busid_priv(udev_busid);
        if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) ||
@@ -318,6 +326,9 @@ static int stub_probe(struct usb_device *udev)
                 * See driver_probe_device() in driver/base/dd.c
                 */
                rc = -ENODEV;
+               if (!busid_priv)
+                       goto sdev_free;
+
                goto call_put_busid_priv;
        }
 
@@ -337,12 +348,6 @@ static int stub_probe(struct usb_device *udev)
                goto call_put_busid_priv;
        }
 
-       /* ok, this is my device */
-       sdev = stub_device_alloc(udev);
-       if (!sdev) {
-               rc = -ENOMEM;
-               goto call_put_busid_priv;
-       }
 
        dev_info(&udev->dev,
                "usbip-host: register new device (bus %u dev %u)\n",
@@ -352,9 +357,16 @@ static int stub_probe(struct usb_device *udev)
 
        /* set private data to usb_device */
        dev_set_drvdata(&udev->dev, sdev);
+
        busid_priv->sdev = sdev;
        busid_priv->udev = udev;
 
+       save_status = busid_priv->status;
+       busid_priv->status = STUB_BUSID_ALLOC;
+
+       /* release the busid_lock */
+       put_busid_priv(busid_priv);
+
        /*
         * Claim this hub port.
         * It doesn't matter what value we pass as owner
@@ -372,10 +384,8 @@ static int stub_probe(struct usb_device *udev)
                dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid);
                goto err_files;
        }
-       busid_priv->status = STUB_BUSID_ALLOC;
 
-       rc = 0;
-       goto call_put_busid_priv;
+       return 0;
 
 err_files:
        usb_hub_release_port(udev->parent, udev->portnum,
@@ -384,23 +394,30 @@ err_port:
        dev_set_drvdata(&udev->dev, NULL);
        usb_put_dev(udev);
 
+       /* we already have busid_priv, just lock busid_lock */
+       spin_lock(&busid_priv->busid_lock);
        busid_priv->sdev = NULL;
-       stub_device_free(sdev);
+       busid_priv->status = save_status;
+       spin_unlock(&busid_priv->busid_lock);
+       /* lock is released - go to free */
+       goto sdev_free;
 
 call_put_busid_priv:
+       /* release the busid_lock */
        put_busid_priv(busid_priv);
+
+sdev_free:
+       stub_device_free(sdev);
+
        return rc;
 }
 
 static void shutdown_busid(struct bus_id_priv *busid_priv)
 {
-       if (busid_priv->sdev && !busid_priv->shutdown_busid) {
-               busid_priv->shutdown_busid = 1;
-               usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED);
+       usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED);
 
-               /* wait for the stop of the event handler */
-               usbip_stop_eh(&busid_priv->sdev->ud);
-       }
+       /* wait for the stop of the event handler */
+       usbip_stop_eh(&busid_priv->sdev->ud);
 }
 
 /*
@@ -427,11 +444,16 @@ static void stub_disconnect(struct usb_device *udev)
        /* get stub_device */
        if (!sdev) {
                dev_err(&udev->dev, "could not get device");
-               goto call_put_busid_priv;
+               /* release busid_lock */
+               put_busid_priv(busid_priv);
+               return;
        }
 
        dev_set_drvdata(&udev->dev, NULL);
 
+       /* release busid_lock before call to remove device files */
+       put_busid_priv(busid_priv);
+
        /*
         * NOTE: rx/tx threads are invoked for each usb_device.
         */
@@ -442,27 +464,36 @@ static void stub_disconnect(struct usb_device *udev)
                                  (struct usb_dev_state *) udev);
        if (rc) {
                dev_dbg(&udev->dev, "unable to release port\n");
-               goto call_put_busid_priv;
+               return;
        }
 
        /* If usb reset is called from event handler */
        if (usbip_in_eh(current))
-               goto call_put_busid_priv;
+               return;
+
+       /* we already have busid_priv, just lock busid_lock */
+       spin_lock(&busid_priv->busid_lock);
+       if (!busid_priv->shutdown_busid)
+               busid_priv->shutdown_busid = 1;
+       /* release busid_lock */
+       spin_unlock(&busid_priv->busid_lock);
 
        /* shutdown the current connection */
        shutdown_busid(busid_priv);
 
        usb_put_dev(sdev->udev);
 
+       /* we already have busid_priv, just lock busid_lock */
+       spin_lock(&busid_priv->busid_lock);
        /* free sdev */
        busid_priv->sdev = NULL;
        stub_device_free(sdev);
 
        if (busid_priv->status == STUB_BUSID_ALLOC)
                busid_priv->status = STUB_BUSID_ADDED;
-
-call_put_busid_priv:
-       put_busid_priv(busid_priv);
+       /* release busid_lock */
+       spin_unlock(&busid_priv->busid_lock);
+       return;
 }
 
 #ifdef CONFIG_PM