]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.5-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 1 Aug 2012 15:42:43 +0000 (08:42 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 1 Aug 2012 15:42:43 +0000 (08:42 -0700)
added patches:
revert-usb-uas-make-sure-data-urb-is-gone-if-we-receive-status-before-that.patch
usbdevfs-correct-amount-of-data-copied-to-user-in-processcompl_compat.patch
usb-gadget-fix-g_ether-interface-link-status.patch
usb-option-add-zte-mf821d.patch

queue-3.5/revert-usb-uas-make-sure-data-urb-is-gone-if-we-receive-status-before-that.patch [new file with mode: 0644]
queue-3.5/series
queue-3.5/usb-gadget-fix-g_ether-interface-link-status.patch [new file with mode: 0644]
queue-3.5/usb-option-add-zte-mf821d.patch [new file with mode: 0644]
queue-3.5/usbdevfs-correct-amount-of-data-copied-to-user-in-processcompl_compat.patch [new file with mode: 0644]

diff --git a/queue-3.5/revert-usb-uas-make-sure-data-urb-is-gone-if-we-receive-status-before-that.patch b/queue-3.5/revert-usb-uas-make-sure-data-urb-is-gone-if-we-receive-status-before-that.patch
new file mode 100644 (file)
index 0000000..5af7de3
--- /dev/null
@@ -0,0 +1,214 @@
+From c621a81edecdee85da32c566c21836332c764fda Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 19 Jun 2012 09:54:48 +0200
+Subject: Revert "usb/uas: make sure data urb is gone if we receive status before that"
+
+From: Gerd Hoffmann <kraxel@redhat.com>
+
+commit c621a81edecdee85da32c566c21836332c764fda upstream.
+
+This reverts commit e4d8318a85779b25b880187b1b1c44e797bd7d4b.
+
+This patch makes uas.c call usb_unlink_urb on data urbs.  The data urbs
+get freed in the completion callback.  This is illegal according to the
+usb_unlink_urb documentation.
+
+This patch also makes the code expect the data completion callback
+being called before the status completion callback.  This isn't
+guaranteed to be the case, even though the actual data transfer should
+be finished by the time the status is received.
+
+Background:  The ehci irq handler for example only know that there are
+finished transfers, it then has go check the QHs & TDs to see which
+transfers did actually finish.  It has no way to figure in which order
+the transfers did complete.  The xhci driver can call the callbacks in
+completion order thanks to the event queue.  This does nicely explain
+why the driver is solid on a (usb2) xhci port whereas it goes crazy on
+ehci in my testing.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/uas.c |   90 +++++++---------------------------------------
+ 1 file changed, 15 insertions(+), 75 deletions(-)
+
+--- a/drivers/usb/storage/uas.c
++++ b/drivers/usb/storage/uas.c
+@@ -58,9 +58,6 @@ enum {
+       SUBMIT_DATA_OUT_URB     = (1 << 5),
+       ALLOC_CMD_URB           = (1 << 6),
+       SUBMIT_CMD_URB          = (1 << 7),
+-      COMPLETED_DATA_IN       = (1 << 8),
+-      COMPLETED_DATA_OUT      = (1 << 9),
+-      DATA_COMPLETES_CMD      = (1 << 10),
+ };
+ /* Overrides scsi_pointer */
+@@ -114,7 +111,6 @@ static void uas_sense(struct urb *urb, s
+ {
+       struct sense_iu *sense_iu = urb->transfer_buffer;
+       struct scsi_device *sdev = cmnd->device;
+-      struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+       if (urb->actual_length > 16) {
+               unsigned len = be16_to_cpup(&sense_iu->len);
+@@ -132,15 +128,13 @@ static void uas_sense(struct urb *urb, s
+       }
+       cmnd->result = sense_iu->status;
+-      if (!(cmdinfo->state & DATA_COMPLETES_CMD))
+-              cmnd->scsi_done(cmnd);
++      cmnd->scsi_done(cmnd);
+ }
+ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
+ {
+       struct sense_iu_old *sense_iu = urb->transfer_buffer;
+       struct scsi_device *sdev = cmnd->device;
+-      struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+       if (urb->actual_length > 8) {
+               unsigned len = be16_to_cpup(&sense_iu->len) - 2;
+@@ -158,8 +152,7 @@ static void uas_sense_old(struct urb *ur
+       }
+       cmnd->result = sense_iu->status;
+-      if (!(cmdinfo->state & DATA_COMPLETES_CMD))
+-              cmnd->scsi_done(cmnd);
++      cmnd->scsi_done(cmnd);
+ }
+ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
+@@ -184,7 +177,6 @@ static void uas_stat_cmplt(struct urb *u
+       struct Scsi_Host *shost = urb->context;
+       struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
+       struct scsi_cmnd *cmnd;
+-      struct uas_cmd_info *cmdinfo;
+       u16 tag;
+       int ret;
+@@ -210,32 +202,12 @@ static void uas_stat_cmplt(struct urb *u
+                       dev_err(&urb->dev->dev, "failed submit status urb\n");
+               return;
+       }
+-      cmdinfo = (void *)&cmnd->SCp;
+       switch (iu->iu_id) {
+       case IU_ID_STATUS:
+               if (devinfo->cmnd == cmnd)
+                       devinfo->cmnd = NULL;
+-              if (!(cmdinfo->state & COMPLETED_DATA_IN) &&
+-                              cmdinfo->data_in_urb) {
+-                     if (devinfo->use_streams) {
+-                             cmdinfo->state |= DATA_COMPLETES_CMD;
+-                             usb_unlink_urb(cmdinfo->data_in_urb);
+-                     } else {
+-                             usb_free_urb(cmdinfo->data_in_urb);
+-                     }
+-              }
+-              if (!(cmdinfo->state & COMPLETED_DATA_OUT) &&
+-                              cmdinfo->data_out_urb) {
+-                      if (devinfo->use_streams) {
+-                              cmdinfo->state |= DATA_COMPLETES_CMD;
+-                              usb_unlink_urb(cmdinfo->data_in_urb);
+-                      } else {
+-                              usb_free_urb(cmdinfo->data_out_urb);
+-                      }
+-              }
+-
+               if (urb->actual_length < 16)
+                       devinfo->uas_sense_old = 1;
+               if (devinfo->uas_sense_old)
+@@ -264,59 +236,27 @@ static void uas_stat_cmplt(struct urb *u
+               dev_err(&urb->dev->dev, "failed submit status urb\n");
+ }
+-static void uas_data_out_cmplt(struct urb *urb)
+-{
+-      struct scsi_cmnd *cmnd = urb->context;
+-      struct scsi_data_buffer *sdb = scsi_out(cmnd);
+-      struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+-
+-      cmdinfo->state |= COMPLETED_DATA_OUT;
+-
+-      sdb->resid = sdb->length - urb->actual_length;
+-      usb_free_urb(urb);
+-
+-      if (cmdinfo->state & DATA_COMPLETES_CMD)
+-              cmnd->scsi_done(cmnd);
+-}
+-
+-static void uas_data_in_cmplt(struct urb *urb)
++static void uas_data_cmplt(struct urb *urb)
+ {
+-      struct scsi_cmnd *cmnd = urb->context;
+-      struct scsi_data_buffer *sdb = scsi_in(cmnd);
+-      struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+-
+-      cmdinfo->state |= COMPLETED_DATA_IN;
+-
++      struct scsi_data_buffer *sdb = urb->context;
+       sdb->resid = sdb->length - urb->actual_length;
+       usb_free_urb(urb);
+-
+-      if (cmdinfo->state & DATA_COMPLETES_CMD)
+-              cmnd->scsi_done(cmnd);
+ }
+ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
+-              unsigned int pipe, struct scsi_cmnd *cmnd,
+-              enum dma_data_direction dir)
++                              unsigned int pipe, u16 stream_id,
++                              struct scsi_data_buffer *sdb,
++                              enum dma_data_direction dir)
+ {
+-      struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+       struct usb_device *udev = devinfo->udev;
+       struct urb *urb = usb_alloc_urb(0, gfp);
+-      struct scsi_data_buffer *sdb;
+-      usb_complete_t complete_fn;
+-      u16 stream_id = cmdinfo->stream;
+       if (!urb)
+               goto out;
+-      if (dir == DMA_FROM_DEVICE) {
+-              sdb = scsi_in(cmnd);
+-              complete_fn = uas_data_in_cmplt;
+-      } else {
+-              sdb = scsi_out(cmnd);
+-              complete_fn = uas_data_out_cmplt;
+-      }
+-      usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length,
+-                      complete_fn, cmnd);
+-      urb->stream_id = stream_id;
++      usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt,
++                                                                      sdb);
++      if (devinfo->use_streams)
++              urb->stream_id = stream_id;
+       urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0;
+       urb->sg = sdb->table.sgl;
+  out:
+@@ -418,8 +358,8 @@ static int uas_submit_urbs(struct scsi_c
+       if (cmdinfo->state & ALLOC_DATA_IN_URB) {
+               cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp,
+-                                      devinfo->data_in_pipe, cmnd,
+-                                      DMA_FROM_DEVICE);
++                                      devinfo->data_in_pipe, cmdinfo->stream,
++                                      scsi_in(cmnd), DMA_FROM_DEVICE);
+               if (!cmdinfo->data_in_urb)
+                       return SCSI_MLQUEUE_DEVICE_BUSY;
+               cmdinfo->state &= ~ALLOC_DATA_IN_URB;
+@@ -436,8 +376,8 @@ static int uas_submit_urbs(struct scsi_c
+       if (cmdinfo->state & ALLOC_DATA_OUT_URB) {
+               cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp,
+-                                      devinfo->data_out_pipe, cmnd,
+-                                      DMA_TO_DEVICE);
++                                      devinfo->data_out_pipe, cmdinfo->stream,
++                                      scsi_out(cmnd), DMA_TO_DEVICE);
+               if (!cmdinfo->data_out_urb)
+                       return SCSI_MLQUEUE_DEVICE_BUSY;
+               cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
index 83c8507f2c03d191bdad8de67c5145b58ab60b72..4f7bd1034ee73bfed312138ff3b42114cf9ba0a9 100644 (file)
@@ -25,3 +25,7 @@ alsa-hda-add-support-for-realtek-alc282.patch
 alsa-hda-turn-on-pin_out-from-hdmi-playback-prepare.patch
 alsa-hda-don-t-power-up-when-not-powered-down.patch
 hid-hid-multitouch-fix-input-mode-feature-command.patch
+usbdevfs-correct-amount-of-data-copied-to-user-in-processcompl_compat.patch
+usb-gadget-fix-g_ether-interface-link-status.patch
+usb-option-add-zte-mf821d.patch
+revert-usb-uas-make-sure-data-urb-is-gone-if-we-receive-status-before-that.patch
diff --git a/queue-3.5/usb-gadget-fix-g_ether-interface-link-status.patch b/queue-3.5/usb-gadget-fix-g_ether-interface-link-status.patch
new file mode 100644 (file)
index 0000000..903a89c
--- /dev/null
@@ -0,0 +1,59 @@
+From 31bde1ceaa873bcaecd49e829bfabceacc4c512d Mon Sep 17 00:00:00 2001
+From: Kevin Cernekee <cernekee@gmail.com>
+Date: Sun, 24 Jun 2012 21:11:22 -0700
+Subject: usb: gadget: Fix g_ether interface link status
+
+From: Kevin Cernekee <cernekee@gmail.com>
+
+commit 31bde1ceaa873bcaecd49e829bfabceacc4c512d upstream.
+
+A "usb0" interface that has never been connected to a host has an unknown
+operstate, and therefore the IFF_RUNNING flag is (incorrectly) asserted
+when queried by ifconfig, ifplugd, etc.  This is a result of calling
+netif_carrier_off() too early in the probe function; it should be called
+after register_netdev().
+
+Similar problems have been fixed in many other drivers, e.g.:
+
+    e826eafa6 (bonding: Call netif_carrier_off after register_netdevice)
+    0d672e9f8 (drivers/net: Call netif_carrier_off at the end of the probe)
+    6a3c869a6 (cxgb4: fix reported state of interfaces without link)
+
+Fix is to move netif_carrier_off() to the end of the function.
+
+Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/u_ether.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -798,12 +798,6 @@ int gether_setup_name(struct usb_gadget
+       SET_ETHTOOL_OPS(net, &ops);
+-      /* two kinds of host-initiated state changes:
+-       *  - iff DATA transfer is active, carrier is "on"
+-       *  - tx queueing enabled if open *and* carrier is "on"
+-       */
+-      netif_carrier_off(net);
+-
+       dev->gadget = g;
+       SET_NETDEV_DEV(net, &g->dev);
+       SET_NETDEV_DEVTYPE(net, &gadget_type);
+@@ -817,6 +811,12 @@ int gether_setup_name(struct usb_gadget
+               INFO(dev, "HOST MAC %pM\n", dev->host_mac);
+               the_dev = dev;
++
++              /* two kinds of host-initiated state changes:
++               *  - iff DATA transfer is active, carrier is "on"
++               *  - tx queueing enabled if open *and* carrier is "on"
++               */
++              netif_carrier_off(net);
+       }
+       return status;
diff --git a/queue-3.5/usb-option-add-zte-mf821d.patch b/queue-3.5/usb-option-add-zte-mf821d.patch
new file mode 100644 (file)
index 0000000..1c51853
--- /dev/null
@@ -0,0 +1,30 @@
+From 09110529780890804b22e997ae6b4fe3f0b3b158 Mon Sep 17 00:00:00 2001
+From: Bjørn Mork <bjorn@mork.no>
+Date: Thu, 12 Jul 2012 12:37:32 +0200
+Subject: USB: option: add ZTE MF821D
+
+From: Bjørn Mork <bjorn@mork.no>
+
+commit 09110529780890804b22e997ae6b4fe3f0b3b158 upstream.
+
+Sold by O2 (telefonica germany) under the name "LTE4G"
+
+Tested-by: Thomas Schäfer <tschaefer@t-online.de>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -936,6 +936,8 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff),
+         .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff),
++        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff),
+         .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff),
diff --git a/queue-3.5/usbdevfs-correct-amount-of-data-copied-to-user-in-processcompl_compat.patch b/queue-3.5/usbdevfs-correct-amount-of-data-copied-to-user-in-processcompl_compat.patch
new file mode 100644 (file)
index 0000000..a6ecdae
--- /dev/null
@@ -0,0 +1,41 @@
+From 2102e06a5f2e414694921f23591f072a5ba7db9f Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 4 Jul 2012 09:18:01 +0200
+Subject: usbdevfs: Correct amount of data copied to user in processcompl_compat
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 2102e06a5f2e414694921f23591f072a5ba7db9f upstream.
+
+iso data buffers may have holes in them if some packets were short, so for
+iso urbs we should always copy the entire buffer, just like the regular
+processcompl does.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/devio.c |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -1604,10 +1604,14 @@ static int processcompl_compat(struct as
+       void __user *addr = as->userurb;
+       unsigned int i;
+-      if (as->userbuffer && urb->actual_length)
+-              if (copy_to_user(as->userbuffer, urb->transfer_buffer,
+-                               urb->actual_length))
++      if (as->userbuffer && urb->actual_length) {
++              if (urb->number_of_packets > 0)         /* Isochronous */
++                      i = urb->transfer_buffer_length;
++              else                                    /* Non-Isoc */
++                      i = urb->actual_length;
++              if (copy_to_user(as->userbuffer, urb->transfer_buffer, i))
+                       return -EFAULT;
++      }
+       if (put_user(as->status, &userurb->status))
+               return -EFAULT;
+       if (put_user(urb->actual_length, &userurb->actual_length))