From: Greg Kroah-Hartman Date: Mon, 7 Dec 2009 00:28:42 +0000 (-0800) Subject: start 2.6.27.40 review cycle X-Git-Tag: v2.6.31.7~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=298d9dc768a7d3a7f3aaad65a13f6e0f2d310bab;p=thirdparty%2Fkernel%2Fstable-queue.git start 2.6.27.40 review cycle --- diff --git a/queue-2.6.27/alsa-aaci-fix-ac97-multiple-open-bug.patch b/review-2.6.27/alsa-aaci-fix-ac97-multiple-open-bug.patch similarity index 100% rename from queue-2.6.27/alsa-aaci-fix-ac97-multiple-open-bug.patch rename to review-2.6.27/alsa-aaci-fix-ac97-multiple-open-bug.patch diff --git a/queue-2.6.27/alsa-aaci-fix-recording-bug.patch b/review-2.6.27/alsa-aaci-fix-recording-bug.patch similarity index 100% rename from queue-2.6.27/alsa-aaci-fix-recording-bug.patch rename to review-2.6.27/alsa-aaci-fix-recording-bug.patch diff --git a/queue-2.6.27/alsa-usb-audio-fix-combine_word-problem.patch b/review-2.6.27/alsa-usb-audio-fix-combine_word-problem.patch similarity index 100% rename from queue-2.6.27/alsa-usb-audio-fix-combine_word-problem.patch rename to review-2.6.27/alsa-usb-audio-fix-combine_word-problem.patch diff --git a/queue-2.6.27/dca-redesign-locks-to-fix-deadlocks.patch b/review-2.6.27/dca-redesign-locks-to-fix-deadlocks.patch similarity index 100% rename from queue-2.6.27/dca-redesign-locks-to-fix-deadlocks.patch rename to review-2.6.27/dca-redesign-locks-to-fix-deadlocks.patch diff --git a/queue-2.6.27/enable-acpi-pdc-handshake-for-via-centaur-cpus.patch b/review-2.6.27/enable-acpi-pdc-handshake-for-via-centaur-cpus.patch similarity index 100% rename from queue-2.6.27/enable-acpi-pdc-handshake-for-via-centaur-cpus.patch rename to review-2.6.27/enable-acpi-pdc-handshake-for-via-centaur-cpus.patch diff --git a/queue-2.6.27/fuse-prevent-fuse_put_request-on-invalid-pointer.patch b/review-2.6.27/fuse-prevent-fuse_put_request-on-invalid-pointer.patch similarity index 100% rename from queue-2.6.27/fuse-prevent-fuse_put_request-on-invalid-pointer.patch rename to review-2.6.27/fuse-prevent-fuse_put_request-on-invalid-pointer.patch diff --git a/queue-2.6.27/fuse-reject-o_direct-flag-also-in-fuse_create.patch b/review-2.6.27/fuse-reject-o_direct-flag-also-in-fuse_create.patch similarity index 100% rename from queue-2.6.27/fuse-reject-o_direct-flag-also-in-fuse_create.patch rename to review-2.6.27/fuse-reject-o_direct-flag-also-in-fuse_create.patch diff --git a/queue-2.6.27/gdth-prevent-negative-offsets-in-ioctl-cve-2009-3080.patch b/review-2.6.27/gdth-prevent-negative-offsets-in-ioctl-cve-2009-3080.patch similarity index 100% rename from queue-2.6.27/gdth-prevent-negative-offsets-in-ioctl-cve-2009-3080.patch rename to review-2.6.27/gdth-prevent-negative-offsets-in-ioctl-cve-2009-3080.patch diff --git a/queue-2.6.27/hwmon-it87-fix-vid-reading-on-it8718f.patch b/review-2.6.27/hwmon-it87-fix-vid-reading-on-it8718f.patch similarity index 100% rename from queue-2.6.27/hwmon-it87-fix-vid-reading-on-it8718f.patch rename to review-2.6.27/hwmon-it87-fix-vid-reading-on-it8718f.patch diff --git a/queue-2.6.27/isdn-hfc_usb-fix-read-buffer-overflow.patch b/review-2.6.27/isdn-hfc_usb-fix-read-buffer-overflow.patch similarity index 100% rename from queue-2.6.27/isdn-hfc_usb-fix-read-buffer-overflow.patch rename to review-2.6.27/isdn-hfc_usb-fix-read-buffer-overflow.patch diff --git a/queue-2.6.27/jffs2-fix-memory-corruption-in-jffs2_read_inode_range.patch b/review-2.6.27/jffs2-fix-memory-corruption-in-jffs2_read_inode_range.patch similarity index 100% rename from queue-2.6.27/jffs2-fix-memory-corruption-in-jffs2_read_inode_range.patch rename to review-2.6.27/jffs2-fix-memory-corruption-in-jffs2_read_inode_range.patch diff --git a/review-2.6.27/mbox b/review-2.6.27/mbox new file mode 100644 index 00000000000..e459972d33c --- /dev/null +++ b/review-2.6.27/mbox @@ -0,0 +1,3143 @@ +From gregkh@mini.kroah.org Sun Dec 6 15:32:08 2009 +Message-Id: <20091206233208.133827759@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:33 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Russell King , + Takashi Iwai +Subject: [01/20] ALSA: AACI: fix AC97 multiple-open bug +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=alsa-aaci-fix-ac97-multiple-open-bug.patch +Content-Length: 661 +Lines: 26 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Russell King + +commit 4acd57c3de62374fe5bb52e5cd24538190f4eab2 upstream. + +Signed-off-by: Russell King +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/arm/aaci.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/sound/arm/aaci.c ++++ b/sound/arm/aaci.c +@@ -504,6 +504,10 @@ static int aaci_pcm_hw_params(struct snd + int err; + + aaci_pcm_hw_free(substream); ++ if (aacirun->pcm_open) { ++ snd_ac97_pcm_close(aacirun->pcm); ++ aacirun->pcm_open = 0; ++ } + + err = devdma_hw_alloc(NULL, substream, + params_buffer_bytes(params)); + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:08 2009 +Message-Id: <20091206233208.269420973@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:34 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Russell King , + Takashi Iwai +Subject: [02/20] ALSA: AACI: fix recording bug +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=alsa-aaci-fix-recording-bug.patch +Content-Length: 794 +Lines: 28 + + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Russell King + +commit 8ee763b9c82c6ca0a59a7271ce4fa29d7baf5c09 upstream. + +pcm->r[1].slots is the double rate slot information, not the +capture information. For capture, 'pcm' will already be the +capture ac97 pcm structure. + +Signed-off-by: Russell King +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/arm/aaci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/arm/aaci.c ++++ b/sound/arm/aaci.c +@@ -521,7 +521,7 @@ static int aaci_pcm_hw_params(struct snd + else + err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), + params_channels(params), +- aacirun->pcm->r[1].slots); ++ aacirun->pcm->r[0].slots); + + if (err) + goto out; + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:08 2009 +Message-Id: <20091206233208.427626071@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:35 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Julian Anastasov , + Takashi Iwai +Subject: [03/20] ALSA: usb-audio: fix combine_word problem +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=alsa-usb-audio-fix-combine_word-problem.patch +Content-Length: 1318 +Lines: 39 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Julian Anastasov + +commit f495088210c8b9e20791d995a8210170c68d2deb upstream. + +Fix combine_word problem where first octet is not +read properly. The only affected place seems to be the +INPUT_TERMINAL type. Before now, sound controls can be created +with the output terminal's name which is a fallback mechanism +used only for unknown input terminal types. For example, +Line can wrongly appear as Speaker. After the change it +should appear as Line. + + The side effect of this change can be that users +can expect the wrong control name in their scripts or +programs while now we return the correct one. + + Probably, these defines should use get_unaligned_le16 and +friends. + +Signed-off-by: Julian Anastasov +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/usbaudio.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/usb/usbaudio.h ++++ b/sound/usb/usbaudio.h +@@ -209,7 +209,7 @@ struct snd_usb_midi_endpoint_info { + /* + */ + +-#define combine_word(s) ((*s) | ((unsigned int)(s)[1] << 8)) ++#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8)) + #define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16)) + #define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24)) + + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:08 2009 +Message-Id: <20091206233208.580098254@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:36 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Dave Jones , + James Bottomley +Subject: [04/20] [SCSI] gdth: Prevent negative offsets in ioctl CVE-2009-3080 +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=gdth-prevent-negative-offsets-in-ioctl-cve-2009-3080.patch +Content-Length: 769 +Lines: 27 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Dave Jones + +commit 690e744869f3262855b83b4fb59199cf142765b0 upstream. + +A negative offset could be used to index before the event buffer and +lead to a security breach. + +Signed-off-by: Dave Jones +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/gdth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/gdth.c ++++ b/drivers/scsi/gdth.c +@@ -2912,7 +2912,7 @@ static int gdth_read_event(gdth_ha_str * + eindex = handle; + estr->event_source = 0; + +- if (eindex >= MAX_EVENTS) { ++ if (eindex < 0 || eindex >= MAX_EVENTS) { + spin_unlock_irqrestore(&ha->smp_lock, flags); + return eindex; + } + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:08 2009 +Message-Id: <20091206233208.744542128@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:37 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + David Woodhouse +Subject: [05/20] jffs2: Fix memory corruption in jffs2_read_inode_range() +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=jffs2-fix-memory-corruption-in-jffs2_read_inode_range.patch +Content-Length: 3423 +Lines: 80 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: David Woodhouse + +commit 199bc9ff5ca5e4b3bcaff8927b2983c65f34c263 upstream. + +In 2.6.23 kernel, commit a32ea1e1f925399e0d81ca3f7394a44a6dafa12c +("Fix read/truncate race") fixed a race in the generic code, and as a +side effect, now do_generic_file_read() can ask us to readpage() past +the i_size. This seems to be correctly handled by the block routines +(e.g. block_read_full_page() fills the page with zeroes in case if +somebody is trying to read past the last inode's block). + +JFFS2 doesn't handle this; it assumes that it won't be asked to read +pages which don't exist -- and thus that there will be at least _one_ +valid 'frag' on the page it's being asked to read. It will fill any +holes with the following memset: + + memset(buf, 0, min(end, frag->ofs + frag->size) - offset); + +When the 'closest smaller match' returned by jffs2_lookup_node_frag() is +actually on a previous page and ends before 'offset', that results in: + + memset(buf, 0, ); + +Hopefully, in most cases the corruption is fatal, and quickly causing +random oopses, like this: + + root@10.0.0.4:~/ltp-fs-20090531# ./testcases/kernel/fs/ftest/ftest01 + Unable to handle kernel paging request for data at address 0x00000008 + Faulting instruction address: 0xc01cd980 + Oops: Kernel access of bad area, sig: 11 [#1] + [...] + NIP [c01cd980] rb_insert_color+0x38/0x184 + LR [c0043978] enqueue_hrtimer+0x88/0xc4 + Call Trace: + [c6c63b60] [c004f9a8] tick_sched_timer+0xa0/0xe4 (unreliable) + [c6c63b80] [c0043978] enqueue_hrtimer+0x88/0xc4 + [c6c63b90] [c0043a48] __run_hrtimer+0x94/0xbc + [c6c63bb0] [c0044628] hrtimer_interrupt+0x140/0x2b8 + [c6c63c10] [c000f8e8] timer_interrupt+0x13c/0x254 + [c6c63c30] [c001352c] ret_from_except+0x0/0x14 + --- Exception: 901 at memset+0x38/0x5c + LR = jffs2_read_inode_range+0x144/0x17c + [c6c63cf0] [00000000] (null) (unreliable) + +This patch fixes the issue, plus fixes all LTP tests on NAND/UBI with +JFFS2 filesystem that were failing since 2.6.23 (seems like the bug +above also broke the truncation). + +Reported-By: Anton Vorontsov +Tested-By: Anton Vorontsov +Signed-off-by: David Woodhouse +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jffs2/read.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/fs/jffs2/read.c ++++ b/fs/jffs2/read.c +@@ -164,12 +164,15 @@ int jffs2_read_inode_range(struct jffs2_ + + /* XXX FIXME: Where a single physical node actually shows up in two + frags, we read it twice. Don't do that. */ +- /* Now we're pointing at the first frag which overlaps our page */ ++ /* Now we're pointing at the first frag which overlaps our page ++ * (or perhaps is before it, if we've been asked to read off the ++ * end of the file). */ + while(offset < end) { + D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end)); +- if (unlikely(!frag || frag->ofs > offset)) { ++ if (unlikely(!frag || frag->ofs > offset || ++ frag->ofs + frag->size <= offset)) { + uint32_t holesize = end - offset; +- if (frag) { ++ if (frag && frag->ofs > offset) { + D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset)); + holesize = min(holesize, frag->ofs - offset); + } + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:09 2009 +Message-Id: <20091206233208.909016800@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:38 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Martin Samek , + Devin Heitmueller , + Mauro Carvalho Chehab +Subject: [06/20] V4L/DVB (13079): dib0700: fixed xc2028 firmware loading kernel oops +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=v4l-dvb-13079-dib0700-fixed-xc2028-firmware-loading-kernel-oops.patch +Content-Length: 1410 +Lines: 36 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Martin Samek + +commit 7646b9de26c54cf4bc9c446d7ada9f91ece31e0a upstream. + +Fixing kernel oops when driver attemps to load xc2028 firmware. + +Note by djh: the patch contribute by Martin is a port of a fix I made during +the PCTV 340e development. It's a temporary workaround that fixes a regression +(an OOPS condition) and the real fix should be in the code that manages the +i2c master on the dib7000p. But this fix does address the immmediate +regression and should be merged upstream until we do a cleaner fix. + +Signed-off-by: Martin Samek +Signed-off-by: Devin Heitmueller +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/dvb/frontends/dib7000p.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/media/dvb/frontends/dib7000p.c ++++ b/drivers/media/dvb/frontends/dib7000p.c +@@ -1343,6 +1343,11 @@ struct dvb_frontend * dib7000p_attach(st + if (dib7000p_identify(st) != 0) + goto error; + ++ /* FIXME: make sure the dev.parent field is initialized, or else ++ request_firmware() will hit an OOPS (this should be moved somewhere ++ more common) */ ++ st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent; ++ + dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); + + dib7000p_demod_reset(st); + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:09 2009 +Message-Id: <20091206233209.140733272@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:39 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Henk Vergonet , + Michael Krufky , + Mauro Carvalho Chehab +Subject: [07/20] V4L/DVB (13107): tda18271: fix overflow in FM radio frequency calculation +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=v4l-dvb-13107-tda18271-fix-overflow-in-fm-radio-frequency-calculation.patch +Content-Length: 1300 +Lines: 38 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Michael Krufky + +commit 4d8317876d5f53ef792e90f89d8f162d7bca5c81 upstream. + +Multiplication by 62500 causes an overflow in the 32 bit freq variable, +which is later divided by 1000 when using FM radio. + +This patch prevents the overflow by scaling the frequency value correctly +upfront. Thanks to Henk Vergonet for spotting the problem and providing +a preliminary patch, which this changeset was based upon. + +Cc: Henk Vergonet +Signed-off-by: Michael Krufky +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/common/tuners/tda18271-fe.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/common/tuners/tda18271-fe.c ++++ b/drivers/media/common/tuners/tda18271-fe.c +@@ -927,12 +927,12 @@ static int tda18271_set_analog_params(st + struct tda18271_std_map_item *map; + char *mode; + int ret; +- u32 freq = params->frequency * 62500; ++ u32 freq = params->frequency * 125 * ++ ((params->mode == V4L2_TUNER_RADIO) ? 1 : 1000) / 2; + + priv->mode = TDA18271_ANALOG; + + if (params->mode == V4L2_TUNER_RADIO) { +- freq = freq / 1000; + map = &std_map->fm_radio; + mode = "fm"; + } else if (params->std & V4L2_STD_MN) { + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:09 2009 +Message-Id: <20091206233209.309431448@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:40 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Seth Barry , + Michael Krufky , + Mauro Carvalho Chehab +Subject: [08/20] V4L/DVB (13109): tda18271: fix signedness issue in tda18271_rf_tracking_filters_init +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=v4l-dvb-13109-tda18271-fix-signedness-issue-in-tda18271_rf_tracking_filters_init.patch +Content-Length: 2897 +Lines: 61 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Seth Barry + +commit a57c1dcb93e43357ed3f666e5a2b5d5071dd3930 upstream. + +While having tda18271 module set with debug=17 (cal & info prints) and +cal=0 (delay calibration process until first use) - I discovered that +during the calibration process, if the frequency test for 69750000 +returned a bcal of 0 (see tda18721-fe.c in tda18271_powerscan func) that +the tuner wouldn't be able to pickup any of the frequencies in the range +(all the other frequencies bands returned bcal=1). I spent some time +going over the code and the NXP's tda18271 spec (ver.4 of it i think) and +adding a lot of debug prints and walking/stepping through the calibration +process. I found that when the powerscan fails to find a frequency, the +rf calibration is not run and the default value is supposed to be used in +its place (pulled from the RF_CAL_map table) - but something was getting +goofed up there. + +Now, my c coding skills are very rusty, but i think root of the problem is +a signedness issue with the math operation for calculating the rf_a1 and +rf_a2 values in tda18271_rf_tracking_filters_init func, which results in +values like 20648 for rf_a1 (when it should probably have a value like 0, +or so slightly negative that it should be zero - this bad value for rf_a1 +would in turn makes the approx calc within +tda18271c2_rf_tracking_filters_correction go out of whack). The simplest +solution i found was to explicitly convert the signedness of the +denominator to avoid the implicit conversion. The values placed into the +u32 rf_freq array should never exceed about 900mhz, so i think the s32 max +value shouldn't be an issue in this case. + +I've tested it out a little, and even when i get a bcal=0 with the +modified code, the default calibration value gets used, rf_a1 is zero, and +the tuner seems to lock on the stream and mythtv seems to play it fine. + +Signed-off-by: Seth Barry +Signed-off-by: Michael Krufky +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/common/tuners/tda18271-fe.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/common/tuners/tda18271-fe.c ++++ b/drivers/media/common/tuners/tda18271-fe.c +@@ -595,13 +595,13 @@ static int tda18271_rf_tracking_filters_ + case RF2: + map[i].rf_a1 = (prog_cal[RF2] - prog_tab[RF2] - + prog_cal[RF1] + prog_tab[RF1]) / +- ((rf_freq[RF2] - rf_freq[RF1]) / 1000); ++ (s32)((rf_freq[RF2] - rf_freq[RF1]) / 1000); + map[i].rf2 = rf_freq[RF2] / 1000; + break; + case RF3: + map[i].rf_a2 = (prog_cal[RF3] - prog_tab[RF3] - + prog_cal[RF2] + prog_tab[RF2]) / +- ((rf_freq[RF3] - rf_freq[RF2]) / 1000); ++ (s32)((rf_freq[RF3] - rf_freq[RF2]) / 1000); + map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2]; + map[i].rf3 = rf_freq[RF3] / 1000; + break; + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:09 2009 +Message-Id: <20091206233209.440225308@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:41 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Devin Heitmueller , + Mauro Carvalho Chehab +Subject: [09/20] V4L/DVB (13190): em28xx: fix panic that can occur when starting audio streaming +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=v4l-dvb-13190-em28xx-fix-panic-that-can-occur-when-starting-audio-streaming.patch +Content-Length: 1170 +Lines: 34 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Devin Heitmueller + +commit 96fbf771d86a90ff006bc62ca4d4de6474b3de31 upstream. + +Because the counters were not reset when starting up streaming, they would +be reused from the previous run. This can result in cases such that when the +second instance of streaming starts up, the "cnt" variable in +em28xx_audio_isocirq() can end up being negative, resulting in attempting to +write to memory before the start of runtime->dma_area (as well as having a +negative number of bytes to copy). + +Signed-off-by: Devin Heitmueller +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/video/em28xx/em28xx-audio.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/media/video/em28xx/em28xx-audio.c ++++ b/drivers/media/video/em28xx/em28xx-audio.c +@@ -365,6 +365,11 @@ static int snd_em28xx_hw_capture_free(st + + static int snd_em28xx_prepare(struct snd_pcm_substream *substream) + { ++ struct em28xx *dev = snd_pcm_substream_chip(substream); ++ ++ dev->adev.hwptr_done_capture = 0; ++ dev->adev.capture_transfer_done = 0; ++ + return 0; + } + + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:09 2009 +Message-Id: <20091206233209.565626658@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:42 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Mike Isely , + Mauro Carvalho Chehab +Subject: [10/20] V4L/DVB (13230): s2255drv: Dont conditionalize video buffer completion on waiting processes +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=v4l-dvb-13230-s2255drv-don-t-conditionalize-video-buffer-completion-on-waiting-processes.patch +Content-Length: 1820 +Lines: 44 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Mike Isely + +commit 1f95725755ab67f3198df3b5bf7517f926f310ca upstream. + +The s2255 driver had logic which aborted processing of a video frame +if there was no process waiting on the video buffer in question. That +simply doesn't work when the application is doing things in an +asynchronous manner. If the application went to the trouble to queue +the buffer in the first place, then the driver should always attempt +to complete it - even if the application at that moment has its +attention turned elsewhere. Applications which always blocked waiting +for I/O on the capture device would not have been affected by this. +Applications which *mostly* blocked waiting for I/O on the capture +device probably only would have been somewhat affected (frame lossage, +at a rate which goes up as the application blocks less). Applications +which never blocked on the capture device (e.g. polling only) however +would never have been able to receive any video frames, since in that +case this "is anyone waiting on this?" check on the buffer never would +have evalutated true. This patch just deletes that harmful check +against the buffer's wait queue. + +Signed-off-by: Mike Isely +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/video/s2255drv.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/media/video/s2255drv.c ++++ b/drivers/media/video/s2255drv.c +@@ -578,11 +578,6 @@ static int s2255_got_frame(struct s2255_ + buf = list_entry(dma_q->active.next, + struct s2255_buffer, vb.queue); + +- if (!waitqueue_active(&buf->vb.done)) { +- /* no one active */ +- rc = -1; +- goto unlock; +- } + list_del(&buf->vb.queue); + do_gettimeofday(&buf->vb.ts); + dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i); + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:09 2009 +Message-Id: <20091206233209.736223758@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:43 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Harald Welte , + Dave Jones +Subject: [11/20] [CPUFREQ] Enable ACPI PDC handshake for VIA/Centaur CPUs +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=enable-acpi-pdc-handshake-for-via-centaur-cpus.patch +Content-Length: 1447 +Lines: 40 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Harald Welte + +commit d77b81974521c82fa6fda38dfff1b491dcc62a32 upstream. + +In commit 0de51088e6a82bc8413d3ca9e28bbca2788b5b53, we introduced the +use of acpi-cpufreq on VIA/Centaur CPU's by removing a vendor check for +VENDOR_INTEL. However, as it turns out, at least the Nano CPU's also +need the PDC (processor driver capabilities) handshake in order to +activate the methods required for acpi-cpufreq. + +Since arch_acpi_processor_init_pdc() contains another vendor check for +Intel, the PDC is not initialized on VIA CPU's. The resulting behavior +of a current mainline kernel on such systems is: acpi-cpufreq +loads and it indicates CPU frequency changes. However, the CPU stays at +a single frequency + +This trivial patch ensures that init_intel_pdc() is called on Intel and +VIA/Centaur CPU's alike. + +Signed-off-by: Harald Welte +Signed-off-by: Dave Jones +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/acpi/processor.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/acpi/processor.c ++++ b/arch/x86/kernel/acpi/processor.c +@@ -78,7 +78,8 @@ void arch_acpi_processor_init_pdc(struct + struct cpuinfo_x86 *c = &cpu_data(pr->id); + + pr->pdc = NULL; +- if (c->x86_vendor == X86_VENDOR_INTEL) ++ if (c->x86_vendor == X86_VENDOR_INTEL || ++ c->x86_vendor == X86_VENDOR_CENTAUR) + init_intel_pdc(pr, c); + + return; + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:10 2009 +Message-Id: <20091206233209.900445809@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:44 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Csaba Henk , + Miklos Szeredi , + Harshavardhana +Subject: [12/20] fuse: reject O_DIRECT flag also in fuse_create +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=fuse-reject-o_direct-flag-also-in-fuse_create.patch +Content-Length: 1088 +Lines: 39 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Csaba Henk + +commit 1b7323965a8c6eee9dc4e345a7ae4bff1dc93149 upstream. + +The comment in fuse_open about O_DIRECT: + + "VFS checks this, but only _after_ ->open()" + +also holds for fuse_create, however, the same kind of check was missing there. + +As an impact of this bug, open(newfile, O_RDWR|O_CREAT|O_DIRECT) fails, but a +stub newfile will remain if the fuse server handled the implied FUSE_CREATE +request appropriately. + +Other impact: in the above situation ima_file_free() will complain to open/free +imbalance if CONFIG_IMA is set. + +Signed-off-by: Csaba Henk +Signed-off-by: Miklos Szeredi +Cc: Harshavardhana +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dir.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -398,6 +398,9 @@ static int fuse_create_open(struct inode + if (fc->no_create) + return -ENOSYS; + ++ if (flags & O_DIRECT) ++ return -EINVAL; ++ + forget_req = fuse_get_req(fc); + if (IS_ERR(forget_req)) + return PTR_ERR(forget_req); + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:10 2009 +Message-Id: <20091206233210.067773370@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:45 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + "Anand V. Avati" , + Miklos Szeredi +Subject: [13/20] fuse: prevent fuse_put_request on invalid pointer +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=fuse-prevent-fuse_put_request-on-invalid-pointer.patch +Content-Length: 808 +Lines: 29 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Anand V. Avati + +commit f60311d5f7670d9539b424e4ed8b5c0872fc9e83 upstream. + +fuse_direct_io() has a loop where requests are allocated in each +iteration. if allocation fails, the loop is broken out and follows +into an unconditional fuse_put_request() on that invalid pointer. + +Signed-off-by: Anand V. Avati +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/file.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -1005,7 +1005,8 @@ static ssize_t fuse_direct_io(struct fil + break; + } + } +- fuse_put_request(fc, req); ++ if (!IS_ERR(req)) ++ fuse_put_request(fc, req); + if (res > 0) { + if (write) + fuse_write_update_size(inode, pos); + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:10 2009 +Message-Id: <20091206233210.240780761@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:46 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Roel Kluin , + Karsten Keil , + "David S. Miller" +Subject: [14/20] isdn: hfc_usb: Fix read buffer overflow +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=isdn-hfc_usb-fix-read-buffer-overflow.patch +Content-Length: 939 +Lines: 30 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Roel Kluin + +commit 286e633ef0ff5bb63c07b4516665da8004966fec upstream. + +Check whether index is within bounds before testing the element. + +Signed-off-by: Roel Kluin +Cc: Karsten Keil +Signed-off-by: Andrew Morton +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/isdn/hisax/hfc_usb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/isdn/hisax/hfc_usb.c ++++ b/drivers/isdn/hisax/hfc_usb.c +@@ -818,8 +818,8 @@ collect_rx_frame(usb_fifo * fifo, __u8 * + } + /* we have a complete hdlc packet */ + if (finish) { +- if ((!fifo->skbuff->data[fifo->skbuff->len - 1]) +- && (fifo->skbuff->len > 3)) { ++ if (fifo->skbuff->len > 3 && ++ !fifo->skbuff->data[fifo->skbuff->len - 1]) { + + if (fifon == HFCUSB_D_RX) { + DBG(HFCUSB_DBG_DCHANNEL, + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:10 2009 +Message-Id: <20091206233210.382595495@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:47 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Roel Kluin , + Henrique de Moraes Holschuh , + Len Brown +Subject: [15/20] thinkpad-acpi: fix sign of ERESTARTSYS return +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=thinkpad-acpi-fix-sign-of-erestartsys-return.patch +Content-Length: 874 +Lines: 28 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Roel Kluin + +commit 80a8d1228e90349b4514e8c925c061fa5cbcea75 upstream. + +The returned error should be negative + +Signed-off-by: Roel Kluin +Acked-by: Henrique de Moraes Holschuh +Signed-off-by: Andrew Morton +Signed-off-by: Len Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/thinkpad_acpi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/misc/thinkpad_acpi.c ++++ b/drivers/misc/thinkpad_acpi.c +@@ -5042,7 +5042,7 @@ static int brightness_write(char *buf) + * Doing it this way makes the syscall restartable in case of EINTR + */ + rc = brightness_set(level); +- return (rc == -EINTR)? ERESTARTSYS : rc; ++ return (rc == -EINTR)? -ERESTARTSYS : rc; + } + + static struct ibm_struct brightness_driver_data = { + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:10 2009 +Message-Id: <20091206233210.538424805@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:48 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Libin Yang , + David Brownell , + Alan Stern +Subject: [16/20] USB: ohci: quirk AMD prefetch for USB 1.1 ISO transfer +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=usb-ohci-quirk-amd-prefetch-for-usb-1.1-iso-transfer.patch +Content-Length: 4442 +Lines: 145 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Libin Yang + +commit a1f17a872bc7b1cb7efdd5486a2963e88a536e61 upstream. + +The following patch in the driver is required to avoid USB 1.1 device +failures that may occur due to requests from USB OHCI controllers may +be overwritten if the latency for any pending request by the USB +controller is very long (in the range of milliseconds). + +Signed-off-by: Libin Yang +Cc: David Brownell +Cc: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ohci-hcd.c | 5 +++++ + drivers/usb/host/ohci-pci.c | 20 ++++++++++++++++++++ + drivers/usb/host/ohci-q.c | 18 ++++++++++++------ + drivers/usb/host/ohci.h | 9 +++++++++ + 4 files changed, 46 insertions(+), 6 deletions(-) + +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -89,6 +89,7 @@ static int ohci_restart (struct ohci_hcd + #ifdef CONFIG_PCI + static void quirk_amd_pll(int state); + static void amd_iso_dev_put(void); ++static void sb800_prefetch(struct ohci_hcd *ohci, int on); + #else + static inline void quirk_amd_pll(int state) + { +@@ -98,6 +99,10 @@ static inline void amd_iso_dev_put(void) + { + return; + } ++static inline void sb800_prefetch(struct ohci_hcd *ohci, int on) ++{ ++ return; ++} + #endif + + +--- a/drivers/usb/host/ohci-pci.c ++++ b/drivers/usb/host/ohci-pci.c +@@ -177,6 +177,13 @@ static int ohci_quirk_amd700(struct usb_ + return 0; + + pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); ++ ++ /* SB800 needs pre-fetch fix */ ++ if ((rev >= 0x40) && (rev <= 0x4f)) { ++ ohci->flags |= OHCI_QUIRK_AMD_PREFETCH; ++ ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); ++ } ++ + if ((rev > 0x3b) || (rev < 0x30)) { + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; +@@ -262,6 +269,19 @@ static void amd_iso_dev_put(void) + + } + ++static void sb800_prefetch(struct ohci_hcd *ohci, int on) ++{ ++ struct pci_dev *pdev; ++ u16 misc; ++ ++ pdev = to_pci_dev(ohci_to_hcd(ohci)->self.controller); ++ pci_read_config_word(pdev, 0x50, &misc); ++ if (on == 0) ++ pci_write_config_word(pdev, 0x50, misc & 0xfcff); ++ else ++ pci_write_config_word(pdev, 0x50, misc | 0x0300); ++} ++ + /* List of quirks for OHCI */ + static const struct pci_device_id ohci_pci_quirks[] = { + { +--- a/drivers/usb/host/ohci-q.c ++++ b/drivers/usb/host/ohci-q.c +@@ -49,9 +49,12 @@ __acquires(ohci->lock) + switch (usb_pipetype (urb->pipe)) { + case PIPE_ISOCHRONOUS: + ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; +- if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 +- && quirk_amdiso(ohci)) +- quirk_amd_pll(1); ++ if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { ++ if (quirk_amdiso(ohci)) ++ quirk_amd_pll(1); ++ if (quirk_amdprefetch(ohci)) ++ sb800_prefetch(ohci, 0); ++ } + break; + case PIPE_INTERRUPT: + ohci_to_hcd(ohci)->self.bandwidth_int_reqs--; +@@ -680,9 +683,12 @@ static void td_submit_urb ( + data + urb->iso_frame_desc [cnt].offset, + urb->iso_frame_desc [cnt].length, urb, cnt); + } +- if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 +- && quirk_amdiso(ohci)) +- quirk_amd_pll(0); ++ if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { ++ if (quirk_amdiso(ohci)) ++ quirk_amd_pll(0); ++ if (quirk_amdprefetch(ohci)) ++ sb800_prefetch(ohci, 1); ++ } + periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0 + && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0; + break; +--- a/drivers/usb/host/ohci.h ++++ b/drivers/usb/host/ohci.h +@@ -402,6 +402,7 @@ struct ohci_hcd { + #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ + #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ + #define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ ++#define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ + // there are also chip quirks/bugs in init logic + + struct work_struct nec_work; /* Worker for NEC quirk */ +@@ -433,6 +434,10 @@ static inline int quirk_amdiso(struct oh + { + return ohci->flags & OHCI_QUIRK_AMD_ISO; + } ++static inline int quirk_amdprefetch(struct ohci_hcd *ohci) ++{ ++ return ohci->flags & OHCI_QUIRK_AMD_PREFETCH; ++} + #else + static inline int quirk_nec(struct ohci_hcd *ohci) + { +@@ -446,6 +451,10 @@ static inline int quirk_amdiso(struct oh + { + return 0; + } ++static inline int quirk_amdprefetch(struct ohci_hcd *ohci) ++{ ++ return 0; ++} + #endif + + /* convert between an hcd pointer and the corresponding ohci_hcd */ + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:10 2009 +Message-Id: <20091206233210.667934007@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:49 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Oliver Neukum , + Matthias Urlichs +Subject: [17/20] USB: suspend/resume support for option driver +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=usb-suspend-resume-support-for-option-driver.patch +Content-Length: 4791 +Lines: 168 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Oliver Neukum + +commit 4901b2c34ecb6fc45909228ad269c8126efe4401 upstream. + +This patch implements suspend and resume methods for the +option driver. With my hardware I can even suspend the system +and keep up a connection for a short time. + +Signed-off-by: Oliver Neukum +Signed-Off-By: Matthias Urlichs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 86 ++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 80 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -62,6 +62,8 @@ static int option_tiocmget(struct tty_s + static int option_tiocmset(struct tty_struct *tty, struct file *file, + unsigned int set, unsigned int clear); + static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port); ++static int option_suspend(struct usb_serial *serial, pm_message_t message); ++static int option_resume(struct usb_serial *serial); + + /* Vendor and product IDs */ + #define OPTION_VENDOR_ID 0x0AF0 +@@ -511,6 +513,8 @@ static struct usb_driver option_driver = + .name = "option", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, ++ .suspend = usb_serial_suspend, ++ .resume = usb_serial_resume, + .id_table = option_ids, + .no_dynamic_id = 1, + }; +@@ -539,6 +543,8 @@ static struct usb_serial_driver option_1 + .attach = option_startup, + .shutdown = option_shutdown, + .read_int_callback = option_instat_callback, ++ .suspend = option_suspend, ++ .resume = option_resume, + }; + + static int debug; +@@ -809,10 +815,10 @@ static void option_instat_callback(struc + req_pkt->bRequestType, req_pkt->bRequest); + } + } else +- dbg("%s: error %d", __func__, status); ++ err("%s: error %d", __func__, status); + + /* Resubmit urb so we continue receiving IRQ data */ +- if (status != -ESHUTDOWN) { ++ if (status != -ESHUTDOWN && status != -ENOENT) { + urb->dev = serial->dev; + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err) +@@ -831,7 +837,6 @@ static int option_write_room(struct tty_ + + portdata = usb_get_serial_port_data(port); + +- + for (i = 0; i < N_OUT_URB; i++) { + this_urb = portdata->out_urbs[i]; + if (this_urb && !test_bit(i, &portdata->out_busy)) +@@ -1090,14 +1095,12 @@ bail_out_error: + return 1; + } + +-static void option_shutdown(struct usb_serial *serial) ++static void stop_read_write_urbs(struct usb_serial *serial) + { + int i, j; + struct usb_serial_port *port; + struct option_port_private *portdata; + +- dbg("%s", __func__); +- + /* Stop reading/writing urbs */ + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; +@@ -1107,6 +1110,17 @@ static void option_shutdown(struct usb_s + for (j = 0; j < N_OUT_URB; j++) + usb_kill_urb(portdata->out_urbs[j]); + } ++} ++ ++static void option_shutdown(struct usb_serial *serial) ++{ ++ int i, j; ++ struct usb_serial_port *port; ++ struct option_port_private *portdata; ++ ++ dbg("%s", __func__); ++ ++ stop_read_write_urbs(serial); + + /* Now free them */ + for (i = 0; i < serial->num_ports; ++i) { +@@ -1137,6 +1151,66 @@ static void option_shutdown(struct usb_s + } + } + ++static int option_suspend(struct usb_serial *serial, pm_message_t message) ++{ ++ dbg("%s entered", __func__); ++ stop_read_write_urbs(serial); ++ ++ return 0; ++} ++ ++static int option_resume(struct usb_serial *serial) ++{ ++ int err, i, j; ++ struct usb_serial_port *port; ++ struct urb *urb; ++ struct option_port_private *portdata; ++ ++ dbg("%s entered", __func__); ++ /* get the interrupt URBs resubmitted unconditionally */ ++ for (i = 0; i < serial->num_ports; i++) { ++ port = serial->port[i]; ++ if (!port->interrupt_in_urb) { ++ dbg("%s: No interrupt URB for port %d\n", __func__, i); ++ continue; ++ } ++ port->interrupt_in_urb->dev = serial->dev; ++ err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); ++ dbg("Submitted interrupt URB for port %d (result %d)", i, err); ++ if (err < 0) { ++ err("%s: Error %d for interrupt URB of port%d", ++ __func__, err, i); ++ return err; ++ } ++ } ++ ++ for (i = 0; i < serial->num_ports; i++) { ++ /* walk all ports */ ++ port = serial->port[i]; ++ portdata = usb_get_serial_port_data(port); ++ mutex_lock(&port->mutex); ++ ++ /* skip closed ports */ ++ if (!port->port.count) { ++ mutex_unlock(&port->mutex); ++ continue; ++ } ++ ++ for (j = 0; j < N_IN_URB; j++) { ++ urb = portdata->in_urbs[j]; ++ err = usb_submit_urb(urb, GFP_NOIO); ++ if (err < 0) { ++ mutex_unlock(&port->mutex); ++ err("%s: Error %d for bulk URB %d", ++ __func__, err, i); ++ return err; ++ } ++ } ++ mutex_unlock(&port->mutex); ++ } ++ return 0; ++} ++ + MODULE_AUTHOR(DRIVER_AUTHOR); + MODULE_DESCRIPTION(DRIVER_DESC); + MODULE_VERSION(DRIVER_VERSION); + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:10 2009 +Message-Id: <20091206233210.832793005@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:50 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org, + Greg KH +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Rory Filer , + USB list , + Alan Stern +Subject: [18/20] USB: usb-serial: replace shutdown with disconnect, release +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=usb-usb-serial-replace-shutdown-with-disconnect-release.patch +Content-Length: 49323 +Lines: 1499 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +This is commit f9c99bb8b3a1ec81af68d484a551307326c2e933 back-ported to +2.6.27.39. + +This patch (as1254-2) splits up the shutdown method of usb_serial_driver +into a disconnect and a release method. + +The problem is that the usb-serial core was calling shutdown during +disconnect handling, but drivers didn't expect it to be called until +after all the open file references had been closed. The result was an +oops when the close method tried to use memory that had been +deallocated by shutdown. + +Signed-off-by: Alan Stern +Tested-by: Rory Filer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/aircable.c | 5 +-- + drivers/usb/serial/belkin_sa.c | 7 ++-- + drivers/usb/serial/cp2101.c | 6 ++-- + drivers/usb/serial/cyberjack.c | 20 ++++++++++---- + drivers/usb/serial/cypress_m8.c | 11 +++---- + drivers/usb/serial/digi_acceleport.c | 20 ++++++++++---- + drivers/usb/serial/empeg.c | 8 ----- + drivers/usb/serial/ftdi_sio.c | 14 --------- + drivers/usb/serial/garmin_gps.c | 16 +++++++++-- + drivers/usb/serial/generic.c | 9 ++++-- + drivers/usb/serial/io_edgeport.c | 29 ++++++++++++++------ + drivers/usb/serial/io_tables.h | 12 +++++--- + drivers/usb/serial/io_ti.c | 22 ++++++++++++--- + drivers/usb/serial/ipaq.c | 7 ---- + drivers/usb/serial/iuu_phoenix.c | 6 ++-- + drivers/usb/serial/keyspan.c | 13 ++++++++- + drivers/usb/serial/keyspan.h | 12 +++++--- + drivers/usb/serial/keyspan_pda.c | 4 +- + drivers/usb/serial/kl5kusb105.c | 39 +++++++++++++++------------ + drivers/usb/serial/kobil_sct.c | 12 ++------ + drivers/usb/serial/mct_u232.c | 13 +++------ + drivers/usb/serial/mos7720.c | 9 ++---- + drivers/usb/serial/mos7840.c | 48 ++++++++++++++++++++++++++++------ + drivers/usb/serial/omninet.c | 19 ++++++++++--- + drivers/usb/serial/option.c | 17 ++++++++---- + drivers/usb/serial/oti6858.c | 7 ++-- + drivers/usb/serial/pl2303.c | 5 +-- + drivers/usb/serial/sierra.c | 28 +++++++++++++++++-- + drivers/usb/serial/spcp8x5.c | 5 +-- + drivers/usb/serial/ti_usb_3410_5052.c | 10 ++----- + drivers/usb/serial/usb-serial.c | 29 +++++++++----------- + drivers/usb/serial/visor.c | 13 +++------ + drivers/usb/serial/whiteheat.c | 6 ++-- + include/linux/usb/serial.h | 12 +++++--- + 34 files changed, 298 insertions(+), 195 deletions(-) + +--- a/drivers/usb/serial/aircable.c ++++ b/drivers/usb/serial/aircable.c +@@ -362,7 +362,7 @@ static int aircable_attach(struct usb_se + return 0; + } + +-static void aircable_shutdown(struct usb_serial *serial) ++static void aircable_release(struct usb_serial *serial) + { + + struct usb_serial_port *port = serial->port[0]; +@@ -373,7 +373,6 @@ static void aircable_shutdown(struct usb + if (priv) { + serial_buf_free(priv->tx_buf); + serial_buf_free(priv->rx_buf); +- usb_set_serial_port_data(port, NULL); + kfree(priv); + } + } +@@ -598,7 +597,7 @@ static struct usb_serial_driver aircable + .num_ports = 1, + .attach = aircable_attach, + .probe = aircable_probe, +- .shutdown = aircable_shutdown, ++ .release = aircable_release, + .write = aircable_write, + .write_room = aircable_write_room, + .write_bulk_callback = aircable_write_bulk_callback, +--- a/drivers/usb/serial/belkin_sa.c ++++ b/drivers/usb/serial/belkin_sa.c +@@ -90,7 +90,7 @@ static int debug; + + /* function prototypes for a Belkin USB Serial Adapter F5U103 */ + static int belkin_sa_startup(struct usb_serial *serial); +-static void belkin_sa_shutdown(struct usb_serial *serial); ++static void belkin_sa_release(struct usb_serial *serial); + static int belkin_sa_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); + static void belkin_sa_close(struct tty_struct *tty, +@@ -143,7 +143,7 @@ static struct usb_serial_driver belkin_d + .tiocmget = belkin_sa_tiocmget, + .tiocmset = belkin_sa_tiocmset, + .attach = belkin_sa_startup, +- .shutdown = belkin_sa_shutdown, ++ .release = belkin_sa_release, + }; + + +@@ -198,14 +198,13 @@ static int belkin_sa_startup(struct usb_ + } + + +-static void belkin_sa_shutdown(struct usb_serial *serial) ++static void belkin_sa_release(struct usb_serial *serial) + { + struct belkin_sa_private *priv; + int i; + + dbg("%s", __func__); + +- /* stop reads and writes on all ports */ + for (i = 0; i < serial->num_ports; ++i) { + /* My special items, the standard routines free my urbs */ + priv = usb_get_serial_port_data(serial->port[i]); +--- a/drivers/usb/serial/cp2101.c ++++ b/drivers/usb/serial/cp2101.c +@@ -50,7 +50,7 @@ static int cp2101_tiocmset(struct tty_st + unsigned int, unsigned int); + static void cp2101_break_ctl(struct tty_struct *, int); + static int cp2101_startup(struct usb_serial *); +-static void cp2101_shutdown(struct usb_serial *); ++static void cp2101_disconnect(struct usb_serial *); + + + static int debug; +@@ -125,7 +125,7 @@ static struct usb_serial_driver cp2101_d + .tiocmget = cp2101_tiocmget, + .tiocmset = cp2101_tiocmset, + .attach = cp2101_startup, +- .shutdown = cp2101_shutdown, ++ .disconnect = cp2101_disconnect, + }; + + /* Config request types */ +@@ -727,7 +727,7 @@ static int cp2101_startup(struct usb_ser + return 0; + } + +-static void cp2101_shutdown(struct usb_serial *serial) ++static void cp2101_disconnect(struct usb_serial *serial) + { + int i; + +--- a/drivers/usb/serial/cyberjack.c ++++ b/drivers/usb/serial/cyberjack.c +@@ -58,7 +58,8 @@ static int debug; + + /* Function prototypes */ + static int cyberjack_startup(struct usb_serial *serial); +-static void cyberjack_shutdown(struct usb_serial *serial); ++static void cyberjack_disconnect(struct usb_serial *serial); ++static void cyberjack_release(struct usb_serial *serial); + static int cyberjack_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); + static void cyberjack_close(struct tty_struct *tty, +@@ -95,7 +96,8 @@ static struct usb_serial_driver cyberjac + .id_table = id_table, + .num_ports = 1, + .attach = cyberjack_startup, +- .shutdown = cyberjack_shutdown, ++ .disconnect = cyberjack_disconnect, ++ .release = cyberjack_release, + .open = cyberjack_open, + .close = cyberjack_close, + .write = cyberjack_write, +@@ -148,17 +150,25 @@ static int cyberjack_startup(struct usb_ + return 0; + } + +-static void cyberjack_shutdown(struct usb_serial *serial) ++static void cyberjack_disconnect(struct usb_serial *serial) + { + int i; + + dbg("%s", __func__); + +- for (i = 0; i < serial->num_ports; ++i) { ++ for (i = 0; i < serial->num_ports; ++i) + usb_kill_urb(serial->port[i]->interrupt_in_urb); ++} ++ ++static void cyberjack_release(struct usb_serial *serial) ++{ ++ int i; ++ ++ dbg("%s", __func__); ++ ++ for (i = 0; i < serial->num_ports; ++i) { + /* My special items, the standard routines free my urbs */ + kfree(usb_get_serial_port_data(serial->port[i])); +- usb_set_serial_port_data(serial->port[i], NULL); + } + } + +--- a/drivers/usb/serial/cypress_m8.c ++++ b/drivers/usb/serial/cypress_m8.c +@@ -171,7 +171,7 @@ struct cypress_buf { + static int cypress_earthmate_startup(struct usb_serial *serial); + static int cypress_hidcom_startup(struct usb_serial *serial); + static int cypress_ca42v2_startup(struct usb_serial *serial); +-static void cypress_shutdown(struct usb_serial *serial); ++static void cypress_release(struct usb_serial *serial); + static int cypress_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); + static void cypress_close(struct tty_struct *tty, +@@ -215,7 +215,7 @@ static struct usb_serial_driver cypress_ + .id_table = id_table_earthmate, + .num_ports = 1, + .attach = cypress_earthmate_startup, +- .shutdown = cypress_shutdown, ++ .release = cypress_release, + .open = cypress_open, + .close = cypress_close, + .write = cypress_write, +@@ -241,7 +241,7 @@ static struct usb_serial_driver cypress_ + .id_table = id_table_cyphidcomrs232, + .num_ports = 1, + .attach = cypress_hidcom_startup, +- .shutdown = cypress_shutdown, ++ .release = cypress_release, + .open = cypress_open, + .close = cypress_close, + .write = cypress_write, +@@ -267,7 +267,7 @@ static struct usb_serial_driver cypress_ + .id_table = id_table_nokiaca42v2, + .num_ports = 1, + .attach = cypress_ca42v2_startup, +- .shutdown = cypress_shutdown, ++ .release = cypress_release, + .open = cypress_open, + .close = cypress_close, + .write = cypress_write, +@@ -612,7 +612,7 @@ static int cypress_ca42v2_startup(struct + } /* cypress_ca42v2_startup */ + + +-static void cypress_shutdown(struct usb_serial *serial) ++static void cypress_release(struct usb_serial *serial) + { + struct cypress_private *priv; + +@@ -625,7 +625,6 @@ static void cypress_shutdown(struct usb_ + if (priv) { + cypress_buf_free(priv->buf); + kfree(priv); +- usb_set_serial_port_data(serial->port[0], NULL); + } + } + +--- a/drivers/usb/serial/digi_acceleport.c ++++ b/drivers/usb/serial/digi_acceleport.c +@@ -460,7 +460,8 @@ static void digi_close(struct tty_struct + struct file *filp); + static int digi_startup_device(struct usb_serial *serial); + static int digi_startup(struct usb_serial *serial); +-static void digi_shutdown(struct usb_serial *serial); ++static void digi_disconnect(struct usb_serial *serial); ++static void digi_release(struct usb_serial *serial); + static void digi_read_bulk_callback(struct urb *urb); + static int digi_read_inb_callback(struct urb *urb); + static int digi_read_oob_callback(struct urb *urb); +@@ -522,7 +523,8 @@ static struct usb_serial_driver digi_acc + .tiocmget = digi_tiocmget, + .tiocmset = digi_tiocmset, + .attach = digi_startup, +- .shutdown = digi_shutdown, ++ .disconnect = digi_disconnect, ++ .release = digi_release, + }; + + static struct usb_serial_driver digi_acceleport_4_device = { +@@ -548,7 +550,8 @@ static struct usb_serial_driver digi_acc + .tiocmget = digi_tiocmget, + .tiocmset = digi_tiocmset, + .attach = digi_startup, +- .shutdown = digi_shutdown, ++ .disconnect = digi_disconnect, ++ .release = digi_release, + }; + + +@@ -1586,16 +1589,23 @@ static int digi_startup(struct usb_seria + } + + +-static void digi_shutdown(struct usb_serial *serial) ++static void digi_disconnect(struct usb_serial *serial) + { + int i; +- dbg("digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt()); ++ dbg("digi_disconnect: TOP, in_interrupt()=%ld", in_interrupt()); + + /* stop reads and writes on all ports */ + for (i = 0; i < serial->type->num_ports + 1; i++) { + usb_kill_urb(serial->port[i]->read_urb); + usb_kill_urb(serial->port[i]->write_urb); + } ++} ++ ++ ++static void digi_release(struct usb_serial *serial) ++{ ++ int i; ++ dbg("digi_release: TOP, in_interrupt()=%ld", in_interrupt()); + + /* free the private data structures for all ports */ + /* number of regular ports + 1 for the out-of-band port */ +--- a/drivers/usb/serial/empeg.c ++++ b/drivers/usb/serial/empeg.c +@@ -92,7 +92,6 @@ static int empeg_chars_in_buffer(struct + static void empeg_throttle(struct tty_struct *tty); + static void empeg_unthrottle(struct tty_struct *tty); + static int empeg_startup(struct usb_serial *serial); +-static void empeg_shutdown(struct usb_serial *serial); + static void empeg_set_termios(struct tty_struct *tty, + struct usb_serial_port *port, struct ktermios *old_termios); + static void empeg_write_bulk_callback(struct urb *urb); +@@ -126,7 +125,6 @@ static struct usb_serial_driver empeg_de + .throttle = empeg_throttle, + .unthrottle = empeg_unthrottle, + .attach = empeg_startup, +- .shutdown = empeg_shutdown, + .set_termios = empeg_set_termios, + .write = empeg_write, + .write_room = empeg_write_room, +@@ -429,12 +427,6 @@ static int empeg_startup(struct usb_ser + } + + +-static void empeg_shutdown(struct usb_serial *serial) +-{ +- dbg("%s", __func__); +-} +- +- + static void empeg_set_termios(struct tty_struct *tty, + struct usb_serial_port *port, struct ktermios *old_termios) + { +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -708,7 +708,6 @@ static const char *ftdi_chip_name[] = { + /* function prototypes for a FTDI serial converter */ + static int ftdi_sio_probe(struct usb_serial *serial, + const struct usb_device_id *id); +-static void ftdi_shutdown(struct usb_serial *serial); + static int ftdi_sio_port_probe(struct usb_serial_port *port); + static int ftdi_sio_port_remove(struct usb_serial_port *port); + static int ftdi_open(struct tty_struct *tty, +@@ -764,7 +763,6 @@ static struct usb_serial_driver ftdi_sio + .ioctl = ftdi_ioctl, + .set_termios = ftdi_set_termios, + .break_ctl = ftdi_break_ctl, +- .shutdown = ftdi_shutdown, + }; + + +@@ -1442,18 +1440,6 @@ static int ftdi_mtxorb_hack_setup(struct + return 0; + } + +-/* ftdi_shutdown is called from usbserial:usb_serial_disconnect +- * it is called when the usb device is disconnected +- * +- * usbserial:usb_serial_disconnect +- * calls __serial_close for each open of the port +- * shutdown is called then (ie ftdi_shutdown) +- */ +-static void ftdi_shutdown(struct usb_serial *serial) +-{ +- dbg("%s", __func__); +-} +- + static int ftdi_sio_port_remove(struct usb_serial_port *port) + { + struct ftdi_private *priv = usb_get_serial_port_data(port); +--- a/drivers/usb/serial/garmin_gps.c ++++ b/drivers/usb/serial/garmin_gps.c +@@ -1527,7 +1527,7 @@ static int garmin_attach(struct usb_seri + } + + +-static void garmin_shutdown(struct usb_serial *serial) ++static void garmin_disconnect(struct usb_serial *serial) + { + struct usb_serial_port *port = serial->port[0]; + struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); +@@ -1536,8 +1536,17 @@ static void garmin_shutdown(struct usb_s + + usb_kill_urb(port->interrupt_in_urb); + del_timer_sync(&garmin_data_p->timer); ++} ++ ++ ++static void garmin_release(struct usb_serial *serial) ++{ ++ struct usb_serial_port *port = serial->port[0]; ++ struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); ++ ++ dbg("%s", __func__); ++ + kfree(garmin_data_p); +- usb_set_serial_port_data(port, NULL); + } + + +@@ -1556,7 +1565,8 @@ static struct usb_serial_driver garmin_d + .throttle = garmin_throttle, + .unthrottle = garmin_unthrottle, + .attach = garmin_attach, +- .shutdown = garmin_shutdown, ++ .disconnect = garmin_disconnect, ++ .release = garmin_release, + .write = garmin_write, + .write_room = garmin_write_room, + .write_bulk_callback = garmin_write_bulk_callback, +--- a/drivers/usb/serial/generic.c ++++ b/drivers/usb/serial/generic.c +@@ -63,7 +63,8 @@ struct usb_serial_driver usb_serial_gene + .id_table = generic_device_ids, + .usb_driver = &generic_driver, + .num_ports = 1, +- .shutdown = usb_serial_generic_shutdown, ++ .disconnect = usb_serial_generic_disconnect, ++ .release = usb_serial_generic_release, + .throttle = usb_serial_generic_throttle, + .unthrottle = usb_serial_generic_unthrottle, + .resume = usb_serial_generic_resume, +@@ -419,7 +420,7 @@ void usb_serial_generic_unthrottle(struc + } + } + +-void usb_serial_generic_shutdown(struct usb_serial *serial) ++void usb_serial_generic_disconnect(struct usb_serial *serial) + { + int i; + +@@ -430,3 +431,7 @@ void usb_serial_generic_shutdown(struct + generic_cleanup(serial->port[i]); + } + ++void usb_serial_generic_release(struct usb_serial *serial) ++{ ++ dbg("%s", __func__); ++} +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -225,7 +225,8 @@ static int edge_tiocmget(struct tty_str + static int edge_tiocmset(struct tty_struct *tty, struct file *file, + unsigned int set, unsigned int clear); + static int edge_startup(struct usb_serial *serial); +-static void edge_shutdown(struct usb_serial *serial); ++static void edge_disconnect(struct usb_serial *serial); ++static void edge_release(struct usb_serial *serial); + + #include "io_tables.h" /* all of the devices that this driver supports */ + +@@ -3178,21 +3179,16 @@ static int edge_startup(struct usb_seria + + + /**************************************************************************** +- * edge_shutdown ++ * edge_disconnect + * This function is called whenever the device is removed from the usb bus. + ****************************************************************************/ +-static void edge_shutdown(struct usb_serial *serial) ++static void edge_disconnect(struct usb_serial *serial) + { + struct edgeport_serial *edge_serial = usb_get_serial_data(serial); +- int i; + + dbg("%s", __func__); + + /* stop reads and writes on all ports */ +- for (i = 0; i < serial->num_ports; ++i) { +- kfree(usb_get_serial_port_data(serial->port[i])); +- usb_set_serial_port_data(serial->port[i], NULL); +- } + /* free up our endpoint stuff */ + if (edge_serial->is_epic) { + usb_kill_urb(edge_serial->interrupt_read_urb); +@@ -3203,9 +3199,24 @@ static void edge_shutdown(struct usb_ser + usb_free_urb(edge_serial->read_urb); + kfree(edge_serial->bulk_in_buffer); + } ++} ++ ++ ++/**************************************************************************** ++ * edge_release ++ * This function is called when the device structure is deallocated. ++ ****************************************************************************/ ++static void edge_release(struct usb_serial *serial) ++{ ++ struct edgeport_serial *edge_serial = usb_get_serial_data(serial); ++ int i; ++ ++ dbg("%s", __func__); ++ ++ for (i = 0; i < serial->num_ports; ++i) ++ kfree(usb_get_serial_port_data(serial->port[i])); + + kfree(edge_serial); +- usb_set_serial_data(serial, NULL); + } + + +--- a/drivers/usb/serial/io_tables.h ++++ b/drivers/usb/serial/io_tables.h +@@ -117,7 +117,8 @@ static struct usb_serial_driver edgeport + .throttle = edge_throttle, + .unthrottle = edge_unthrottle, + .attach = edge_startup, +- .shutdown = edge_shutdown, ++ .disconnect = edge_disconnect, ++ .release = edge_release, + .ioctl = edge_ioctl, + .set_termios = edge_set_termios, + .tiocmget = edge_tiocmget, +@@ -145,7 +146,8 @@ static struct usb_serial_driver edgeport + .throttle = edge_throttle, + .unthrottle = edge_unthrottle, + .attach = edge_startup, +- .shutdown = edge_shutdown, ++ .disconnect = edge_disconnect, ++ .release = edge_release, + .ioctl = edge_ioctl, + .set_termios = edge_set_termios, + .tiocmget = edge_tiocmget, +@@ -173,7 +175,8 @@ static struct usb_serial_driver edgeport + .throttle = edge_throttle, + .unthrottle = edge_unthrottle, + .attach = edge_startup, +- .shutdown = edge_shutdown, ++ .disconnect = edge_disconnect, ++ .release = edge_release, + .ioctl = edge_ioctl, + .set_termios = edge_set_termios, + .tiocmget = edge_tiocmget, +@@ -200,7 +203,8 @@ static struct usb_serial_driver epic_dev + .throttle = edge_throttle, + .unthrottle = edge_unthrottle, + .attach = edge_startup, +- .shutdown = edge_shutdown, ++ .disconnect = edge_disconnect, ++ .release = edge_release, + .ioctl = edge_ioctl, + .set_termios = edge_set_termios, + .tiocmget = edge_tiocmget, +--- a/drivers/usb/serial/io_ti.c ++++ b/drivers/usb/serial/io_ti.c +@@ -2652,7 +2652,7 @@ cleanup: + return -ENOMEM; + } + +-static void edge_shutdown(struct usb_serial *serial) ++static void edge_disconnect(struct usb_serial *serial) + { + int i; + struct edgeport_port *edge_port; +@@ -2662,12 +2662,22 @@ static void edge_shutdown(struct usb_ser + for (i = 0; i < serial->num_ports; ++i) { + edge_port = usb_get_serial_port_data(serial->port[i]); + edge_remove_sysfs_attrs(edge_port->port); ++ } ++} ++ ++static void edge_release(struct usb_serial *serial) ++{ ++ int i; ++ struct edgeport_port *edge_port; ++ ++ dbg("%s", __func__); ++ ++ for (i = 0; i < serial->num_ports; ++i) { ++ edge_port = usb_get_serial_port_data(serial->port[i]); + edge_buf_free(edge_port->ep_out_buf); + kfree(edge_port); +- usb_set_serial_port_data(serial->port[i], NULL); + } + kfree(usb_get_serial_data(serial)); +- usb_set_serial_data(serial, NULL); + } + + +@@ -2904,7 +2914,8 @@ static struct usb_serial_driver edgeport + .throttle = edge_throttle, + .unthrottle = edge_unthrottle, + .attach = edge_startup, +- .shutdown = edge_shutdown, ++ .disconnect = edge_disconnect, ++ .release = edge_release, + .port_probe = edge_create_sysfs_attrs, + .ioctl = edge_ioctl, + .set_termios = edge_set_termios, +@@ -2933,7 +2944,8 @@ static struct usb_serial_driver edgeport + .throttle = edge_throttle, + .unthrottle = edge_unthrottle, + .attach = edge_startup, +- .shutdown = edge_shutdown, ++ .disconnect = edge_disconnect, ++ .release = edge_release, + .port_probe = edge_create_sysfs_attrs, + .ioctl = edge_ioctl, + .set_termios = edge_set_termios, +--- a/drivers/usb/serial/ipaq.c ++++ b/drivers/usb/serial/ipaq.c +@@ -79,7 +79,6 @@ static int ipaq_open(struct tty_struct + static void ipaq_close(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); + static int ipaq_startup(struct usb_serial *serial); +-static void ipaq_shutdown(struct usb_serial *serial); + static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, + const unsigned char *buf, int count); + static int ipaq_write_bulk(struct usb_serial_port *port, +@@ -581,7 +580,6 @@ static struct usb_serial_driver ipaq_dev + .open = ipaq_open, + .close = ipaq_close, + .attach = ipaq_startup, +- .shutdown = ipaq_shutdown, + .write = ipaq_write, + .write_room = ipaq_write_room, + .chars_in_buffer = ipaq_chars_in_buffer, +@@ -957,11 +955,6 @@ static int ipaq_startup(struct usb_seria + return usb_reset_configuration(serial->dev); + } + +-static void ipaq_shutdown(struct usb_serial *serial) +-{ +- dbg("%s", __func__); +-} +- + static int __init ipaq_init(void) + { + int retval; +--- a/drivers/usb/serial/iuu_phoenix.c ++++ b/drivers/usb/serial/iuu_phoenix.c +@@ -122,8 +122,8 @@ static int iuu_startup(struct usb_serial + return 0; + } + +-/* Shutdown function */ +-static void iuu_shutdown(struct usb_serial *serial) ++/* Release function */ ++static void iuu_release(struct usb_serial *serial) + { + struct usb_serial_port *port = serial->port[0]; + struct iuu_private *priv = usb_get_serial_port_data(port); +@@ -1171,7 +1171,7 @@ static struct usb_serial_driver iuu_devi + .tiocmget = iuu_tiocmget, + .tiocmset = iuu_tiocmset, + .attach = iuu_startup, +- .shutdown = iuu_shutdown, ++ .release = iuu_release, + }; + + static int __init iuu_init(void) +--- a/drivers/usb/serial/keyspan.c ++++ b/drivers/usb/serial/keyspan.c +@@ -2678,7 +2678,7 @@ static int keyspan_startup(struct usb_se + return 0; + } + +-static void keyspan_shutdown(struct usb_serial *serial) ++static void keyspan_disconnect(struct usb_serial *serial) + { + int i, j; + struct usb_serial_port *port; +@@ -2718,6 +2718,17 @@ static void keyspan_shutdown(struct usb_ + usb_free_urb(p_priv->out_urbs[j]); + } + } ++} ++ ++static void keyspan_release(struct usb_serial *serial) ++{ ++ int i; ++ struct usb_serial_port *port; ++ struct keyspan_serial_private *s_priv; ++ ++ dbg("%s", __func__); ++ ++ s_priv = usb_get_serial_data(serial); + + /* dbg("Freeing serial->private."); */ + kfree(s_priv); +--- a/drivers/usb/serial/keyspan.h ++++ b/drivers/usb/serial/keyspan.h +@@ -42,7 +42,8 @@ static void keyspan_close (struct tty_s + struct usb_serial_port *port, + struct file *filp); + static int keyspan_startup (struct usb_serial *serial); +-static void keyspan_shutdown (struct usb_serial *serial); ++static void keyspan_disconnect (struct usb_serial *serial); ++static void keyspan_release (struct usb_serial *serial); + static int keyspan_write_room (struct tty_struct *tty); + + static int keyspan_write (struct tty_struct *tty, +@@ -569,7 +570,8 @@ static struct usb_serial_driver keyspan_ + .tiocmget = keyspan_tiocmget, + .tiocmset = keyspan_tiocmset, + .attach = keyspan_startup, +- .shutdown = keyspan_shutdown, ++ .disconnect = keyspan_disconnect, ++ .release = keyspan_release, + }; + + static struct usb_serial_driver keyspan_2port_device = { +@@ -589,7 +591,8 @@ static struct usb_serial_driver keyspan_ + .tiocmget = keyspan_tiocmget, + .tiocmset = keyspan_tiocmset, + .attach = keyspan_startup, +- .shutdown = keyspan_shutdown, ++ .disconnect = keyspan_disconnect, ++ .release = keyspan_release, + }; + + static struct usb_serial_driver keyspan_4port_device = { +@@ -609,7 +612,8 @@ static struct usb_serial_driver keyspan_ + .tiocmget = keyspan_tiocmget, + .tiocmset = keyspan_tiocmset, + .attach = keyspan_startup, +- .shutdown = keyspan_shutdown, ++ .disconnect = keyspan_disconnect, ++ .release = keyspan_release, + }; + + #endif +--- a/drivers/usb/serial/keyspan_pda.c ++++ b/drivers/usb/serial/keyspan_pda.c +@@ -789,7 +789,7 @@ static int keyspan_pda_startup(struct us + return 0; + } + +-static void keyspan_pda_shutdown(struct usb_serial *serial) ++static void keyspan_pda_release(struct usb_serial *serial) + { + dbg("%s", __func__); + +@@ -847,7 +847,7 @@ static struct usb_serial_driver keyspan_ + .tiocmget = keyspan_pda_tiocmget, + .tiocmset = keyspan_pda_tiocmset, + .attach = keyspan_pda_startup, +- .shutdown = keyspan_pda_shutdown, ++ .release = keyspan_pda_release, + }; + + +--- a/drivers/usb/serial/kl5kusb105.c ++++ b/drivers/usb/serial/kl5kusb105.c +@@ -73,7 +73,8 @@ static int debug; + * Function prototypes + */ + static int klsi_105_startup(struct usb_serial *serial); +-static void klsi_105_shutdown(struct usb_serial *serial); ++static void klsi_105_disconnect(struct usb_serial *serial); ++static void klsi_105_release(struct usb_serial *serial); + static int klsi_105_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); + static void klsi_105_close(struct tty_struct *tty, +@@ -132,7 +133,8 @@ static struct usb_serial_driver kl5kusb1 + .tiocmget = klsi_105_tiocmget, + .tiocmset = klsi_105_tiocmset, + .attach = klsi_105_startup, +- .shutdown = klsi_105_shutdown, ++ .disconnect = klsi_105_disconnect, ++ .release = klsi_105_release, + .throttle = klsi_105_throttle, + .unthrottle = klsi_105_unthrottle, + }; +@@ -314,7 +316,7 @@ err_cleanup: + } /* klsi_105_startup */ + + +-static void klsi_105_shutdown(struct usb_serial *serial) ++static void klsi_105_disconnect(struct usb_serial *serial) + { + int i; + +@@ -324,33 +326,36 @@ static void klsi_105_shutdown(struct usb + for (i = 0; i < serial->num_ports; ++i) { + struct klsi_105_private *priv = + usb_get_serial_port_data(serial->port[i]); +- unsigned long flags; + + if (priv) { + /* kill our write urb pool */ + int j; + struct urb **write_urbs = priv->write_urb_pool; +- spin_lock_irqsave(&priv->lock, flags); + + for (j = 0; j < NUM_URBS; j++) { + if (write_urbs[j]) { +- /* FIXME - uncomment the following +- * usb_kill_urb call when the host +- * controllers get fixed to set +- * urb->dev = NULL after the urb is +- * finished. Otherwise this call +- * oopses. */ +- /* usb_kill_urb(write_urbs[j]); */ +- kfree(write_urbs[j]->transfer_buffer); ++ usb_kill_urb(write_urbs[j]); + usb_free_urb(write_urbs[j]); + } + } +- spin_unlock_irqrestore(&priv->lock, flags); +- kfree(priv); +- usb_set_serial_port_data(serial->port[i], NULL); + } + } +-} /* klsi_105_shutdown */ ++} /* klsi_105_disconnect */ ++ ++ ++static void klsi_105_release(struct usb_serial *serial) ++{ ++ int i; ++ ++ dbg("%s", __func__); ++ ++ for (i = 0; i < serial->num_ports; ++i) { ++ struct klsi_105_private *priv = ++ usb_get_serial_port_data(serial->port[i]); ++ ++ kfree(priv); ++ } ++} /* klsi_105_release */ + + static int klsi_105_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp) +--- a/drivers/usb/serial/kobil_sct.c ++++ b/drivers/usb/serial/kobil_sct.c +@@ -69,7 +69,7 @@ static int debug; + + /* Function prototypes */ + static int kobil_startup(struct usb_serial *serial); +-static void kobil_shutdown(struct usb_serial *serial); ++static void kobil_release(struct usb_serial *serial); + static int kobil_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); + static void kobil_close(struct tty_struct *tty, struct usb_serial_port *port, +@@ -118,7 +118,7 @@ static struct usb_serial_driver kobil_de + .id_table = id_table, + .num_ports = 1, + .attach = kobil_startup, +- .shutdown = kobil_shutdown, ++ .release = kobil_release, + .ioctl = kobil_ioctl, + .set_termios = kobil_set_termios, + .tiocmget = kobil_tiocmget, +@@ -202,17 +202,13 @@ static int kobil_startup(struct usb_seri + } + + +-static void kobil_shutdown(struct usb_serial *serial) ++static void kobil_release(struct usb_serial *serial) + { + int i; + dbg("%s - port %d", __func__, serial->port[0]->number); + +- for (i = 0; i < serial->num_ports; ++i) { +- while (serial->port[i]->port.count > 0) +- kobil_close(NULL, serial->port[i], NULL); ++ for (i = 0; i < serial->num_ports; ++i) + kfree(usb_get_serial_port_data(serial->port[i])); +- usb_set_serial_port_data(serial->port[i], NULL); +- } + } + + +--- a/drivers/usb/serial/mct_u232.c ++++ b/drivers/usb/serial/mct_u232.c +@@ -92,7 +92,7 @@ static int debug; + * Function prototypes + */ + static int mct_u232_startup(struct usb_serial *serial); +-static void mct_u232_shutdown(struct usb_serial *serial); ++static void mct_u232_release(struct usb_serial *serial); + static int mct_u232_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); + static void mct_u232_close(struct tty_struct *tty, +@@ -148,7 +148,7 @@ static struct usb_serial_driver mct_u232 + .tiocmget = mct_u232_tiocmget, + .tiocmset = mct_u232_tiocmset, + .attach = mct_u232_startup, +- .shutdown = mct_u232_shutdown, ++ .release = mct_u232_release, + }; + + +@@ -401,7 +401,7 @@ static int mct_u232_startup(struct usb_s + } /* mct_u232_startup */ + + +-static void mct_u232_shutdown(struct usb_serial *serial) ++static void mct_u232_release(struct usb_serial *serial) + { + struct mct_u232_private *priv; + int i; +@@ -411,12 +411,9 @@ static void mct_u232_shutdown(struct usb + for (i = 0; i < serial->num_ports; ++i) { + /* My special items, the standard routines free my urbs */ + priv = usb_get_serial_port_data(serial->port[i]); +- if (priv) { +- usb_set_serial_port_data(serial->port[i], NULL); +- kfree(priv); +- } ++ kfree(priv); + } +-} /* mct_u232_shutdown */ ++} /* mct_u232_release */ + + static int mct_u232_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp) +--- a/drivers/usb/serial/mos7720.c ++++ b/drivers/usb/serial/mos7720.c +@@ -1547,19 +1547,16 @@ static int mos7720_startup(struct usb_se + return 0; + } + +-static void mos7720_shutdown(struct usb_serial *serial) ++static void mos7720_release(struct usb_serial *serial) + { + int i; + + /* free private structure allocated for serial port */ +- for (i = 0; i < serial->num_ports; ++i) { ++ for (i = 0; i < serial->num_ports; ++i) + kfree(usb_get_serial_port_data(serial->port[i])); +- usb_set_serial_port_data(serial->port[i], NULL); +- } + + /* free private structure allocated for serial device */ + kfree(usb_get_serial_data(serial)); +- usb_set_serial_data(serial, NULL); + } + + static struct usb_driver usb_driver = { +@@ -1584,7 +1581,7 @@ static struct usb_serial_driver moschip7 + .throttle = mos7720_throttle, + .unthrottle = mos7720_unthrottle, + .attach = mos7720_startup, +- .shutdown = mos7720_shutdown, ++ .release = mos7720_release, + .ioctl = mos7720_ioctl, + .set_termios = mos7720_set_termios, + .write = mos7720_write, +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -2643,16 +2643,16 @@ error: + } + + /**************************************************************************** +- * mos7840_shutdown ++ * mos7840_disconnect + * This function is called whenever the device is removed from the usb bus. + ****************************************************************************/ + +-static void mos7840_shutdown(struct usb_serial *serial) ++static void mos7840_disconnect(struct usb_serial *serial) + { + int i; + unsigned long flags; + struct moschip_port *mos7840_port; +- dbg("%s \n", " shutdown :entering.........."); ++ dbg("%s\n", " disconnect :entering.........."); + + if (!serial) { + dbg("%s", "Invalid Handler \n"); +@@ -2670,10 +2670,41 @@ static void mos7840_shutdown(struct usb_ + mos7840_port->zombie = 1; + spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); + usb_kill_urb(mos7840_port->control_urb); +- kfree(mos7840_port->ctrl_buf); +- kfree(mos7840_port->dr); +- kfree(mos7840_port); +- mos7840_set_port_private(serial->port[i], NULL); ++ } ++ ++ dbg("%s\n", "Thank u ::"); ++ ++} ++ ++/**************************************************************************** ++ * mos7840_release ++ * This function is called when the usb_serial structure is freed. ++ ****************************************************************************/ ++ ++static void mos7840_release(struct usb_serial *serial) ++{ ++ int i; ++ struct moschip_port *mos7840_port; ++ dbg("%s\n", " release :entering.........."); ++ ++ if (!serial) { ++ dbg("%s", "Invalid Handler"); ++ return; ++ } ++ ++ /* check for the ports to be closed,close the ports and disconnect */ ++ ++ /* free private structure allocated for serial port * ++ * stop reads and writes on all ports */ ++ ++ for (i = 0; i < serial->num_ports; ++i) { ++ mos7840_port = mos7840_get_port_private(serial->port[i]); ++ dbg("mos7840_port %d = %p", i, mos7840_port); ++ if (mos7840_port) { ++ kfree(mos7840_port->ctrl_buf); ++ kfree(mos7840_port->dr); ++ kfree(mos7840_port); ++ } + } + + dbg("%s\n", "Thank u :: "); +@@ -2714,7 +2745,8 @@ static struct usb_serial_driver moschip7 + .tiocmget = mos7840_tiocmget, + .tiocmset = mos7840_tiocmset, + .attach = mos7840_startup, +- .shutdown = mos7840_shutdown, ++ .disconnect = mos7840_disconnect, ++ .release = mos7840_release, + .read_bulk_callback = mos7840_bulk_in_callback, + .read_int_callback = mos7840_interrupt_callback, + }; +--- a/drivers/usb/serial/omninet.c ++++ b/drivers/usb/serial/omninet.c +@@ -73,7 +73,8 @@ static void omninet_write_bulk_callback( + static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, + const unsigned char *buf, int count); + static int omninet_write_room(struct tty_struct *tty); +-static void omninet_shutdown(struct usb_serial *serial); ++static void omninet_disconnect(struct usb_serial *serial); ++static void omninet_release(struct usb_serial *serial); + static int omninet_attach(struct usb_serial *serial); + + static struct usb_device_id id_table[] = { +@@ -109,7 +110,8 @@ static struct usb_serial_driver zyxel_om + .write_room = omninet_write_room, + .read_bulk_callback = omninet_read_bulk_callback, + .write_bulk_callback = omninet_write_bulk_callback, +- .shutdown = omninet_shutdown, ++ .disconnect = omninet_disconnect, ++ .release = omninet_release, + }; + + +@@ -342,13 +344,22 @@ static void omninet_write_bulk_callback( + } + + +-static void omninet_shutdown(struct usb_serial *serial) ++static void omninet_disconnect(struct usb_serial *serial) + { + struct usb_serial_port *wport = serial->port[1]; +- struct usb_serial_port *port = serial->port[0]; ++ + dbg("%s", __func__); + + usb_kill_urb(wport->write_urb); ++} ++ ++ ++static void omninet_release(struct usb_serial *serial) ++{ ++ struct usb_serial_port *port = serial->port[0]; ++ ++ dbg("%s", __func__); ++ + kfree(usb_get_serial_port_data(port)); + } + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -48,7 +48,8 @@ static int option_open(struct tty_struc + static void option_close(struct tty_struct *tty, struct usb_serial_port *port, + struct file *filp); + static int option_startup(struct usb_serial *serial); +-static void option_shutdown(struct usb_serial *serial); ++static void option_disconnect(struct usb_serial *serial); ++static void option_release(struct usb_serial *serial); + static int option_write_room(struct tty_struct *tty); + + static void option_instat_callback(struct urb *urb); +@@ -541,7 +542,8 @@ static struct usb_serial_driver option_1 + .tiocmget = option_tiocmget, + .tiocmset = option_tiocmset, + .attach = option_startup, +- .shutdown = option_shutdown, ++ .disconnect = option_disconnect, ++ .release = option_release, + .read_int_callback = option_instat_callback, + .suspend = option_suspend, + .resume = option_resume, +@@ -1112,7 +1114,14 @@ static void stop_read_write_urbs(struct + } + } + +-static void option_shutdown(struct usb_serial *serial) ++static void option_disconnect(struct usb_serial *serial) ++{ ++ dbg("%s", __func__); ++ ++ stop_read_write_urbs(serial); ++} ++ ++static void option_release(struct usb_serial *serial) + { + int i, j; + struct usb_serial_port *port; +@@ -1120,8 +1129,6 @@ static void option_shutdown(struct usb_s + + dbg("%s", __func__); + +- stop_read_write_urbs(serial); +- + /* Now free them */ + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; +--- a/drivers/usb/serial/oti6858.c ++++ b/drivers/usb/serial/oti6858.c +@@ -160,7 +160,7 @@ static int oti6858_tiocmget(struct tty_s + static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, + unsigned int set, unsigned int clear); + static int oti6858_startup(struct usb_serial *serial); +-static void oti6858_shutdown(struct usb_serial *serial); ++static void oti6858_release(struct usb_serial *serial); + + /* functions operating on buffers */ + static struct oti6858_buf *oti6858_buf_alloc(unsigned int size); +@@ -195,7 +195,7 @@ static struct usb_serial_driver oti6858_ + .write_room = oti6858_write_room, + .chars_in_buffer = oti6858_chars_in_buffer, + .attach = oti6858_startup, +- .shutdown = oti6858_shutdown, ++ .release = oti6858_release, + }; + + struct oti6858_private { +@@ -833,7 +833,7 @@ static int oti6858_ioctl(struct tty_stru + } + + +-static void oti6858_shutdown(struct usb_serial *serial) ++static void oti6858_release(struct usb_serial *serial) + { + struct oti6858_private *priv; + int i; +@@ -845,7 +845,6 @@ static void oti6858_shutdown(struct usb_ + if (priv) { + oti6858_buf_free(priv->buf); + kfree(priv); +- usb_set_serial_port_data(serial->port[i], NULL); + } + } + } +--- a/drivers/usb/serial/pl2303.c ++++ b/drivers/usb/serial/pl2303.c +@@ -905,7 +905,7 @@ static void pl2303_break_ctl(struct tty_ + dbg("%s - error sending break = %d", __func__, result); + } + +-static void pl2303_shutdown(struct usb_serial *serial) ++static void pl2303_release(struct usb_serial *serial) + { + int i; + struct pl2303_private *priv; +@@ -917,7 +917,6 @@ static void pl2303_shutdown(struct usb_s + if (priv) { + pl2303_buf_free(priv->buf); + kfree(priv); +- usb_set_serial_port_data(serial->port[i], NULL); + } + } + } +@@ -1145,7 +1144,7 @@ static struct usb_serial_driver pl2303_d + .write_room = pl2303_write_room, + .chars_in_buffer = pl2303_chars_in_buffer, + .attach = pl2303_startup, +- .shutdown = pl2303_shutdown, ++ .release = pl2303_release, + }; + + static int __init pl2303_init(void) +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -677,7 +677,7 @@ static int sierra_startup(struct usb_ser + return 0; + } + +-static void sierra_shutdown(struct usb_serial *serial) ++static void sierra_disconnect(struct usb_serial *serial) + { + int i, j; + struct usb_serial_port *port; +@@ -696,10 +696,29 @@ static void sierra_shutdown(struct usb_s + for (j = 0; j < N_IN_URB; j++) { + usb_kill_urb(portdata->in_urbs[j]); + usb_free_urb(portdata->in_urbs[j]); +- kfree(portdata->in_buffer[j]); + } ++ } ++} ++ ++static void sierra_release(struct usb_serial *serial) ++{ ++ int i, j; ++ struct usb_serial_port *port; ++ struct sierra_port_private *portdata; ++ ++ dev_dbg(&serial->dev->dev, "%s\n", __func__); ++ ++ for (i = 0; i < serial->num_ports; ++i) { ++ port = serial->port[i]; ++ if (!port) ++ continue; ++ portdata = usb_get_serial_port_data(port); ++ if (!portdata) ++ continue; ++ ++ for (j = 0; j < N_IN_URB; j++) ++ kfree(portdata->in_buffer[j]); + kfree(portdata); +- usb_set_serial_port_data(port, NULL); + } + } + +@@ -721,7 +740,8 @@ static struct usb_serial_driver sierra_d + .tiocmget = sierra_tiocmget, + .tiocmset = sierra_tiocmset, + .attach = sierra_startup, +- .shutdown = sierra_shutdown, ++ .disconnect = sierra_disconnect, ++ .release = sierra_release, + .read_int_callback = sierra_instat_callback, + }; + +--- a/drivers/usb/serial/spcp8x5.c ++++ b/drivers/usb/serial/spcp8x5.c +@@ -356,7 +356,7 @@ cleanup: + } + + /* call when the device plug out. free all the memory alloced by probe */ +-static void spcp8x5_shutdown(struct usb_serial *serial) ++static void spcp8x5_release(struct usb_serial *serial) + { + int i; + struct spcp8x5_private *priv; +@@ -366,7 +366,6 @@ static void spcp8x5_shutdown(struct usb_ + if (priv) { + free_ringbuf(priv->buf); + kfree(priv); +- usb_set_serial_port_data(serial->port[i] , NULL); + } + } + } +@@ -1041,7 +1040,7 @@ static struct usb_serial_driver spcp8x5_ + .write_bulk_callback = spcp8x5_write_bulk_callback, + .chars_in_buffer = spcp8x5_chars_in_buffer, + .attach = spcp8x5_startup, +- .shutdown = spcp8x5_shutdown, ++ .release = spcp8x5_release, + }; + + static int __init spcp8x5_init(void) +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -148,7 +148,7 @@ struct ti_device { + /* Function Declarations */ + + static int ti_startup(struct usb_serial *serial); +-static void ti_shutdown(struct usb_serial *serial); ++static void ti_release(struct usb_serial *serial); + static int ti_open(struct tty_struct *tty, struct usb_serial_port *port, + struct file *file); + static void ti_close(struct tty_struct *tty, struct usb_serial_port *port, +@@ -271,7 +271,7 @@ static struct usb_serial_driver ti_1port + .id_table = ti_id_table_3410, + .num_ports = 1, + .attach = ti_startup, +- .shutdown = ti_shutdown, ++ .release = ti_release, + .open = ti_open, + .close = ti_close, + .write = ti_write, +@@ -299,7 +299,7 @@ static struct usb_serial_driver ti_2port + .id_table = ti_id_table_5052, + .num_ports = 2, + .attach = ti_startup, +- .shutdown = ti_shutdown, ++ .release = ti_release, + .open = ti_open, + .close = ti_close, + .write = ti_write, +@@ -506,7 +506,7 @@ free_tdev: + } + + +-static void ti_shutdown(struct usb_serial *serial) ++static void ti_release(struct usb_serial *serial) + { + int i; + struct ti_device *tdev = usb_get_serial_data(serial); +@@ -519,12 +519,10 @@ static void ti_shutdown(struct usb_seria + if (tport) { + ti_buf_free(tport->tp_write_buf); + kfree(tport); +- usb_set_serial_port_data(serial->port[i], NULL); + } + } + + kfree(tdev); +- usb_set_serial_data(serial, NULL); + } + + +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -140,6 +140,14 @@ static void destroy_serial(struct kref * + if (serial->minor != SERIAL_TTY_NO_MINOR) + return_serial(serial); + ++ serial->type->release(serial); ++ ++ for (i = 0; i < serial->num_ports; ++i) { ++ port = serial->port[i]; ++ if (port) ++ put_device(&port->dev); ++ } ++ + /* If this is a "fake" port, we have to clean it up here, as it will + * not get cleaned up in port_release() as it was never registered with + * the driver core */ +@@ -147,9 +155,8 @@ static void destroy_serial(struct kref * + for (i = serial->num_ports; + i < serial->num_port_pointers; ++i) { + port = serial->port[i]; +- if (!port) +- continue; +- port_free(port); ++ if (port) ++ port_free(port); + } + } + +@@ -1061,10 +1068,6 @@ void usb_serial_disconnect(struct usb_in + serial->disconnected = 1; + mutex_unlock(&serial->disc_mutex); + +- /* Unfortunately, many of the sub-drivers expect the port structures +- * to exist when their shutdown method is called, so we have to go +- * through this awkward two-step unregistration procedure. +- */ + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + if (port) { +@@ -1075,14 +1078,7 @@ void usb_serial_disconnect(struct usb_in + device_del(&port->dev); + } + } +- serial->type->shutdown(serial); +- for (i = 0; i < serial->num_ports; ++i) { +- port = serial->port[i]; +- if (port) { +- put_device(&port->dev); +- serial->port[i] = NULL; +- } +- } ++ serial->type->disconnect(serial); + + /* let the last holder of this object + * cause it to be cleaned up */ +@@ -1246,7 +1242,8 @@ static void fixup_generic(struct usb_ser + set_to_generic_if_null(device, chars_in_buffer); + set_to_generic_if_null(device, read_bulk_callback); + set_to_generic_if_null(device, write_bulk_callback); +- set_to_generic_if_null(device, shutdown); ++ set_to_generic_if_null(device, disconnect); ++ set_to_generic_if_null(device, release); + set_to_generic_if_null(device, resume); + } + +--- a/drivers/usb/serial/visor.c ++++ b/drivers/usb/serial/visor.c +@@ -48,7 +48,7 @@ static void visor_unthrottle(struct tty_ + static int visor_probe(struct usb_serial *serial, + const struct usb_device_id *id); + static int visor_calc_num_ports(struct usb_serial *serial); +-static void visor_shutdown(struct usb_serial *serial); ++static void visor_release(struct usb_serial *serial); + static void visor_write_bulk_callback(struct urb *urb); + static void visor_read_bulk_callback(struct urb *urb); + static void visor_read_int_callback(struct urb *urb); +@@ -203,7 +203,7 @@ static struct usb_serial_driver handspri + .attach = treo_attach, + .probe = visor_probe, + .calc_num_ports = visor_calc_num_ports, +- .shutdown = visor_shutdown, ++ .release = visor_release, + .write = visor_write, + .write_room = visor_write_room, + .write_bulk_callback = visor_write_bulk_callback, +@@ -228,7 +228,7 @@ static struct usb_serial_driver clie_5_d + .attach = clie_5_attach, + .probe = visor_probe, + .calc_num_ports = visor_calc_num_ports, +- .shutdown = visor_shutdown, ++ .release = visor_release, + .write = visor_write, + .write_room = visor_write_room, + .write_bulk_callback = visor_write_bulk_callback, +@@ -916,7 +916,7 @@ static int clie_5_attach(struct usb_seri + return generic_startup(serial); + } + +-static void visor_shutdown(struct usb_serial *serial) ++static void visor_release(struct usb_serial *serial) + { + struct visor_private *priv; + int i; +@@ -925,10 +925,7 @@ static void visor_shutdown(struct usb_se + + for (i = 0; i < serial->num_ports; i++) { + priv = usb_get_serial_port_data(serial->port[i]); +- if (priv) { +- usb_set_serial_port_data(serial->port[i], NULL); +- kfree(priv); +- } ++ kfree(priv); + } + } + +--- a/drivers/usb/serial/whiteheat.c ++++ b/drivers/usb/serial/whiteheat.c +@@ -144,7 +144,7 @@ static int whiteheat_firmware_attach(st + + /* function prototypes for the Connect Tech WhiteHEAT serial converter */ + static int whiteheat_attach(struct usb_serial *serial); +-static void whiteheat_shutdown(struct usb_serial *serial); ++static void whiteheat_release(struct usb_serial *serial); + static int whiteheat_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); + static void whiteheat_close(struct tty_struct *tty, +@@ -190,7 +190,7 @@ static struct usb_serial_driver whitehea + .id_table = id_table_std, + .num_ports = 4, + .attach = whiteheat_attach, +- .shutdown = whiteheat_shutdown, ++ .release = whiteheat_release, + .open = whiteheat_open, + .close = whiteheat_close, + .write = whiteheat_write, +@@ -600,7 +600,7 @@ no_command_buffer: + } + + +-static void whiteheat_shutdown(struct usb_serial *serial) ++static void whiteheat_release(struct usb_serial *serial) + { + struct usb_serial_port *command_port; + struct usb_serial_port *port; +--- a/include/linux/usb/serial.h ++++ b/include/linux/usb/serial.h +@@ -177,8 +177,10 @@ static inline void usb_set_serial_data(s + * This will be called when the struct usb_serial structure is fully set + * set up. Do any local initialization of the device, or any private + * memory structure allocation at this point in time. +- * @shutdown: pointer to the driver's shutdown function. This will be +- * called when the device is removed from the system. ++ * @disconnect: pointer to the driver's disconnect function. This will be ++ * called when the device is unplugged or unbound from the driver. ++ * @release: pointer to the driver's release function. This will be called ++ * when the usb_serial data structure is about to be destroyed. + * @usb_driver: pointer to the struct usb_driver that controls this + * device. This is necessary to allow dynamic ids to be added to + * the driver from sysfs. +@@ -208,7 +210,8 @@ struct usb_serial_driver { + int (*attach)(struct usb_serial *serial); + int (*calc_num_ports) (struct usb_serial *serial); + +- void (*shutdown)(struct usb_serial *serial); ++ void (*disconnect)(struct usb_serial *serial); ++ void (*release)(struct usb_serial *serial); + + int (*port_probe)(struct usb_serial_port *port); + int (*port_remove)(struct usb_serial_port *port); +@@ -288,7 +291,8 @@ extern void usb_serial_generic_read_bulk + extern void usb_serial_generic_write_bulk_callback(struct urb *urb); + extern void usb_serial_generic_throttle(struct tty_struct *tty); + extern void usb_serial_generic_unthrottle(struct tty_struct *tty); +-extern void usb_serial_generic_shutdown(struct usb_serial *serial); ++extern void usb_serial_generic_disconnect(struct usb_serial *serial); ++extern void usb_serial_generic_release(struct usb_serial *serial); + extern int usb_serial_generic_register(int debug); + extern void usb_serial_generic_deregister(void); + + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:11 2009 +Message-Id: <20091206233210.990907937@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:51 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Maciej Sosnowski , + Jeff Kirsher , + "David S. Miller" +Subject: [19/20] dca: redesign locks to fix deadlocks +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=dca-redesign-locks-to-fix-deadlocks.patch +Content-Length: 4060 +Lines: 165 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Maciej Sosnowski + +commit eb4400e3a040b90a3ad805b01fcbc99a5f615c8f upstream. + +Change spin_locks to irqsave to prevent dead-locks. +Protect adding and deleting to/from dca_providers list. +Drop the lock during dca_sysfs_add_req() and dca_sysfs_remove_req() calls +as they might sleep (use GFP_KERNEL allocation). + +Signed-off-by: Maciej Sosnowski +Acked-by: Jeff Kirsher +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dca/dca-core.c | 51 +++++++++++++++++++++++++++++++------------------ + 1 file changed, 33 insertions(+), 18 deletions(-) + +--- a/drivers/dca/dca-core.c ++++ b/drivers/dca/dca-core.c +@@ -28,7 +28,7 @@ + #include + #include + +-#define DCA_VERSION "1.4" ++#define DCA_VERSION "1.8" + + MODULE_VERSION(DCA_VERSION); + MODULE_LICENSE("GPL"); +@@ -60,16 +60,17 @@ int dca_add_requester(struct device *dev + { + struct dca_provider *dca; + int err, slot = -ENODEV; ++ unsigned long flags; + + if (!dev) + return -EFAULT; + +- spin_lock(&dca_lock); ++ spin_lock_irqsave(&dca_lock, flags); + + /* check if the requester has not been added already */ + dca = dca_find_provider_by_dev(dev); + if (dca) { +- spin_unlock(&dca_lock); ++ spin_unlock_irqrestore(&dca_lock, flags); + return -EEXIST; + } + +@@ -78,19 +79,21 @@ int dca_add_requester(struct device *dev + if (slot >= 0) + break; + } +- if (slot < 0) { +- spin_unlock(&dca_lock); ++ ++ spin_unlock_irqrestore(&dca_lock, flags); ++ ++ if (slot < 0) + return slot; +- } + + err = dca_sysfs_add_req(dca, dev, slot); + if (err) { +- dca->ops->remove_requester(dca, dev); +- spin_unlock(&dca_lock); ++ spin_lock_irqsave(&dca_lock, flags); ++ if (dca == dca_find_provider_by_dev(dev)) ++ dca->ops->remove_requester(dca, dev); ++ spin_unlock_irqrestore(&dca_lock, flags); + return err; + } + +- spin_unlock(&dca_lock); + return 0; + } + EXPORT_SYMBOL_GPL(dca_add_requester); +@@ -103,25 +106,25 @@ int dca_remove_requester(struct device * + { + struct dca_provider *dca; + int slot; ++ unsigned long flags; + + if (!dev) + return -EFAULT; + +- spin_lock(&dca_lock); ++ spin_lock_irqsave(&dca_lock, flags); + dca = dca_find_provider_by_dev(dev); + if (!dca) { +- spin_unlock(&dca_lock); ++ spin_unlock_irqrestore(&dca_lock, flags); + return -ENODEV; + } + slot = dca->ops->remove_requester(dca, dev); +- if (slot < 0) { +- spin_unlock(&dca_lock); ++ spin_unlock_irqrestore(&dca_lock, flags); ++ ++ if (slot < 0) + return slot; +- } + + dca_sysfs_remove_req(dca, slot); + +- spin_unlock(&dca_lock); + return 0; + } + EXPORT_SYMBOL_GPL(dca_remove_requester); +@@ -135,17 +138,18 @@ u8 dca_common_get_tag(struct device *dev + { + struct dca_provider *dca; + u8 tag; ++ unsigned long flags; + +- spin_lock(&dca_lock); ++ spin_lock_irqsave(&dca_lock, flags); + + dca = dca_find_provider_by_dev(dev); + if (!dca) { +- spin_unlock(&dca_lock); ++ spin_unlock_irqrestore(&dca_lock, flags); + return -ENODEV; + } + tag = dca->ops->get_tag(dca, dev, cpu); + +- spin_unlock(&dca_lock); ++ spin_unlock_irqrestore(&dca_lock, flags); + return tag; + } + +@@ -217,11 +221,16 @@ static BLOCKING_NOTIFIER_HEAD(dca_provid + int register_dca_provider(struct dca_provider *dca, struct device *dev) + { + int err; ++ unsigned long flags; + + err = dca_sysfs_add_provider(dca, dev); + if (err) + return err; ++ ++ spin_lock_irqsave(&dca_lock, flags); + list_add(&dca->node, &dca_providers); ++ spin_unlock_irqrestore(&dca_lock, flags); ++ + blocking_notifier_call_chain(&dca_provider_chain, + DCA_PROVIDER_ADD, NULL); + return 0; +@@ -234,9 +243,15 @@ EXPORT_SYMBOL_GPL(register_dca_provider) + */ + void unregister_dca_provider(struct dca_provider *dca) + { ++ unsigned long flags; ++ + blocking_notifier_call_chain(&dca_provider_chain, + DCA_PROVIDER_REMOVE, NULL); ++ ++ spin_lock_irqsave(&dca_lock, flags); + list_del(&dca->node); ++ spin_unlock_irqrestore(&dca_lock, flags); ++ + dca_sysfs_remove_provider(dca); + } + EXPORT_SYMBOL_GPL(unregister_dca_provider); + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:11 2009 +Message-Id: <20091206233211.121828427@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:52 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk, + Willy Tarreau , + Jean Delvare +Subject: [20/20] hwmon: (it87) Fix VID reading on IT8718F +References: <20091206233032.387950574@mini.kroah.org> +Content-Disposition: inline; filename=hwmon-it87-fix-vid-reading-on-it8718f.patch +Content-Length: 752 +Lines: 28 + +2.6.27-stable review patch. If anyone has any objections, please let us know. + +------------------ +From: Jean Delvare + +commit 371dc4a6d8c3c74a9a1c74b87c2affb3fcef6500 upstream + +Comparing apples to bananas doesn't seem right. + +The bug has been there since support for the IT8718F was added, so +VID never worked for this chip. + +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/it87.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwmon/it87.c ++++ b/drivers/hwmon/it87.c +@@ -1017,7 +1017,7 @@ static int __init it87_find(unsigned sho + int reg; + + superio_select(GPIO); +- if (chip_type == it8718) ++ if (sio_data->type == it8718) + sio_data->vid_value = superio_inb(IT87_SIO_VID_REG); + + reg = superio_inb(IT87_SIO_PINX2_REG); + + +From gregkh@mini.kroah.org Sun Dec 6 15:32:08 2009 +Message-Id: <20091206233032.387950574@mini.kroah.org> +User-Agent: quilt/0.48-1 +Date: Sun, 06 Dec 2009 15:30:32 -0800 +From: Greg KH +To: linux-kernel@vger.kernel.org, + stable@kernel.org +Cc: stable-review@kernel.org, + torvalds@linux-foundation.org, + akpm@linux-foundation.org, + alan@lxorguk.ukuu.org.uk +Subject: [00/20] 2.6.27.40-stable review +Content-Length: 3708 +Lines: 73 + + +This is the start of the stable review cycle for the 2.6.27.40 release. +There are 20 patches in this series, all will be posted as a response to +this one. If anyone has any issues with these being applied, please let +us know. If anyone is a maintainer of the proper subsystem, and wants +to add a Signed-off-by: line to the patch, please respond with it. + +Responses should be made by Tuesday Dec 8, 20:00:00 UTC. Anything +received after that time might be too late. + +The whole patch series can be found in one patch at: + kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.27.40-rc1.gz +and the diffstat can be found below. + +thanks, + +greg k-h + + Makefile | 2 +- + arch/x86/kernel/acpi/processor.c | 3 +- + drivers/dca/dca-core.c | 51 ++++++++++----- + drivers/hwmon/it87.c | 2 +- + drivers/isdn/hisax/hfc_usb.c | 4 +- + drivers/media/common/tuners/tda18271-fe.c | 8 +- + drivers/media/dvb/frontends/dib7000p.c | 5 ++ + drivers/media/video/em28xx/em28xx-audio.c | 5 ++ + drivers/media/video/s2255drv.c | 5 -- + drivers/misc/thinkpad_acpi.c | 2 +- + drivers/scsi/gdth.c | 2 +- + drivers/usb/host/ohci-hcd.c | 5 ++ + drivers/usb/host/ohci-pci.c | 20 ++++++ + drivers/usb/host/ohci-q.c | 18 ++++-- + drivers/usb/host/ohci.h | 9 +++ + drivers/usb/serial/aircable.c | 5 +- + drivers/usb/serial/belkin_sa.c | 7 +- + drivers/usb/serial/cp2101.c | 6 +- + drivers/usb/serial/cyberjack.c | 20 +++++-- + drivers/usb/serial/cypress_m8.c | 11 ++-- + drivers/usb/serial/digi_acceleport.c | 20 +++++-- + drivers/usb/serial/empeg.c | 8 --- + drivers/usb/serial/ftdi_sio.c | 14 ---- + drivers/usb/serial/garmin_gps.c | 16 ++++- + drivers/usb/serial/generic.c | 9 ++- + drivers/usb/serial/io_edgeport.c | 29 ++++++--- + drivers/usb/serial/io_tables.h | 12 +++- + drivers/usb/serial/io_ti.c | 22 +++++-- + drivers/usb/serial/ipaq.c | 7 -- + drivers/usb/serial/iuu_phoenix.c | 6 +- + drivers/usb/serial/keyspan.c | 13 ++++- + drivers/usb/serial/keyspan.h | 12 +++- + drivers/usb/serial/keyspan_pda.c | 4 +- + drivers/usb/serial/kl5kusb105.c | 39 +++++++----- + drivers/usb/serial/kobil_sct.c | 12 +--- + drivers/usb/serial/mct_u232.c | 13 ++--- + drivers/usb/serial/mos7720.c | 9 +-- + drivers/usb/serial/mos7840.c | 48 ++++++++++++--- + drivers/usb/serial/omninet.c | 19 +++++- + drivers/usb/serial/option.c | 97 ++++++++++++++++++++++++++--- + drivers/usb/serial/oti6858.c | 7 +- + drivers/usb/serial/pl2303.c | 5 +- + drivers/usb/serial/sierra.c | 28 +++++++- + drivers/usb/serial/spcp8x5.c | 5 +- + drivers/usb/serial/ti_usb_3410_5052.c | 10 +-- + drivers/usb/serial/usb-serial.c | 29 ++++----- + drivers/usb/serial/visor.c | 13 ++--- + drivers/usb/serial/whiteheat.c | 6 +- + fs/fuse/dir.c | 3 + + fs/fuse/file.c | 3 +- + fs/jffs2/read.c | 9 ++- + include/linux/usb/serial.h | 12 +++- + sound/arm/aaci.c | 6 ++- + sound/usb/usbaudio.h | 2 +- + 54 files changed, 493 insertions(+), 244 deletions(-) + diff --git a/queue-2.6.27/series b/review-2.6.27/series similarity index 100% rename from queue-2.6.27/series rename to review-2.6.27/series diff --git a/queue-2.6.27/thinkpad-acpi-fix-sign-of-erestartsys-return.patch b/review-2.6.27/thinkpad-acpi-fix-sign-of-erestartsys-return.patch similarity index 100% rename from queue-2.6.27/thinkpad-acpi-fix-sign-of-erestartsys-return.patch rename to review-2.6.27/thinkpad-acpi-fix-sign-of-erestartsys-return.patch diff --git a/queue-2.6.27/usb-ohci-quirk-amd-prefetch-for-usb-1.1-iso-transfer.patch b/review-2.6.27/usb-ohci-quirk-amd-prefetch-for-usb-1.1-iso-transfer.patch similarity index 100% rename from queue-2.6.27/usb-ohci-quirk-amd-prefetch-for-usb-1.1-iso-transfer.patch rename to review-2.6.27/usb-ohci-quirk-amd-prefetch-for-usb-1.1-iso-transfer.patch diff --git a/queue-2.6.27/usb-suspend-resume-support-for-option-driver.patch b/review-2.6.27/usb-suspend-resume-support-for-option-driver.patch similarity index 100% rename from queue-2.6.27/usb-suspend-resume-support-for-option-driver.patch rename to review-2.6.27/usb-suspend-resume-support-for-option-driver.patch diff --git a/queue-2.6.27/usb-usb-serial-replace-shutdown-with-disconnect-release.patch b/review-2.6.27/usb-usb-serial-replace-shutdown-with-disconnect-release.patch similarity index 100% rename from queue-2.6.27/usb-usb-serial-replace-shutdown-with-disconnect-release.patch rename to review-2.6.27/usb-usb-serial-replace-shutdown-with-disconnect-release.patch diff --git a/queue-2.6.27/v4l-dvb-13079-dib0700-fixed-xc2028-firmware-loading-kernel-oops.patch b/review-2.6.27/v4l-dvb-13079-dib0700-fixed-xc2028-firmware-loading-kernel-oops.patch similarity index 100% rename from queue-2.6.27/v4l-dvb-13079-dib0700-fixed-xc2028-firmware-loading-kernel-oops.patch rename to review-2.6.27/v4l-dvb-13079-dib0700-fixed-xc2028-firmware-loading-kernel-oops.patch diff --git a/queue-2.6.27/v4l-dvb-13107-tda18271-fix-overflow-in-fm-radio-frequency-calculation.patch b/review-2.6.27/v4l-dvb-13107-tda18271-fix-overflow-in-fm-radio-frequency-calculation.patch similarity index 100% rename from queue-2.6.27/v4l-dvb-13107-tda18271-fix-overflow-in-fm-radio-frequency-calculation.patch rename to review-2.6.27/v4l-dvb-13107-tda18271-fix-overflow-in-fm-radio-frequency-calculation.patch diff --git a/queue-2.6.27/v4l-dvb-13109-tda18271-fix-signedness-issue-in-tda18271_rf_tracking_filters_init.patch b/review-2.6.27/v4l-dvb-13109-tda18271-fix-signedness-issue-in-tda18271_rf_tracking_filters_init.patch similarity index 100% rename from queue-2.6.27/v4l-dvb-13109-tda18271-fix-signedness-issue-in-tda18271_rf_tracking_filters_init.patch rename to review-2.6.27/v4l-dvb-13109-tda18271-fix-signedness-issue-in-tda18271_rf_tracking_filters_init.patch diff --git a/queue-2.6.27/v4l-dvb-13190-em28xx-fix-panic-that-can-occur-when-starting-audio-streaming.patch b/review-2.6.27/v4l-dvb-13190-em28xx-fix-panic-that-can-occur-when-starting-audio-streaming.patch similarity index 100% rename from queue-2.6.27/v4l-dvb-13190-em28xx-fix-panic-that-can-occur-when-starting-audio-streaming.patch rename to review-2.6.27/v4l-dvb-13190-em28xx-fix-panic-that-can-occur-when-starting-audio-streaming.patch diff --git a/queue-2.6.27/v4l-dvb-13230-s2255drv-don-t-conditionalize-video-buffer-completion-on-waiting-processes.patch b/review-2.6.27/v4l-dvb-13230-s2255drv-don-t-conditionalize-video-buffer-completion-on-waiting-processes.patch similarity index 100% rename from queue-2.6.27/v4l-dvb-13230-s2255drv-don-t-conditionalize-video-buffer-completion-on-waiting-processes.patch rename to review-2.6.27/v4l-dvb-13230-s2255drv-don-t-conditionalize-video-buffer-completion-on-waiting-processes.patch