From: Greg Kroah-Hartman Date: Wed, 2 Oct 2013 21:50:44 +0000 (-0700) Subject: 3.11-stable patches X-Git-Tag: v3.0.99~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c5ac1f7ec994787ce970bab425851674cfb005d9;p=thirdparty%2Fkernel%2Fstable-queue.git 3.11-stable patches added patches: dm-mpath-disable-write-same-if-it-fails.patch dm-snapshot-fix-performance-degradation-due-to-small-hash-size.patch dm-snapshot-workaround-for-a-false-positive-lockdep-warning.patch driver-core-fix-use-after-free-of-dev-parent-in-device_shutdown.patch fsl-usb-resolve-phy_clk_vld-instability-issue-for-ulpi-phy.patch usb-core-devio.c-don-t-reject-control-message-to-endpoint-with-wrong-direction-bit.patch usb-dwc3-add-support-for-merrifield.patch usb-dwc3-pci-add-support-for-baytrail.patch usb-fix-breakage-in-ffs_fs_mount.patch usb-fix-pm-config-symbol-in-uhci-hcd-ehci-hcd-and-xhci-hcd.patch usb-ohci-accept-very-late-isochronous-urbs.patch usb-uhci-accept-very-late-isochronous-urbs.patch xhci-ensure-a-command-structure-points-to-the-correct-trb-on-the-command-ring.patch xhci-fix-oops-happening-after-address-device-timeout.patch xhci-fix-race-between-ep-halt-and-urb-cancellation.patch --- diff --git a/queue-3.11/dm-mpath-disable-write-same-if-it-fails.patch b/queue-3.11/dm-mpath-disable-write-same-if-it-fails.patch new file mode 100644 index 00000000000..97864b27db3 --- /dev/null +++ b/queue-3.11/dm-mpath-disable-write-same-if-it-fails.patch @@ -0,0 +1,152 @@ +From f84cb8a46a771f36a04a02c61ea635c968ed5f6a Mon Sep 17 00:00:00 2001 +From: Mike Snitzer +Date: Thu, 19 Sep 2013 12:13:58 -0400 +Subject: dm mpath: disable WRITE SAME if it fails + +From: Mike Snitzer + +commit f84cb8a46a771f36a04a02c61ea635c968ed5f6a upstream. + +Workaround the SCSI layer's problematic WRITE SAME heuristics by +disabling WRITE SAME in the DM multipath device's queue_limits if an +underlying device disabled it. + +The WRITE SAME heuristics, with both the original commit 5db44863b6eb +("[SCSI] sd: Implement support for WRITE SAME") and the updated commit +66c28f971 ("[SCSI] sd: Update WRITE SAME heuristics"), default to enabling +WRITE SAME(10) even without successfully determining it is supported. +After the first failed WRITE SAME the SCSI layer will disable WRITE SAME +for the device (by setting sdkp->device->no_write_same which results in +'max_write_same_sectors' in device's queue_limits to be set to 0). + +When a device is stacked ontop of such a SCSI device any changes to that +SCSI device's queue_limits do not automatically propagate up the stack. +As such, a DM multipath device will not have its WRITE SAME support +disabled. This causes the block layer to continue to issue WRITE SAME +requests to the mpath device which causes paths to fail and (if mpath IO +isn't configured to queue when no paths are available) it will result in +actual IO errors to the upper layers. + +This fix doesn't help configurations that have additional devices +stacked ontop of the mpath device (e.g. LVM created linear DM devices +ontop). A proper fix that restacks all the queue_limits from the bottom +of the device stack up will need to be explored if SCSI will continue to +use this model of optimistically allowing op codes and then disabling +them after they fail for the first time. + +Before this patch: + +EXT4-fs (dm-6): mounted filesystem with ordered data mode. Opts: (null) +device-mapper: multipath: XXX snitm debugging: got -EREMOTEIO (-121) +device-mapper: multipath: XXX snitm debugging: failing WRITE SAME IO with error=-121 +end_request: critical target error, dev dm-6, sector 528 +dm-6: WRITE SAME failed. Manually zeroing. +device-mapper: multipath: Failing path 8:112. +end_request: I/O error, dev dm-6, sector 4616 +dm-6: WRITE SAME failed. Manually zeroing. +end_request: I/O error, dev dm-6, sector 4616 +end_request: I/O error, dev dm-6, sector 5640 +end_request: I/O error, dev dm-6, sector 6664 +end_request: I/O error, dev dm-6, sector 7688 +end_request: I/O error, dev dm-6, sector 524288 +Buffer I/O error on device dm-6, logical block 65536 +lost page write due to I/O error on dm-6 +JBD2: Error -5 detected when updating journal superblock for dm-6-8. +end_request: I/O error, dev dm-6, sector 524296 +Aborting journal on device dm-6-8. +end_request: I/O error, dev dm-6, sector 524288 +Buffer I/O error on device dm-6, logical block 65536 +lost page write due to I/O error on dm-6 +JBD2: Error -5 detected when updating journal superblock for dm-6-8. + +# cat /sys/block/sdh/queue/write_same_max_bytes +0 +# cat /sys/block/dm-6/queue/write_same_max_bytes +33553920 + +After this patch: + +EXT4-fs (dm-6): mounted filesystem with ordered data mode. Opts: (null) +device-mapper: multipath: XXX snitm debugging: got -EREMOTEIO (-121) +device-mapper: multipath: XXX snitm debugging: WRITE SAME I/O failed with error=-121 +end_request: critical target error, dev dm-6, sector 528 +dm-6: WRITE SAME failed. Manually zeroing. + +# cat /sys/block/sdh/queue/write_same_max_bytes +0 +# cat /sys/block/dm-6/queue/write_same_max_bytes +0 + +It should be noted that WRITE SAME support wasn't enabled in DM +multipath until v3.10. + +Signed-off-by: Mike Snitzer +Cc: Martin K. Petersen +Cc: Hannes Reinecke +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-mpath.c | 11 ++++++++++- + drivers/md/dm.c | 11 +++++++++++ + include/linux/device-mapper.h | 3 ++- + 3 files changed, 23 insertions(+), 2 deletions(-) + +--- a/drivers/md/dm-mpath.c ++++ b/drivers/md/dm-mpath.c +@@ -1284,8 +1284,17 @@ static int do_end_io(struct multipath *m + if (!error && !clone->errors) + return 0; /* I/O complete */ + +- if (error == -EOPNOTSUPP || error == -EREMOTEIO || error == -EILSEQ) ++ if (error == -EOPNOTSUPP || error == -EREMOTEIO || error == -EILSEQ) { ++ if ((clone->cmd_flags & REQ_WRITE_SAME) && ++ !clone->q->limits.max_write_same_sectors) { ++ struct queue_limits *limits; ++ ++ /* device doesn't really support WRITE SAME, disable it */ ++ limits = dm_get_queue_limits(dm_table_get_md(m->ti->table)); ++ limits->max_write_same_sectors = 0; ++ } + return error; ++ } + + if (mpio->pgpath) + fail_path(mpio->pgpath); +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -2250,6 +2250,17 @@ struct target_type *dm_get_immutable_tar + } + + /* ++ * The queue_limits are only valid as long as you have a reference ++ * count on 'md'. ++ */ ++struct queue_limits *dm_get_queue_limits(struct mapped_device *md) ++{ ++ BUG_ON(!atomic_read(&md->holders)); ++ return &md->queue->limits; ++} ++EXPORT_SYMBOL_GPL(dm_get_queue_limits); ++ ++/* + * Fully initialize a request-based queue (->elevator, ->request_fn, etc). + */ + static int dm_init_request_based_queue(struct mapped_device *md) +--- a/include/linux/device-mapper.h ++++ b/include/linux/device-mapper.h +@@ -405,13 +405,14 @@ int dm_noflush_suspending(struct dm_targ + union map_info *dm_get_mapinfo(struct bio *bio); + union map_info *dm_get_rq_mapinfo(struct request *rq); + ++struct queue_limits *dm_get_queue_limits(struct mapped_device *md); ++ + /* + * Geometry functions. + */ + int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo); + int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); + +- + /*----------------------------------------------------------------- + * Functions for manipulating device-mapper tables. + *---------------------------------------------------------------*/ diff --git a/queue-3.11/dm-snapshot-fix-performance-degradation-due-to-small-hash-size.patch b/queue-3.11/dm-snapshot-fix-performance-degradation-due-to-small-hash-size.patch new file mode 100644 index 00000000000..e34115f68fc --- /dev/null +++ b/queue-3.11/dm-snapshot-fix-performance-degradation-due-to-small-hash-size.patch @@ -0,0 +1,50 @@ +From 60e356f381954d79088d0455e357db48cfdd6857 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Wed, 18 Sep 2013 19:40:42 -0400 +Subject: dm-snapshot: fix performance degradation due to small hash size + +From: Mikulas Patocka + +commit 60e356f381954d79088d0455e357db48cfdd6857 upstream. + +LVM2, since version 2.02.96, creates origin with zero size, then loads +the snapshot driver and then loads the origin. Consequently, the +snapshot driver sees the origin size zero and sets the hash size to the +lower bound 64. Such small hash table causes performance degradation. + +This patch changes it so that the hash size is determined by the size of +snapshot volume, not minimum of origin and snapshot size. It doesn't +make sense to set the snapshot size significantly larger than the origin +size, so we do not need to take origin size into account when +calculating the hash size. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-snap.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -725,17 +725,16 @@ static int calc_max_buckets(void) + */ + static int init_hash_tables(struct dm_snapshot *s) + { +- sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; ++ sector_t hash_size, cow_dev_size, max_buckets; + + /* + * Calculate based on the size of the original volume or + * the COW volume... + */ + cow_dev_size = get_dev_size(s->cow->bdev); +- origin_dev_size = get_dev_size(s->origin->bdev); + max_buckets = calc_max_buckets(); + +- hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift; ++ hash_size = cow_dev_size >> s->store->chunk_shift; + hash_size = min(hash_size, max_buckets); + + if (hash_size < 64) diff --git a/queue-3.11/dm-snapshot-workaround-for-a-false-positive-lockdep-warning.patch b/queue-3.11/dm-snapshot-workaround-for-a-false-positive-lockdep-warning.patch new file mode 100644 index 00000000000..4c9304d50ee --- /dev/null +++ b/queue-3.11/dm-snapshot-workaround-for-a-false-positive-lockdep-warning.patch @@ -0,0 +1,47 @@ +From 5ea330a75bd86b2b2a01d7b85c516983238306fb Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Wed, 18 Sep 2013 19:14:22 -0400 +Subject: dm snapshot: workaround for a false positive lockdep warning + +From: Mikulas Patocka + +commit 5ea330a75bd86b2b2a01d7b85c516983238306fb upstream. + +The kernel reports a lockdep warning if a snapshot is invalidated because +it runs out of space. + +The lockdep warning was triggered by commit 0976dfc1d0cd80a4e9dfaf87bd87 +("workqueue: Catch more locking problems with flush_work()") in v3.5. + +The warning is false positive. The real cause for the warning is that +the lockdep engine treats different instances of md->lock as a single +lock. + +This patch is a workaround - we use flush_workqueue instead of flush_work. +This code path is not performance sensitive (it is called only on +initialization or invalidation), thus it doesn't matter that we flush the +whole workqueue. + +The real fix for the problem would be to teach the lockdep engine to treat +different instances of md->lock as separate locks. + +Signed-off-by: Mikulas Patocka +Acked-by: Alasdair G Kergon +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-snap-persistent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/md/dm-snap-persistent.c ++++ b/drivers/md/dm-snap-persistent.c +@@ -256,7 +256,7 @@ static int chunk_io(struct pstore *ps, v + */ + INIT_WORK_ONSTACK(&req.work, do_metadata); + queue_work(ps->metadata_wq, &req.work); +- flush_work(&req.work); ++ flush_workqueue(ps->metadata_wq); + + return req.result; + } diff --git a/queue-3.11/driver-core-fix-use-after-free-of-dev-parent-in-device_shutdown.patch b/queue-3.11/driver-core-fix-use-after-free-of-dev-parent-in-device_shutdown.patch new file mode 100644 index 00000000000..2c1b598775f --- /dev/null +++ b/queue-3.11/driver-core-fix-use-after-free-of-dev-parent-in-device_shutdown.patch @@ -0,0 +1,91 @@ +From f123db8e9d6c84c863cb3c44d17e61995dc984fb Mon Sep 17 00:00:00 2001 +From: Benson Leung +Date: Tue, 24 Sep 2013 20:05:11 -0700 +Subject: driver core : Fix use after free of dev->parent in device_shutdown + +From: Benson Leung + +commit f123db8e9d6c84c863cb3c44d17e61995dc984fb upstream. + +The put_device(dev) at the bottom of the loop of device_shutdown +may result in the dev being cleaned up. In device_create_release, +the dev is kfreed. + +However, device_shutdown attempts to use the dev pointer again after +put_device by referring to dev->parent. + +Copy the parent pointer instead to avoid this condition. + +This bug was found on Chromium OS's chromeos-3.8, which is based on v3.8.11. +See bug report : https://code.google.com/p/chromium/issues/detail?id=297842 +This can easily be reproduced when shutting down with +hidraw devices that report battery condition. +Two examples are the HP Bluetooth Mouse X4000b and the Apple Magic Mouse. +For example, with the magic mouse : +The dev in question is "hidraw0" +dev->parent is "magicmouse" + +In the course of the shutdown for this device, the input event cleanup calls +a put on hidraw0, decrementing its reference count. +When we finally get to put_device(dev) in device_shutdown, kobject_cleanup +is called and device_create_release does kfree(dev). +dev->parent is no longer valid, and we may crash in +put_device(dev->parent). + +This change should be applied on any kernel with this change : +d1c6c030fcec6f860d9bb6c632a3ebe62e28440b + +Signed-off-by: Benson Leung +Reviewed-by: Ming Lei +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/core.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -2033,7 +2033,7 @@ EXPORT_SYMBOL_GPL(device_move); + */ + void device_shutdown(void) + { +- struct device *dev; ++ struct device *dev, *parent; + + spin_lock(&devices_kset->list_lock); + /* +@@ -2050,7 +2050,7 @@ void device_shutdown(void) + * prevent it from being freed because parent's + * lock is to be held + */ +- get_device(dev->parent); ++ parent = get_device(dev->parent); + get_device(dev); + /* + * Make sure the device is off the kset list, in the +@@ -2060,8 +2060,8 @@ void device_shutdown(void) + spin_unlock(&devices_kset->list_lock); + + /* hold lock to avoid race with probe/release */ +- if (dev->parent) +- device_lock(dev->parent); ++ if (parent) ++ device_lock(parent); + device_lock(dev); + + /* Don't allow any more runtime suspends */ +@@ -2079,11 +2079,11 @@ void device_shutdown(void) + } + + device_unlock(dev); +- if (dev->parent) +- device_unlock(dev->parent); ++ if (parent) ++ device_unlock(parent); + + put_device(dev); +- put_device(dev->parent); ++ put_device(parent); + + spin_lock(&devices_kset->list_lock); + } diff --git a/queue-3.11/fsl-usb-resolve-phy_clk_vld-instability-issue-for-ulpi-phy.patch b/queue-3.11/fsl-usb-resolve-phy_clk_vld-instability-issue-for-ulpi-phy.patch new file mode 100644 index 00000000000..804a76c8a77 --- /dev/null +++ b/queue-3.11/fsl-usb-resolve-phy_clk_vld-instability-issue-for-ulpi-phy.patch @@ -0,0 +1,50 @@ +From ad1260e9fbf768d6bed227d9604ebee76a84aae3 Mon Sep 17 00:00:00 2001 +From: Ramneek Mehresh +Date: Mon, 16 Sep 2013 15:11:33 +0530 +Subject: fsl/usb: Resolve PHY_CLK_VLD instability issue for ULPI phy + +From: Ramneek Mehresh + +commit ad1260e9fbf768d6bed227d9604ebee76a84aae3 upstream. + +For controller versions greater than 1.6, setting ULPI_PHY_CLK_SEL +bit when USB_EN bit is already set causes instability issues with +PHY_CLK_VLD bit. So USB_EN is set only for IP controller version +below 1.6 before setting ULPI_PHY_CLK_SEL bit + +Signed-off-by: Ramneek Mehresh +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-fsl.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +--- a/drivers/usb/host/ehci-fsl.c ++++ b/drivers/usb/host/ehci-fsl.c +@@ -130,7 +130,7 @@ static int usb_hcd_fsl_probe(const struc + } + + /* Enable USB controller, 83xx or 8536 */ +- if (pdata->have_sysif_regs) ++ if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) + setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4); + + /* Don't need to set host mode here. It will be done by tdi_reset() */ +@@ -232,15 +232,9 @@ static int ehci_fsl_setup_phy(struct usb + case FSL_USB2_PHY_ULPI: + if (pdata->have_sysif_regs && pdata->controller_ver) { + /* controller version 1.6 or above */ ++ clrbits32(non_ehci + FSL_SOC_USB_CTRL, UTMI_PHY_EN); + setbits32(non_ehci + FSL_SOC_USB_CTRL, +- ULPI_PHY_CLK_SEL); +- /* +- * Due to controller issue of PHY_CLK_VALID in ULPI +- * mode, we set USB_CTRL_USB_EN before checking +- * PHY_CLK_VALID, otherwise PHY_CLK_VALID doesn't work. +- */ +- clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, +- UTMI_PHY_EN, USB_CTRL_USB_EN); ++ ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN); + } + portsc |= PORT_PTS_ULPI; + break; diff --git a/queue-3.11/series b/queue-3.11/series index 897a7161609..8c16ef77ae8 100644 --- a/queue-3.11/series +++ b/queue-3.11/series @@ -26,3 +26,18 @@ staging-vt6656-iwctl_siwencodeext-return-if-device-not-open.patch drm-i915-tv-clear-adjusted_mode.flags.patch revert-cw1200-don-t-perform-spi-transfers-in-interrupt-context.patch cw1200-use-a-threaded-oneshot-irq-handler-for-cw1200_spi.patch +xhci-ensure-a-command-structure-points-to-the-correct-trb-on-the-command-ring.patch +xhci-fix-oops-happening-after-address-device-timeout.patch +usb-fix-pm-config-symbol-in-uhci-hcd-ehci-hcd-and-xhci-hcd.patch +xhci-fix-race-between-ep-halt-and-urb-cancellation.patch +usb-ohci-accept-very-late-isochronous-urbs.patch +usb-uhci-accept-very-late-isochronous-urbs.patch +usb-fix-breakage-in-ffs_fs_mount.patch +fsl-usb-resolve-phy_clk_vld-instability-issue-for-ulpi-phy.patch +usb-dwc3-pci-add-support-for-baytrail.patch +usb-dwc3-add-support-for-merrifield.patch +usb-core-devio.c-don-t-reject-control-message-to-endpoint-with-wrong-direction-bit.patch +driver-core-fix-use-after-free-of-dev-parent-in-device_shutdown.patch +dm-snapshot-workaround-for-a-false-positive-lockdep-warning.patch +dm-snapshot-fix-performance-degradation-due-to-small-hash-size.patch +dm-mpath-disable-write-same-if-it-fails.patch diff --git a/queue-3.11/usb-core-devio.c-don-t-reject-control-message-to-endpoint-with-wrong-direction-bit.patch b/queue-3.11/usb-core-devio.c-don-t-reject-control-message-to-endpoint-with-wrong-direction-bit.patch new file mode 100644 index 00000000000..4a37ea832e5 --- /dev/null +++ b/queue-3.11/usb-core-devio.c-don-t-reject-control-message-to-endpoint-with-wrong-direction-bit.patch @@ -0,0 +1,83 @@ +From 831abf76643555a99b80a3b54adfa7e4fa0a3259 Mon Sep 17 00:00:00 2001 +From: Kurt Garloff +Date: Tue, 24 Sep 2013 14:13:48 +0200 +Subject: usb/core/devio.c: Don't reject control message to endpoint with wrong direction bit + +From: Kurt Garloff + +commit 831abf76643555a99b80a3b54adfa7e4fa0a3259 upstream. + +Trying to read data from the Pegasus Technologies NoteTaker (0e20:0101) +[1] with the Windows App (EasyNote) works natively but fails when +Windows is running under KVM (and the USB device handed to KVM). + +The reason is a USB control message + usb 4-2.2: control urb: bRequestType=22 bRequest=09 wValue=0200 wIndex=0001 wLength=0008 +This goes to endpoint address 0x01 (wIndex); however, endpoint address +0x01 does not exist. There is an endpoint 0x81 though (same number, +but other direction); the app may have meant that endpoint instead. + +The kernel thus rejects the IO and thus we see the failure. + +Apparently, Linux is more strict here than Windows ... we can't change +the Win app easily, so that's a problem. + +It seems that the Win app/driver is buggy here and the driver does not +behave fully according to the USB HID class spec that it claims to +belong to. The device seems to happily deal with that though (and +seems to not really care about this value much). + +So the question is whether the Linux kernel should filter here. +Rejecting has the risk that somewhat non-compliant userspace apps/ +drivers (most likely in a virtual machine) are prevented from working. +Not rejecting has the risk of confusing an overly sensitive device with +such a transfer. Given the fact that Windows does not filter it makes +this risk rather small though. + +The patch makes the kernel more tolerant: If the endpoint address in +wIndex does not exist, but an endpoint with toggled direction bit does, +it will let the transfer through. (It does NOT change the message.) + +With attached patch, the app in Windows in KVM works. + usb 4-2.2: check_ctrlrecip: process 13073 (qemu-kvm) requesting ep 01 but needs 81 + +I suspect this will mostly affect apps in virtual environments; as on +Linux the apps would have been adapted to the stricter handling of the +kernel. I have done that for mine[2]. + +[1] http://www.pegatech.com/ +[2] https://sourceforge.net/projects/notetakerpen/ + +Signed-off-by: Kurt Garloff +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devio.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -742,6 +742,22 @@ static int check_ctrlrecip(struct dev_st + if ((index & ~USB_DIR_IN) == 0) + return 0; + ret = findintfep(ps->dev, index); ++ if (ret < 0) { ++ /* ++ * Some not fully compliant Win apps seem to get ++ * index wrong and have the endpoint number here ++ * rather than the endpoint address (with the ++ * correct direction). Win does let this through, ++ * so we'll not reject it here but leave it to ++ * the device to not break KVM. But we warn. ++ */ ++ ret = findintfep(ps->dev, index ^ 0x80); ++ if (ret >= 0) ++ dev_info(&ps->dev->dev, ++ "%s: process %i (%s) requesting ep %02x but needs %02x\n", ++ __func__, task_pid_nr(current), ++ current->comm, index, index ^ 0x80); ++ } + if (ret >= 0) + ret = checkintf(ps, ret); + break; diff --git a/queue-3.11/usb-dwc3-add-support-for-merrifield.patch b/queue-3.11/usb-dwc3-add-support-for-merrifield.patch new file mode 100644 index 00000000000..ee89f29173c --- /dev/null +++ b/queue-3.11/usb-dwc3-add-support-for-merrifield.patch @@ -0,0 +1,36 @@ +From 85601f8cf67c56a561a6dd5e130e65fdc179047d Mon Sep 17 00:00:00 2001 +From: David Cohen +Date: Thu, 26 Sep 2013 13:01:44 -0700 +Subject: usb: dwc3: add support for Merrifield + +From: David Cohen + +commit 85601f8cf67c56a561a6dd5e130e65fdc179047d upstream. + +Add PCI id for Intel Merrifield + +Signed-off-by: David Cohen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/dwc3-pci.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -49,6 +49,7 @@ + #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 + #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd + #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 ++#define PCI_DEVICE_ID_INTEL_MRFLD 0x119e + + struct dwc3_pci { + struct device *dev; +@@ -209,6 +210,7 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_ + PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), + }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, + { } /* Terminating Entry */ + }; + MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); diff --git a/queue-3.11/usb-dwc3-pci-add-support-for-baytrail.patch b/queue-3.11/usb-dwc3-pci-add-support-for-baytrail.patch new file mode 100644 index 00000000000..259c40ef845 --- /dev/null +++ b/queue-3.11/usb-dwc3-pci-add-support-for-baytrail.patch @@ -0,0 +1,37 @@ +From b62cd96de3161dfb125a769030eec35a4cab3d3a Mon Sep 17 00:00:00 2001 +From: Heikki Krogerus +Date: Tue, 17 Sep 2013 10:38:13 +0300 +Subject: usb: dwc3: pci: add support for BayTrail + +From: Heikki Krogerus + +commit b62cd96de3161dfb125a769030eec35a4cab3d3a upstream. + +Add PCI id for Intel BayTrail. + +Signed-off-by: Heikki Krogerus +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/dwc3-pci.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -48,6 +48,7 @@ + /* FIXME define these in */ + #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 + #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd ++#define PCI_DEVICE_ID_INTEL_BYT 0x0f37 + + struct dwc3_pci { + struct device *dev; +@@ -207,6 +208,7 @@ static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_ + PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, + PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), + }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, + { } /* Terminating Entry */ + }; + MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); diff --git a/queue-3.11/usb-fix-breakage-in-ffs_fs_mount.patch b/queue-3.11/usb-fix-breakage-in-ffs_fs_mount.patch new file mode 100644 index 00000000000..847c44a59c4 --- /dev/null +++ b/queue-3.11/usb-fix-breakage-in-ffs_fs_mount.patch @@ -0,0 +1,187 @@ +From 2606b28aabd7dea1766c23a105e1124c95409c96 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 20 Sep 2013 17:14:21 +0100 +Subject: USB: Fix breakage in ffs_fs_mount() + +From: Al Viro + +commit 2606b28aabd7dea1766c23a105e1124c95409c96 upstream. + + There's a bunch of failure exits in ffs_fs_mount() with +seriously broken recovery logics. Most of that appears to stem +from misunderstanding of the ->kill_sb() semantics; unlike +->put_super() it is called for *all* superblocks of given type, +no matter how (in)complete the setup had been. ->put_super() +is called only if ->s_root is not NULL; any failure prior to +setting ->s_root will have the call of ->put_super() skipped. +->kill_sb(), OTOH, awaits every superblock that has come from +sget(). + +Current behaviour of ffs_fs_mount(): + +We have struct ffs_sb_fill_data data on stack there. We do + ffs_dev = functionfs_acquire_dev_callback(dev_name); +and store that in data.private_data. Then we call mount_nodev(), +passing it ffs_sb_fill() as a callback. That will either fail +outright, or manage to call ffs_sb_fill(). There we allocate an +instance of struct ffs_data, slap the value of ffs_dev (picked +from data.private_data) into ffs->private_data and overwrite +data.private_data by storing ffs into an overlapping member +(data.ffs_data). Then we store ffs into sb->s_fs_info and attempt +to set the rest of the things up (root inode, root dentry, then +create /ep0 there). Any of those might fail. Should that +happen, we get ffs_fs_kill_sb() called before mount_nodev() +returns. If mount_nodev() fails for any reason whatsoever, +we proceed to + functionfs_release_dev_callback(data.ffs_data); + +That's broken in a lot of ways. Suppose the thing has failed in +allocation of e.g. root inode or dentry. We have + functionfs_release_dev_callback(ffs); + ffs_data_put(ffs); +done by ffs_fs_kill_sb() (ffs accessed via sb->s_fs_info), followed by + functionfs_release_dev_callback(ffs); +from ffs_fs_mount() (via data.ffs_data). Note that the second +functionfs_release_dev_callback() has every chance to be done to freed memory. + +Suppose we fail *before* root inode allocation. What happens then? +ffs_fs_kill_sb() doesn't do anything to ffs (it's either not called at all, +or it doesn't have a pointer to ffs stored in sb->s_fs_info). And + functionfs_release_dev_callback(data.ffs_data); +is called by ffs_fs_mount(), but here we are in nasal daemon country - we +are reading from a member of union we'd never stored into. In practice, +we'll get what we used to store into the overlapping field, i.e. ffs_dev. +And then we get screwed, since we treat it (struct gfs_ffs_obj * in +disguise, returned by functionfs_acquire_dev_callback()) as struct +ffs_data *, pick what would've been ffs_data ->private_data from it +(*well* past the actual end of the struct gfs_ffs_obj - struct ffs_data +is much bigger) and poke in whatever it points to. + +FWIW, there's a minor leak on top of all that in case if ffs_sb_fill() +fails on kstrdup() - ffs is obviously forgotten. + +The thing is, there is no point in playing all those games with union. +Just allocate and initialize ffs_data *before* calling mount_nodev() and +pass a pointer to it via data.ffs_data. And once it's stored in +sb->s_fs_info, clear data.ffs_data, so that ffs_fs_mount() knows that +it doesn't need to kill the sucker manually - from that point on +we'll have it done by ->kill_sb(). + +Signed-off-by: Al Viro +Acked-by: Michal Nazarewicz +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/f_fs.c | 60 +++++++++++++++++++--------------------------- + 1 file changed, 26 insertions(+), 34 deletions(-) + +--- a/drivers/usb/gadget/f_fs.c ++++ b/drivers/usb/gadget/f_fs.c +@@ -1034,37 +1034,19 @@ struct ffs_sb_fill_data { + struct ffs_file_perms perms; + umode_t root_mode; + const char *dev_name; +- union { +- /* set by ffs_fs_mount(), read by ffs_sb_fill() */ +- void *private_data; +- /* set by ffs_sb_fill(), read by ffs_fs_mount */ +- struct ffs_data *ffs_data; +- }; ++ struct ffs_data *ffs_data; + }; + + static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) + { + struct ffs_sb_fill_data *data = _data; + struct inode *inode; +- struct ffs_data *ffs; ++ struct ffs_data *ffs = data->ffs_data; + + ENTER(); + +- /* Initialise data */ +- ffs = ffs_data_new(); +- if (unlikely(!ffs)) +- goto Enomem; +- + ffs->sb = sb; +- ffs->dev_name = kstrdup(data->dev_name, GFP_KERNEL); +- if (unlikely(!ffs->dev_name)) +- goto Enomem; +- ffs->file_perms = data->perms; +- ffs->private_data = data->private_data; +- +- /* used by the caller of this function */ +- data->ffs_data = ffs; +- ++ data->ffs_data = NULL; + sb->s_fs_info = ffs; + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; +@@ -1080,17 +1062,14 @@ static int ffs_sb_fill(struct super_bloc + &data->perms); + sb->s_root = d_make_root(inode); + if (unlikely(!sb->s_root)) +- goto Enomem; ++ return -ENOMEM; + + /* EP0 file */ + if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs, + &ffs_ep0_operations, NULL))) +- goto Enomem; ++ return -ENOMEM; + + return 0; +- +-Enomem: +- return -ENOMEM; + } + + static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) +@@ -1193,6 +1172,7 @@ ffs_fs_mount(struct file_system_type *t, + struct dentry *rv; + int ret; + void *ffs_dev; ++ struct ffs_data *ffs; + + ENTER(); + +@@ -1200,18 +1180,30 @@ ffs_fs_mount(struct file_system_type *t, + if (unlikely(ret < 0)) + return ERR_PTR(ret); + ++ ffs = ffs_data_new(); ++ if (unlikely(!ffs)) ++ return ERR_PTR(-ENOMEM); ++ ffs->file_perms = data.perms; ++ ++ ffs->dev_name = kstrdup(dev_name, GFP_KERNEL); ++ if (unlikely(!ffs->dev_name)) { ++ ffs_data_put(ffs); ++ return ERR_PTR(-ENOMEM); ++ } ++ + ffs_dev = functionfs_acquire_dev_callback(dev_name); +- if (IS_ERR(ffs_dev)) +- return ffs_dev; ++ if (IS_ERR(ffs_dev)) { ++ ffs_data_put(ffs); ++ return ERR_CAST(ffs_dev); ++ } ++ ffs->private_data = ffs_dev; ++ data.ffs_data = ffs; + +- data.dev_name = dev_name; +- data.private_data = ffs_dev; + rv = mount_nodev(t, flags, &data, ffs_sb_fill); +- +- /* data.ffs_data is set by ffs_sb_fill */ +- if (IS_ERR(rv)) ++ if (IS_ERR(rv) && data.ffs_data) { + functionfs_release_dev_callback(data.ffs_data); +- ++ ffs_data_put(data.ffs_data); ++ } + return rv; + } + diff --git a/queue-3.11/usb-fix-pm-config-symbol-in-uhci-hcd-ehci-hcd-and-xhci-hcd.patch b/queue-3.11/usb-fix-pm-config-symbol-in-uhci-hcd-ehci-hcd-and-xhci-hcd.patch new file mode 100644 index 00000000000..760efbac7bc --- /dev/null +++ b/queue-3.11/usb-fix-pm-config-symbol-in-uhci-hcd-ehci-hcd-and-xhci-hcd.patch @@ -0,0 +1,60 @@ +From f875fdbf344b9fde207f66b392c40845dd7e5aa6 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 24 Sep 2013 15:45:25 -0400 +Subject: USB: fix PM config symbol in uhci-hcd, ehci-hcd, and xhci-hcd + +From: Alan Stern + +commit f875fdbf344b9fde207f66b392c40845dd7e5aa6 upstream. + +Since uhci-hcd, ehci-hcd, and xhci-hcd support runtime PM, the .pm +field in their pci_driver structures should be protected by CONFIG_PM +rather than CONFIG_PM_SLEEP. The corresponding change has already +been made for ohci-hcd. + +Without this change, controllers won't do runtime suspend if system +suspend or hibernation isn't enabled. + +Signed-off-by: Alan Stern +CC: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-pci.c | 2 +- + drivers/usb/host/uhci-pci.c | 2 +- + drivers/usb/host/xhci-pci.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/ehci-pci.c ++++ b/drivers/usb/host/ehci-pci.c +@@ -403,7 +403,7 @@ static struct pci_driver ehci_pci_driver + .remove = usb_hcd_pci_remove, + .shutdown = usb_hcd_pci_shutdown, + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, +--- a/drivers/usb/host/uhci-pci.c ++++ b/drivers/usb/host/uhci-pci.c +@@ -293,7 +293,7 @@ static struct pci_driver uhci_pci_driver + .remove = usb_hcd_pci_remove, + .shutdown = uhci_shutdown, + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -345,7 +345,7 @@ static struct pci_driver xhci_pci_driver + /* suspend and resume implemented later */ + + .shutdown = usb_hcd_pci_shutdown, +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_PM + .driver = { + .pm = &usb_hcd_pci_pm_ops + }, diff --git a/queue-3.11/usb-ohci-accept-very-late-isochronous-urbs.patch b/queue-3.11/usb-ohci-accept-very-late-isochronous-urbs.patch new file mode 100644 index 00000000000..be803673e5a --- /dev/null +++ b/queue-3.11/usb-ohci-accept-very-late-isochronous-urbs.patch @@ -0,0 +1,166 @@ +From a8693424c751b8247ee19bd8b857f1d4f432b972 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 24 Sep 2013 15:46:45 -0400 +Subject: USB: OHCI: accept very late isochronous URBs + +From: Alan Stern + +commit a8693424c751b8247ee19bd8b857f1d4f432b972 upstream. + +Commit 24f531371de1 (USB: EHCI: accept very late isochronous URBs) +changed the isochronous API provided by ehci-hcd. URBs submitted too +late, so that the time slots for all their packets have already +expired, are no longer rejected outright. Instead the submission is +accepted, and the URB completes normally with a -EXDEV error for each +packet. This is what client drivers expect. + +This patch implements the same policy in ohci-hcd. The change is more +complicated than it was in ehci-hcd, because ohci-hcd doesn't scan for +isochronous completions in the same way as ehci-hcd does. Rather, it +depends on the hardware adding completed TDs to a "done queue". Some +OHCI controller don't handle this properly when a TD's time slot has +already expired, so we have to avoid adding such TDs to the schedule +in the first place. As a result, if the URB was submitted too late +then none of its TDs will get put on the schedule, so none of them +will end up on the done queue, so the driver will never realize that +the URB should be completed. + +To solve this problem, the patch adds one to urb_priv->td_cnt for such +URBs, making it larger than urb_priv->length (td_cnt already gets set +to the number of TD's that had to be skipped because their slots have +expired). Each time an URB is given back, the finish_urb() routine +looks to see if urb_priv->td_cnt for the next URB on the same endpoint +is marked in this way. If so, it gives back the next URB right away. + +This should be applied to all kernels containing commit 815fa7b91761 +(USB: OHCI: fix logic for scheduling isochronous URBs). + +Signed-off-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ohci-hcd.c | 22 ++++++++++++---------- + drivers/usb/host/ohci-q.c | 26 ++++++++++++++++++++++---- + 2 files changed, 34 insertions(+), 14 deletions(-) + +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -216,31 +216,26 @@ static int ohci_urb_enqueue ( + frame &= ~(ed->interval - 1); + frame |= ed->branch; + urb->start_frame = frame; ++ ed->last_iso = frame + ed->interval * (size - 1); + } + } else if (ed->type == PIPE_ISOCHRONOUS) { + u16 next = ohci_frame_no(ohci) + 1; + u16 frame = ed->last_iso + ed->interval; ++ u16 length = ed->interval * (size - 1); + + /* Behind the scheduling threshold? */ + if (unlikely(tick_before(frame, next))) { + +- /* USB_ISO_ASAP: Round up to the first available slot */ ++ /* URB_ISO_ASAP: Round up to the first available slot */ + if (urb->transfer_flags & URB_ISO_ASAP) { + frame += (next - frame + ed->interval - 1) & + -ed->interval; + + /* +- * Not ASAP: Use the next slot in the stream. If +- * the entire URB falls before the threshold, fail. ++ * Not ASAP: Use the next slot in the stream, ++ * no matter what. + */ + } else { +- if (tick_before(frame + ed->interval * +- (urb->number_of_packets - 1), next)) { +- retval = -EXDEV; +- usb_hcd_unlink_urb_from_ep(hcd, urb); +- goto fail; +- } +- + /* + * Some OHCI hardware doesn't handle late TDs + * correctly. After retiring them it proceeds +@@ -251,9 +246,16 @@ static int ohci_urb_enqueue ( + urb_priv->td_cnt = DIV_ROUND_UP( + (u16) (next - frame), + ed->interval); ++ if (urb_priv->td_cnt >= urb_priv->length) { ++ ++urb_priv->td_cnt; /* Mark it */ ++ ohci_dbg(ohci, "iso underrun %p (%u+%u < %u)\n", ++ urb, frame, length, ++ next); ++ } + } + } + urb->start_frame = frame; ++ ed->last_iso = frame + length; + } + + /* fill the TDs and link them to the ed; and +--- a/drivers/usb/host/ohci-q.c ++++ b/drivers/usb/host/ohci-q.c +@@ -41,9 +41,13 @@ finish_urb(struct ohci_hcd *ohci, struct + __releases(ohci->lock) + __acquires(ohci->lock) + { +- struct device *dev = ohci_to_hcd(ohci)->self.controller; ++ struct device *dev = ohci_to_hcd(ohci)->self.controller; ++ struct usb_host_endpoint *ep = urb->ep; ++ struct urb_priv *urb_priv; ++ + // ASSERT (urb->hcpriv != 0); + ++ restart: + urb_free_priv (ohci, urb->hcpriv); + urb->hcpriv = NULL; + if (likely(status == -EINPROGRESS)) +@@ -80,6 +84,21 @@ __acquires(ohci->lock) + ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_IE); + ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); + } ++ ++ /* ++ * An isochronous URB that is sumitted too late won't have any TDs ++ * (marked by the fact that the td_cnt value is larger than the ++ * actual number of TDs). If the next URB on this endpoint is like ++ * that, give it back now. ++ */ ++ if (!list_empty(&ep->urb_list)) { ++ urb = list_first_entry(&ep->urb_list, struct urb, urb_list); ++ urb_priv = urb->hcpriv; ++ if (urb_priv->td_cnt > urb_priv->length) { ++ status = 0; ++ goto restart; ++ } ++ } + } + + +@@ -546,7 +565,6 @@ td_fill (struct ohci_hcd *ohci, u32 info + td->hwCBP = cpu_to_hc32 (ohci, data & 0xFFFFF000); + *ohci_hwPSWp(ohci, td, 0) = cpu_to_hc16 (ohci, + (data & 0x0FFF) | 0xE000); +- td->ed->last_iso = info & 0xffff; + } else { + td->hwCBP = cpu_to_hc32 (ohci, data); + } +@@ -996,7 +1014,7 @@ rescan_this: + urb_priv->td_cnt++; + + /* if URB is done, clean up */ +- if (urb_priv->td_cnt == urb_priv->length) { ++ if (urb_priv->td_cnt >= urb_priv->length) { + modified = completed = 1; + finish_urb(ohci, urb, 0); + } +@@ -1086,7 +1104,7 @@ static void takeback_td(struct ohci_hcd + urb_priv->td_cnt++; + + /* If all this urb's TDs are done, call complete() */ +- if (urb_priv->td_cnt == urb_priv->length) ++ if (urb_priv->td_cnt >= urb_priv->length) + finish_urb(ohci, urb, status); + + /* clean schedule: unlink EDs that are no longer busy */ diff --git a/queue-3.11/usb-uhci-accept-very-late-isochronous-urbs.patch b/queue-3.11/usb-uhci-accept-very-late-isochronous-urbs.patch new file mode 100644 index 00000000000..3d33f67c231 --- /dev/null +++ b/queue-3.11/usb-uhci-accept-very-late-isochronous-urbs.patch @@ -0,0 +1,59 @@ +From bef073b067a7b1874a6b381e0035bb0516d71a77 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 24 Sep 2013 15:47:20 -0400 +Subject: USB: UHCI: accept very late isochronous URBs + +From: Alan Stern + +commit bef073b067a7b1874a6b381e0035bb0516d71a77 upstream. + +Commit 24f531371de1 (USB: EHCI: accept very late isochronous URBs) +changed the isochronous API provided by ehci-hcd. URBs submitted too +late, so that the time slots for all their packets have already +expired, are no longer rejected outright. Instead the submission is +accepted, and the URB completes normally with a -EXDEV error for each +packet. This is what client drivers expect. + +This patch implements the same policy in uhci-hcd. It should be +applied to all kernels containing commit c44b225077bb (UHCI: implement +new semantics for URB_ISO_ASAP). + +Signed-off-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/uhci-q.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/uhci-q.c ++++ b/drivers/usb/host/uhci-q.c +@@ -1303,7 +1303,7 @@ static int uhci_submit_isochronous(struc + } + + /* Fell behind? */ +- if (uhci_frame_before_eq(frame, next)) { ++ if (!uhci_frame_before_eq(next, frame)) { + + /* USB_ISO_ASAP: Round up to the first available slot */ + if (urb->transfer_flags & URB_ISO_ASAP) +@@ -1311,13 +1311,17 @@ static int uhci_submit_isochronous(struc + -qh->period; + + /* +- * Not ASAP: Use the next slot in the stream. If +- * the entire URB falls before the threshold, fail. ++ * Not ASAP: Use the next slot in the stream, ++ * no matter what. + */ + else if (!uhci_frame_before_eq(next, + frame + (urb->number_of_packets - 1) * + qh->period)) +- return -EXDEV; ++ dev_dbg(uhci_dev(uhci), "iso underrun %p (%u+%u < %u)\n", ++ urb, frame, ++ (urb->number_of_packets - 1) * ++ qh->period, ++ next); + } + } + diff --git a/queue-3.11/xhci-ensure-a-command-structure-points-to-the-correct-trb-on-the-command-ring.patch b/queue-3.11/xhci-ensure-a-command-structure-points-to-the-correct-trb-on-the-command-ring.patch new file mode 100644 index 00000000000..80f12946c01 --- /dev/null +++ b/queue-3.11/xhci-ensure-a-command-structure-points-to-the-correct-trb-on-the-command-ring.patch @@ -0,0 +1,144 @@ +From ec7e43e2d98173483866fe2e4e690143626b659c Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Fri, 30 Aug 2013 18:25:49 +0300 +Subject: xhci: Ensure a command structure points to the correct trb on the command ring + +From: Mathias Nyman + +commit ec7e43e2d98173483866fe2e4e690143626b659c upstream. + +If a command on the command ring needs to be cancelled before it is handled +it can be turned to a no-op operation when the ring is stopped. +We want to store the command ring enqueue pointer in the command structure +when the command in enqueued for the cancellation case. + +Some commands used to store the command ring dequeue pointers instead of enqueue +(these often worked because enqueue happends to equal dequeue quite often) + +Other commands correctly used the enqueue pointer but did not check if it pointed +to a valid trb or a link trb, this caused for example stop endpoint command to timeout in +xhci_stop_device() in about 2% of suspend/resume cases. + +This should also solve some weird behavior happening in command cancellation cases. + +This patch is based on a patch submitted by Sarah Sharp to linux-usb, but +then forgotten: + http://marc.info/?l=linux-usb&m=136269803207465&w=2 + +This patch should be backported to kernels as old as 3.7, that contain +the commit b92cc66c047ff7cf587b318fe377061a353c120f "xHCI: add aborting +command ring function" + +Signed-off-by: Mathias Nyman +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hub.c | 2 +- + drivers/usb/host/xhci-ring.c | 10 ++++++++++ + drivers/usb/host/xhci.c | 25 +++++-------------------- + drivers/usb/host/xhci.h | 1 + + 4 files changed, 17 insertions(+), 21 deletions(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -286,7 +286,7 @@ static int xhci_stop_device(struct xhci_ + if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) + xhci_queue_stop_endpoint(xhci, slot_id, i, suspend); + } +- cmd->command_trb = xhci->cmd_ring->enqueue; ++ cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); + list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list); + xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend); + xhci_ring_cmd_db(xhci); +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -122,6 +122,16 @@ static int enqueue_is_link_trb(struct xh + return TRB_TYPE_LINK_LE32(link->control); + } + ++union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring) ++{ ++ /* Enqueue pointer can be left pointing to the link TRB, ++ * we must handle that ++ */ ++ if (TRB_TYPE_LINK_LE32(ring->enqueue->link.control)) ++ return ring->enq_seg->next->trbs; ++ return ring->enqueue; ++} ++ + /* Updates trb to point to the next TRB in the ring, and updates seg if the next + * TRB is in a new segment. This does not skip over link TRBs, and it does not + * effect the ring dequeue or enqueue pointers. +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -2635,15 +2635,7 @@ static int xhci_configure_endpoint(struc + if (command) { + cmd_completion = command->completion; + cmd_status = &command->status; +- command->command_trb = xhci->cmd_ring->enqueue; +- +- /* Enqueue pointer can be left pointing to the link TRB, +- * we must handle that +- */ +- if (TRB_TYPE_LINK_LE32(command->command_trb->link.control)) +- command->command_trb = +- xhci->cmd_ring->enq_seg->next->trbs; +- ++ command->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); + list_add_tail(&command->cmd_list, &virt_dev->cmd_list); + } else { + cmd_completion = &virt_dev->cmd_completion; +@@ -2651,7 +2643,7 @@ static int xhci_configure_endpoint(struc + } + init_completion(cmd_completion); + +- cmd_trb = xhci->cmd_ring->dequeue; ++ cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); + if (!ctx_change) + ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, + udev->slot_id, must_succeed); +@@ -3468,14 +3460,7 @@ int xhci_discover_or_reset_device(struct + + /* Attempt to submit the Reset Device command to the command ring */ + spin_lock_irqsave(&xhci->lock, flags); +- reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; +- +- /* Enqueue pointer can be left pointing to the link TRB, +- * we must handle that +- */ +- if (TRB_TYPE_LINK_LE32(reset_device_cmd->command_trb->link.control)) +- reset_device_cmd->command_trb = +- xhci->cmd_ring->enq_seg->next->trbs; ++ reset_device_cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); + + list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); + ret = xhci_queue_reset_device(xhci, slot_id); +@@ -3679,7 +3664,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, + union xhci_trb *cmd_trb; + + spin_lock_irqsave(&xhci->lock, flags); +- cmd_trb = xhci->cmd_ring->dequeue; ++ cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); + ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); +@@ -3811,7 +3796,7 @@ int xhci_address_device(struct usb_hcd * + xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); + + spin_lock_irqsave(&xhci->lock, flags); +- cmd_trb = xhci->cmd_ring->dequeue; ++ cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); + ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, + udev->slot_id); + if (ret) { +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1851,6 +1851,7 @@ int xhci_cancel_cmd(struct xhci_hcd *xhc + union xhci_trb *cmd_trb); + void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, + unsigned int ep_index, unsigned int stream_id); ++union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring); + + /* xHCI roothub code */ + void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array, diff --git a/queue-3.11/xhci-fix-oops-happening-after-address-device-timeout.patch b/queue-3.11/xhci-fix-oops-happening-after-address-device-timeout.patch new file mode 100644 index 00000000000..ba7d1af6557 --- /dev/null +++ b/queue-3.11/xhci-fix-oops-happening-after-address-device-timeout.patch @@ -0,0 +1,45 @@ +From 284d20552461466b04d6bfeafeb1c47a8891b591 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 5 Sep 2013 11:01:20 +0300 +Subject: xhci: Fix oops happening after address device timeout + +From: Mathias Nyman + +commit 284d20552461466b04d6bfeafeb1c47a8891b591 upstream. + +When a command times out, the command ring is first aborted, +and then stopped. If the command ring is empty when it is stopped +the stop event will point to next command which is not yet set. +xHCI tries to handle this next event often causing an oops. + +Don't handle command completion events on stopped cmd ring if ring is +empty. + +This patch should be backported to kernels as old as 3.7, that contain +the commit b92cc66c047ff7cf587b318fe377061a353c120f "xHCI: add aborting +command ring function" + +Signed-off-by: Mathias Nyman +Reported-by: Giovanni +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1400,6 +1400,12 @@ static void handle_cmd_completion(struct + inc_deq(xhci, xhci->cmd_ring); + return; + } ++ /* There is no command to handle if we get a stop event when the ++ * command ring is empty, event->cmd_trb points to the next ++ * unset command ++ */ ++ if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue) ++ return; + } + + switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) diff --git a/queue-3.11/xhci-fix-race-between-ep-halt-and-urb-cancellation.patch b/queue-3.11/xhci-fix-race-between-ep-halt-and-urb-cancellation.patch new file mode 100644 index 00000000000..9b6ad5ed754 --- /dev/null +++ b/queue-3.11/xhci-fix-race-between-ep-halt-and-urb-cancellation.patch @@ -0,0 +1,41 @@ +From 526867c3ca0caa2e3e846cb993b0f961c33c2abb Mon Sep 17 00:00:00 2001 +From: Florian Wolter +Date: Wed, 14 Aug 2013 10:33:16 +0200 +Subject: xhci: Fix race between ep halt and URB cancellation + +From: Florian Wolter + +commit 526867c3ca0caa2e3e846cb993b0f961c33c2abb upstream. + +The halted state of a endpoint cannot be cleared over CLEAR_HALT from a +user process, because the stopped_td variable was overwritten in the +handle_stopped_endpoint() function. So the xhci_endpoint_reset() function will +refuse the reset and communication with device can not run over this endpoint. +https://bugzilla.kernel.org/show_bug.cgi?id=60699 + +Signed-off-by: Florian Wolter +Signed-off-by: Sarah Sharp +Cc: Jonghwan Choi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -857,8 +857,12 @@ remove_finished_td: + /* Otherwise ring the doorbell(s) to restart queued transfers */ + ring_doorbell_for_active_rings(xhci, slot_id, ep_index); + } +- ep->stopped_td = NULL; +- ep->stopped_trb = NULL; ++ ++ /* Clear stopped_td and stopped_trb if endpoint is not halted */ ++ if (!(ep->ep_state & EP_HALTED)) { ++ ep->stopped_td = NULL; ++ ep->stopped_trb = NULL; ++ } + + /* + * Drop the lock and complete the URBs in the cancelled TD list.