From cc33b86f10fdf051d02104cc21bd16fec0b1f591 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 5 Dec 2009 11:41:07 -0800 Subject: [PATCH] more .31 patches --- ...fix-for-read-error-handling-in-raid1.patch | 50 ++++ ...on-names-of-empty-sections-via-sysfs.patch | 74 ++++++ ...plain-about-unused-module-parameters.patch | 51 ++++ ...remove_host-before-freeing-resources.patch | 93 ++++++++ queue-2.6.31/series | 11 + ...22ab144dae4b276d74644a2f11c44a60ac5c.patch | 67 ++++++ ...king-open-of-a-dead-port-corner-case.patch | 35 +++ ...hared-interrupt-bug-and-warning-oops.patch | 122 ++++++++++ ...nd-clear-tt-buffer-following-a-stall.patch | 71 ++++++ ...ng-when-write-errors-are-encountered.patch | 45 ++++ .../usb-musb_gadget-fix-stall-handling.patch | 223 ++++++++++++++++++ ...-ehci-with-quirky-periodic-schedules.patch | 102 ++++++++ 12 files changed, 944 insertions(+) create mode 100644 queue-2.6.31/md-revert-incorrect-fix-for-read-error-handling-in-raid1.patch create mode 100644 queue-2.6.31/modules-don-t-export-section-names-of-empty-sections-via-sysfs.patch create mode 100644 queue-2.6.31/param-don-t-complain-about-unused-module-parameters.patch create mode 100644 queue-2.6.31/pxamci-call-mmc_remove_host-before-freeing-resources.patch create mode 100644 queue-2.6.31/speedstep-ich-fix-error-caused-by-394122ab144dae4b276d74644a2f11c44a60ac5c.patch create mode 100644 queue-2.6.31/tty_port-handle-the-nonblocking-open-of-a-dead-port-corner-case.patch create mode 100644 queue-2.6.31/usb-amd5536udc-fixed-shared-interrupt-bug-and-warning-oops.patch create mode 100644 queue-2.6.31/usb-ehci-don-t-send-clear-tt-buffer-following-a-stall.patch create mode 100644 queue-2.6.31/usb-ftdi_sio-keep-going-when-write-errors-are-encountered.patch create mode 100644 queue-2.6.31/usb-musb_gadget-fix-stall-handling.patch create mode 100644 queue-2.6.31/usb-work-around-for-ehci-with-quirky-periodic-schedules.patch diff --git a/queue-2.6.31/md-revert-incorrect-fix-for-read-error-handling-in-raid1.patch b/queue-2.6.31/md-revert-incorrect-fix-for-read-error-handling-in-raid1.patch new file mode 100644 index 00000000000..9f18a33c201 --- /dev/null +++ b/queue-2.6.31/md-revert-incorrect-fix-for-read-error-handling-in-raid1.patch @@ -0,0 +1,50 @@ +From d0e260782c3702a009645c3caa02e381dab8798b Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Tue, 1 Dec 2009 17:30:59 +1100 +Subject: md: revert incorrect fix for read error handling in raid1. + +From: NeilBrown + +commit d0e260782c3702a009645c3caa02e381dab8798b upstream. + +commit 4706b349f was a forward port of a fix that was needed +for SLES10. But in fact it is not needed in mainline because +the earlier commit dd00a99e7a fixes the same problem in a +better way. +Further, this commit introduces a bug in the way it interacts with +the automatic read-error-correction. If, after a read error is +successfully corrected, the same disk is chosen to re-read - the +re-read won't be attempted but an error will be returned instead. + +After reverting that commit, there is the possibility that a +read error on a read-only array (where read errors cannot +be corrected as that requires a write) will repeatedly read the same +device and continue to get an error. +So in the "Array is readonly" case, fail the drive immediately on +a read error. + +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid1.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -1643,11 +1643,12 @@ static void raid1d(mddev_t *mddev) + r1_bio->sector, + r1_bio->sectors); + unfreeze_array(conf); +- } ++ } else ++ md_error(mddev, ++ conf->mirrors[r1_bio->read_disk].rdev); + + bio = r1_bio->bios[r1_bio->read_disk]; +- if ((disk=read_balance(conf, r1_bio)) == -1 || +- disk == r1_bio->read_disk) { ++ if ((disk=read_balance(conf, r1_bio)) == -1) { + printk(KERN_ALERT "raid1: %s: unrecoverable I/O" + " read error for block %llu\n", + bdevname(bio->bi_bdev,b), diff --git a/queue-2.6.31/modules-don-t-export-section-names-of-empty-sections-via-sysfs.patch b/queue-2.6.31/modules-don-t-export-section-names-of-empty-sections-via-sysfs.patch new file mode 100644 index 00000000000..b007c847b91 --- /dev/null +++ b/queue-2.6.31/modules-don-t-export-section-names-of-empty-sections-via-sysfs.patch @@ -0,0 +1,74 @@ +From 35dead4235e2b67da7275b4122fed37099c2f462 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Thu, 3 Dec 2009 00:29:15 +0100 +Subject: modules: don't export section names of empty sections via sysfs + +From: Helge Deller + +commit 35dead4235e2b67da7275b4122fed37099c2f462 upstream. + +On the parisc architecture we face for each and every loaded kernel module +this kernel "badness warning": + sysfs: cannot create duplicate filename '/module/ac97_bus/sections/.text' + Badness at fs/sysfs/dir.c:487 + +Reason for that is, that on parisc all kernel modules do have multiple +.text sections due to the usage of the -ffunction-sections compiler flag +which is needed to reach all jump targets on this platform. + +An objdump on such a kernel module gives: +Sections: +Idx Name Size VMA LMA File off Algn + 0 .note.gnu.build-id 00000024 00000000 00000000 00000034 2**2 + CONTENTS, ALLOC, LOAD, READONLY, DATA + 1 .text 00000000 00000000 00000000 00000058 2**0 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 2 .text.ac97_bus_match 0000001c 00000000 00000000 00000058 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 3 .text 00000000 00000000 00000000 000000d4 2**0 + CONTENTS, ALLOC, LOAD, READONLY, CODE +... +Since the .text sections are empty (size of 0 bytes) and won't be +loaded by the kernel module loader anyway, I don't see a reason +why such sections need to be listed under +/sys/module//sections/ either. + +The attached patch does solve this issue by not exporting section +names which are empty. + +This fixes bugzilla http://bugzilla.kernel.org/show_bug.cgi?id=14703 + +Signed-off-by: Helge Deller +CC: rusty@rustcorp.com.au +CC: akpm@linux-foundation.org +CC: James.Bottomley@HansenPartnership.com +CC: roland@redhat.com +CC: dave@hiauly1.hia.nrc.ca +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/module.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -1179,7 +1179,8 @@ static void add_sect_attrs(struct module + + /* Count loaded sections and allocate structures */ + for (i = 0; i < nsect; i++) +- if (sechdrs[i].sh_flags & SHF_ALLOC) ++ if (sechdrs[i].sh_flags & SHF_ALLOC ++ && sechdrs[i].sh_size) + nloaded++; + size[0] = ALIGN(sizeof(*sect_attrs) + + nloaded * sizeof(sect_attrs->attrs[0]), +@@ -1199,6 +1200,8 @@ static void add_sect_attrs(struct module + for (i = 0; i < nsect; i++) { + if (! (sechdrs[i].sh_flags & SHF_ALLOC)) + continue; ++ if (!sechdrs[i].sh_size) ++ continue; + sattr->address = sechdrs[i].sh_addr; + sattr->name = kstrdup(secstrings + sechdrs[i].sh_name, + GFP_KERNEL); diff --git a/queue-2.6.31/param-don-t-complain-about-unused-module-parameters.patch b/queue-2.6.31/param-don-t-complain-about-unused-module-parameters.patch new file mode 100644 index 00000000000..f55370bde57 --- /dev/null +++ b/queue-2.6.31/param-don-t-complain-about-unused-module-parameters.patch @@ -0,0 +1,51 @@ +From f066a4f6df68f03b565dfe867dde54dfeb26576e Mon Sep 17 00:00:00 2001 +From: Rusty Russell +Date: Tue, 1 Dec 2009 14:56:44 +1030 +Subject: param: don't complain about unused module parameters. + +From: Rusty Russell + +commit f066a4f6df68f03b565dfe867dde54dfeb26576e upstream. + +Jon confirms that recent modprobe will look in /proc/cmdline, so these +cmdline options can still be used. + +See http://bugzilla.kernel.org/show_bug.cgi?id=14164 + +Reported-by: Adam Williamson +Signed-off-by: Rusty Russell +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + init/main.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +--- a/init/main.c ++++ b/init/main.c +@@ -250,7 +250,7 @@ early_param("loglevel", loglevel); + + /* + * Unknown boot options get handed to init, unless they look like +- * failed parameters ++ * unused parameters (modprobe will find them in /proc/cmdline). + */ + static int __init unknown_bootoption(char *param, char *val) + { +@@ -271,14 +271,9 @@ static int __init unknown_bootoption(cha + if (obsolete_checksetup(param)) + return 0; + +- /* +- * Preemptive maintenance for "why didn't my misspelled command +- * line work?" +- */ +- if (strchr(param, '.') && (!val || strchr(param, '.') < val)) { +- printk(KERN_ERR "Unknown boot option `%s': ignoring\n", param); ++ /* Unused module parameter. */ ++ if (strchr(param, '.') && (!val || strchr(param, '.') < val)) + return 0; +- } + + if (panic_later) + return 0; diff --git a/queue-2.6.31/pxamci-call-mmc_remove_host-before-freeing-resources.patch b/queue-2.6.31/pxamci-call-mmc_remove_host-before-freeing-resources.patch new file mode 100644 index 00000000000..dded178a67e --- /dev/null +++ b/queue-2.6.31/pxamci-call-mmc_remove_host-before-freeing-resources.patch @@ -0,0 +1,93 @@ +From 5d6b1edf8ccc4b7e4e77dff3fc80882833d6186e Mon Sep 17 00:00:00 2001 +From: Daniel Mack +Date: Tue, 1 Dec 2009 18:17:18 +0100 +Subject: [ARM] pxamci: call mmc_remove_host() before freeing resources + +From: Daniel Mack + +commit 5d6b1edf8ccc4b7e4e77dff3fc80882833d6186e upstream. + +mmc_remove_host() will cause the mmc core to switch off the bus power by +eventually calling pxamci_set_ios(). This function uses the regulator or +the GPIO which have been freed already. + +This causes the following Oops on module unload. + +[ 49.519649] Unable to handle kernel paging request at virtual address 30303a70 +[ 49.526878] pgd = c7084000 +[ 49.529563] [30303a70] *pgd=00000000 +[ 49.533136] Internal error: Oops: 5 [#1] +[ 49.537025] last sysfs file: /sys/devices/platform/pxa27x-ohci/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/scsi_level +[ 49.547471] Modules linked in: pxamci(-) eeti_ts +[ 49.552061] CPU: 0 Not tainted (2.6.32-rc8 #322) +[ 49.557001] PC is at regulator_is_enabled+0x3c/0xbc +[ 49.561846] LR is at regulator_is_enabled+0x30/0xbc +[ 49.566691] pc : [] lr : [] psr: 60000013 +[ 49.566702] sp : c7083e70 ip : 30303a30 fp : 00000000 +[ 49.578093] r10: c705e200 r9 : c7082000 r8 : c705e2e0 +[ 49.583280] r7 : c7061340 r6 : c7061340 r5 : c7083e70 r4 : 00000000 +[ 49.589759] r3 : c04dc434 r2 : c04dc434 r1 : c03eecea r0 : 00000047 +[ 49.596241] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user +[ 49.603329] Control: 0000397f Table: a7084018 DAC: 00000015 +[ 49.609031] Process rmmod (pid: 1101, stack limit = 0xc7082278) +[ 49.614908] Stack: (0xc7083e70 to 0xc7084000) +[ 49.619238] 3e60: c7082000 c703c4f8 c705ea00 c04f4074 +[ 49.627366] 3e80: 00000000 c705e3a0 ffffffff c0247ddc c70361a0 00000000 c705e3a0 ffffffff +[ 49.635499] 3ea0: c705e200 bf006400 c78c4f00 c705e200 c705e3a0 ffffffff c705e200 ffffffff +[ 49.643633] 3ec0: c04d8ac8 c02476d0 ffffffff c0247c60 c705e200 c0248678 c705e200 c0249064 +[ 49.651765] 3ee0: ffffffff bf006204 c04d8ad0 c04d8ad0 c04d8ac8 bf007490 00000880 c00440c4 +[ 49.659898] 3f00: 0000b748 c01c5708 bf007490 c01c44c8 c04d8ac8 c04d8afc bf007490 c01c4570 +[ 49.668031] 3f20: bf007490 bf00750c c04f4258 c01c37a4 00000000 bf00750c c7083f44 c007b014 +[ 49.676162] 3f40: 4000d000 6d617870 08006963 00000001 00000000 c7085000 00000001 00000000 +[ 49.684287] 3f60: 4000d000 c7083f8c 00000001 bea01a54 00005401 c7ab1400 c00440c4 00082000 +[ 49.692420] 3f80: bf00750c 00000880 c7083f8c 00000000 4000cfa8 00000000 00000880 bea01cc8 +[ 49.700552] 3fa0: 00000081 c0043f40 00000000 00000880 bea01cc8 00000880 00000006 00000000 +[ 49.708677] 3fc0: 00000000 00000880 bea01cc8 00000081 00000097 0000cca4 0000b748 00000000 +[ 49.716802] 3fe0: 4001a4f0 bea01cc0 00018bf4 4001a4fc 20000010 bea01cc8 a063e021 a063e421 +[ 49.724958] [] (regulator_is_enabled+0x3c/0xbc) from [] (mmc_regulator_set_ocr+0x14/0xd8) +[ 49.734836] [] (mmc_regulator_set_ocr+0x14/0xd8) from [] (pxamci_set_ios+0xd8/0x17c [pxamci]) +[ 49.745044] [] (pxamci_set_ios+0xd8/0x17c [pxamci]) from [] (mmc_power_off+0x50/0x58) +[ 49.754555] [] (mmc_power_off+0x50/0x58) from [] (mmc_detach_bus+0x68/0xc4) +[ 49.763207] [] (mmc_detach_bus+0x68/0xc4) from [] (mmc_stop_host+0xd4/0x1bc) +[ 49.771944] [] (mmc_stop_host+0xd4/0x1bc) from [] (mmc_remove_host+0xc/0x20) +[ 49.780681] [] (mmc_remove_host+0xc/0x20) from [] (pxamci_remove+0xc8/0x174 [pxamci]) +[ 49.790211] [] (pxamci_remove+0xc8/0x174 [pxamci]) from [] (platform_drv_remove+0x1c/0x24) +[ 49.800164] [] (platform_drv_remove+0x1c/0x24) from [] (__device_release_driver+0x7c/0xc4) +[ 49.810110] [] (__device_release_driver+0x7c/0xc4) from [] (driver_detach+0x60/0x8c) +[ 49.819535] [] (driver_detach+0x60/0x8c) from [] (bus_remove_driver+0x90/0xcc) +[ 49.828452] [] (bus_remove_driver+0x90/0xcc) from [] (sys_delete_module+0x1d8/0x254) +[ 49.837891] [] (sys_delete_module+0x1d8/0x254) from [] (ret_fast_syscall+0x0/0x28) +[ 49.847145] Code: eb06c53a e596c030 e1a0500d e59f106c (e59c0040) +[ 49.853566] ---[ end trace b5fa66a00cea142f ]--- + +Signed-off-by: Daniel Mack +Reported-by: Sven Neumann +Cc: Pierre Ossman +Cc: linux-mmc@vger.kernel.org +Cc: linux-arm-kernel@lists.infradead.org +Signed-off-by: Eric Miao +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/pxamci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/mmc/host/pxamci.c ++++ b/drivers/mmc/host/pxamci.c +@@ -694,14 +694,14 @@ static int pxamci_remove(struct platform + if (mmc) { + struct pxamci_host *host = mmc_priv(mmc); + ++ mmc_remove_host(mmc); ++ + if (host->vcc) + regulator_put(host->vcc); + + if (host->pdata && host->pdata->exit) + host->pdata->exit(&pdev->dev, mmc); + +- mmc_remove_host(mmc); +- + pxamci_stop_clock(host); + writel(TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD| + END_CMD_RES|PRG_DONE|DATA_TRAN_DONE, diff --git a/queue-2.6.31/series b/queue-2.6.31/series index 7a712013715..e7cad40dbd1 100644 --- a/queue-2.6.31/series +++ b/queue-2.6.31/series @@ -82,3 +82,14 @@ v4l-dvb-13202-smsusb-add-autodetection-support-for-three-additional-hauppauge-us v4l-dvb-13313-saa7134-add-support-for-force_ts_valid-mode-for-mpeg-ts-input.patch v4l-dvb-13314-saa7134-set-ts_force_val-for-the-hauppauge-wintv-hvr-1150.patch ipv4-additional-update-of-dev_net-dev-to-struct-net-in-ip_fragment.c-null-ptr-oops.patch +speedstep-ich-fix-error-caused-by-394122ab144dae4b276d74644a2f11c44a60ac5c.patch +usb-ehci-don-t-send-clear-tt-buffer-following-a-stall.patch +usb-musb_gadget-fix-stall-handling.patch +usb-amd5536udc-fixed-shared-interrupt-bug-and-warning-oops.patch +usb-ftdi_sio-keep-going-when-write-errors-are-encountered.patch +usb-work-around-for-ehci-with-quirky-periodic-schedules.patch +tty_port-handle-the-nonblocking-open-of-a-dead-port-corner-case.patch +pxamci-call-mmc_remove_host-before-freeing-resources.patch +param-don-t-complain-about-unused-module-parameters.patch +modules-don-t-export-section-names-of-empty-sections-via-sysfs.patch +md-revert-incorrect-fix-for-read-error-handling-in-raid1.patch diff --git a/queue-2.6.31/speedstep-ich-fix-error-caused-by-394122ab144dae4b276d74644a2f11c44a60ac5c.patch b/queue-2.6.31/speedstep-ich-fix-error-caused-by-394122ab144dae4b276d74644a2f11c44a60ac5c.patch new file mode 100644 index 00000000000..34e85491752 --- /dev/null +++ b/queue-2.6.31/speedstep-ich-fix-error-caused-by-394122ab144dae4b276d74644a2f11c44a60ac5c.patch @@ -0,0 +1,67 @@ +From 8dca15e40889e5d5e9655b03ba79c26200f760ce Mon Sep 17 00:00:00 2001 +From: Rusty Russell +Date: Mon, 2 Nov 2009 23:35:30 -0800 +Subject: [CPUFREQ] speedstep-ich: fix error caused by 394122ab144dae4b276d74644a2f11c44a60ac5c + +From: Rusty Russell + +commit 8dca15e40889e5d5e9655b03ba79c26200f760ce upstream. + +"[CPUFREQ] cpumask: avoid playing with cpus_allowed in speedstep-ich.c" +changed the code to mistakenly pass the current cpu as the "processor" +argument of speedstep_get_frequency(), whereas it should be the type of +the processor. + +Addresses http://bugzilla.kernel.org/show_bug.cgi?id=14340 + +Based on a patch by Dave Mueller. + +Signed-off-by: Rusty Russell +Acked-by: Dominik Brodowski +Reported-by: Dave Mueller +Signed-off-by: Andrew Morton +Signed-off-by: Dave Jones +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c ++++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +@@ -232,28 +232,23 @@ static unsigned int speedstep_detect_chi + return 0; + } + +-struct get_freq_data { +- unsigned int speed; +- unsigned int processor; +-}; +- +-static void get_freq_data(void *_data) ++static void get_freq_data(void *_speed) + { +- struct get_freq_data *data = _data; ++ unsigned int *speed = _speed; + +- data->speed = speedstep_get_frequency(data->processor); ++ *speed = speedstep_get_frequency(speedstep_processor); + } + + static unsigned int speedstep_get(unsigned int cpu) + { +- struct get_freq_data data = { .processor = cpu }; ++ unsigned int speed; + + /* You're supposed to ensure CPU is online. */ +- if (smp_call_function_single(cpu, get_freq_data, &data, 1) != 0) ++ if (smp_call_function_single(cpu, get_freq_data, &speed, 1) != 0) + BUG(); + +- dprintk("detected %u kHz as current frequency\n", data.speed); +- return data.speed; ++ dprintk("detected %u kHz as current frequency\n", speed); ++ return speed; + } + + /** diff --git a/queue-2.6.31/tty_port-handle-the-nonblocking-open-of-a-dead-port-corner-case.patch b/queue-2.6.31/tty_port-handle-the-nonblocking-open-of-a-dead-port-corner-case.patch new file mode 100644 index 00000000000..4d13771c746 --- /dev/null +++ b/queue-2.6.31/tty_port-handle-the-nonblocking-open-of-a-dead-port-corner-case.patch @@ -0,0 +1,35 @@ +From 8627b96dd80dca440d91fbb1ec733be25912d0dd Mon Sep 17 00:00:00 2001 +From: Alan Cox +Date: Wed, 18 Nov 2009 14:12:58 +0000 +Subject: tty_port: handle the nonblocking open of a dead port corner case + +From: Alan Cox + +commit 8627b96dd80dca440d91fbb1ec733be25912d0dd upstream. + +Some drivers allow O_NDELAY of a dead port (eg for setserial to work). In that +situation we must not try to raise the carrier. + +Signed-off-by: Alan Cox +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tty_port.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/char/tty_port.c ++++ b/drivers/char/tty_port.c +@@ -217,8 +217,11 @@ int tty_port_block_til_ready(struct tty_ + + /* if non-blocking mode is set we can pass directly to open unless + the port has just hung up or is in another error state */ +- if ((filp->f_flags & O_NONBLOCK) || +- (tty->flags & (1 << TTY_IO_ERROR))) { ++ if (tty->flags & (1 << TTY_IO_ERROR)) { ++ port->flags |= ASYNC_NORMAL_ACTIVE; ++ return 0; ++ } ++ if (filp->f_flags & O_NONBLOCK) { + /* Indicate we are open */ + if (tty->termios->c_cflag & CBAUD) + tty_port_raise_dtr_rts(port); diff --git a/queue-2.6.31/usb-amd5536udc-fixed-shared-interrupt-bug-and-warning-oops.patch b/queue-2.6.31/usb-amd5536udc-fixed-shared-interrupt-bug-and-warning-oops.patch new file mode 100644 index 00000000000..e0e1798cfc9 --- /dev/null +++ b/queue-2.6.31/usb-amd5536udc-fixed-shared-interrupt-bug-and-warning-oops.patch @@ -0,0 +1,122 @@ +From c5deb832d7a3f9618b09e6eeaa91a1a845c90c65 Mon Sep 17 00:00:00 2001 +From: Thomas Dahlmann +Date: Tue, 17 Nov 2009 14:18:27 -0800 +Subject: usb: amd5536udc: fixed shared interrupt bug and warning oops + +From: Thomas Dahlmann + +commit c5deb832d7a3f9618b09e6eeaa91a1a845c90c65 upstream. + +- fixed shared interrupt bug reported by Vadim Lobanov + - fixed possible warning oops on driver unload when connected + - prevent interrupt flood in PIO mode ("modprobe amd5536udc use_dma=0") + when using gadget ether + +Signed-off-by: Thomas Dahlmann +Cc: Robert Richter +Cc: David Brownell +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/amd5536udc.c | 49 ++++++++++++++++++++++++---------------- + 1 file changed, 30 insertions(+), 19 deletions(-) + +--- a/drivers/usb/gadget/amd5536udc.c ++++ b/drivers/usb/gadget/amd5536udc.c +@@ -1213,7 +1213,12 @@ udc_queue(struct usb_ep *usbep, struct u + tmp &= AMD_UNMASK_BIT(ep->num); + writel(tmp, &dev->regs->ep_irqmsk); + } +- } ++ } else if (ep->in) { ++ /* enable ep irq */ ++ tmp = readl(&dev->regs->ep_irqmsk); ++ tmp &= AMD_UNMASK_BIT(ep->num); ++ writel(tmp, &dev->regs->ep_irqmsk); ++ } + + } else if (ep->dma) { + +@@ -2005,18 +2010,17 @@ __acquires(dev->lock) + { + int tmp; + +- /* empty queues and init hardware */ +- udc_basic_init(dev); +- for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { +- empty_req_queue(&dev->ep[tmp]); +- } +- + if (dev->gadget.speed != USB_SPEED_UNKNOWN) { + spin_unlock(&dev->lock); + driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } +- /* init */ ++ ++ /* empty queues and init hardware */ ++ udc_basic_init(dev); ++ for (tmp = 0; tmp < UDC_EP_NUM; tmp++) ++ empty_req_queue(&dev->ep[tmp]); ++ + udc_setup_endpoints(dev); + } + +@@ -2478,6 +2482,13 @@ static irqreturn_t udc_data_in_isr(struc + } + } + ++ } else if (!use_dma && ep->in) { ++ /* disable interrupt */ ++ tmp = readl( ++ &dev->regs->ep_irqmsk); ++ tmp |= AMD_BIT(ep->num); ++ writel(tmp, ++ &dev->regs->ep_irqmsk); + } + } + /* clear status bits */ +@@ -3285,6 +3296,17 @@ static int udc_pci_probe( + goto finished; + } + ++ spin_lock_init(&dev->lock); ++ /* udc csr registers base */ ++ dev->csr = dev->virt_addr + UDC_CSR_ADDR; ++ /* dev registers base */ ++ dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR; ++ /* ep registers base */ ++ dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR; ++ /* fifo's base */ ++ dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR); ++ dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR); ++ + if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { + dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); + kfree(dev); +@@ -3337,7 +3359,6 @@ static int udc_probe(struct udc *dev) + udc_pollstall_timer.data = 0; + + /* device struct setup */ +- spin_lock_init(&dev->lock); + dev->gadget.ops = &udc_ops; + + dev_set_name(&dev->gadget.dev, "gadget"); +@@ -3346,16 +3367,6 @@ static int udc_probe(struct udc *dev) + dev->gadget.name = name; + dev->gadget.is_dualspeed = 1; + +- /* udc csr registers base */ +- dev->csr = dev->virt_addr + UDC_CSR_ADDR; +- /* dev registers base */ +- dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR; +- /* ep registers base */ +- dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR; +- /* fifo's base */ +- dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR); +- dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR); +- + /* init registers, interrupts, ... */ + startup_registers(dev); + diff --git a/queue-2.6.31/usb-ehci-don-t-send-clear-tt-buffer-following-a-stall.patch b/queue-2.6.31/usb-ehci-don-t-send-clear-tt-buffer-following-a-stall.patch new file mode 100644 index 00000000000..3f46596f500 --- /dev/null +++ b/queue-2.6.31/usb-ehci-don-t-send-clear-tt-buffer-following-a-stall.patch @@ -0,0 +1,71 @@ +From c2f6595fbdb408d3d6850cfae590c8fa93e27399 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 18 Nov 2009 11:37:15 -0500 +Subject: USB: EHCI: don't send Clear-TT-Buffer following a STALL + +From: Alan Stern + +commit c2f6595fbdb408d3d6850cfae590c8fa93e27399 upstream. + +This patch (as1304) fixes a regression in ehci-hcd. Evidently some +hubs don't handle Clear-TT-Buffer requests correctly, so we should +avoid sending them when they don't appear to be absolutely necessary. +The reported symptom is that output on a downstream audio device cuts +out because the hub stops relaying isochronous packets. + +The patch prevents Clear-TT-Buffer requests from being sent following +a STALL handshake. In theory a STALL indicates either that the +downstream device sent a STALL or that no matching TT buffer could be +found. In either case, the transfer is completed and the TT buffer +does not remain busy, so it doesn't need to be cleared. + +Also, the patch fixes a minor flaw in the code that actually sends the +Clear-TT-Buffer requests. Although the pipe direction isn't really +used for control transfers, it should be a Send rather than a Receive. + +Signed-off-by: Alan Stern +Reported-by: Javier Kohen +CC: David Brownell +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 2 +- + drivers/usb/host/ehci-q.c | 16 ++++++++++++++-- + 2 files changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -439,7 +439,7 @@ resubmit: + static inline int + hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) + { +- return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0), ++ return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), + HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo, + tt, NULL, 0, 1000); + } +--- a/drivers/usb/host/ehci-q.c ++++ b/drivers/usb/host/ehci-q.c +@@ -475,8 +475,20 @@ halt: + * we must clear the TT buffer (11.17.5). + */ + if (unlikely(last_status != -EINPROGRESS && +- last_status != -EREMOTEIO)) +- ehci_clear_tt_buffer(ehci, qh, urb, token); ++ last_status != -EREMOTEIO)) { ++ /* The TT's in some hubs malfunction when they ++ * receive this request following a STALL (they ++ * stop sending isochronous packets). Since a ++ * STALL can't leave the TT buffer in a busy ++ * state (if you believe Figures 11-48 - 11-51 ++ * in the USB 2.0 spec), we won't clear the TT ++ * buffer in this case. Strictly speaking this ++ * is a violation of the spec. ++ */ ++ if (last_status != -EPIPE) ++ ehci_clear_tt_buffer(ehci, qh, urb, ++ token); ++ } + } + + /* if we're removing something not at the queue head, diff --git a/queue-2.6.31/usb-ftdi_sio-keep-going-when-write-errors-are-encountered.patch b/queue-2.6.31/usb-ftdi_sio-keep-going-when-write-errors-are-encountered.patch new file mode 100644 index 00000000000..9d8c7949e4d --- /dev/null +++ b/queue-2.6.31/usb-ftdi_sio-keep-going-when-write-errors-are-encountered.patch @@ -0,0 +1,45 @@ +From 0de6ab8b91f2e1e8e7fc66a8b5c5e8ca82ea16b7 Mon Sep 17 00:00:00 2001 +From: Eric W. Biederman +Date: Tue, 17 Nov 2009 19:10:48 -0800 +Subject: USB: ftdi_sio: Keep going when write errors are encountered. + +From: Eric W. Biederman + +commit 0de6ab8b91f2e1e8e7fc66a8b5c5e8ca82ea16b7 upstream. + +The use of urb->actual_length to update tx_outstanding_bytes +implicitly assumes that the number of bytes actually written is the +same as the number of bytes we tried to write. On error that +assumption is violated so just use transfer_buffer_length the number +of bytes we intended to write to the device. + +If an error occurs we need to fall through and call +usb_serial_port_softint to wake up processes waiting in +tty_wait_until_sent. + +Signed-off-by: Eric W. Biederman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ftdi_sio.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1939,7 +1939,7 @@ static void ftdi_write_bulk_callback(str + return; + } + /* account for transferred data */ +- countback = urb->actual_length; ++ countback = urb->transfer_buffer_length; + data_offset = priv->write_offset; + if (data_offset > 0) { + /* Subtract the control bytes */ +@@ -1952,7 +1952,6 @@ static void ftdi_write_bulk_callback(str + + if (status) { + dbg("nonzero write bulk status received: %d", status); +- return; + } + + usb_serial_port_softint(port); diff --git a/queue-2.6.31/usb-musb_gadget-fix-stall-handling.patch b/queue-2.6.31/usb-musb_gadget-fix-stall-handling.patch new file mode 100644 index 00000000000..4e5efe89523 --- /dev/null +++ b/queue-2.6.31/usb-musb_gadget-fix-stall-handling.patch @@ -0,0 +1,223 @@ +From cea83241b3a84499c4f9b12f8288f787e7aa6383 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov +Date: Wed, 18 Nov 2009 22:51:18 +0300 +Subject: USB: musb_gadget: fix STALL handling + +From: Sergei Shtylyov + +commit cea83241b3a84499c4f9b12f8288f787e7aa6383 upstream. + +The driver incorrectly cancels the mass-storage device CSW request +(which leads to device reset) due to giving back URB at the head of +endpoint's queue after sending each STALL handshake; stop doing that +and start checking for the queue being non-empty before stalling an +endpoint and disallowing stall in such case in musb_gadget_set_halt() +like the other gadget drivers do. + +Moreover, the driver starts Rx request despite of the endpoint being +halted -- fix this by moving the SendStall bit check from musb_g_rx() +to rxstate(). And we also sometimes get into rxstate() with DMA still +active after clearing an endpoint's halt (not clear why), so bail out +in this case, similarly to what txstate() does... + +While at it, also do the following changes : + +- in musb_gadget_set_halt(), remove pointless Tx FIFO flushing (the + driver does not allow stalling with non-empty Tx FIFO anyway); + +- in rxstate(), stop pointlessly zeroing the 'csr' variable; + +- in musb_gadget_set_halt(), move the 'done' label to a more proper + place; + +- in musb_g_rx(), eliminate the 'done' label completely... + +Signed-off-by: Sergei Shtylyov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/musb/musb_gadget.c | 79 +++++++++++++++++------------------------ + 1 file changed, 34 insertions(+), 45 deletions(-) + +--- a/drivers/usb/musb/musb_gadget.c ++++ b/drivers/usb/musb/musb_gadget.c +@@ -4,6 +4,7 @@ + * Copyright 2005 Mentor Graphics Corporation + * Copyright (C) 2005-2006 by Texas Instruments + * Copyright (C) 2006-2007 Nokia Corporation ++ * Copyright (C) 2009 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -436,14 +437,6 @@ void musb_g_tx(struct musb *musb, u8 epn + csr |= MUSB_TXCSR_P_WZC_BITS; + csr &= ~MUSB_TXCSR_P_SENTSTALL; + musb_writew(epio, MUSB_TXCSR, csr); +- if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { +- dma->status = MUSB_DMA_STATUS_CORE_ABORT; +- musb->dma_controller->channel_abort(dma); +- } +- +- if (request) +- musb_g_giveback(musb_ep, request, -EPIPE); +- + break; + } + +@@ -582,15 +575,25 @@ void musb_g_tx(struct musb *musb, u8 epn + */ + static void rxstate(struct musb *musb, struct musb_request *req) + { +- u16 csr = 0; + const u8 epnum = req->epnum; + struct usb_request *request = &req->request; + struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; + void __iomem *epio = musb->endpoints[epnum].regs; + unsigned fifo_count = 0; + u16 len = musb_ep->packet_sz; ++ u16 csr = musb_readw(epio, MUSB_RXCSR); + +- csr = musb_readw(epio, MUSB_RXCSR); ++ /* We shouldn't get here while DMA is active, but we do... */ ++ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { ++ DBG(4, "DMA pending...\n"); ++ return; ++ } ++ ++ if (csr & MUSB_RXCSR_P_SENDSTALL) { ++ DBG(5, "%s stalling, RXCSR %04x\n", ++ musb_ep->end_point.name, csr); ++ return; ++ } + + if (is_cppi_enabled() && musb_ep->dma) { + struct dma_controller *c = musb->dma_controller; +@@ -761,19 +764,10 @@ void musb_g_rx(struct musb *musb, u8 epn + csr, dma ? " (dma)" : "", request); + + if (csr & MUSB_RXCSR_P_SENTSTALL) { +- if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { +- dma->status = MUSB_DMA_STATUS_CORE_ABORT; +- (void) musb->dma_controller->channel_abort(dma); +- request->actual += musb_ep->dma->actual_len; +- } +- + csr |= MUSB_RXCSR_P_WZC_BITS; + csr &= ~MUSB_RXCSR_P_SENTSTALL; + musb_writew(epio, MUSB_RXCSR, csr); +- +- if (request) +- musb_g_giveback(musb_ep, request, -EPIPE); +- goto done; ++ return; + } + + if (csr & MUSB_RXCSR_P_OVERRUN) { +@@ -795,7 +789,7 @@ void musb_g_rx(struct musb *musb, u8 epn + DBG((csr & MUSB_RXCSR_DMAENAB) ? 4 : 1, + "%s busy, csr %04x\n", + musb_ep->end_point.name, csr); +- goto done; ++ return; + } + + if (dma && (csr & MUSB_RXCSR_DMAENAB)) { +@@ -826,22 +820,15 @@ void musb_g_rx(struct musb *musb, u8 epn + if ((request->actual < request->length) + && (musb_ep->dma->actual_len + == musb_ep->packet_sz)) +- goto done; ++ return; + #endif + musb_g_giveback(musb_ep, request, 0); + + request = next_request(musb_ep); + if (!request) +- goto done; +- +- /* don't start more i/o till the stall clears */ +- musb_ep_select(mbase, epnum); +- csr = musb_readw(epio, MUSB_RXCSR); +- if (csr & MUSB_RXCSR_P_SENDSTALL) +- goto done; ++ return; + } + +- + /* analyze request if the ep is hot */ + if (request) + rxstate(musb, to_musb_request(request)); +@@ -849,8 +836,6 @@ void musb_g_rx(struct musb *musb, u8 epn + DBG(3, "packet waiting for %s%s request\n", + musb_ep->desc ? "" : "inactive ", + musb_ep->end_point.name); +- +-done: + return; + } + +@@ -1244,7 +1229,7 @@ int musb_gadget_set_halt(struct usb_ep * + void __iomem *mbase; + unsigned long flags; + u16 csr; +- struct musb_request *request = NULL; ++ struct musb_request *request; + int status = 0; + + if (!ep) +@@ -1260,24 +1245,29 @@ int musb_gadget_set_halt(struct usb_ep * + + musb_ep_select(mbase, epnum); + +- /* cannot portably stall with non-empty FIFO */ + request = to_musb_request(next_request(musb_ep)); +- if (value && musb_ep->is_in) { +- csr = musb_readw(epio, MUSB_TXCSR); +- if (csr & MUSB_TXCSR_FIFONOTEMPTY) { +- DBG(3, "%s fifo busy, cannot halt\n", ep->name); +- spin_unlock_irqrestore(&musb->lock, flags); +- return -EAGAIN; ++ if (value) { ++ if (request) { ++ DBG(3, "request in progress, cannot halt %s\n", ++ ep->name); ++ status = -EAGAIN; ++ goto done; ++ } ++ /* Cannot portably stall with non-empty FIFO */ ++ if (musb_ep->is_in) { ++ csr = musb_readw(epio, MUSB_TXCSR); ++ if (csr & MUSB_TXCSR_FIFONOTEMPTY) { ++ DBG(3, "FIFO busy, cannot halt %s\n", ep->name); ++ status = -EAGAIN; ++ goto done; ++ } + } +- + } + + /* set/clear the stall and toggle bits */ + DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear"); + if (musb_ep->is_in) { + csr = musb_readw(epio, MUSB_TXCSR); +- if (csr & MUSB_TXCSR_FIFONOTEMPTY) +- csr |= MUSB_TXCSR_FLUSHFIFO; + csr |= MUSB_TXCSR_P_WZC_BITS + | MUSB_TXCSR_CLRDATATOG; + if (value) +@@ -1300,14 +1290,13 @@ int musb_gadget_set_halt(struct usb_ep * + musb_writew(epio, MUSB_RXCSR, csr); + } + +-done: +- + /* maybe start the first request in the queue */ + if (!musb_ep->busy && !value && request) { + DBG(3, "restarting the request\n"); + musb_ep_restart(musb, request); + } + ++done: + spin_unlock_irqrestore(&musb->lock, flags); + return status; + } diff --git a/queue-2.6.31/usb-work-around-for-ehci-with-quirky-periodic-schedules.patch b/queue-2.6.31/usb-work-around-for-ehci-with-quirky-periodic-schedules.patch new file mode 100644 index 00000000000..ee99c1d01e4 --- /dev/null +++ b/queue-2.6.31/usb-work-around-for-ehci-with-quirky-periodic-schedules.patch @@ -0,0 +1,102 @@ +From ee4ecb8ac63a5792bec448037d4b82ec4144f94b Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Fri, 27 Nov 2009 15:17:59 +0100 +Subject: USB: work around for EHCI with quirky periodic schedules + +From: Oliver Neukum + +commit ee4ecb8ac63a5792bec448037d4b82ec4144f94b upstream. + +a quirky chipset needs periodic schedules to run for a minimum +time before they can be disabled again. This enforces the requirement +with a time stamp and a calculated delay + +Signed-off-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-hcd.c | 2 ++ + drivers/usb/host/ehci-pci.c | 6 ++++++ + drivers/usb/host/ehci-sched.c | 12 ++++++++++++ + drivers/usb/host/ehci.h | 2 ++ + 4 files changed, 22 insertions(+) + +--- a/drivers/usb/host/ehci.h ++++ b/drivers/usb/host/ehci.h +@@ -118,6 +118,7 @@ struct ehci_hcd { /* one per controlle + unsigned stamp; + unsigned random_frame; + unsigned long next_statechange; ++ ktime_t last_periodic_enable; + u32 command; + + /* SILICON QUIRKS */ +@@ -126,6 +127,7 @@ struct ehci_hcd { /* one per controlle + unsigned big_endian_mmio:1; + unsigned big_endian_desc:1; + unsigned has_amcc_usb23:1; ++ unsigned broken_periodic:1; + + /* required for usb32 quirk */ + #define OHCI_CTRL_HCFS (3 << 6) +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -655,6 +656,7 @@ static int ehci_run (struct usb_hcd *hcd + ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ + msleep(5); + up_write(&ehci_cf_port_reset_rwsem); ++ ehci->last_periodic_enable = ktime_get_real(); + + temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); + ehci_info (ehci, +--- a/drivers/usb/host/ehci-pci.c ++++ b/drivers/usb/host/ehci-pci.c +@@ -72,6 +72,12 @@ static int ehci_pci_setup(struct usb_hcd + int retval; + + switch (pdev->vendor) { ++ case PCI_VENDOR_ID_INTEL: ++ if (pdev->device == 0x27cc) { ++ ehci->broken_periodic = 1; ++ ehci_info(ehci, "using broken periodic workaround\n"); ++ } ++ break; + case PCI_VENDOR_ID_TOSHIBA_2: + /* celleb's companion chip */ + if (pdev->device == 0x01b5) { +--- a/drivers/usb/host/ehci-sched.c ++++ b/drivers/usb/host/ehci-sched.c +@@ -456,6 +456,8 @@ static int enable_periodic (struct ehci_ + /* make sure ehci_work scans these */ + ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index) + % (ehci->periodic_size << 3); ++ if (unlikely(ehci->broken_periodic)) ++ ehci->last_periodic_enable = ktime_get_real(); + return 0; + } + +@@ -467,6 +469,16 @@ static int disable_periodic (struct ehci + if (--ehci->periodic_sched) + return 0; + ++ if (unlikely(ehci->broken_periodic)) { ++ /* delay experimentally determined */ ++ ktime_t safe = ktime_add_us(ehci->last_periodic_enable, 1000); ++ ktime_t now = ktime_get_real(); ++ s64 delay = ktime_us_delta(safe, now); ++ ++ if (unlikely(delay > 0)) ++ udelay(delay); ++ } ++ + /* did setting PSE not take effect yet? + * takes effect only at frame boundaries... + */ -- 2.47.3