--- /dev/null
+From jejb@kernel.org Tue Nov 4 11:38:02 2008
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 30 Oct 2008 19:10:15 GMT
+Subject: ALSA: hda - Add reboot notifier
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810301910.m9UJAFgE013161@hera.kernel.org>
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 0cbf00980f0fc4cc064a15ab3dfce19b5fae9130 upstream
+
+The current snd-hda-intel driver seems blocking the power-off on some
+devices like eeepc. Although this is likely a BIOS problem, we can add
+a workaround by disabling IRQ lines before power-off operation.
+This patch adds the reboot notifier to achieve it.
+
+The detailed problem description is found in bug#11889:
+ http://bugme.linux-foundation.org/show_bug.cgi?id=11889
+
+Tested-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/hda_intel.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -45,6 +45,7 @@
+ #include <linux/slab.h>
+ #include <linux/pci.h>
+ #include <linux/mutex.h>
++#include <linux/reboot.h>
+ #include <sound/core.h>
+ #include <sound/initval.h>
+ #include "hda_codec.h"
+@@ -385,6 +386,9 @@ struct azx {
+
+ /* for pending irqs */
+ struct work_struct irq_pending_work;
++
++ /* reboot notifier (for mysterious hangup problem at power-down) */
++ struct notifier_block reboot_notifier;
+ };
+
+ /* driver types */
+@@ -1890,12 +1894,36 @@ static int azx_resume(struct pci_dev *pc
+
+
+ /*
++ * reboot notifier for hang-up problem at power-down
++ */
++static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
++{
++ struct azx *chip = container_of(nb, struct azx, reboot_notifier);
++ azx_stop_chip(chip);
++ return NOTIFY_OK;
++}
++
++static void azx_notifier_register(struct azx *chip)
++{
++ chip->reboot_notifier.notifier_call = azx_halt;
++ register_reboot_notifier(&chip->reboot_notifier);
++}
++
++static void azx_notifier_unregister(struct azx *chip)
++{
++ if (chip->reboot_notifier.notifier_call)
++ unregister_reboot_notifier(&chip->reboot_notifier);
++}
++
++/*
+ * destructor
+ */
+ static int azx_free(struct azx *chip)
+ {
+ int i;
+
++ azx_notifier_unregister(chip);
++
+ if (chip->initialized) {
+ azx_clear_irq_pending(chip);
+ for (i = 0; i < chip->num_streams; i++)
+@@ -2250,6 +2278,7 @@ static int __devinit azx_probe(struct pc
+ pci_set_drvdata(pci, card);
+ chip->running = 1;
+ power_down_all_codecs(chip);
++ azx_notifier_register(chip);
+
+ dev++;
+ return err;
--- /dev/null
+From jejb@kernel.org Tue Nov 4 11:43:39 2008
+From: Jay Cliburn <jacliburn@bellsouth.net>
+Date: Sun, 2 Nov 2008 19:30:07 GMT
+Subject: atl1: fix vlan tag regression
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200811021930.mA2JU74e008939@hera.kernel.org>
+
+From: Jay Cliburn <jacliburn@bellsouth.net>
+
+commit dc5596d920b504d263c7ca38bd76326179b13dee upstream
+
+Commit 401c0aabec4b97320f962a0161a846d230a6f7aa introduced a regression
+in the atl1 driver by storing the VLAN tag in the wrong TX descriptor
+field.
+
+This patch causes the VLAN tag to be stored in its proper location.
+
+Tested-by: Ramon Casellas <ramon.casellas@cttc.es>
+Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
+Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/atlx/atl1.c | 7 ++++---
+ drivers/net/atlx/atl1.h | 2 +-
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/atlx/atl1.c
++++ b/drivers/net/atlx/atl1.c
+@@ -2317,7 +2317,8 @@ static void atl1_tx_queue(struct atl1_ad
+ if (tpd != ptpd)
+ memcpy(tpd, ptpd, sizeof(struct tx_packet_desc));
+ tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+- tpd->word2 = (cpu_to_le16(buffer_info->length) &
++ tpd->word2 &= ~(TPD_BUFLEN_MASK << TPD_BUFLEN_SHIFT);
++ tpd->word2 |= (cpu_to_le16(buffer_info->length) &
+ TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT;
+
+ /*
+@@ -2426,8 +2427,8 @@ static int atl1_xmit_frame(struct sk_buf
+ vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
+ ((vlan_tag >> 9) & 0x8);
+ ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
+- ptpd->word3 |= (vlan_tag & TPD_VL_TAGGED_MASK) <<
+- TPD_VL_TAGGED_SHIFT;
++ ptpd->word2 |= (vlan_tag & TPD_VLANTAG_MASK) <<
++ TPD_VLANTAG_SHIFT;
+ }
+
+ tso = atl1_tso(adapter, skb, ptpd);
+--- a/drivers/net/atlx/atl1.h
++++ b/drivers/net/atlx/atl1.h
+@@ -504,7 +504,7 @@ struct rx_free_desc {
+ #define TPD_PKTNT_MASK 0x0001
+ #define TPD_PKTINT_SHIFT 15
+ #define TPD_VLANTAG_MASK 0xFFFF
+-#define TPD_VLAN_SHIFT 16
++#define TPD_VLANTAG_SHIFT 16
+
+ /* tpd word 3 bits 0:13 */
+ #define TPD_EOP_MASK 0x0001
--- /dev/null
+From jejb@kernel.org Tue Nov 4 11:35:00 2008
+From: Scott James Remnant <scott@canonical.com>
+Date: Thu, 30 Oct 2008 19:10:04 GMT
+Subject: ipmi: add MODULE_ALIAS to load ipmi_devintf with ipmi_si
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810301910.m9UJA4GB012904@hera.kernel.org>
+
+From: Scott James Remnant <scott@canonical.com>
+
+commit 6c89161b10f5771ee0b51ada0fce0e8835e72ade upstream
+
+The ipmi_devintf module contains the userspace interface for IPMI devices,
+yet will not be loaded automatically with a system interface handler
+driver.
+
+Add a MODULE_ALIAS for the "platform:ipmi_si" MODALIAS exported by the
+ipmi_si driver, so that userspace knows of the recommendation.
+
+Signed-off-by: Scott James Remnant <scott@ubuntu.com>
+Cc: Tim Gardner <tcanonical@tpi.com>
+Cc: Corey Minyard <minyard@acm.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/ipmi/ipmi_devintf.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/char/ipmi/ipmi_devintf.c
++++ b/drivers/char/ipmi/ipmi_devintf.c
+@@ -957,3 +957,4 @@ module_exit(cleanup_ipmi);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
+ MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
++MODULE_ALIAS("platform:ipmi_si");
--- /dev/null
+From jejb@kernel.org Tue Nov 4 11:41:57 2008
+From: Evgeniy Manachkin <sfstudio@mail.ru>
+Date: Thu, 30 Oct 2008 23:10:14 GMT
+Subject: kbuild: mkspec - fix build rpm
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810302310.m9UNAE1C020732@hera.kernel.org>
+
+From: Evgeniy Manachkin <sfstudio@mail.ru>
+
+commit 46dca86cb93db80992a45e4b55737ff2b2f61cd0 upstream
+Date: Wed, 15 Oct 2008 23:37:26 +0600
+Subject: kbuild: mkspec - fix build rpm
+
+This is patch to fix incorrect mkspec script to make rpm correctly at 2.6.27 vanilla kernel.
+This is regression in 2.6.27. 2.6.26 make rpm work good.
+In 2.6.27 'make rpm' say error from rpmbuild "Many unpacked files (*.fw)."
+
+Signed-off-by: Evgeniy Manachkin <sfstudio@mail.ru>
+Acked-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ scripts/package/mkspec | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/scripts/package/mkspec
++++ b/scripts/package/mkspec
+@@ -64,8 +64,10 @@ fi
+ echo "%install"
+ echo "%ifarch ia64"
+ echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi $RPM_BUILD_ROOT/lib/modules'
++echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware'
+ echo "%else"
+ echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
++echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware'
+ echo "%endif"
+
+ echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install'
+@@ -92,5 +94,6 @@ echo "%files"
+ echo '%defattr (-, root, root)'
+ echo "%dir /lib/modules"
+ echo "/lib/modules/$KERNELRELEASE"
++echo "/lib/firmware"
+ echo "/boot/*"
+ echo ""
--- /dev/null
+From jejb@kernel.org Tue Nov 4 11:44:30 2008
+From: Johannes Berg <johannes@sipsolutions.net>
+Date: Sun, 2 Nov 2008 19:30:21 GMT
+Subject: libertas: fix buffer overrun
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200811021930.mA2JULX5009457@hera.kernel.org>
+
+From: Johannes Berg <johannes@sipsolutions.net>
+
+commit 48735d8d8bd701b1e0cd3d49c21e5e385ddcb077 upstream
+
+If somebody sends an invalid beacon/probe response, that can trash the
+whole BSS descriptor. The descriptor is, luckily, large enough so that
+it cannot scribble past the end of it; it's well above 400 bytes long.
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/libertas/scan.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/libertas/scan.c
++++ b/drivers/net/wireless/libertas/scan.c
+@@ -598,8 +598,8 @@ static int lbs_process_bss(struct bss_de
+
+ switch (elem->id) {
+ case MFIE_TYPE_SSID:
+- bss->ssid_len = elem->len;
+- memcpy(bss->ssid, elem->data, elem->len);
++ bss->ssid_len = min_t(int, 32, elem->len);
++ memcpy(bss->ssid, elem->data, bss->ssid_len);
+ lbs_deb_scan("got SSID IE: '%s', len %u\n",
+ escape_essid(bss->ssid, bss->ssid_len),
+ bss->ssid_len);
--- /dev/null
+From jejb@kernel.org Tue Nov 4 11:33:37 2008
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+Date: Tue, 28 Oct 2008 17:15:07 GMT
+Subject: S390: Fix sysdev class file creation.
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810281715.m9SHF7lf001667@hera.kernel.org>
+
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+
+commit da5aae7036692fa8d03da1b705c76fd750ed9e38 upstream
+
+Use sysdev_class_create_file() to create create sysdev class attributes
+instead of sysfs_create_file(). Using sysfs_create_file() wasn't a very
+good idea since the show and store functions have a different amount of
+parameters for sysfs files and sysdev class files.
+In particular the pointer to the buffer is the last argument and
+therefore accesses to random memory regions happened.
+Still worked surprisingly well until we got a kernel panic.
+
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/s390/kernel/smp.c | 24 +++++++++---------------
+ 1 file changed, 9 insertions(+), 15 deletions(-)
+
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -1117,9 +1117,7 @@ out:
+ return rc;
+ }
+
+-static ssize_t __ref rescan_store(struct sys_device *dev,
+- struct sysdev_attribute *attr,
+- const char *buf,
++static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf,
+ size_t count)
+ {
+ int rc;
+@@ -1127,12 +1125,10 @@ static ssize_t __ref rescan_store(struct
+ rc = smp_rescan_cpus();
+ return rc ? rc : count;
+ }
+-static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);
++static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store);
+ #endif /* CONFIG_HOTPLUG_CPU */
+
+-static ssize_t dispatching_show(struct sys_device *dev,
+- struct sysdev_attribute *attr,
+- char *buf)
++static ssize_t dispatching_show(struct sysdev_class *class, char *buf)
+ {
+ ssize_t count;
+
+@@ -1142,9 +1138,8 @@ static ssize_t dispatching_show(struct s
+ return count;
+ }
+
+-static ssize_t dispatching_store(struct sys_device *dev,
+- struct sysdev_attribute *attr,
+- const char *buf, size_t count)
++static ssize_t dispatching_store(struct sysdev_class *dev, const char *buf,
++ size_t count)
+ {
+ int val, rc;
+ char delim;
+@@ -1166,7 +1161,8 @@ out:
+ put_online_cpus();
+ return rc ? rc : count;
+ }
+-static SYSDEV_ATTR(dispatching, 0644, dispatching_show, dispatching_store);
++static SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show,
++ dispatching_store);
+
+ static int __init topology_init(void)
+ {
+@@ -1176,13 +1172,11 @@ static int __init topology_init(void)
+ register_cpu_notifier(&smp_cpu_nb);
+
+ #ifdef CONFIG_HOTPLUG_CPU
+- rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+- &attr_rescan.attr);
++ rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_rescan);
+ if (rc)
+ return rc;
+ #endif
+- rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+- &attr_dispatching.attr);
++ rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_dispatching);
+ if (rc)
+ return rc;
+ for_each_present_cpu(cpu) {
--- /dev/null
+From 10dab22664914505dcb804d9ad09cad6bc94d349 Mon Sep 17 00:00:00 2001
+From: Jamie Wellnitz <Jamie.Wellnitz@emulex.com>
+Date: Thu, 11 Sep 2008 21:39:36 -0400
+Subject: SCSI: sd: Fix handling of NO_SENSE check condition
+
+From: Jamie Wellnitz <Jamie.Wellnitz@emulex.com>
+
+commit 10dab22664914505dcb804d9ad09cad6bc94d349 upstream
+
+The current handling of NO_SENSE check condition is the same as
+RECOVERED_ERROR, and assumes that in both cases, the I/O was fully
+transferred.
+
+We have seen cases of arrays returning with NO_SENSE (no error), but
+the I/O was not completely transferred, thus residual set. Thus,
+rather than return good_bytes as the entire transfer, set good_bytes
+to 0, so that the midlayer then applies the residual in calculating
+the transfer, and for sd, will fail the I/O and fall into a retry
+path.
+
+Signed-off-by: Jamie Wellnitz <Jamie.Wellnitz@emulex.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/sd.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -1047,7 +1047,6 @@ static int sd_done(struct scsi_cmnd *SCp
+ good_bytes = sd_completed_bytes(SCpnt);
+ break;
+ case RECOVERED_ERROR:
+- case NO_SENSE:
+ /* Inform the user, but make sure that it's not treated
+ * as a hard error.
+ */
+@@ -1056,6 +1055,15 @@ static int sd_done(struct scsi_cmnd *SCp
+ memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+ good_bytes = scsi_bufflen(SCpnt);
+ break;
++ case NO_SENSE:
++ /* This indicates a false check condition, so ignore it. An
++ * unknown amount of data was transferred so treat it as an
++ * error.
++ */
++ scsi_print_sense("sd", SCpnt);
++ SCpnt->result = 0;
++ memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
++ break;
+ case ABORTED_COMMAND:
+ if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */
+ scsi_print_result(SCpnt);
agp-fix-stolen-memory-counting-on-g4x.patch
+scsi-sd-fix-handling-of-no_sense-check-condition.patch
+s390-fix-sysdev-class-file-creation.patch
+sysfs-fix-return-values-for-sysdev_store_-ulong-int.patch
+ipmi-add-module_alias-to-load-ipmi_devintf-with-ipmi_si.patch
+usb-fix-crash-when-urbs-are-unlinked-after-the-device-is-gone.patch
+alsa-hda-add-reboot-notifier.patch
+kbuild-mkspec-fix-build-rpm.patch
+x86-fix-dev-mem-mmap-breakage-when-pat-is-disabled.patch
+atl1-fix-vlan-tag-regression.patch
+libertas-fix-buffer-overrun.patch
--- /dev/null
+From jejb@kernel.org Tue Nov 4 11:34:23 2008
+From: Andi Kleen <andi@firstfloor.org>
+Date: Thu, 30 Oct 2008 19:10:08 GMT
+Subject: sysfs: Fix return values for sysdev_store_{ulong, int}
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810301910.m9UJA8qi013019@hera.kernel.org>
+
+From: Andi Kleen <andi@firstfloor.org>
+
+commit 4e318d7c6c9dd5cdae48bcf61558bbc0c09b12ac upstream
+
+SYSFS: Fix return values for sysdev_store_{ulong,int}
+
+Always return the full size instead of the consumed
+length of the string in sysdev_store_{ulong,int}
+
+This avoids EINVAL errors in some echo versions.
+
+Signed-off-by: Andi Kleen <ak@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/base/sys.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/base/sys.c
++++ b/drivers/base/sys.c
+@@ -488,7 +488,8 @@ ssize_t sysdev_store_ulong(struct sys_de
+ if (end == buf)
+ return -EINVAL;
+ *(unsigned long *)(ea->var) = new;
+- return end - buf;
++ /* Always return full write size even if we didn't consume all */
++ return size;
+ }
+ EXPORT_SYMBOL_GPL(sysdev_store_ulong);
+
+@@ -511,7 +512,8 @@ ssize_t sysdev_store_int(struct sys_devi
+ if (end == buf || new > INT_MAX || new < INT_MIN)
+ return -EINVAL;
+ *(int *)(ea->var) = new;
+- return end - buf;
++ /* Always return full write size even if we didn't consume all */
++ return size;
+ }
+ EXPORT_SYMBOL_GPL(sysdev_store_int);
+
--- /dev/null
+From jejb@kernel.org Tue Nov 4 11:35:41 2008
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Thu, 30 Oct 2008 19:10:11 GMT
+Subject: USB: fix crash when URBs are unlinked after the device is gone
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810301910.m9UJAB0k013078@hera.kernel.org>
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit cde217a556ec552d28ac9e136c5a94684a69ae94 upstream
+
+This patch (as1151) protects usbcore against drivers that try to
+unlink an URB after the URB's device or bus have been removed. The
+core does not currently check for this, and certain drivers can cause
+a crash if they are running while an HCD is unloaded.
+
+Certainly it would be best to fix the guilty drivers. But a little
+defensive programming doesn't hurt, especially since it appears that
+quite a few drivers need to be fixed.
+
+The patch prevents the problem by grabbing a reference to the device
+while an unlink is in progress and using a new spinlock to synchronize
+unlinks with device removal. (There's no need to acquire a reference
+to the bus as well, since the device structure itself keeps a
+reference to the bus.) In addition, the kerneldoc is updated to
+indicate that URBs should not be unlinked after the disconnect method
+returns.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/hcd.c | 35 ++++++++++++++++++++++++++++++++---
+ drivers/usb/core/hcd.h | 1 +
+ drivers/usb/core/hub.c | 1 +
+ drivers/usb/core/urb.c | 15 +++++++++++++++
+ 4 files changed, 49 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -106,6 +106,9 @@ static DEFINE_SPINLOCK(hcd_root_hub_lock
+ /* used when updating an endpoint's URB list */
+ static DEFINE_SPINLOCK(hcd_urb_list_lock);
+
++/* used to protect against unlinking URBs after the device is gone */
++static DEFINE_SPINLOCK(hcd_urb_unlink_lock);
++
+ /* wait queue for synchronous unlinks */
+ DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue);
+
+@@ -1377,10 +1380,25 @@ static int unlink1(struct usb_hcd *hcd,
+ int usb_hcd_unlink_urb (struct urb *urb, int status)
+ {
+ struct usb_hcd *hcd;
+- int retval;
++ int retval = -EIDRM;
++ unsigned long flags;
+
+- hcd = bus_to_hcd(urb->dev->bus);
+- retval = unlink1(hcd, urb, status);
++ /* Prevent the device and bus from going away while
++ * the unlink is carried out. If they are already gone
++ * then urb->use_count must be 0, since disconnected
++ * devices can't have any active URBs.
++ */
++ spin_lock_irqsave(&hcd_urb_unlink_lock, flags);
++ if (atomic_read(&urb->use_count) > 0) {
++ retval = 0;
++ usb_get_dev(urb->dev);
++ }
++ spin_unlock_irqrestore(&hcd_urb_unlink_lock, flags);
++ if (retval == 0) {
++ hcd = bus_to_hcd(urb->dev->bus);
++ retval = unlink1(hcd, urb, status);
++ usb_put_dev(urb->dev);
++ }
+
+ if (retval == 0)
+ retval = -EINPROGRESS;
+@@ -1529,6 +1547,17 @@ void usb_hcd_disable_endpoint(struct usb
+ hcd->driver->endpoint_disable(hcd, ep);
+ }
+
++/* Protect against drivers that try to unlink URBs after the device
++ * is gone, by waiting until all unlinks for @udev are finished.
++ * Since we don't currently track URBs by device, simply wait until
++ * nothing is running in the locked region of usb_hcd_unlink_urb().
++ */
++void usb_hcd_synchronize_unlinks(struct usb_device *udev)
++{
++ spin_lock_irq(&hcd_urb_unlink_lock);
++ spin_unlock_irq(&hcd_urb_unlink_lock);
++}
++
+ /*-------------------------------------------------------------------------*/
+
+ /* called in any context */
+--- a/drivers/usb/core/hcd.h
++++ b/drivers/usb/core/hcd.h
+@@ -232,6 +232,7 @@ extern void usb_hcd_flush_endpoint(struc
+ struct usb_host_endpoint *ep);
+ extern void usb_hcd_disable_endpoint(struct usb_device *udev,
+ struct usb_host_endpoint *ep);
++extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);
+ extern int usb_hcd_get_frame_number(struct usb_device *udev);
+
+ extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1349,6 +1349,7 @@ void usb_disconnect(struct usb_device **
+ */
+ dev_dbg (&udev->dev, "unregistering device\n");
+ usb_disable_device(udev, 0);
++ usb_hcd_synchronize_unlinks(udev);
+
+ usb_unlock_device(udev);
+
+--- a/drivers/usb/core/urb.c
++++ b/drivers/usb/core/urb.c
+@@ -465,6 +465,12 @@ EXPORT_SYMBOL_GPL(usb_submit_urb);
+ * indicating that the request has been canceled (rather than any other
+ * code).
+ *
++ * Drivers should not call this routine or related routines, such as
++ * usb_kill_urb() or usb_unlink_anchored_urbs(), after their disconnect
++ * method has returned. The disconnect function should synchronize with
++ * a driver's I/O routines to insure that all URB-related activity has
++ * completed before it returns.
++ *
+ * This request is always asynchronous. Success is indicated by
+ * returning -EINPROGRESS, at which time the URB will probably not yet
+ * have been given back to the device driver. When it is eventually
+@@ -541,6 +547,9 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);
+ * This routine may not be used in an interrupt context (such as a bottom
+ * half or a completion handler), or when holding a spinlock, or in other
+ * situations where the caller can't schedule().
++ *
++ * This routine should not be called by a driver after its disconnect
++ * method has returned.
+ */
+ void usb_kill_urb(struct urb *urb)
+ {
+@@ -568,6 +577,9 @@ EXPORT_SYMBOL_GPL(usb_kill_urb);
+ *
+ * this allows all outstanding URBs to be killed starting
+ * from the back of the queue
++ *
++ * This routine should not be called by a driver after its disconnect
++ * method has returned.
+ */
+ void usb_kill_anchored_urbs(struct usb_anchor *anchor)
+ {
+@@ -597,6 +609,9 @@ EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs
+ * from the back of the queue. This function is asynchronous.
+ * The unlinking is just tiggered. It may happen after this
+ * function has returned.
++ *
++ * This routine should not be called by a driver after its disconnect
++ * method has returned.
+ */
+ void usb_unlink_anchored_urbs(struct usb_anchor *anchor)
+ {
--- /dev/null
+From jejb@kernel.org Tue Nov 4 11:42:52 2008
+From: Ravikiran G Thirumalai <kiran@scalex86.org>
+Date: Fri, 31 Oct 2008 01:40:03 GMT
+Subject: x86: fix /dev/mem mmap breakage when PAT is disabled
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810310140.m9V1e3kj005479@hera.kernel.org>
+
+From: Ravikiran G Thirumalai <kiran@scalex86.org>
+
+commit 9e41bff2708e420e61e6b89a54c15232857069b1 upstream
+
+Impact: allow /dev/mem mmaps on non-PAT CPUs/platforms
+
+Fix mmap to /dev/mem when CONFIG_X86_PAT is off and CONFIG_STRICT_DEVMEM is
+off
+
+mmap to /dev/mem on kernel memory has been failing since the
+introduction of PAT (CONFIG_STRICT_DEVMEM=n case). Seems like
+the check to avoid cache aliasing with PAT is kicking in even
+when PAT is disabled. The bug seems to have crept in 2.6.26.
+
+This patch makes sure that the mmap to regular
+kernel memory succeeds if CONFIG_STRICT_DEVMEM=n and
+PAT is disabled, and the checks to avoid cache aliasing
+still happens if PAT is enabled.
+
+Signed-off-by: Ravikiran Thirumalai <kiran@scalex86.org>
+Tested-by: Tim Sirianni <tim@scalemp.com>
+Acked-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/mm/pat.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/x86/mm/pat.c
++++ b/arch/x86/mm/pat.c
+@@ -403,12 +403,16 @@ static inline int range_is_allowed(unsig
+ return 1;
+ }
+ #else
++/* This check is needed to avoid cache aliasing when PAT is enabled */
+ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
+ {
+ u64 from = ((u64)pfn) << PAGE_SHIFT;
+ u64 to = from + size;
+ u64 cursor = from;
+
++ if (!pat_enabled)
++ return 1;
++
+ while (cursor < to) {
+ if (!devmem_is_allowed(pfn)) {
+ printk(KERN_INFO