[kernel] r12385 - in dists/trunk/linux-2.6/debian: . patches/bugfix/all/stable patches/series
Maximilian Attems
maks at alioth.debian.org
Sun Nov 16 09:28:41 UTC 2008
Author: maks
Date: Sun Nov 16 09:28:39 2008
New Revision: 12385
Log:
add stable 2.6.27.X stable releases
no point in pasting changelog as not intended for unstable.
snapshot users shouldn't be left unsupported. ;)
Added:
dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.1
dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.2
dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.3
dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.4
dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.5
dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.6
Modified:
dists/trunk/linux-2.6/debian/changelog
dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog (original)
+++ dists/trunk/linux-2.6/debian/changelog Sun Nov 16 09:28:39 2008
@@ -13,6 +13,7 @@
SCSI_DH_ALUA, MAC80211_HWSIM, USB_HSO.
* [x86] set MOUSE_BCM5974.
* [x86_64] set AMD_IOMMU, MTRR_SANITIZER.
+ * Add stable releases 2.6.27.1-2.6.27.6.
[ Martin Michlmayr ]
* [mips/r4k-ip22, mips/sb1-bcm91250a] Don't build in ISO9660.
Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.1
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.1 Sun Nov 16 09:28:39 2008
@@ -0,0 +1,14 @@
+diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
+index 263e9e6..aa53fdd 100644
+--- a/kernel/trace/Kconfig
++++ b/kernel/trace/Kconfig
+@@ -103,7 +103,8 @@ config CONTEXT_SWITCH_TRACER
+ all switching of tasks.
+
+ config DYNAMIC_FTRACE
+- bool "enable/disable ftrace tracepoints dynamically"
++ bool "enable/disable ftrace tracepoints dynamically (BROKEN)"
++ depends on BROKEN
+ depends on FTRACE
+ depends on HAVE_DYNAMIC_FTRACE
+ default y
Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.2
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.2 Sun Nov 16 09:28:39 2008
@@ -0,0 +1,567 @@
+diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
+index 65a0c1b..f509cfc 100644
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -444,7 +444,7 @@ void __init alternative_instructions(void)
+ _text, _etext);
+
+ /* Only switch to UP mode if we don't immediately boot others */
+- if (num_possible_cpus() == 1 || setup_max_cpus <= 1)
++ if (num_present_cpus() == 1 || setup_max_cpus <= 1)
+ alternatives_smp_switch(0);
+ }
+ #endif
+diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
+index 4353cf5..6b839b1 100644
+--- a/arch/x86/kernel/early-quirks.c
++++ b/arch/x86/kernel/early-quirks.c
+@@ -95,6 +95,52 @@ static void __init nvidia_bugs(int num, int slot, int func)
+
+ }
+
++static u32 ati_ixp4x0_rev(int num, int slot, int func)
++{
++ u32 d;
++ u8 b;
++
++ b = read_pci_config_byte(num, slot, func, 0xac);
++ b &= ~(1<<5);
++ write_pci_config_byte(num, slot, func, 0xac, b);
++
++ d = read_pci_config(num, slot, func, 0x70);
++ d |= 1<<8;
++ write_pci_config(num, slot, func, 0x70, d);
++
++ d = read_pci_config(num, slot, func, 0x8);
++ d &= 0xff;
++ return d;
++}
++
++static void __init ati_bugs(int num, int slot, int func)
++{
++#if defined(CONFIG_ACPI) && defined (CONFIG_X86_IO_APIC)
++ u32 d;
++ u8 b;
++
++ if (acpi_use_timer_override)
++ return;
++
++ d = ati_ixp4x0_rev(num, slot, func);
++ if (d < 0x82)
++ acpi_skip_timer_override = 1;
++ else {
++ /* check for IRQ0 interrupt swap */
++ outb(0x72, 0xcd6); b = inb(0xcd7);
++ if (!(b & 0x2))
++ acpi_skip_timer_override = 1;
++ }
++
++ if (acpi_skip_timer_override) {
++ printk(KERN_INFO "SB4X0 revision 0x%x\n", d);
++ printk(KERN_INFO "Ignoring ACPI timer override.\n");
++ printk(KERN_INFO "If you got timer trouble "
++ "try acpi_use_timer_override\n");
++ }
++#endif
++}
++
+ #define QFLAG_APPLY_ONCE 0x1
+ #define QFLAG_APPLIED 0x2
+ #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED)
+@@ -114,6 +160,8 @@ static struct chipset early_qrk[] __initdata = {
+ PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, via_bugs },
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB,
+ PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, fix_hypertransport_config },
++ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS,
++ PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },
+ {}
+ };
+
+diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
+index 09cddb5..bfd9fc5 100644
+--- a/arch/x86/kernel/io_apic_32.c
++++ b/arch/x86/kernel/io_apic_32.c
+@@ -2314,6 +2314,9 @@ void __init setup_IO_APIC(void)
+ for (i = first_system_vector; i < NR_VECTORS; i++)
+ set_bit(i, used_vectors);
+
++ /* Mark FIRST_DEVICE_VECTOR which is assigned to IRQ0 as used. */
++ set_bit(FIRST_DEVICE_VECTOR, used_vectors);
++
+ enable_IO_APIC();
+
+ io_apic_irqs = ~PIC_IRQS;
+diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
+index d4b6e6a..d0975fc 100644
+--- a/arch/x86/mm/ioremap.c
++++ b/arch/x86/mm/ioremap.c
+@@ -595,7 +595,7 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
+ */
+ offset = phys_addr & ~PAGE_MASK;
+ phys_addr &= PAGE_MASK;
+- size = PAGE_ALIGN(last_addr) - phys_addr;
++ size = PAGE_ALIGN(last_addr + 1) - phys_addr;
+
+ /*
+ * Mappings have to fit in the FIX_BTMAP area.
+diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
+index e4dce87..0232485 100644
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -2996,7 +2996,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ case TIOCSTI:
+ return tiocsti(tty, p);
+ case TIOCGWINSZ:
+- return tiocgwinsz(tty, p);
++ return tiocgwinsz(real_tty, p);
+ case TIOCSWINSZ:
+ return tiocswinsz(tty, real_tty, p);
+ case TIOCCONS:
+diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
+index 7685b99..9b60352 100644
+--- a/drivers/net/atl1e/atl1e_main.c
++++ b/drivers/net/atl1e/atl1e_main.c
+@@ -2390,9 +2390,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
+ }
+
+ /* Init GPHY as early as possible due to power saving issue */
+- spin_lock(&adapter->mdio_lock);
+ atl1e_phy_init(&adapter->hw);
+- spin_unlock(&adapter->mdio_lock);
+ /* reset the controller to
+ * put the device in a known good starting state */
+ err = atl1e_reset_hw(&adapter->hw);
+diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
+index e24b25c..b4be33a 100644
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -3034,7 +3034,8 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+ struct sky2_port *sky2 = netdev_priv(dev);
+ struct sky2_hw *hw = sky2->hw;
+
+- if (wol->wolopts & ~sky2_wol_supported(sky2->hw))
++ if ((wol->wolopts & ~sky2_wol_supported(sky2->hw))
++ || !device_can_wakeup(&hw->pdev->dev))
+ return -EOPNOTSUPP;
+
+ sky2->wol = wol->wolopts;
+@@ -3045,6 +3046,8 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+ sky2_write32(hw, B0_CTST, sky2->wol
+ ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
+
++ device_set_wakeup_enable(&hw->pdev->dev, sky2->wol);
++
+ if (!netif_running(dev))
+ sky2_wol_init(sky2);
+ return 0;
+@@ -4166,18 +4169,6 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
+ return err;
+ }
+
+-static int __devinit pci_wake_enabled(struct pci_dev *dev)
+-{
+- int pm = pci_find_capability(dev, PCI_CAP_ID_PM);
+- u16 value;
+-
+- if (!pm)
+- return 0;
+- if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value))
+- return 0;
+- return value & PCI_PM_CTRL_PME_ENABLE;
+-}
+-
+ /* This driver supports yukon2 chipset only */
+ static const char *sky2_name(u8 chipid, char *buf, int sz)
+ {
+@@ -4238,7 +4229,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
+ }
+ }
+
+- wol_default = pci_wake_enabled(pdev) ? WAKE_MAGIC : 0;
++ wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0;
+
+ err = -ENOMEM;
+ hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
+index 68e1f8c..8d5ff62 100644
+--- a/drivers/net/wireless/b43legacy/xmit.c
++++ b/drivers/net/wireless/b43legacy/xmit.c
+@@ -626,7 +626,7 @@ void b43legacy_handle_hwtxstatus(struct b43legacy_wldev *dev,
+ tmp = hw->count;
+ status.frame_count = (tmp >> 4);
+ status.rts_count = (tmp & 0x0F);
+- tmp = hw->flags;
++ tmp = hw->flags << 1;
+ status.supp_reason = ((tmp & 0x1C) >> 2);
+ status.pm_indicated = !!(tmp & 0x80);
+ status.intermediate = !!(tmp & 0x40);
+diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
+index bd32ac0..5bcf561 100644
+--- a/drivers/net/wireless/libertas/main.c
++++ b/drivers/net/wireless/libertas/main.c
+@@ -1196,7 +1196,13 @@ void lbs_remove_card(struct lbs_private *priv)
+ cancel_delayed_work_sync(&priv->scan_work);
+ cancel_delayed_work_sync(&priv->assoc_work);
+ cancel_work_sync(&priv->mcast_work);
++
++ /* worker thread destruction blocks on the in-flight command which
++ * should have been cleared already in lbs_stop_card().
++ */
++ lbs_deb_main("destroying worker thread\n");
+ destroy_workqueue(priv->work_thread);
++ lbs_deb_main("done destroying worker thread\n");
+
+ if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
+ priv->psmode = LBS802_11POWERMODECAM;
+@@ -1314,14 +1320,26 @@ void lbs_stop_card(struct lbs_private *priv)
+ device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
+ }
+
+- /* Flush pending command nodes */
++ /* Delete the timeout of the currently processing command */
+ del_timer_sync(&priv->command_timer);
++
++ /* Flush pending command nodes */
+ spin_lock_irqsave(&priv->driver_lock, flags);
++ lbs_deb_main("clearing pending commands\n");
+ list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
+ cmdnode->result = -ENOENT;
+ cmdnode->cmdwaitqwoken = 1;
+ wake_up_interruptible(&cmdnode->cmdwait_q);
+ }
++
++ /* Flush the command the card is currently processing */
++ if (priv->cur_cmd) {
++ lbs_deb_main("clearing current command\n");
++ priv->cur_cmd->result = -ENOENT;
++ priv->cur_cmd->cmdwaitqwoken = 1;
++ wake_up_interruptible(&priv->cur_cmd->cmdwait_q);
++ }
++ lbs_deb_main("done clearing commands\n");
+ spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+ unregister_netdev(dev);
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 8dfd6f2..0d22479 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -309,6 +309,7 @@ struct cifs_search_info {
+ __u32 resume_key;
+ char *ntwrk_buf_start;
+ char *srch_entries_start;
++ char *last_entry;
+ char *presume_name;
+ unsigned int resume_name_len;
+ bool endOfSearch:1;
+diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
+index 994de7c..77a0d1f 100644
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -3636,6 +3636,8 @@ findFirstRetry:
+ le16_to_cpu(parms->SearchCount);
+ psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
+ psrch_inf->entries_in_buffer;
++ psrch_inf->last_entry = psrch_inf->srch_entries_start +
++ le16_to_cpu(parms->LastNameOffset);
+ *pnetfid = parms->SearchHandle;
+ } else {
+ cifs_buf_release(pSMB);
+@@ -3751,6 +3753,8 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
+ le16_to_cpu(parms->SearchCount);
+ psrch_inf->index_of_last_entry +=
+ psrch_inf->entries_in_buffer;
++ psrch_inf->last_entry = psrch_inf->srch_entries_start +
++ le16_to_cpu(parms->LastNameOffset);
+ /* cFYI(1,("fnxt2 entries in buf %d index_of_last %d",
+ psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */
+
+diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
+index 5f40ed3..765adf1 100644
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -640,6 +640,70 @@ static int is_dir_changed(struct file *file)
+
+ }
+
++static int cifs_save_resume_key(const char *current_entry,
++ struct cifsFileInfo *cifsFile)
++{
++ int rc = 0;
++ unsigned int len = 0;
++ __u16 level;
++ char *filename;
++
++ if ((cifsFile == NULL) || (current_entry == NULL))
++ return -EINVAL;
++
++ level = cifsFile->srch_inf.info_level;
++
++ if (level == SMB_FIND_FILE_UNIX) {
++ FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
++
++ filename = &pFindData->FileName[0];
++ if (cifsFile->srch_inf.unicode) {
++ len = cifs_unicode_bytelen(filename);
++ } else {
++ /* BB should we make this strnlen of PATH_MAX? */
++ len = strnlen(filename, PATH_MAX);
++ }
++ cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
++ } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
++ FILE_DIRECTORY_INFO *pFindData =
++ (FILE_DIRECTORY_INFO *)current_entry;
++ filename = &pFindData->FileName[0];
++ len = le32_to_cpu(pFindData->FileNameLength);
++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
++ } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
++ FILE_FULL_DIRECTORY_INFO *pFindData =
++ (FILE_FULL_DIRECTORY_INFO *)current_entry;
++ filename = &pFindData->FileName[0];
++ len = le32_to_cpu(pFindData->FileNameLength);
++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
++ } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
++ SEARCH_ID_FULL_DIR_INFO *pFindData =
++ (SEARCH_ID_FULL_DIR_INFO *)current_entry;
++ filename = &pFindData->FileName[0];
++ len = le32_to_cpu(pFindData->FileNameLength);
++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
++ } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
++ FILE_BOTH_DIRECTORY_INFO *pFindData =
++ (FILE_BOTH_DIRECTORY_INFO *)current_entry;
++ filename = &pFindData->FileName[0];
++ len = le32_to_cpu(pFindData->FileNameLength);
++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
++ } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
++ FIND_FILE_STANDARD_INFO *pFindData =
++ (FIND_FILE_STANDARD_INFO *)current_entry;
++ filename = &pFindData->FileName[0];
++ /* one byte length, no name conversion */
++ len = (unsigned int)pFindData->FileNameLength;
++ cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
++ } else {
++ cFYI(1, ("Unknown findfirst level %d", level));
++ return -EINVAL;
++ }
++ cifsFile->srch_inf.resume_name_len = len;
++ cifsFile->srch_inf.presume_name = filename;
++ return rc;
++}
++
+ /* find the corresponding entry in the search */
+ /* Note that the SMB server returns search entries for . and .. which
+ complicates logic here if we choose to parse for them and we do not
+@@ -703,6 +767,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
+ while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
+ (rc == 0) && !cifsFile->srch_inf.endOfSearch) {
+ cFYI(1, ("calling findnext2"));
++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
+ rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
+ &cifsFile->srch_inf);
+ if (rc)
+@@ -919,69 +984,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
+ return rc;
+ }
+
+-static int cifs_save_resume_key(const char *current_entry,
+- struct cifsFileInfo *cifsFile)
+-{
+- int rc = 0;
+- unsigned int len = 0;
+- __u16 level;
+- char *filename;
+-
+- if ((cifsFile == NULL) || (current_entry == NULL))
+- return -EINVAL;
+-
+- level = cifsFile->srch_inf.info_level;
+-
+- if (level == SMB_FIND_FILE_UNIX) {
+- FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
+-
+- filename = &pFindData->FileName[0];
+- if (cifsFile->srch_inf.unicode) {
+- len = cifs_unicode_bytelen(filename);
+- } else {
+- /* BB should we make this strnlen of PATH_MAX? */
+- len = strnlen(filename, PATH_MAX);
+- }
+- cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
+- } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
+- FILE_DIRECTORY_INFO *pFindData =
+- (FILE_DIRECTORY_INFO *)current_entry;
+- filename = &pFindData->FileName[0];
+- len = le32_to_cpu(pFindData->FileNameLength);
+- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
+- } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
+- FILE_FULL_DIRECTORY_INFO *pFindData =
+- (FILE_FULL_DIRECTORY_INFO *)current_entry;
+- filename = &pFindData->FileName[0];
+- len = le32_to_cpu(pFindData->FileNameLength);
+- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
+- } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
+- SEARCH_ID_FULL_DIR_INFO *pFindData =
+- (SEARCH_ID_FULL_DIR_INFO *)current_entry;
+- filename = &pFindData->FileName[0];
+- len = le32_to_cpu(pFindData->FileNameLength);
+- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
+- } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
+- FILE_BOTH_DIRECTORY_INFO *pFindData =
+- (FILE_BOTH_DIRECTORY_INFO *)current_entry;
+- filename = &pFindData->FileName[0];
+- len = le32_to_cpu(pFindData->FileNameLength);
+- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
+- } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
+- FIND_FILE_STANDARD_INFO *pFindData =
+- (FIND_FILE_STANDARD_INFO *)current_entry;
+- filename = &pFindData->FileName[0];
+- /* one byte length, no name conversion */
+- len = (unsigned int)pFindData->FileNameLength;
+- cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
+- } else {
+- cFYI(1, ("Unknown findfirst level %d", level));
+- return -EINVAL;
+- }
+- cifsFile->srch_inf.resume_name_len = len;
+- cifsFile->srch_inf.presume_name = filename;
+- return rc;
+-}
+
+ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
+ {
+diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
+index 986061a..36d5fcd 100644
+--- a/fs/xfs/linux-2.6/xfs_buf.c
++++ b/fs/xfs/linux-2.6/xfs_buf.c
+@@ -1001,12 +1001,13 @@ xfs_buf_iodone_work(
+ * We can get an EOPNOTSUPP to ordered writes. Here we clear the
+ * ordered flag and reissue them. Because we can't tell the higher
+ * layers directly that they should not issue ordered I/O anymore, they
+- * need to check if the ordered flag was cleared during I/O completion.
++ * need to check if the _XFS_BARRIER_FAILED flag was set during I/O completion.
+ */
+ if ((bp->b_error == EOPNOTSUPP) &&
+ (bp->b_flags & (XBF_ORDERED|XBF_ASYNC)) == (XBF_ORDERED|XBF_ASYNC)) {
+ XB_TRACE(bp, "ordered_retry", bp->b_iodone);
+ bp->b_flags &= ~XBF_ORDERED;
++ bp->b_flags |= _XFS_BARRIER_FAILED;
+ xfs_buf_iorequest(bp);
+ } else if (bp->b_iodone)
+ (*(bp->b_iodone))(bp);
+diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
+index fe01099..456519a 100644
+--- a/fs/xfs/linux-2.6/xfs_buf.h
++++ b/fs/xfs/linux-2.6/xfs_buf.h
+@@ -85,6 +85,14 @@ typedef enum {
+ * modifications being lost.
+ */
+ _XBF_PAGE_LOCKED = (1 << 22),
++
++ /*
++ * If we try a barrier write, but it fails we have to communicate
++ * this to the upper layers. Unfortunately b_error gets overwritten
++ * when the buffer is re-issued so we have to add another flag to
++ * keep this information.
++ */
++ _XFS_BARRIER_FAILED = (1 << 23),
+ } xfs_buf_flags_t;
+
+ typedef enum {
+diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
+index 503ea89..0b02c64 100644
+--- a/fs/xfs/xfs_log.c
++++ b/fs/xfs/xfs_log.c
+@@ -1033,11 +1033,12 @@ xlog_iodone(xfs_buf_t *bp)
+ l = iclog->ic_log;
+
+ /*
+- * If the ordered flag has been removed by a lower
+- * layer, it means the underlyin device no longer supports
++ * If the _XFS_BARRIER_FAILED flag was set by a lower
++ * layer, it means the underlying device no longer supports
+ * barrier I/O. Warn loudly and turn off barriers.
+ */
+- if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ISORDERED(bp)) {
++ if (bp->b_flags & _XFS_BARRIER_FAILED) {
++ bp->b_flags &= ~_XFS_BARRIER_FAILED;
+ l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER;
+ xfs_fs_cmn_err(CE_WARN, l->l_mp,
+ "xlog_iodone: Barriers are no longer supported"
+diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
+index 1113157..37f0721 100644
+--- a/kernel/sched_rt.c
++++ b/kernel/sched_rt.c
+@@ -102,12 +102,12 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se);
+
+ static void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
+ {
++ struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
+ struct sched_rt_entity *rt_se = rt_rq->rt_se;
+
+- if (rt_se && !on_rt_rq(rt_se) && rt_rq->rt_nr_running) {
+- struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
+-
+- enqueue_rt_entity(rt_se);
++ if (rt_rq->rt_nr_running) {
++ if (rt_se && !on_rt_rq(rt_se))
++ enqueue_rt_entity(rt_se);
+ if (rt_rq->highest_prio < curr->prio)
+ resched_task(curr);
+ }
+diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
+index 8165df5..5c7bbe0 100644
+--- a/net/mac80211/debugfs_netdev.c
++++ b/net/mac80211/debugfs_netdev.c
+@@ -537,6 +537,7 @@ static int netdev_notify(struct notifier_block *nb,
+ {
+ struct net_device *dev = ndev;
+ struct dentry *dir;
++ struct ieee80211_local *local;
+ struct ieee80211_sub_if_data *sdata;
+ char buf[10+IFNAMSIZ];
+
+@@ -549,10 +550,19 @@ static int netdev_notify(struct notifier_block *nb,
+ if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
+ return 0;
+
+- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++ /*
++ * Do not use IEEE80211_DEV_TO_SUB_IF because that
++ * BUG_ONs for the master netdev which we need to
++ * handle here.
++ */
++ sdata = netdev_priv(dev);
+
+- sprintf(buf, "netdev:%s", dev->name);
+ dir = sdata->debugfsdir;
++
++ if (!dir)
++ return 0;
++
++ sprintf(buf, "netdev:%s", dev->name);
+ if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
+ printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
+ "dir to %s\n", buf);
+diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
+index 74aecc0..10b05ce 100644
+--- a/net/rfkill/rfkill.c
++++ b/net/rfkill/rfkill.c
+@@ -117,6 +117,7 @@ static void rfkill_led_trigger_activate(struct led_classdev *led)
+
+ static void notify_rfkill_state_change(struct rfkill *rfkill)
+ {
++ rfkill_led_trigger(rfkill, rfkill->state);
+ blocking_notifier_call_chain(&rfkill_notifier_list,
+ RFKILL_STATE_CHANGED,
+ rfkill);
+@@ -204,10 +205,8 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
+ rfkill->state = state;
+ }
+
+- if (force || rfkill->state != oldstate) {
+- rfkill_led_trigger(rfkill, rfkill->state);
++ if (force || rfkill->state != oldstate)
+ notify_rfkill_state_change(rfkill);
+- }
+
+ return retval;
+ }
Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.3
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.3 Sun Nov 16 09:28:39 2008
@@ -0,0 +1,739 @@
+diff --git a/Documentation/video4linux/CARDLIST.au0828 b/Documentation/video4linux/CARDLIST.au0828
+index aa05e5b..d5cb4ea 100644
+--- a/Documentation/video4linux/CARDLIST.au0828
++++ b/Documentation/video4linux/CARDLIST.au0828
+@@ -1,5 +1,5 @@
+ 0 -> Unknown board (au0828)
+- 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
++ 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721e,2040:721f,2040:7280,0fd9:0008]
+ 2 -> Hauppauge HVR850 (au0828) [2040:7240]
+ 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620]
+ 4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281]
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index d021c98..473c323 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -523,11 +523,16 @@ static void klist_children_put(struct klist_node *n)
+ * device_initialize - init device structure.
+ * @dev: device.
+ *
+- * This prepares the device for use by other layers,
+- * including adding it to the device hierarchy.
++ * This prepares the device for use by other layers by initializing
++ * its fields.
+ * It is the first half of device_register(), if called by
+- * that, though it can also be called separately, so one
+- * may use @dev's fields (e.g. the refcount).
++ * that function, though it can also be called separately, so one
++ * may use @dev's fields. In particular, get_device()/put_device()
++ * may be used for reference counting of @dev after calling this
++ * function.
++ *
++ * NOTE: Use put_device() to give up your reference instead of freeing
++ * @dev directly once you have called this function.
+ */
+ void device_initialize(struct device *dev)
+ {
+@@ -836,9 +841,13 @@ static void device_remove_sys_dev_entry(struct device *dev)
+ * This is part 2 of device_register(), though may be called
+ * separately _iff_ device_initialize() has been called separately.
+ *
+- * This adds it to the kobject hierarchy via kobject_add(), adds it
++ * This adds @dev to the kobject hierarchy via kobject_add(), adds it
+ * to the global and sibling lists for the device, then
+ * adds it to the other relevant subsystems of the driver model.
++ *
++ * NOTE: _Never_ directly free @dev after calling this function, even
++ * if it returned an error! Always use put_device() to give up your
++ * reference instead.
+ */
+ int device_add(struct device *dev)
+ {
+@@ -965,6 +974,10 @@ done:
+ * I.e. you should only call the two helpers separately if
+ * have a clearly defined need to use and refcount the device
+ * before it is added to the hierarchy.
++ *
++ * NOTE: _Never_ directly free @dev after calling this function, even
++ * if it returned an error! Always use put_device() to give up the
++ * reference initialized in this function instead.
+ */
+ int device_register(struct device *dev)
+ {
+@@ -1243,7 +1256,7 @@ struct device *device_create_vargs(struct class *class, struct device *parent,
+ return dev;
+
+ error:
+- kfree(dev);
++ put_device(dev);
+ return ERR_PTR(retval);
+ }
+ EXPORT_SYMBOL_GPL(device_create_vargs);
+diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
+index 8897434..a219ae4 100644
+--- a/drivers/gpu/drm/i915/i915_dma.c
++++ b/drivers/gpu/drm/i915/i915_dma.c
+@@ -836,7 +836,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
+ DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
+ DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
+ DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
+- DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
++ DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ };
+
+ int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index deeac4b..fe6eccd 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -2109,8 +2109,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
+
+ if (strict_strtoull(buf, 10, &size) < 0)
+ return -EINVAL;
+- if (size < my_mddev->size)
+- return -EINVAL;
+ if (my_mddev->pers && rdev->raid_disk >= 0) {
+ if (my_mddev->persistent) {
+ size = super_types[my_mddev->major_version].
+@@ -2121,9 +2119,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
+ size = (rdev->bdev->bd_inode->i_size >> 10);
+ size -= rdev->data_offset/2;
+ }
+- if (size < my_mddev->size)
+- return -EINVAL; /* component must fit device */
+ }
++ if (size < my_mddev->size)
++ return -EINVAL; /* component must fit device */
+
+ rdev->size = size;
+ if (size > oldsize && my_mddev->external) {
+diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
+index 9da260f..6f9b773 100644
+--- a/drivers/media/dvb/siano/sms-cards.c
++++ b/drivers/media/dvb/siano/sms-cards.c
+@@ -42,6 +42,10 @@ struct usb_device_id smsusb_id_table[] = {
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5510),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
++ { USB_DEVICE(0x2040, 0x5520),
++ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
++ { USB_DEVICE(0x2040, 0x5530),
++ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5580),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5590),
+diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
+index ed48908..6294938 100644
+--- a/drivers/media/video/au0828/au0828-cards.c
++++ b/drivers/media/video/au0828/au0828-cards.c
+@@ -90,6 +90,7 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
+ case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
+ case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
+ case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */
++ case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
+ case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */
+ case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
+ break;
+@@ -198,6 +199,8 @@ struct usb_device_id au0828_usb_id_table [] = {
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+ { USB_DEVICE(0x2040, 0x721b),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
++ { USB_DEVICE(0x2040, 0x721e),
++ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+ { USB_DEVICE(0x2040, 0x721f),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+ { USB_DEVICE(0x2040, 0x7280),
+diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
+index 463680b..b59e472 100644
+--- a/drivers/media/video/tvaudio.c
++++ b/drivers/media/video/tvaudio.c
+@@ -1792,7 +1792,7 @@ static int chip_command(struct i2c_client *client,
+ break;
+ case VIDIOC_S_FREQUENCY:
+ chip->mode = 0; /* automatic */
+- if (desc->checkmode) {
++ if (desc->checkmode && desc->setmode) {
+ desc->setmode(chip,V4L2_TUNER_MODE_MONO);
+ if (chip->prevmode != V4L2_TUNER_MODE_MONO)
+ chip->prevmode = -1; /* reset previous mode */
+diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
+index 2f84093..88f4cc3 100644
+--- a/drivers/net/wireless/ath9k/core.h
++++ b/drivers/net/wireless/ath9k/core.h
+@@ -316,7 +316,7 @@ void ath_descdma_cleanup(struct ath_softc *sc,
+ #define ATH_RX_TIMEOUT 40 /* 40 milliseconds */
+ #define WME_NUM_TID 16
+ #define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */
+-#define IEEE80211_BAR_CTL_TID_S 2 /* tid shift */
++#define IEEE80211_BAR_CTL_TID_S 12 /* tid shift */
+
+ enum ATH_RX_TYPE {
+ ATH_RX_NON_CONSUMED = 0,
+diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
+index acebdf1..b4c7174 100644
+--- a/drivers/net/wireless/ath9k/main.c
++++ b/drivers/net/wireless/ath9k/main.c
+@@ -1007,6 +1007,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
+ return ret;
+ }
+
++static int ath9k_no_fragmentation(struct ieee80211_hw *hw, u32 value)
++{
++ return -EOPNOTSUPP;
++}
++
+ static struct ieee80211_ops ath9k_ops = {
+ .tx = ath9k_tx,
+ .start = ath9k_start,
+@@ -1031,7 +1036,8 @@ static struct ieee80211_ops ath9k_ops = {
+ .get_tsf = ath9k_get_tsf,
+ .reset_tsf = ath9k_reset_tsf,
+ .tx_last_beacon = NULL,
+- .ampdu_action = ath9k_ampdu_action
++ .ampdu_action = ath9k_ampdu_action,
++ .set_frag_threshold = ath9k_no_fragmentation,
+ };
+
+ void ath_get_beaconconfig(struct ath_softc *sc,
+diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
+index 8ab389d..706f3e6 100644
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -81,6 +81,10 @@
+
+ /*-------------------------------------------------------------------------*/
+
++/* Keep track of which host controller drivers are loaded */
++unsigned long usb_hcds_loaded;
++EXPORT_SYMBOL_GPL(usb_hcds_loaded);
++
+ /* host controllers we manage */
+ LIST_HEAD (usb_bus_list);
+ EXPORT_SYMBOL_GPL (usb_bus_list);
+diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
+index e710ce0..2dcde61 100644
+--- a/drivers/usb/core/hcd.h
++++ b/drivers/usb/core/hcd.h
+@@ -482,4 +482,10 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
+ */
+ extern struct rw_semaphore ehci_cf_port_reset_rwsem;
+
++/* Keep track of which host controller drivers are loaded */
++#define USB_UHCI_LOADED 0
++#define USB_OHCI_LOADED 1
++#define USB_EHCI_LOADED 2
++extern unsigned long usb_hcds_loaded;
++
+ #endif /* __KERNEL__ */
+diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
+index 29d13eb..48f51b1 100644
+--- a/drivers/usb/gadget/s3c2410_udc.c
++++ b/drivers/usb/gadget/s3c2410_udc.c
+@@ -1651,7 +1651,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+ return -EBUSY;
+
+ if (!driver->bind || !driver->setup
+- || driver->speed != USB_SPEED_FULL) {
++ || driver->speed < USB_SPEED_FULL) {
+ printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n",
+ driver->bind, driver->setup, driver->speed);
+ return -EINVAL;
+diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
+index 3791e62..38a55af 100644
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -873,6 +873,13 @@ struct net_device *gether_connect(struct gether *link)
+ spin_lock(&dev->lock);
+ dev->port_usb = link;
+ link->ioport = dev;
++ if (netif_running(dev->net)) {
++ if (link->open)
++ link->open(link);
++ } else {
++ if (link->close)
++ link->close(link);
++ }
+ spin_unlock(&dev->lock);
+
+ netif_carrier_on(dev->net);
+diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
+index 8409e07..86e38b0 100644
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -1049,6 +1049,12 @@ static int __init ehci_hcd_init(void)
+ {
+ int retval = 0;
+
++ set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
++ if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
++ test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
++ printk(KERN_WARNING "Warning! ehci_hcd should always be loaded"
++ " before uhci_hcd and ohci_hcd, not after\n");
++
+ pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
+ hcd_name,
+ sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
+@@ -1056,8 +1062,10 @@ static int __init ehci_hcd_init(void)
+
+ #ifdef DEBUG
+ ehci_debug_root = debugfs_create_dir("ehci", NULL);
+- if (!ehci_debug_root)
+- return -ENOENT;
++ if (!ehci_debug_root) {
++ retval = -ENOENT;
++ goto err_debug;
++ }
+ #endif
+
+ #ifdef PLATFORM_DRIVER
+@@ -1104,7 +1112,9 @@ clean0:
+ #ifdef DEBUG
+ debugfs_remove(ehci_debug_root);
+ ehci_debug_root = NULL;
++err_debug:
+ #endif
++ clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
+ return retval;
+ }
+ module_init(ehci_hcd_init);
+@@ -1126,6 +1136,7 @@ static void __exit ehci_hcd_cleanup(void)
+ #ifdef DEBUG
+ debugfs_remove(ehci_debug_root);
+ #endif
++ clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
+ }
+ module_exit(ehci_hcd_cleanup);
+
+diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
+index 8990196..8bec02c 100644
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -1098,6 +1098,7 @@ static int __init ohci_hcd_mod_init(void)
+ printk (KERN_DEBUG "%s: " DRIVER_INFO "\n", hcd_name);
+ pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
+ sizeof (struct ed), sizeof (struct td));
++ set_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
+
+ #ifdef DEBUG
+ ohci_debug_root = debugfs_create_dir("ohci", NULL);
+@@ -1184,6 +1185,7 @@ static int __init ohci_hcd_mod_init(void)
+ error_debug:
+ #endif
+
++ clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
+ return retval;
+ }
+ module_init(ohci_hcd_mod_init);
+@@ -1214,6 +1216,7 @@ static void __exit ohci_hcd_mod_exit(void)
+ #ifdef DEBUG
+ debugfs_remove(ohci_debug_root);
+ #endif
++ clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
+ }
+ module_exit(ohci_hcd_mod_exit);
+
+diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
+index 7ea9a7b..32bbce9 100644
+--- a/drivers/usb/host/ohci-hub.c
++++ b/drivers/usb/host/ohci-hub.c
+@@ -359,21 +359,24 @@ static void ohci_finish_controller_resume(struct usb_hcd *hcd)
+
+ /* Carry out polling-, autostop-, and autoresume-related state changes */
+ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
+- int any_connected)
++ int any_connected, int rhsc_status)
+ {
+ int poll_rh = 1;
+- int rhsc;
++ int rhsc_enable;
+
+- rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC;
+- switch (ohci->hc_control & OHCI_CTRL_HCFS) {
++ /* Some broken controllers never turn off RHCS in the interrupt
++ * status register. For their sake we won't re-enable RHSC
++ * interrupts if the interrupt bit is already active.
++ */
++ rhsc_enable = ohci_readl(ohci, &ohci->regs->intrenable) &
++ OHCI_INTR_RHSC;
+
++ switch (ohci->hc_control & OHCI_CTRL_HCFS) {
+ case OHCI_USB_OPER:
+- /* If no status changes are pending, enable status-change
+- * interrupts.
+- */
+- if (!rhsc && !changed) {
+- rhsc = OHCI_INTR_RHSC;
+- ohci_writel(ohci, rhsc, &ohci->regs->intrenable);
++ /* If no status changes are pending, enable RHSC interrupts. */
++ if (!rhsc_enable && !rhsc_status && !changed) {
++ rhsc_enable = OHCI_INTR_RHSC;
++ ohci_writel(ohci, rhsc_enable, &ohci->regs->intrenable);
+ }
+
+ /* Keep on polling until we know a device is connected
+@@ -383,7 +386,7 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
+ if (any_connected ||
+ !device_may_wakeup(&ohci_to_hcd(ohci)
+ ->self.root_hub->dev)) {
+- if (rhsc)
++ if (rhsc_enable)
+ poll_rh = 0;
+ } else {
+ ohci->autostop = 1;
+@@ -396,34 +399,45 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
+ ohci->autostop = 0;
+ ohci->next_statechange = jiffies +
+ STATECHANGE_DELAY;
+- } else if (rhsc && time_after_eq(jiffies,
++ } else if (time_after_eq(jiffies,
+ ohci->next_statechange)
+ && !ohci->ed_rm_list
+ && !(ohci->hc_control &
+ OHCI_SCHED_ENABLES)) {
+ ohci_rh_suspend(ohci, 1);
+- poll_rh = 0;
++ if (rhsc_enable)
++ poll_rh = 0;
+ }
+ }
+ break;
+
+- /* if there is a port change, autostart or ask to be resumed */
+ case OHCI_USB_SUSPEND:
+ case OHCI_USB_RESUME:
++ /* if there is a port change, autostart or ask to be resumed */
+ if (changed) {
+ if (ohci->autostop)
+ ohci_rh_resume(ohci);
+ else
+ usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
+- } else {
+- if (!rhsc && (ohci->autostop ||
+- ohci_to_hcd(ohci)->self.root_hub->
+- do_remote_wakeup))
+- ohci_writel(ohci, OHCI_INTR_RHSC,
+- &ohci->regs->intrenable);
+
+- /* everything is idle, no need for polling */
++ /* If remote wakeup is disabled, stop polling */
++ } else if (!ohci->autostop &&
++ !ohci_to_hcd(ohci)->self.root_hub->
++ do_remote_wakeup) {
+ poll_rh = 0;
++
++ } else {
++ /* If no status changes are pending,
++ * enable RHSC interrupts
++ */
++ if (!rhsc_enable && !rhsc_status) {
++ rhsc_enable = OHCI_INTR_RHSC;
++ ohci_writel(ohci, rhsc_enable,
++ &ohci->regs->intrenable);
++ }
++ /* Keep polling until RHSC is enabled */
++ if (rhsc_enable)
++ poll_rh = 0;
+ }
+ break;
+ }
+@@ -441,18 +455,22 @@ static inline int ohci_rh_resume(struct ohci_hcd *ohci)
+ * autostop isn't used when CONFIG_PM is turned off.
+ */
+ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
+- int any_connected)
++ int any_connected, int rhsc_status)
+ {
+ /* If RHSC is enabled, don't poll */
+ if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
+ return 0;
+
+- /* If no status changes are pending, enable status-change interrupts */
+- if (!changed) {
+- ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
+- return 0;
+- }
+- return 1;
++ /* If status changes are pending, continue polling.
++ * Conversely, if no status changes are pending but the RHSC
++ * status bit was set, then RHSC may be broken so continue polling.
++ */
++ if (changed || rhsc_status)
++ return 1;
++
++ /* It's safe to re-enable RHSC interrupts */
++ ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
++ return 0;
+ }
+
+ #endif /* CONFIG_PM */
+@@ -467,6 +485,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ int i, changed = 0, length = 1;
+ int any_connected = 0;
++ int rhsc_status;
+ unsigned long flags;
+
+ spin_lock_irqsave (&ohci->lock, flags);
+@@ -492,12 +511,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
+ length++;
+ }
+
+- /* Some broken controllers never turn off RHCS in the interrupt
+- * status register. For their sake we won't re-enable RHSC
+- * interrupts if the flag is already set.
+- */
+- if (ohci_readl(ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC)
+- changed = 1;
++ /* Clear the RHSC status flag before reading the port statuses */
++ ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrstatus);
++ rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) &
++ OHCI_INTR_RHSC;
+
+ /* look at each port */
+ for (i = 0; i < ohci->num_ports; i++) {
+@@ -517,7 +534,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
+ }
+
+ hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed,
+- any_connected);
++ any_connected, rhsc_status);
+
+ done:
+ spin_unlock_irqrestore (&ohci->lock, flags);
+diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
+index 3a7bfe7..59bed3c 100644
+--- a/drivers/usb/host/uhci-hcd.c
++++ b/drivers/usb/host/uhci-hcd.c
+@@ -953,6 +953,7 @@ static int __init uhci_hcd_init(void)
+
+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "%s\n",
+ ignore_oc ? ", overcurrent ignored" : "");
++ set_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
+
+ if (usb_disabled())
+ return -ENODEV;
+@@ -988,6 +989,7 @@ debug_failed:
+
+ errbuf_failed:
+
++ clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
+ return retval;
+ }
+
+@@ -997,6 +999,7 @@ static void __exit uhci_hcd_cleanup(void)
+ kmem_cache_destroy(uhci_up_cachep);
+ debugfs_remove(uhci_debugfs_root);
+ kfree(errbuf);
++ clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
+ }
+
+ module_init(uhci_hcd_init);
+diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
+index 58b2b8f..4b9542b 100644
+--- a/drivers/usb/musb/Kconfig
++++ b/drivers/usb/musb/Kconfig
+@@ -33,10 +33,6 @@ config USB_MUSB_SOC
+ default y if ARCH_DAVINCI
+ default y if ARCH_OMAP2430
+ default y if ARCH_OMAP34XX
+- help
+- Use a static <asm/arch/hdrc_cnf.h> file to describe how the
+- controller is configured (endpoints, mechanisms, etc) on the
+- current iteration of a given system-on-chip.
+
+ comment "DaVinci 644x USB support"
+ depends on USB_MUSB_HDRC && ARCH_DAVINCI
+diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h
+index fc5216b..729b407 100644
+--- a/drivers/usb/musb/cppi_dma.h
++++ b/drivers/usb/musb/cppi_dma.h
+@@ -119,8 +119,8 @@ struct cppi {
+ void __iomem *mregs; /* Mentor regs */
+ void __iomem *tibase; /* TI/CPPI regs */
+
+- struct cppi_channel tx[MUSB_C_NUM_EPT - 1];
+- struct cppi_channel rx[MUSB_C_NUM_EPR - 1];
++ struct cppi_channel tx[4];
++ struct cppi_channel rx[4];
+
+ struct dma_pool *pool;
+
+diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
+index 75baf18..dfb3bcb 100644
+--- a/drivers/usb/musb/davinci.c
++++ b/drivers/usb/musb/davinci.c
+@@ -30,6 +30,7 @@
+ #include <linux/delay.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
++#include <linux/gpio.h>
+
+ #include <asm/arch/hardware.h>
+ #include <asm/arch/memory.h>
+@@ -39,7 +40,7 @@
+ #include "musb_core.h"
+
+ #ifdef CONFIG_MACH_DAVINCI_EVM
+-#include <asm/arch/i2c-client.h>
++#define GPIO_nVBUS_DRV 87
+ #endif
+
+ #include "davinci.h"
+@@ -138,7 +139,6 @@ static int vbus_state = -1;
+ /* VBUS SWITCHING IS BOARD-SPECIFIC */
+
+ #ifdef CONFIG_MACH_DAVINCI_EVM
+-#ifndef CONFIG_MACH_DAVINCI_EVM_OTG
+
+ /* I2C operations are always synchronous, and require a task context.
+ * With unloaded systems, using the shared workqueue seems to suffice
+@@ -146,12 +146,11 @@ static int vbus_state = -1;
+ */
+ static void evm_deferred_drvvbus(struct work_struct *ignored)
+ {
+- davinci_i2c_expander_op(0x3a, USB_DRVVBUS, vbus_state);
++ gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
+ vbus_state = !vbus_state;
+ }
+ static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
+
+-#endif /* modified board */
+ #endif /* EVM */
+
+ static void davinci_source_power(struct musb *musb, int is_on, int immediate)
+@@ -165,21 +164,10 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate)
+
+ #ifdef CONFIG_MACH_DAVINCI_EVM
+ if (machine_is_davinci_evm()) {
+-#ifdef CONFIG_MACH_DAVINCI_EVM_OTG
+- /* modified EVM board switching VBUS with GPIO(6) not I2C
+- * NOTE: PINMUX0.RGB888 (bit23) must be clear
+- */
+- if (is_on)
+- gpio_set(GPIO(6));
+- else
+- gpio_clear(GPIO(6));
+- immediate = 1;
+-#else
+ if (immediate)
+- davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on);
++ gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
+ else
+ schedule_work(&evm_vbus_work);
+-#endif
+ }
+ #endif
+ if (immediate)
+diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
+index 128e949..5c5bc1a 100644
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -82,9 +82,9 @@
+ /*
+ * This gets many kinds of configuration information:
+ * - Kconfig for everything user-configurable
+- * - <asm/arch/hdrc_cnf.h> for SOC or family details
+ * - platform_device for addressing, irq, and platform_data
+ * - platform_data is mostly for board-specific informarion
++ * (plus recentrly, SOC or family details)
+ *
+ * Most of the conditional compilation will (someday) vanish.
+ */
+@@ -974,9 +974,9 @@ static void musb_shutdown(struct platform_device *pdev)
+ /*
+ * The silicon either has hard-wired endpoint configurations, or else
+ * "dynamic fifo" sizing. The driver has support for both, though at this
+- * writing only the dynamic sizing is very well tested. We use normal
+- * idioms to so both modes are compile-tested, but dead code elimination
+- * leaves only the relevant one in the object file.
++ * writing only the dynamic sizing is very well tested. Since we switched
++ * away from compile-time hardware parameters, we can no longer rely on
++ * dead code elimination to leave only the relevant one in the object file.
+ *
+ * We don't currently use dynamic fifo setup capability to do anything
+ * more than selecting one of a bunch of predefined configurations.
+diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
+index 8b4be01..13205fe 100644
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -108,7 +108,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
+ /*
+ * Clear TX fifo. Needed to avoid BABBLE errors.
+ */
+-static inline void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
++static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
+ {
+ void __iomem *epio = ep->regs;
+ u16 csr;
+@@ -436,7 +436,7 @@ musb_advance_schedule(struct musb *musb, struct urb *urb,
+ }
+ }
+
+-static inline u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr)
++static u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr)
+ {
+ /* we don't want fifo to fill itself again;
+ * ignore dma (various models),
+@@ -1005,7 +1005,7 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
+
+ /*
+ * Handle default endpoint interrupt as host. Only called in IRQ time
+- * from the LinuxIsr() interrupt service routine.
++ * from musb_interrupt().
+ *
+ * called with controller irqlocked
+ */
+diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
+index 9cbff84..038ea62 100644
+--- a/drivers/video/console/fbcon.c
++++ b/drivers/video/console/fbcon.c
+@@ -2996,8 +2996,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
+ p = &fb_display[vc->vc_num];
+ set_blitting_type(vc, info);
+ var_to_display(p, &info->var, info);
+- cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres);
+- rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres);
++ cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
++ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols /= vc->vc_font.width;
+ rows /= vc->vc_font.height;
+ vc_resize(vc, cols, rows);
+diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
+index 18d3c84..cbdf97d 100644
+--- a/fs/xfs/linux-2.6/xfs_super.c
++++ b/fs/xfs/linux-2.6/xfs_super.c
+@@ -1323,7 +1323,7 @@ xfs_fs_remount(
+ "XFS: mount option \"%s\" not supported for remount\n", p);
+ return -EINVAL;
+ #else
+- return 0;
++ break;
+ #endif
+ }
+ }
+diff --git a/kernel/module.c b/kernel/module.c
+index 9db1191..d5fcd24 100644
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -1173,7 +1173,7 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
+ while (i-- > 0)
+ sysfs_remove_bin_file(notes_attrs->dir,
+ ¬es_attrs->attrs[i]);
+- kobject_del(notes_attrs->dir);
++ kobject_put(notes_attrs->dir);
+ }
+ kfree(notes_attrs);
+ }
+diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
+index 34fa8ed..48db9bb 100644
+--- a/net/mac80211/wext.c
++++ b/net/mac80211/wext.c
+@@ -804,7 +804,7 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
+ * configure it here */
+
+ if (local->ops->set_frag_threshold)
+- local->ops->set_frag_threshold(
++ return local->ops->set_frag_threshold(
+ local_to_hw(local),
+ local->fragmentation_threshold);
+
Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.4
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.4 Sun Nov 16 09:28:39 2008
@@ -0,0 +1,855 @@
+diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
+index 426e5d9..c44cd6d 100644
+--- a/arch/x86/kernel/acpi/sleep.c
++++ b/arch/x86/kernel/acpi/sleep.c
+@@ -10,6 +10,7 @@
+ #include <linux/dmi.h>
+ #include <linux/cpumask.h>
+ #include <asm/segment.h>
++#include <asm/desc.h>
+
+ #include "realmode/wakeup.h"
+ #include "sleep.h"
+@@ -98,6 +99,8 @@ int acpi_save_state_mem(void)
+ header->trampoline_segment = setup_trampoline() >> 4;
+ #ifdef CONFIG_SMP
+ stack_start.sp = temp_stack + 4096;
++ early_gdt_descr.address =
++ (unsigned long)get_cpu_gdt_table(smp_processor_id());
+ #endif
+ initial_code = (unsigned long)wakeup_long64;
+ saved_magic = 0x123456789abcdef0;
+diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
+index a69cc0f..bccd0ef 100644
+--- a/arch/x86/kernel/amd_iommu_init.c
++++ b/arch/x86/kernel/amd_iommu_init.c
+@@ -210,7 +210,7 @@ static void __init iommu_set_exclusion_range(struct amd_iommu *iommu)
+ /* Programs the physical address of the device table into the IOMMU hardware */
+ static void __init iommu_set_device_table(struct amd_iommu *iommu)
+ {
+- u32 entry;
++ u64 entry;
+
+ BUG_ON(iommu->mmio_base == NULL);
+
+diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
+index dba3cfb..ecb6ace 100644
+--- a/drivers/acpi/hardware/hwsleep.c
++++ b/drivers/acpi/hardware/hwsleep.c
+@@ -78,19 +78,17 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address)
+ return_ACPI_STATUS(status);
+ }
+
+- /* Set the vector */
++ /*
++ * According to the ACPI specification 2.0c and later, the 64-bit
++ * waking vector should be cleared and the 32-bit waking vector should
++ * be used, unless we want the wake-up code to be called by the BIOS in
++ * Protected Mode. Some systems (for example HP dv5-1004nr) are known
++ * to fail to resume if the 64-bit vector is used.
++ */
++ if (facs->version >= 1)
++ facs->xfirmware_waking_vector = 0;
+
+- if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
+- /*
+- * ACPI 1.0 FACS or short table or optional X_ field is zero
+- */
+- facs->firmware_waking_vector = (u32) physical_address;
+- } else {
+- /*
+- * ACPI 2.0 FACS with valid X_ field
+- */
+- facs->xfirmware_waking_vector = physical_address;
+- }
++ facs->firmware_waking_vector = (u32)physical_address;
+
+ return_ACPI_STATUS(AE_OK);
+ }
+@@ -134,20 +132,7 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
+ }
+
+ /* Get the vector */
+-
+- if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
+- /*
+- * ACPI 1.0 FACS or short table or optional X_ field is zero
+- */
+- *physical_address =
+- (acpi_physical_address) facs->firmware_waking_vector;
+- } else {
+- /*
+- * ACPI 2.0 FACS with valid X_ field
+- */
+- *physical_address =
+- (acpi_physical_address) facs->xfirmware_waking_vector;
+- }
++ *physical_address = (acpi_physical_address)facs->firmware_waking_vector;
+
+ return_ACPI_STATUS(AE_OK);
+ }
+diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
+index d13194a..4751909 100644
+--- a/drivers/acpi/sleep/main.c
++++ b/drivers/acpi/sleep/main.c
+@@ -200,6 +200,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
+ break;
+ }
+
++ /* If ACPI is not enabled by the BIOS, we need to enable it here. */
++ acpi_enable();
+ /* Reprogram control registers and execute _BFS */
+ acpi_leave_sleep_state_prep(acpi_state);
+
+@@ -296,6 +298,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
+ },
+ },
++ {
++ .callback = init_old_suspend_ordering,
++ .ident = "HP xw4600 Workstation",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
++ },
++ },
+ {},
+ };
+ #endif /* CONFIG_SUSPEND */
+diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
+index fd64137..f2e4caf 100644
+--- a/drivers/char/hvc_console.c
++++ b/drivers/char/hvc_console.c
+@@ -367,13 +367,13 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
+ spin_lock_irqsave(&hp->lock, flags);
+
+ if (--hp->count == 0) {
+- if (hp->ops->notifier_del)
+- hp->ops->notifier_del(hp, hp->data);
+-
+ /* We are done with the tty pointer now. */
+ hp->tty = NULL;
+ spin_unlock_irqrestore(&hp->lock, flags);
+
++ if (hp->ops->notifier_del)
++ hp->ops->notifier_del(hp, hp->data);
++
+ /*
+ * Chain calls chars_in_buffer() and returns immediately if
+ * there is no buffered data otherwise sleeps on a wait queue
+@@ -416,11 +416,11 @@ static void hvc_hangup(struct tty_struct *tty)
+ hp->n_outbuf = 0;
+ hp->tty = NULL;
+
++ spin_unlock_irqrestore(&hp->lock, flags);
++
+ if (hp->ops->notifier_del)
+ hp->ops->notifier_del(hp, hp->data);
+
+- spin_unlock_irqrestore(&hp->lock, flags);
+-
+ while(temp_open_count) {
+ --temp_open_count;
+ kref_put(&hp->kref, destroy_hvc_struct);
+diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c
+index 0e024fe..887072f 100644
+--- a/drivers/edac/cell_edac.c
++++ b/drivers/edac/cell_edac.c
+@@ -142,7 +142,7 @@ static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci)
+ csrow->nr_pages = (r.end - r.start + 1) >> PAGE_SHIFT;
+ csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
+ csrow->mtype = MEM_XDR;
+- csrow->edac_mode = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
++ csrow->edac_mode = EDAC_SECDED;
+ dev_dbg(mci->dev,
+ "Initialized on node %d, chanmask=0x%x,"
+ " first_page=0x%lx, nr_pages=0x%x\n",
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index 8d29405..59f6ad8 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1020,7 +1020,7 @@ int gpio_get_value_cansleep(unsigned gpio)
+
+ might_sleep_if(extra_checks);
+ chip = gpio_to_chip(gpio);
+- return chip->get(chip, gpio - chip->base);
++ return chip->get ? chip->get(chip, gpio - chip->base) : 0;
+ }
+ EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);
+
+diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
+index 996802b..8f15353 100644
+--- a/drivers/md/dm-kcopyd.c
++++ b/drivers/md/dm-kcopyd.c
+@@ -268,6 +268,17 @@ static void push(struct list_head *jobs, struct kcopyd_job *job)
+ spin_unlock_irqrestore(&kc->job_lock, flags);
+ }
+
++
++static void push_head(struct list_head *jobs, struct kcopyd_job *job)
++{
++ unsigned long flags;
++ struct dm_kcopyd_client *kc = job->kc;
++
++ spin_lock_irqsave(&kc->job_lock, flags);
++ list_add(&job->list, jobs);
++ spin_unlock_irqrestore(&kc->job_lock, flags);
++}
++
+ /*
+ * These three functions process 1 item from the corresponding
+ * job list.
+@@ -398,7 +409,7 @@ static int process_jobs(struct list_head *jobs, struct dm_kcopyd_client *kc,
+ * We couldn't service this job ATM, so
+ * push this job back onto the list.
+ */
+- push(jobs, job);
++ push_head(jobs, job);
+ break;
+ }
+
+diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
+index 6e5528a..4ed9b7a 100644
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -824,8 +824,10 @@ static struct bio *put_pending_exception(struct dm_snap_pending_exception *pe)
+ * the bios for the original write to the origin.
+ */
+ if (primary_pe &&
+- atomic_dec_and_test(&primary_pe->ref_count))
++ atomic_dec_and_test(&primary_pe->ref_count)) {
+ origin_bios = bio_list_get(&primary_pe->origin_bios);
++ free_pending_exception(primary_pe);
++ }
+
+ /*
+ * Free the pe if it's not linked to an origin write or if
+@@ -834,12 +836,6 @@ static struct bio *put_pending_exception(struct dm_snap_pending_exception *pe)
+ if (!primary_pe || primary_pe != pe)
+ free_pending_exception(pe);
+
+- /*
+- * Free the primary pe if nothing references it.
+- */
+- if (primary_pe && !atomic_read(&primary_pe->ref_count))
+- free_pending_exception(primary_pe);
+-
+ return origin_bios;
+ }
+
+diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+index f051c6a..7412258 100644
+--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
++++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+@@ -60,7 +60,6 @@ static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
+ static DEFINE_MUTEX(pvr2_unit_mtx);
+
+ static int ctlchg;
+-static int initusbreset = 1;
+ static int procreload;
+ static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
+ static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
+@@ -71,8 +70,6 @@ module_param(ctlchg, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
+ module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
+-module_param(initusbreset, int, S_IRUGO|S_IWUSR);
+-MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
+ module_param(procreload, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(procreload,
+ "Attempt init failure recovery with firmware reload");
+@@ -1698,9 +1695,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
+ }
+ hdw->fw1_state = FW1_STATE_OK;
+
+- if (initusbreset) {
+- pvr2_hdw_device_reset(hdw);
+- }
+ if (!pvr2_hdw_dev_ok(hdw)) return;
+
+ for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {
+diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
+index 54defec..87a68d2 100644
+--- a/drivers/pci/hotplug/cpqphp_core.c
++++ b/drivers/pci/hotplug/cpqphp_core.c
+@@ -435,7 +435,7 @@ static int ctrl_slot_setup(struct controller *ctrl,
+ slot->number, ctrl->slot_device_offset,
+ slot_number);
+ result = pci_hp_register(hotplug_slot,
+- ctrl->pci_dev->subordinate,
++ ctrl->pci_dev->bus,
+ slot->device);
+ if (result) {
+ err("pci_hp_register failed with error %d\n", result);
+diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
+index 6e2f130..d576d4c 100644
+--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
++++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
+@@ -590,6 +590,8 @@ static const struct scsi_dh_devlist rdac_dev_list[] = {
+ {"STK", "OPENstorage D280"},
+ {"SUN", "CSM200_R"},
+ {"SUN", "LCSM100_F"},
++ {"DELL", "MD3000"},
++ {"DELL", "MD3000i"},
+ {NULL, NULL},
+ };
+
+diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
+index 76fce44..3e86240 100644
+--- a/drivers/usb/atm/speedtch.c
++++ b/drivers/usb/atm/speedtch.c
+@@ -722,6 +722,16 @@ static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_de
+ flush_scheduled_work();
+ }
+
++static int speedtch_pre_reset(struct usb_interface *intf)
++{
++ return 0;
++}
++
++static int speedtch_post_reset(struct usb_interface *intf)
++{
++ return 0;
++}
++
+
+ /**********
+ ** USB **
+@@ -740,6 +750,8 @@ static struct usb_driver speedtch_usb_driver = {
+ .name = speedtch_driver_name,
+ .probe = speedtch_usb_probe,
+ .disconnect = usbatm_usb_disconnect,
++ .pre_reset = speedtch_pre_reset,
++ .post_reset = speedtch_post_reset,
+ .id_table = speedtch_usb_ids
+ };
+
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index c257453..d996a61 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -849,9 +849,10 @@ static void acm_write_buffers_free(struct acm *acm)
+ {
+ int i;
+ struct acm_wb *wb;
++ struct usb_device *usb_dev = interface_to_usbdev(acm->control);
+
+ for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
+- usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah);
++ usb_buffer_free(usb_dev, acm->writesize, wb->buf, wb->dmah);
+ }
+ }
+
+diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
+index 7e8e123..023a4e9 100644
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -42,6 +42,8 @@ static struct usb_device_id wdm_ids[] = {
+ { }
+ };
+
++MODULE_DEVICE_TABLE (usb, wdm_ids);
++
+ #define WDM_MINOR_BASE 176
+
+
+diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
+index 5a7fa6f..9f42cb8 100644
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -1609,7 +1609,8 @@ int usb_external_resume_device(struct usb_device *udev)
+ status = usb_resume_both(udev);
+ udev->last_busy = jiffies;
+ usb_pm_unlock(udev);
+- do_unbind_rebind(udev, DO_REBIND);
++ if (status == 0)
++ do_unbind_rebind(udev, DO_REBIND);
+
+ /* Now that the device is awake, we can start trying to autosuspend
+ * it again. */
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index d999638..875de9a 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -3424,7 +3424,7 @@ int usb_reset_device(struct usb_device *udev)
+ USB_INTERFACE_BOUND)
+ rebind = 1;
+ }
+- if (rebind)
++ if (ret == 0 && rebind)
+ usb_rebind_intf(cintf);
+ }
+ }
+diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
+index 765adf1..58d5729 100644
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -762,14 +762,15 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
+ rc));
+ return rc;
+ }
++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
+ }
+
+ while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
+ (rc == 0) && !cifsFile->srch_inf.endOfSearch) {
+ cFYI(1, ("calling findnext2"));
+- cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
+ rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
+ &cifsFile->srch_inf);
++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
+ if (rc)
+ return -ENOENT;
+ }
+diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
+index a78c6b4..11a49ce 100644
+--- a/fs/ext2/dir.c
++++ b/fs/ext2/dir.c
+@@ -103,7 +103,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
+ return err;
+ }
+
+-static void ext2_check_page(struct page *page)
++static void ext2_check_page(struct page *page, int quiet)
+ {
+ struct inode *dir = page->mapping->host;
+ struct super_block *sb = dir->i_sb;
+@@ -146,10 +146,10 @@ out:
+ /* Too bad, we had an error */
+
+ Ebadsize:
+- ext2_error(sb, "ext2_check_page",
+- "size of directory #%lu is not a multiple of chunk size",
+- dir->i_ino
+- );
++ if (!quiet)
++ ext2_error(sb, __func__,
++ "size of directory #%lu is not a multiple "
++ "of chunk size", dir->i_ino);
+ goto fail;
+ Eshort:
+ error = "rec_len is smaller than minimal";
+@@ -166,32 +166,36 @@ Espan:
+ Einumber:
+ error = "inode out of bounds";
+ bad_entry:
+- ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
+- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+- dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+- (unsigned long) le32_to_cpu(p->inode),
+- rec_len, p->name_len);
++ if (!quiet)
++ ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
++ "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
++ dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
++ (unsigned long) le32_to_cpu(p->inode),
++ rec_len, p->name_len);
+ goto fail;
+ Eend:
+- p = (ext2_dirent *)(kaddr + offs);
+- ext2_error (sb, "ext2_check_page",
+- "entry in directory #%lu spans the page boundary"
+- "offset=%lu, inode=%lu",
+- dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+- (unsigned long) le32_to_cpu(p->inode));
++ if (!quiet) {
++ p = (ext2_dirent *)(kaddr + offs);
++ ext2_error(sb, "ext2_check_page",
++ "entry in directory #%lu spans the page boundary"
++ "offset=%lu, inode=%lu",
++ dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
++ (unsigned long) le32_to_cpu(p->inode));
++ }
+ fail:
+ SetPageChecked(page);
+ SetPageError(page);
+ }
+
+-static struct page * ext2_get_page(struct inode *dir, unsigned long n)
++static struct page * ext2_get_page(struct inode *dir, unsigned long n,
++ int quiet)
+ {
+ struct address_space *mapping = dir->i_mapping;
+ struct page *page = read_mapping_page(mapping, n, NULL);
+ if (!IS_ERR(page)) {
+ kmap(page);
+ if (!PageChecked(page))
+- ext2_check_page(page);
++ ext2_check_page(page, quiet);
+ if (PageError(page))
+ goto fail;
+ }
+@@ -292,7 +296,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
+ for ( ; n < npages; n++, offset = 0) {
+ char *kaddr, *limit;
+ ext2_dirent *de;
+- struct page *page = ext2_get_page(inode, n);
++ struct page *page = ext2_get_page(inode, n, 0);
+
+ if (IS_ERR(page)) {
+ ext2_error(sb, __func__,
+@@ -361,6 +365,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
+ struct page *page = NULL;
+ struct ext2_inode_info *ei = EXT2_I(dir);
+ ext2_dirent * de;
++ int dir_has_error = 0;
+
+ if (npages == 0)
+ goto out;
+@@ -374,7 +379,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
+ n = start;
+ do {
+ char *kaddr;
+- page = ext2_get_page(dir, n);
++ page = ext2_get_page(dir, n, dir_has_error);
+ if (!IS_ERR(page)) {
+ kaddr = page_address(page);
+ de = (ext2_dirent *) kaddr;
+@@ -391,7 +396,9 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
+ de = ext2_next_entry(de);
+ }
+ ext2_put_page(page);
+- }
++ } else
++ dir_has_error = 1;
++
+ if (++n >= npages)
+ n = 0;
+ /* next page is past the blocks we've got */
+@@ -414,7 +421,7 @@ found:
+
+ struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
+ {
+- struct page *page = ext2_get_page(dir, 0);
++ struct page *page = ext2_get_page(dir, 0, 0);
+ ext2_dirent *de = NULL;
+
+ if (!IS_ERR(page)) {
+@@ -487,7 +494,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
+ for (n = 0; n <= npages; n++) {
+ char *dir_end;
+
+- page = ext2_get_page(dir, n);
++ page = ext2_get_page(dir, n, 0);
+ err = PTR_ERR(page);
+ if (IS_ERR(page))
+ goto out;
+@@ -655,14 +662,17 @@ int ext2_empty_dir (struct inode * inode)
+ {
+ struct page *page = NULL;
+ unsigned long i, npages = dir_pages(inode);
++ int dir_has_error = 0;
+
+ for (i = 0; i < npages; i++) {
+ char *kaddr;
+ ext2_dirent * de;
+- page = ext2_get_page(inode, i);
++ page = ext2_get_page(inode, i, dir_has_error);
+
+- if (IS_ERR(page))
++ if (IS_ERR(page)) {
++ dir_has_error = 1;
+ continue;
++ }
+
+ kaddr = page_address(page);
+ de = (ext2_dirent *)kaddr;
+diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
+index 2eea96e..1b80f1c 100644
+--- a/fs/ext3/dir.c
++++ b/fs/ext3/dir.c
+@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * filp,
+ int err;
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ int ret = 0;
++ int dir_has_error = 0;
+
+ sb = inode->i_sb;
+
+@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * filp,
+ * of recovering data when there's a bad sector
+ */
+ if (!bh) {
+- ext3_error (sb, "ext3_readdir",
+- "directory #%lu contains a hole at offset %lu",
+- inode->i_ino, (unsigned long)filp->f_pos);
++ if (!dir_has_error) {
++ ext3_error(sb, __func__, "directory #%lu "
++ "contains a hole at offset %lld",
++ inode->i_ino, filp->f_pos);
++ dir_has_error = 1;
++ }
+ /* corrupt size? Maybe no more blocks to read */
+ if (filp->f_pos > inode->i_blocks << 9)
+ break;
+diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
+index ec8e33b..d1d6487 100644
+--- a/fs/ext4/dir.c
++++ b/fs/ext4/dir.c
+@@ -102,6 +102,7 @@ static int ext4_readdir(struct file * filp,
+ int err;
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ int ret = 0;
++ int dir_has_error = 0;
+
+ sb = inode->i_sb;
+
+@@ -148,9 +149,13 @@ static int ext4_readdir(struct file * filp,
+ * of recovering data when there's a bad sector
+ */
+ if (!bh) {
+- ext4_error (sb, "ext4_readdir",
+- "directory #%lu contains a hole at offset %lu",
+- inode->i_ino, (unsigned long)filp->f_pos);
++ if (!dir_has_error) {
++ ext4_error(sb, __func__, "directory #%lu "
++ "contains a hole at offset %Lu",
++ inode->i_ino,
++ (unsigned long long) filp->f_pos);
++ dir_has_error = 1;
++ }
+ /* corrupt size? Maybe no more blocks to read */
+ if (filp->f_pos > inode->i_blocks << 9)
+ break;
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 73d1891..f3ada04 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -198,11 +198,8 @@ static int do_maps_open(struct inode *inode, struct file *file,
+ return ret;
+ }
+
+-static int show_map(struct seq_file *m, void *v)
++static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
+ {
+- struct proc_maps_private *priv = m->private;
+- struct task_struct *task = priv->task;
+- struct vm_area_struct *vma = v;
+ struct mm_struct *mm = vma->vm_mm;
+ struct file *file = vma->vm_file;
+ int flags = vma->vm_flags;
+@@ -210,9 +207,6 @@ static int show_map(struct seq_file *m, void *v)
+ dev_t dev = 0;
+ int len;
+
+- if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
+- return -EACCES;
+-
+ if (file) {
+ struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
+ dev = inode->i_sb->s_dev;
+@@ -257,6 +251,18 @@ static int show_map(struct seq_file *m, void *v)
+ }
+ }
+ seq_putc(m, '\n');
++}
++
++static int show_map(struct seq_file *m, void *v)
++{
++ struct vm_area_struct *vma = v;
++ struct proc_maps_private *priv = m->private;
++ struct task_struct *task = priv->task;
++
++ if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
++ return -EACCES;
++
++ show_map_vma(m, vma);
+
+ if (m->count < m->size) /* vma is copied successfully */
+ m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
+@@ -367,23 +373,25 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
+
+ static int show_smap(struct seq_file *m, void *v)
+ {
++ struct proc_maps_private *priv = m->private;
++ struct task_struct *task = priv->task;
+ struct vm_area_struct *vma = v;
+ struct mem_size_stats mss;
+- int ret;
+ struct mm_walk smaps_walk = {
+ .pmd_entry = smaps_pte_range,
+ .mm = vma->vm_mm,
+ .private = &mss,
+ };
+
++ if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
++ return -EACCES;
++
+ memset(&mss, 0, sizeof mss);
+ mss.vma = vma;
+ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
+ walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
+
+- ret = show_map(m, v);
+- if (ret)
+- return ret;
++ show_map_vma(m, vma);
+
+ seq_printf(m,
+ "Size: %8lu kB\n"
+@@ -405,7 +413,9 @@ static int show_smap(struct seq_file *m, void *v)
+ mss.referenced >> 10,
+ mss.swap >> 10);
+
+- return ret;
++ if (m->count < m->size) /* vma is copied successfully */
++ m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0;
++ return 0;
+ }
+
+ static const struct seq_operations proc_pid_smaps_op = {
+diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h
+index 8385d43..81365b3 100644
+--- a/kernel/sched_stats.h
++++ b/kernel/sched_stats.h
+@@ -9,7 +9,7 @@
+ static int show_schedstat(struct seq_file *seq, void *v)
+ {
+ int cpu;
+- int mask_len = NR_CPUS/32 * 9;
++ int mask_len = (NR_CPUS/32 + 1) * 9;
+ char *mask_str = kmalloc(mask_len, GFP_KERNEL);
+
+ if (mask_str == NULL)
+diff --git a/mm/rmap.c b/mm/rmap.c
+index 0383acf..e8d639b 100644
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -55,7 +55,33 @@
+
+ struct kmem_cache *anon_vma_cachep;
+
+-/* This must be called under the mmap_sem. */
++/**
++ * anon_vma_prepare - attach an anon_vma to a memory region
++ * @vma: the memory region in question
++ *
++ * This makes sure the memory mapping described by 'vma' has
++ * an 'anon_vma' attached to it, so that we can associate the
++ * anonymous pages mapped into it with that anon_vma.
++ *
++ * The common case will be that we already have one, but if
++ * if not we either need to find an adjacent mapping that we
++ * can re-use the anon_vma from (very common when the only
++ * reason for splitting a vma has been mprotect()), or we
++ * allocate a new one.
++ *
++ * Anon-vma allocations are very subtle, because we may have
++ * optimistically looked up an anon_vma in page_lock_anon_vma()
++ * and that may actually touch the spinlock even in the newly
++ * allocated vma (it depends on RCU to make sure that the
++ * anon_vma isn't actually destroyed).
++ *
++ * As a result, we need to do proper anon_vma locking even
++ * for the new allocation. At the same time, we do not want
++ * to do any locking for the common case of already having
++ * an anon_vma.
++ *
++ * This must be called with the mmap_sem held for reading.
++ */
+ int anon_vma_prepare(struct vm_area_struct *vma)
+ {
+ struct anon_vma *anon_vma = vma->anon_vma;
+@@ -63,20 +89,17 @@ int anon_vma_prepare(struct vm_area_struct *vma)
+ might_sleep();
+ if (unlikely(!anon_vma)) {
+ struct mm_struct *mm = vma->vm_mm;
+- struct anon_vma *allocated, *locked;
++ struct anon_vma *allocated;
+
+ anon_vma = find_mergeable_anon_vma(vma);
+- if (anon_vma) {
+- allocated = NULL;
+- locked = anon_vma;
+- spin_lock(&locked->lock);
+- } else {
++ allocated = NULL;
++ if (!anon_vma) {
+ anon_vma = anon_vma_alloc();
+ if (unlikely(!anon_vma))
+ return -ENOMEM;
+ allocated = anon_vma;
+- locked = NULL;
+ }
++ spin_lock(&anon_vma->lock);
+
+ /* page_table_lock to protect against threads */
+ spin_lock(&mm->page_table_lock);
+@@ -87,8 +110,7 @@ int anon_vma_prepare(struct vm_area_struct *vma)
+ }
+ spin_unlock(&mm->page_table_lock);
+
+- if (locked)
+- spin_unlock(&locked->lock);
++ spin_unlock(&anon_vma->lock);
+ if (unlikely(allocated))
+ anon_vma_free(allocated);
+ }
+diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+index 5a955c4..7eb0b61 100644
+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+@@ -150,10 +150,12 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE)
+ /* Previously seen (loopback)? Ignore. Do this before
+ fragment check. */
+ if (skb->nfct)
+ return NF_ACCEPT;
++#endif
+
+ /* Gather fragments. */
+ if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
+diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
+index ffeaffc..8303e4b 100644
+--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
++++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
+@@ -742,6 +742,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx,
+ *obj = kmalloc(sizeof(struct snmp_object) + len,
+ GFP_ATOMIC);
+ if (*obj == NULL) {
++ kfree(p);
+ kfree(id);
+ if (net_ratelimit())
+ printk("OOM in bsalg (%d)\n", __LINE__);
+diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
+index c63e933..4b5741b 100644
+--- a/net/netfilter/xt_iprange.c
++++ b/net/netfilter/xt_iprange.c
+@@ -67,7 +67,7 @@ iprange_mt4(const struct sk_buff *skb, const struct net_device *in,
+ if (info->flags & IPRANGE_SRC) {
+ m = ntohl(iph->saddr) < ntohl(info->src_min.ip);
+ m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
+- m ^= info->flags & IPRANGE_SRC_INV;
++ m ^= !!(info->flags & IPRANGE_SRC_INV);
+ if (m) {
+ pr_debug("src IP " NIPQUAD_FMT " NOT in range %s"
+ NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
+@@ -81,7 +81,7 @@ iprange_mt4(const struct sk_buff *skb, const struct net_device *in,
+ if (info->flags & IPRANGE_DST) {
+ m = ntohl(iph->daddr) < ntohl(info->dst_min.ip);
+ m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
+- m ^= info->flags & IPRANGE_DST_INV;
++ m ^= !!(info->flags & IPRANGE_DST_INV);
+ if (m) {
+ pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s"
+ NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
+@@ -123,14 +123,14 @@ iprange_mt6(const struct sk_buff *skb, const struct net_device *in,
+ if (info->flags & IPRANGE_SRC) {
+ m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0;
+ m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0;
+- m ^= info->flags & IPRANGE_SRC_INV;
++ m ^= !!(info->flags & IPRANGE_SRC_INV);
+ if (m)
+ return false;
+ }
+ if (info->flags & IPRANGE_DST) {
+ m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0;
+ m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0;
+- m ^= info->flags & IPRANGE_DST_INV;
++ m ^= !!(info->flags & IPRANGE_DST_INV);
+ if (m)
+ return false;
+ }
Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.5
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.5 Sun Nov 16 09:28:39 2008
@@ -0,0 +1,2543 @@
+diff --git a/Documentation/i2c/busses/i2c-sis96x b/Documentation/i2c/busses/i2c-sis96x
+index 266481f..70e6a0c 100644
+--- a/Documentation/i2c/busses/i2c-sis96x
++++ b/Documentation/i2c/busses/i2c-sis96x
+@@ -42,7 +42,7 @@ I suspect that this driver could be made to work for the following SiS
+ chipsets as well: 635, and 635T. If anyone owns a board with those chips
+ AND is willing to risk crashing & burning an otherwise well-behaved kernel
+ in the name of progress... please contact me at <mhoffman at lightlink.com> or
+-via the project's mailing list: <i2c at lm-sensors.org>. Please send bug
++via the linux-i2c mailing list: <linux-i2c at vger.kernel.org>. Please send bug
+ reports and/or success stories as well.
+
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 8dae455..ff24d01 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -360,7 +360,7 @@ S: Maintained
+ ALI1563 I2C DRIVER
+ P: Rudolf Marek
+ M: r.marek at assembler.cz
+-L: i2c at lm-sensors.org
++L: linux-i2c at vger.kernel.org
+ S: Maintained
+
+ ALPHA PORT
+@@ -1681,7 +1681,7 @@ FREESCALE I2C CPM DRIVER
+ P: Jochen Friedrich
+ M: jochen at scram.de
+ L: linuxppc-dev at ozlabs.org
+-L: i2c at lm-sensors.org
++L: linux-i2c at vger.kernel.org
+ S: Maintained
+
+ FREESCALE SOC FS_ENET DRIVER
+@@ -1982,7 +1982,7 @@ S: Maintained
+ I2C/SMBUS STUB DRIVER
+ P: Mark M. Hoffman
+ M: mhoffman at lightlink.com
+-L: i2c at lm-sensors.org
++L: linux-i2c at vger.kernel.org
+ S: Maintained
+
+ I2C SUBSYSTEM
+@@ -1990,14 +1990,14 @@ P: Jean Delvare (PC drivers, core)
+ M: khali at linux-fr.org
+ P: Ben Dooks (embedded platforms)
+ M: ben-linux at fluff.org
+-L: i2c at lm-sensors.org
++L: linux-i2c at vger.kernel.org
+ T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/
+ S: Maintained
+
+ I2C-TINY-USB DRIVER
+ P: Till Harbaum
+ M: till at harbaum.org
+-L: i2c at lm-sensors.org
++L: linux-i2c at vger.kernel.org
+ T: http://www.harbaum.org/till/i2c_tiny_usb
+ S: Maintained
+
+@@ -3070,7 +3070,7 @@ S: Maintained
+ OPENCORES I2C BUS DRIVER
+ P: Peter Korsgaard
+ M: jacmet at sunsite.dk
+-L: i2c at lm-sensors.org
++L: linux-i2c at vger.kernel.org
+ S: Maintained
+
+ ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
+@@ -3144,7 +3144,7 @@ S: Maintained
+ PA SEMI SMBUS DRIVER
+ P: Olof Johansson
+ M: olof at lixom.net
+-L: i2c at lm-sensors.org
++L: linux-i2c at vger.kernel.org
+ S: Maintained
+
+ PARALLEL PORT SUPPORT
+@@ -3280,7 +3280,7 @@ S: Maintained
+ PNXxxxx I2C DRIVER
+ P: Vitaly Wool
+ M: vitalywool at gmail.com
+-L: i2c at lm-sensors.org
++L: linux-i2c at vger.kernel.org
+ S: Maintained
+
+ PPP PROTOCOL DRIVERS AND COMPRESSORS
+@@ -3725,7 +3725,7 @@ S: Maintained
+ SIS 96X I2C/SMBUS DRIVER
+ P: Mark M. Hoffman
+ M: mhoffman at lightlink.com
+-L: i2c at lm-sensors.org
++L: linux-i2c at vger.kernel.org
+ S: Maintained
+
+ SIS FRAMEBUFFER DRIVER
+@@ -4445,7 +4445,7 @@ S: Maintained
+ VIAPRO SMBUS DRIVER
+ P: Jean Delvare
+ M: khali at linux-fr.org
+-L: i2c at lm-sensors.org
++L: linux-i2c at vger.kernel.org
+ S: Maintained
+
+ VIA VELOCITY NETWORK DRIVER
+diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig
+index 6fc4c21..d0846ec 100644
+--- a/arch/powerpc/configs/linkstation_defconfig
++++ b/arch/powerpc/configs/linkstation_defconfig
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.27-rc4
+-# Thu Aug 21 00:52:05 2008
++# Linux kernel version: 2.6.27
++# Fri Oct 24 00:42:39 2008
+ #
+ # CONFIG_PPC64 is not set
+
+@@ -934,7 +934,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ # CONFIG_SERIAL_JSM is not set
+-CONFIG_SERIAL_OF_PLATFORM=y
++# CONFIG_SERIAL_OF_PLATFORM is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_LEGACY_PTYS=y
+ CONFIG_LEGACY_PTY_COUNT=256
+@@ -1211,7 +1211,6 @@ CONFIG_USB_STORAGE=m
+ # CONFIG_USB_STORAGE_ALAUDA is not set
+ # CONFIG_USB_STORAGE_ONETOUCH is not set
+ # CONFIG_USB_STORAGE_KARMA is not set
+-# CONFIG_USB_STORAGE_SIERRA is not set
+ # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+ # CONFIG_USB_LIBUSUAL is not set
+
+diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
+index 8920eea..16319a5 100644
+--- a/arch/powerpc/mm/hash_utils_64.c
++++ b/arch/powerpc/mm/hash_utils_64.c
+@@ -381,8 +381,10 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node,
+ printk(KERN_INFO "Huge page(16GB) memory: "
+ "addr = 0x%lX size = 0x%lX pages = %d\n",
+ phys_addr, block_size, expected_pages);
+- lmb_reserve(phys_addr, block_size * expected_pages);
+- add_gpage(phys_addr, block_size, expected_pages);
++ if (phys_addr + (16 * GB) <= lmb_end_of_DRAM()) {
++ lmb_reserve(phys_addr, block_size * expected_pages);
++ add_gpage(phys_addr, block_size, expected_pages);
++ }
+ return 0;
+ }
+
+diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
+index d9a1813..b5ae97e 100644
+--- a/arch/powerpc/mm/numa.c
++++ b/arch/powerpc/mm/numa.c
+@@ -89,6 +89,48 @@ static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
+ return 0;
+ }
+
++/*
++ * get_active_region_work_fn - A helper function for get_node_active_region
++ * Returns datax set to the start_pfn and end_pfn if they contain
++ * the initial value of datax->start_pfn between them
++ * @start_pfn: start page(inclusive) of region to check
++ * @end_pfn: end page(exclusive) of region to check
++ * @datax: comes in with ->start_pfn set to value to search for and
++ * goes out with active range if it contains it
++ * Returns 1 if search value is in range else 0
++ */
++static int __init get_active_region_work_fn(unsigned long start_pfn,
++ unsigned long end_pfn, void *datax)
++{
++ struct node_active_region *data;
++ data = (struct node_active_region *)datax;
++
++ if (start_pfn <= data->start_pfn && end_pfn > data->start_pfn) {
++ data->start_pfn = start_pfn;
++ data->end_pfn = end_pfn;
++ return 1;
++ }
++ return 0;
++
++}
++
++/*
++ * get_node_active_region - Return active region containing start_pfn
++ * Active range returned is empty if none found.
++ * @start_pfn: The page to return the region for.
++ * @node_ar: Returned set to the active region containing start_pfn
++ */
++static void __init get_node_active_region(unsigned long start_pfn,
++ struct node_active_region *node_ar)
++{
++ int nid = early_pfn_to_nid(start_pfn);
++
++ node_ar->nid = nid;
++ node_ar->start_pfn = start_pfn;
++ node_ar->end_pfn = start_pfn;
++ work_with_active_regions(nid, get_active_region_work_fn, node_ar);
++}
++
+ static void __cpuinit map_cpu_to_node(int cpu, int node)
+ {
+ numa_cpu_lookup_table[cpu] = node;
+@@ -837,38 +879,53 @@ void __init do_init_bootmem(void)
+ start_pfn, end_pfn);
+
+ free_bootmem_with_active_regions(nid, end_pfn);
++ }
+
+- /* Mark reserved regions on this node */
+- for (i = 0; i < lmb.reserved.cnt; i++) {
+- unsigned long physbase = lmb.reserved.region[i].base;
+- unsigned long size = lmb.reserved.region[i].size;
+- unsigned long start_paddr = start_pfn << PAGE_SHIFT;
+- unsigned long end_paddr = end_pfn << PAGE_SHIFT;
+-
+- if (early_pfn_to_nid(physbase >> PAGE_SHIFT) != nid &&
+- early_pfn_to_nid((physbase+size-1) >> PAGE_SHIFT) != nid)
+- continue;
+-
+- if (physbase < end_paddr &&
+- (physbase+size) > start_paddr) {
+- /* overlaps */
+- if (physbase < start_paddr) {
+- size -= start_paddr - physbase;
+- physbase = start_paddr;
+- }
+-
+- if (size > end_paddr - physbase)
+- size = end_paddr - physbase;
+-
+- dbg("reserve_bootmem %lx %lx\n", physbase,
+- size);
+- reserve_bootmem_node(NODE_DATA(nid), physbase,
+- size, BOOTMEM_DEFAULT);
+- }
++ /* Mark reserved regions */
++ for (i = 0; i < lmb.reserved.cnt; i++) {
++ unsigned long physbase = lmb.reserved.region[i].base;
++ unsigned long size = lmb.reserved.region[i].size;
++ unsigned long start_pfn = physbase >> PAGE_SHIFT;
++ unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT);
++ struct node_active_region node_ar;
++
++ get_node_active_region(start_pfn, &node_ar);
++ while (start_pfn < end_pfn &&
++ node_ar.start_pfn < node_ar.end_pfn) {
++ unsigned long reserve_size = size;
++ /*
++ * if reserved region extends past active region
++ * then trim size to active region
++ */
++ if (end_pfn > node_ar.end_pfn)
++ reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
++ - (start_pfn << PAGE_SHIFT);
++ dbg("reserve_bootmem %lx %lx nid=%d\n", physbase,
++ reserve_size, node_ar.nid);
++ reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase,
++ reserve_size, BOOTMEM_DEFAULT);
++ /*
++ * if reserved region is contained in the active region
++ * then done.
++ */
++ if (end_pfn <= node_ar.end_pfn)
++ break;
++
++ /*
++ * reserved region extends past the active region
++ * get next active region that contains this
++ * reserved region
++ */
++ start_pfn = node_ar.end_pfn;
++ physbase = start_pfn << PAGE_SHIFT;
++ size = size - reserve_size;
++ get_node_active_region(start_pfn, &node_ar);
+ }
+
+- sparse_memory_present_with_active_regions(nid);
+ }
++
++ for_each_online_node(nid)
++ sparse_memory_present_with_active_regions(nid);
+ }
+
+ void __init paging_init(void)
+diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c
+index eb5d74e..2ca7be6 100644
+--- a/arch/powerpc/platforms/embedded6xx/linkstation.c
++++ b/arch/powerpc/platforms/embedded6xx/linkstation.c
+@@ -13,6 +13,7 @@
+ #include <linux/kernel.h>
+ #include <linux/initrd.h>
+ #include <linux/mtd/physmap.h>
++#include <linux/of_platform.h>
+
+ #include <asm/time.h>
+ #include <asm/prom.h>
+@@ -54,6 +55,19 @@ static struct mtd_partition linkstation_physmap_partitions[] = {
+ },
+ };
+
++static __initdata struct of_device_id of_bus_ids[] = {
++ { .type = "soc", },
++ { .compatible = "simple-bus", },
++ {},
++};
++
++static int __init declare_of_platform_devices(void)
++{
++ of_platform_bus_probe(NULL, of_bus_ids, NULL);
++ return 0;
++}
++machine_device_initcall(linkstation, declare_of_platform_devices);
++
+ static int __init linkstation_add_bridge(struct device_node *dev)
+ {
+ #ifdef CONFIG_PCI
+diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
+index 00b9b4d..fdfca4f 100644
+--- 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 sys_device *dev,
+ 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 sys_device *dev,
+ 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) {
+diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
+index 704a3af..83abd5a 100644
+--- a/arch/sparc64/kernel/trampoline.S
++++ b/arch/sparc64/kernel/trampoline.S
+@@ -328,6 +328,12 @@ after_lock_tlb:
+
+ wrpr %g0, 0, %wstate
+
++ sethi %hi(prom_entry_lock), %g2
++1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
++ membar #StoreLoad | #StoreStore
++ brnz,pn %g1, 1b
++ nop
++
+ /* As a hack, put &init_thread_union into %g6.
+ * prom_world() loads from here to restore the %asi
+ * register.
+@@ -337,7 +343,7 @@ after_lock_tlb:
+
+ sethi %hi(is_sun4v), %o0
+ lduw [%o0 + %lo(is_sun4v)], %o0
+- brz,pt %o0, 1f
++ brz,pt %o0, 2f
+ nop
+
+ TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
+@@ -369,10 +375,10 @@ after_lock_tlb:
+ call %o1
+ add %sp, (2047 + 128), %o0
+
+- ba,pt %xcc, 2f
++ ba,pt %xcc, 3f
+ nop
+
+-1: sethi %hi(sparc64_ttable_tl0), %o0
++2: sethi %hi(sparc64_ttable_tl0), %o0
+ set prom_set_trap_table_name, %g2
+ stx %g2, [%sp + 2047 + 128 + 0x00]
+ mov 1, %g2
+@@ -386,7 +392,11 @@ after_lock_tlb:
+ call %o1
+ add %sp, (2047 + 128), %o0
+
+-2: ldx [%l0], %g6
++3: sethi %hi(prom_entry_lock), %g2
++ stb %g0, [%g2 + %lo(prom_entry_lock)]
++ membar #StoreStore | #StoreLoad
++
++ ldx [%l0], %g6
+ ldx [%g6 + TI_TASK], %g4
+
+ mov 1, %g5
+diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
+index e12e0e4..5a7c539 100644
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -729,12 +729,12 @@ unsigned long get_wchan(struct task_struct *p)
+ if (!p || p == current || p->state==TASK_RUNNING)
+ return 0;
+ stack = (unsigned long)task_stack_page(p);
+- if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)
++ if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
+ return 0;
+ fp = *(u64 *)(p->thread.sp);
+ do {
+ if (fp < (unsigned long)stack ||
+- fp > (unsigned long)stack+THREAD_SIZE)
++ fp >= (unsigned long)stack+THREAD_SIZE)
+ return 0;
+ ip = *(u64 *)(fp+8);
+ if (!in_sched_functions(ip))
+diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
+index 05191bb..0a23b57 100644
+--- a/arch/x86/kernel/rtc.c
++++ b/arch/x86/kernel/rtc.c
+@@ -223,11 +223,25 @@ static struct platform_device rtc_device = {
+ static __init int add_rtc_cmos(void)
+ {
+ #ifdef CONFIG_PNP
+- if (!pnp_platform_devices)
+- platform_device_register(&rtc_device);
+-#else
++ static const char *ids[] __initconst =
++ { "PNP0b00", "PNP0b01", "PNP0b02", };
++ struct pnp_dev *dev;
++ struct pnp_id *id;
++ int i;
++
++ pnp_for_each_dev(dev) {
++ for (id = dev->id; id; id = id->next) {
++ for (i = 0; i < ARRAY_SIZE(ids); i++) {
++ if (compare_pnp_id(id, ids[i]) != 0)
++ return 0;
++ }
++ }
++ }
++#endif
++
+ platform_device_register(&rtc_device);
+-#endif /* CONFIG_PNP */
++ dev_info(&rtc_device.dev,
++ "registered platform RTC device (no PNP device found)\n");
+ return 0;
+ }
+ device_initcall(add_rtc_cmos);
+diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
+index 2a50e0f..ac144c2 100644
+--- a/arch/x86/mm/pat.c
++++ b/arch/x86/mm/pat.c
+@@ -403,12 +403,16 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
+ 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
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 1dfec41..59352d9 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -262,6 +262,7 @@ static int acpi_lid_send_state(struct acpi_button *button)
+ return -ENODEV;
+ /* input layer checks if event is redundant */
+ input_report_switch(button->input, SW_LID, !state);
++ input_sync(button->input);
+ return 0;
+ }
+
+@@ -285,8 +286,8 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
++ input_sync(input);
+ }
+- input_sync(input);
+
+ acpi_bus_generate_proc_event(button->device, event,
+ ++button->pushed);
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index 13593f9..444cd9e 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -1,7 +1,7 @@
+ /*
+- * ec.c - ACPI Embedded Controller Driver (v2.0)
++ * ec.c - ACPI Embedded Controller Driver (v2.1)
+ *
+- * Copyright (C) 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy at intel.com>
++ * Copyright (C) 2006-2008 Alexey Starikovskiy <astarikovskiy at suse.de>
+ * Copyright (C) 2006 Denis Sadykov <denis.m.sadykov at intel.com>
+ * Copyright (C) 2004 Luming Yu <luming.yu at intel.com>
+ * Copyright (C) 2001, 2002 Andy Grover <andrew.grover at intel.com>
+@@ -26,7 +26,7 @@
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+-/* Uncomment next line to get verbose print outs*/
++/* Uncomment next line to get verbose printout */
+ /* #define DEBUG */
+
+ #include <linux/kernel.h>
+@@ -38,6 +38,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/interrupt.h>
+ #include <linux/list.h>
++#include <linux/spinlock.h>
+ #include <asm/io.h>
+ #include <acpi/acpi_bus.h>
+ #include <acpi/acpi_drivers.h>
+@@ -65,22 +66,21 @@ enum ec_command {
+ ACPI_EC_COMMAND_QUERY = 0x84,
+ };
+
+-/* EC events */
+-enum ec_event {
+- ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
+- ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
+-};
+-
+ #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
+ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
+ #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */
+
++#define ACPI_EC_STORM_THRESHOLD 20 /* number of false interrupts
++ per one transaction */
++
+ enum {
+- EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */
+ EC_FLAGS_QUERY_PENDING, /* Query is pending */
+- EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */
++ EC_FLAGS_GPE_MODE, /* Expect GPE to be sent
++ * for status change */
+ EC_FLAGS_NO_GPE, /* Don't use GPE mode */
+- EC_FLAGS_RESCHEDULE_POLL /* Re-schedule poll */
++ EC_FLAGS_GPE_STORM, /* GPE storm detected */
++ EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and
++ * OpReg are installed */
+ };
+
+ /* If we find an EC via the ECDT, we need to keep a ptr to its context */
+@@ -95,6 +95,15 @@ struct acpi_ec_query_handler {
+ u8 query_bit;
+ };
+
++struct transaction {
++ const u8 *wdata;
++ u8 *rdata;
++ unsigned short irq_count;
++ u8 command;
++ u8 wlen;
++ u8 rlen;
++};
++
+ static struct acpi_ec {
+ acpi_handle handle;
+ unsigned long gpe;
+@@ -105,9 +114,8 @@ static struct acpi_ec {
+ struct mutex lock;
+ wait_queue_head_t wait;
+ struct list_head list;
+- struct delayed_work work;
+- atomic_t irq_count;
+- u8 handlers_installed;
++ struct transaction *curr;
++ spinlock_t curr_lock;
+ } *boot_ec, *first_ec;
+
+ /*
+@@ -150,7 +158,7 @@ static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
+ {
+ u8 x = inb(ec->data_addr);
+ pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
+- return inb(ec->data_addr);
++ return x;
+ }
+
+ static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
+@@ -165,158 +173,172 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
+ outb(data, ec->data_addr);
+ }
+
+-static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
++static int ec_transaction_done(struct acpi_ec *ec)
+ {
+- if (test_bit(EC_FLAGS_WAIT_GPE, &ec->flags))
+- return 0;
+- if (event == ACPI_EC_EVENT_OBF_1) {
+- if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
+- return 1;
+- } else if (event == ACPI_EC_EVENT_IBF_0) {
+- if (!(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
+- return 1;
+- }
+-
+- return 0;
++ unsigned long flags;
++ int ret = 0;
++ spin_lock_irqsave(&ec->curr_lock, flags);
++ if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen))
++ ret = 1;
++ spin_unlock_irqrestore(&ec->curr_lock, flags);
++ return ret;
+ }
+
+-static void ec_schedule_ec_poll(struct acpi_ec *ec)
++static void gpe_transaction(struct acpi_ec *ec, u8 status)
+ {
+- if (test_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags))
+- schedule_delayed_work(&ec->work,
+- msecs_to_jiffies(ACPI_EC_DELAY));
++ unsigned long flags;
++ spin_lock_irqsave(&ec->curr_lock, flags);
++ if (!ec->curr)
++ goto unlock;
++ if (ec->curr->wlen > 0) {
++ if ((status & ACPI_EC_FLAG_IBF) == 0) {
++ acpi_ec_write_data(ec, *(ec->curr->wdata++));
++ --ec->curr->wlen;
++ } else
++ /* false interrupt, state didn't change */
++ ++ec->curr->irq_count;
++
++ } else if (ec->curr->rlen > 0) {
++ if ((status & ACPI_EC_FLAG_OBF) == 1) {
++ *(ec->curr->rdata++) = acpi_ec_read_data(ec);
++ --ec->curr->rlen;
++ } else
++ /* false interrupt, state didn't change */
++ ++ec->curr->irq_count;
++ }
++unlock:
++ spin_unlock_irqrestore(&ec->curr_lock, flags);
+ }
+
+-static void ec_switch_to_poll_mode(struct acpi_ec *ec)
++static int acpi_ec_wait(struct acpi_ec *ec)
+ {
++ if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
++ msecs_to_jiffies(ACPI_EC_DELAY)))
++ return 0;
++ /* missing GPEs, switch back to poll mode */
++ if (printk_ratelimit())
++ pr_info(PREFIX "missing confirmations, "
++ "switch off interrupt mode.\n");
+ set_bit(EC_FLAGS_NO_GPE, &ec->flags);
+ clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+- acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+- set_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
++ return 1;
+ }
+
+-static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
++static void acpi_ec_gpe_query(void *ec_cxt);
++
++static int ec_check_sci(struct acpi_ec *ec, u8 state)
+ {
+- atomic_set(&ec->irq_count, 0);
+- if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
+- likely(!force_poll)) {
+- if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
+- msecs_to_jiffies(ACPI_EC_DELAY)))
+- return 0;
+- clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+- if (acpi_ec_check_status(ec, event)) {
+- /* missing GPEs, switch back to poll mode */
+- if (printk_ratelimit())
+- pr_info(PREFIX "missing confirmations, "
+- "switch off interrupt mode.\n");
+- ec_switch_to_poll_mode(ec);
+- ec_schedule_ec_poll(ec);
+- return 0;
+- }
+- } else {
+- unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+- clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+- while (time_before(jiffies, delay)) {
+- if (acpi_ec_check_status(ec, event))
+- return 0;
+- msleep(1);
+- }
+- if (acpi_ec_check_status(ec,event))
++ if (state & ACPI_EC_FLAG_SCI) {
++ if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
++ return acpi_os_execute(OSL_EC_BURST_HANDLER,
++ acpi_ec_gpe_query, ec);
++ }
++ return 0;
++}
++
++static int ec_poll(struct acpi_ec *ec)
++{
++ unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
++ msleep(1);
++ while (time_before(jiffies, delay)) {
++ gpe_transaction(ec, acpi_ec_read_status(ec));
++ msleep(1);
++ if (ec_transaction_done(ec))
+ return 0;
+ }
+- pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n",
+- acpi_ec_read_status(ec),
+- (event == ACPI_EC_EVENT_OBF_1) ? "\"b0=1\"" : "\"b1=0\"");
+ return -ETIME;
+ }
+
+-static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
+- const u8 * wdata, unsigned wdata_len,
+- u8 * rdata, unsigned rdata_len,
++static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
++ struct transaction *t,
+ int force_poll)
+ {
+- int result = 0;
+- set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
++ unsigned long tmp;
++ int ret = 0;
+ pr_debug(PREFIX "transaction start\n");
+- acpi_ec_write_cmd(ec, command);
+- for (; wdata_len > 0; --wdata_len) {
+- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
+- if (result) {
+- pr_err(PREFIX
+- "write_cmd timeout, command = %d\n", command);
+- goto end;
+- }
+- set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+- acpi_ec_write_data(ec, *(wdata++));
++ /* disable GPE during transaction if storm is detected */
++ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
++ clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
++ acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+ }
+-
+- if (!rdata_len) {
+- result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
+- if (result) {
+- pr_err(PREFIX
+- "finish-write timeout, command = %d\n", command);
+- goto end;
+- }
+- } else if (command == ACPI_EC_COMMAND_QUERY)
++ /* start transaction */
++ spin_lock_irqsave(&ec->curr_lock, tmp);
++ /* following two actions should be kept atomic */
++ t->irq_count = 0;
++ ec->curr = t;
++ acpi_ec_write_cmd(ec, ec->curr->command);
++ if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
+ clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+-
+- for (; rdata_len > 0; --rdata_len) {
+- result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll);
+- if (result) {
+- pr_err(PREFIX "read timeout, command = %d\n", command);
+- goto end;
+- }
+- /* Don't expect GPE after last read */
+- if (rdata_len > 1)
+- set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+- *(rdata++) = acpi_ec_read_data(ec);
+- }
+- end:
++ spin_unlock_irqrestore(&ec->curr_lock, tmp);
++ /* if we selected poll mode or failed in GPE-mode do a poll loop */
++ if (force_poll ||
++ !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ||
++ acpi_ec_wait(ec))
++ ret = ec_poll(ec);
+ pr_debug(PREFIX "transaction end\n");
+- return result;
++ spin_lock_irqsave(&ec->curr_lock, tmp);
++ ec->curr = NULL;
++ spin_unlock_irqrestore(&ec->curr_lock, tmp);
++ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
++ /* check if we received SCI during transaction */
++ ec_check_sci(ec, acpi_ec_read_status(ec));
++ /* it is safe to enable GPE outside of transaction */
++ acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
++ } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
++ t->irq_count > ACPI_EC_STORM_THRESHOLD) {
++ pr_debug(PREFIX "GPE storm detected\n");
++ set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
++ }
++ return ret;
++}
++
++static int ec_check_ibf0(struct acpi_ec *ec)
++{
++ u8 status = acpi_ec_read_status(ec);
++ return (status & ACPI_EC_FLAG_IBF) == 0;
+ }
+
+-static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
+- const u8 * wdata, unsigned wdata_len,
+- u8 * rdata, unsigned rdata_len,
++static int ec_wait_ibf0(struct acpi_ec *ec)
++{
++ unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
++ /* interrupt wait manually if GPE mode is not active */
++ unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ?
++ msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1);
++ while (time_before(jiffies, delay))
++ if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout))
++ return 0;
++ return -ETIME;
++}
++
++static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t,
+ int force_poll)
+ {
+ int status;
+ u32 glk;
+-
+- if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
++ if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
+ return -EINVAL;
+-
+- if (rdata)
+- memset(rdata, 0, rdata_len);
+-
++ if (t->rdata)
++ memset(t->rdata, 0, t->rlen);
+ mutex_lock(&ec->lock);
+ if (ec->global_lock) {
+ status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+ if (ACPI_FAILURE(status)) {
+- mutex_unlock(&ec->lock);
+- return -ENODEV;
++ status = -ENODEV;
++ goto unlock;
+ }
+ }
+-
+- status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
+- if (status) {
++ if (ec_wait_ibf0(ec)) {
+ pr_err(PREFIX "input buffer is not empty, "
+ "aborting transaction\n");
++ status = -ETIME;
+ goto end;
+ }
+-
+- status = acpi_ec_transaction_unlocked(ec, command,
+- wdata, wdata_len,
+- rdata, rdata_len,
+- force_poll);
+-
+- end:
+-
++ status = acpi_ec_transaction_unlocked(ec, t, force_poll);
++end:
+ if (ec->global_lock)
+ acpi_release_global_lock(glk);
++unlock:
+ mutex_unlock(&ec->lock);
+-
+ return status;
+ }
+
+@@ -327,21 +349,32 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
+ int acpi_ec_burst_enable(struct acpi_ec *ec)
+ {
+ u8 d;
+- return acpi_ec_transaction(ec, ACPI_EC_BURST_ENABLE, NULL, 0, &d, 1, 0);
++ struct transaction t = {.command = ACPI_EC_BURST_ENABLE,
++ .wdata = NULL, .rdata = &d,
++ .wlen = 0, .rlen = 1};
++
++ return acpi_ec_transaction(ec, &t, 0);
+ }
+
+ int acpi_ec_burst_disable(struct acpi_ec *ec)
+ {
+- return acpi_ec_transaction(ec, ACPI_EC_BURST_DISABLE, NULL, 0, NULL, 0, 0);
++ struct transaction t = {.command = ACPI_EC_BURST_DISABLE,
++ .wdata = NULL, .rdata = NULL,
++ .wlen = 0, .rlen = 0};
++
++ return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
++ acpi_ec_transaction(ec, &t, 0) : 0;
+ }
+
+ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
+ {
+ int result;
+ u8 d;
++ struct transaction t = {.command = ACPI_EC_COMMAND_READ,
++ .wdata = &address, .rdata = &d,
++ .wlen = 1, .rlen = 1};
+
+- result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ,
+- &address, 1, &d, 1, 0);
++ result = acpi_ec_transaction(ec, &t, 0);
+ *data = d;
+ return result;
+ }
+@@ -349,8 +382,11 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
+ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
+ {
+ u8 wdata[2] = { address, data };
+- return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
+- wdata, 2, NULL, 0, 0);
++ struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
++ .wdata = wdata, .rdata = NULL,
++ .wlen = 2, .rlen = 0};
++
++ return acpi_ec_transaction(ec, &t, 0);
+ }
+
+ /*
+@@ -412,12 +448,13 @@ int ec_transaction(u8 command,
+ u8 * rdata, unsigned rdata_len,
+ int force_poll)
+ {
++ struct transaction t = {.command = command,
++ .wdata = wdata, .rdata = rdata,
++ .wlen = wdata_len, .rlen = rdata_len};
+ if (!first_ec)
+ return -ENODEV;
+
+- return acpi_ec_transaction(first_ec, command, wdata,
+- wdata_len, rdata, rdata_len,
+- force_poll);
++ return acpi_ec_transaction(first_ec, &t, force_poll);
+ }
+
+ EXPORT_SYMBOL(ec_transaction);
+@@ -426,7 +463,9 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
+ {
+ int result;
+ u8 d;
+-
++ struct transaction t = {.command = ACPI_EC_COMMAND_QUERY,
++ .wdata = NULL, .rdata = &d,
++ .wlen = 0, .rlen = 1};
+ if (!ec || !data)
+ return -EINVAL;
+
+@@ -436,7 +475,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
+ * bit to be cleared (and thus clearing the interrupt source).
+ */
+
+- result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1, 0);
++ result = acpi_ec_transaction(ec, &t, 0);
+ if (result)
+ return result;
+
+@@ -513,46 +552,26 @@ static void acpi_ec_gpe_query(void *ec_cxt)
+
+ static u32 acpi_ec_gpe_handler(void *data)
+ {
+- acpi_status status = AE_OK;
+ struct acpi_ec *ec = data;
+- u8 state = acpi_ec_read_status(ec);
++ u8 status;
+
+ pr_debug(PREFIX "~~~> interrupt\n");
+- atomic_inc(&ec->irq_count);
+- if (atomic_read(&ec->irq_count) > 5) {
+- pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
+- ec_switch_to_poll_mode(ec);
+- goto end;
+- }
+- clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+- if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
++ status = acpi_ec_read_status(ec);
++
++ gpe_transaction(ec, status);
++ if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
+ wake_up(&ec->wait);
+
+- if (state & ACPI_EC_FLAG_SCI) {
+- if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
+- status = acpi_os_execute(OSL_EC_BURST_HANDLER,
+- acpi_ec_gpe_query, ec);
+- } else if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+- !test_bit(EC_FLAGS_NO_GPE, &ec->flags) &&
+- in_interrupt()) {
++ ec_check_sci(ec, status);
++ if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
++ !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) {
+ /* this is non-query, must be confirmation */
+ if (printk_ratelimit())
+ pr_info(PREFIX "non-query interrupt received,"
+ " switching to interrupt mode\n");
+ set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+- clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
+ }
+-end:
+- ec_schedule_ec_poll(ec);
+- return ACPI_SUCCESS(status) ?
+- ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
+-}
+-
+-static void do_ec_poll(struct work_struct *work)
+-{
+- struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work);
+- atomic_set(&ec->irq_count, 0);
+- (void)acpi_ec_gpe_handler(ec);
++ return ACPI_INTERRUPT_HANDLED;
+ }
+
+ /* --------------------------------------------------------------------------
+@@ -696,8 +715,7 @@ static struct acpi_ec *make_acpi_ec(void)
+ mutex_init(&ec->lock);
+ init_waitqueue_head(&ec->wait);
+ INIT_LIST_HEAD(&ec->list);
+- INIT_DELAYED_WORK_DEFERRABLE(&ec->work, do_ec_poll);
+- atomic_set(&ec->irq_count, 0);
++ spin_lock_init(&ec->curr_lock);
+ return ec;
+ }
+
+@@ -736,22 +754,15 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
+ return AE_CTRL_TERMINATE;
+ }
+
+-static void ec_poll_stop(struct acpi_ec *ec)
+-{
+- clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
+- cancel_delayed_work(&ec->work);
+-}
+-
+ static void ec_remove_handlers(struct acpi_ec *ec)
+ {
+- ec_poll_stop(ec);
+ if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
+ ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
+ pr_err(PREFIX "failed to remove space handler\n");
+ if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
+ &acpi_ec_gpe_handler)))
+ pr_err(PREFIX "failed to remove gpe handler\n");
+- ec->handlers_installed = 0;
++ clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
+ }
+
+ static int acpi_ec_add(struct acpi_device *device)
+@@ -846,17 +857,15 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
+ static int ec_install_handlers(struct acpi_ec *ec)
+ {
+ acpi_status status;
+- if (ec->handlers_installed)
++ if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags))
+ return 0;
+ status = acpi_install_gpe_handler(NULL, ec->gpe,
+- ACPI_GPE_EDGE_TRIGGERED,
+- &acpi_ec_gpe_handler, ec);
++ ACPI_GPE_EDGE_TRIGGERED,
++ &acpi_ec_gpe_handler, ec);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+-
+ acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
+ acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+-
+ status = acpi_install_address_space_handler(ec->handle,
+ ACPI_ADR_SPACE_EC,
+ &acpi_ec_space_handler,
+@@ -866,7 +875,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
+ return -ENODEV;
+ }
+
+- ec->handlers_installed = 1;
++ set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
+ return 0;
+ }
+
+@@ -887,7 +896,6 @@ static int acpi_ec_start(struct acpi_device *device)
+
+ /* EC is fully operational, allow queries */
+ clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+- ec_schedule_ec_poll(ec);
+ return ret;
+ }
+
+@@ -906,7 +914,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
+
+ int __init acpi_boot_ec_enable(void)
+ {
+- if (!boot_ec || boot_ec->handlers_installed)
++ if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags))
+ return 0;
+ if (!ec_install_handlers(boot_ec)) {
+ first_ec = boot_ec;
+diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
+index ecb6ace..25dccdf 100644
+--- a/drivers/acpi/hardware/hwsleep.c
++++ b/drivers/acpi/hardware/hwsleep.c
+@@ -612,6 +612,13 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
+ }
+ /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
+
++ /*
++ * Some BIOSes assume that WAK_STS will be cleared on resume and use
++ * it to determine whether the system is rebooting or resuming. Clear
++ * it for compatibility.
++ */
++ acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
++
+ acpi_gbl_system_awake_and_running = TRUE;
+
+ /* Enable power button */
+diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
+index a6b662c..755baf2 100644
+--- a/drivers/acpi/reboot.c
++++ b/drivers/acpi/reboot.c
+@@ -15,9 +15,28 @@ void acpi_reboot(void)
+
+ rr = &acpi_gbl_FADT.reset_register;
+
+- /* Is the reset register supported? */
+- if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
+- rr->bit_width != 8 || rr->bit_offset != 0)
++ /*
++ * Is the ACPI reset register supported?
++ *
++ * According to ACPI 3.0, FADT.flags.RESET_REG_SUP indicates
++ * whether the ACPI reset mechanism is supported.
++ *
++ * However, some boxes have this bit clear, yet a valid
++ * ACPI_RESET_REG & RESET_VALUE, and ACPI reboot is the only
++ * mechanism that works for them after S3.
++ *
++ * This suggests that other operating systems may not be checking
++ * the RESET_REG_SUP bit, and are using other means to decide
++ * whether to use the ACPI reboot mechanism or not.
++ *
++ * So when acpi reboot is requested,
++ * only the reset_register is checked. If the following
++ * conditions are met, it indicates that the reset register is supported.
++ * a. reset_register is not zero
++ * b. the access width is eight
++ * c. the bit_offset is zero
++ */
++ if (!(rr->address) || rr->bit_width != 8 || rr->bit_offset != 0)
+ return;
+
+ reset_value = acpi_gbl_FADT.reset_value;
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 79e3a8e..8228ae3 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -5259,6 +5259,8 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
+
+ #ifdef CONFIG_ATA_SFF
+ INIT_DELAYED_WORK(&ap->port_task, ata_pio_task);
++#else
++ INIT_DELAYED_WORK(&ap->port_task, NULL);
+ #endif
+ INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
+ INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
+diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
+index 0221c9a..35fd67d 100644
+--- a/drivers/ata/pata_it821x.c
++++ b/drivers/ata/pata_it821x.c
+@@ -557,9 +557,8 @@ static unsigned int it821x_read_id(struct ata_device *adev,
+ if (strstr(model_num, "Integrated Technology Express")) {
+ /* Set feature bits the firmware neglects */
+ id[49] |= 0x0300; /* LBA, DMA */
+- id[82] |= 0x0400; /* LBA48 */
+ id[83] &= 0x7FFF;
+- id[83] |= 0x4000; /* Word 83 is valid */
++ id[83] |= 0x4400; /* Word 83 is valid and LBA48 */
+ id[86] |= 0x0400; /* LBA48 on */
+ id[ATA_ID_MAJOR_VER] |= 0x1F;
+ }
+diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
+index 14601dc..8714c36 100644
+--- a/drivers/ata/sata_nv.c
++++ b/drivers/ata/sata_nv.c
+@@ -307,10 +307,10 @@ static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
+
+ static void nv_nf2_freeze(struct ata_port *ap);
+ static void nv_nf2_thaw(struct ata_port *ap);
++static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline);
+ static void nv_ck804_freeze(struct ata_port *ap);
+ static void nv_ck804_thaw(struct ata_port *ap);
+-static int nv_hardreset(struct ata_link *link, unsigned int *class,
+- unsigned long deadline);
+ static int nv_adma_slave_config(struct scsi_device *sdev);
+ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
+ static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
+@@ -405,17 +405,8 @@ static struct scsi_host_template nv_swncq_sht = {
+ .slave_configure = nv_swncq_slave_config,
+ };
+
+-/* OSDL bz3352 reports that some nv controllers can't determine device
+- * signature reliably and nv_hardreset is implemented to work around
+- * the problem. This was reported on nf3 and it's unclear whether any
+- * other controllers are affected. However, the workaround has been
+- * applied to all variants and there isn't much to gain by trying to
+- * find out exactly which ones are affected at this point especially
+- * because NV has moved over to ahci for newer controllers.
+- */
+ static struct ata_port_operations nv_common_ops = {
+ .inherits = &ata_bmdma_port_ops,
+- .hardreset = nv_hardreset,
+ .scr_read = nv_scr_read,
+ .scr_write = nv_scr_write,
+ };
+@@ -429,12 +420,22 @@ static struct ata_port_operations nv_generic_ops = {
+ .hardreset = ATA_OP_NULL,
+ };
+
++/* OSDL bz3352 reports that nf2/3 controllers can't determine device
++ * signature reliably. Also, the following thread reports detection
++ * failure on cold boot with the standard debouncing timing.
++ *
++ * http://thread.gmane.org/gmane.linux.ide/34098
++ *
++ * Debounce with hotplug timing and request follow-up SRST.
++ */
+ static struct ata_port_operations nv_nf2_ops = {
+ .inherits = &nv_common_ops,
+ .freeze = nv_nf2_freeze,
+ .thaw = nv_nf2_thaw,
++ .hardreset = nv_nf2_hardreset,
+ };
+
++/* CK804 finally gets hardreset right */
+ static struct ata_port_operations nv_ck804_ops = {
+ .inherits = &nv_common_ops,
+ .freeze = nv_ck804_freeze,
+@@ -443,7 +444,7 @@ static struct ata_port_operations nv_ck804_ops = {
+ };
+
+ static struct ata_port_operations nv_adma_ops = {
+- .inherits = &nv_common_ops,
++ .inherits = &nv_ck804_ops,
+
+ .check_atapi_dma = nv_adma_check_atapi_dma,
+ .sff_tf_read = nv_adma_tf_read,
+@@ -467,7 +468,7 @@ static struct ata_port_operations nv_adma_ops = {
+ };
+
+ static struct ata_port_operations nv_swncq_ops = {
+- .inherits = &nv_common_ops,
++ .inherits = &nv_generic_ops,
+
+ .qc_defer = ata_std_qc_defer,
+ .qc_prep = nv_swncq_qc_prep,
+@@ -1553,6 +1554,17 @@ static void nv_nf2_thaw(struct ata_port *ap)
+ iowrite8(mask, scr_addr + NV_INT_ENABLE);
+ }
+
++static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline)
++{
++ bool online;
++ int rc;
++
++ rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
++ &online, NULL);
++ return online ? -EAGAIN : rc;
++}
++
+ static void nv_ck804_freeze(struct ata_port *ap)
+ {
+ void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
+@@ -1605,21 +1617,6 @@ static void nv_mcp55_thaw(struct ata_port *ap)
+ ata_sff_thaw(ap);
+ }
+
+-static int nv_hardreset(struct ata_link *link, unsigned int *class,
+- unsigned long deadline)
+-{
+- int rc;
+-
+- /* SATA hardreset fails to retrieve proper device signature on
+- * some controllers. Request follow up SRST. For more info,
+- * see http://bugzilla.kernel.org/show_bug.cgi?id=3352
+- */
+- rc = sata_sff_hardreset(link, class, deadline);
+- if (rc)
+- return rc;
+- return -EAGAIN;
+-}
+-
+ static void nv_adma_error_handler(struct ata_port *ap)
+ {
+ struct nv_adma_port_priv *pp = ap->private_data;
+diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
+index 030665b..b26885f 100644
+--- a/drivers/ata/sata_promise.c
++++ b/drivers/ata/sata_promise.c
+@@ -153,6 +153,10 @@ static void pdc_freeze(struct ata_port *ap);
+ static void pdc_sata_freeze(struct ata_port *ap);
+ static void pdc_thaw(struct ata_port *ap);
+ static void pdc_sata_thaw(struct ata_port *ap);
++static int pdc_pata_softreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline);
++static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline);
+ static void pdc_error_handler(struct ata_port *ap);
+ static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
+ static int pdc_pata_cable_detect(struct ata_port *ap);
+@@ -186,6 +190,7 @@ static struct ata_port_operations pdc_sata_ops = {
+ .scr_read = pdc_sata_scr_read,
+ .scr_write = pdc_sata_scr_write,
+ .port_start = pdc_sata_port_start,
++ .hardreset = pdc_sata_hardreset,
+ };
+
+ /* First-generation chips need a more restrictive ->check_atapi_dma op */
+@@ -200,6 +205,7 @@ static struct ata_port_operations pdc_pata_ops = {
+ .freeze = pdc_freeze,
+ .thaw = pdc_thaw,
+ .port_start = pdc_common_port_start,
++ .softreset = pdc_pata_softreset,
+ };
+
+ static const struct ata_port_info pdc_port_info[] = {
+@@ -691,6 +697,20 @@ static void pdc_sata_thaw(struct ata_port *ap)
+ readl(host_mmio + hotplug_offset); /* flush */
+ }
+
++static int pdc_pata_softreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline)
++{
++ pdc_reset_port(link->ap);
++ return ata_sff_softreset(link, class, deadline);
++}
++
++static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline)
++{
++ pdc_reset_port(link->ap);
++ return sata_sff_hardreset(link, class, deadline);
++}
++
+ static void pdc_error_handler(struct ata_port *ap)
+ {
+ if (!(ap->pflags & ATA_PFLAG_FROZEN))
+diff --git a/drivers/base/sys.c b/drivers/base/sys.c
+index 75dd6e2..70499cb 100644
+--- a/drivers/base/sys.c
++++ b/drivers/base/sys.c
+@@ -488,7 +488,8 @@ ssize_t sysdev_store_ulong(struct sys_device *sysdev,
+ 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_device *sysdev,
+ 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);
+
+diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
+index 016fdf0..f1fe749 100644
+--- a/drivers/char/agp/intel-agp.c
++++ b/drivers/char/agp/intel-agp.c
+@@ -54,8 +54,7 @@
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \
+- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \
+- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB)
+
+ #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
+@@ -63,7 +62,8 @@
+
+ #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
+- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB)
++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
+
+ extern int agp_memory_reserved;
+
+@@ -525,8 +525,10 @@ static void intel_i830_init_gtt_entries(void)
+ size += 4;
+ } else if (IS_G4X) {
+ /* On 4 series hardware, GTT stolen is separate from graphics
+- * stolen, ignore it in stolen gtt entries counting */
+- size = 0;
++ * stolen, ignore it in stolen gtt entries counting. However,
++ * 4KB of the stolen memory doesn't get mapped to the GTT.
++ */
++ size = 4;
+ } else {
+ /* On previous hardware, the GTT size was just what was
+ * required to map the aperture.
+diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
+index 64e1c16..ecaf369 100644
+--- 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 at mvista.com>");
+ MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");
++MODULE_ALIAS("platform:ipmi_si");
+diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
+index 2e6d584..ed03234 100644
+--- a/drivers/firewire/fw-cdev.c
++++ b/drivers/firewire/fw-cdev.c
+@@ -720,8 +720,8 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
+ #define GET_PAYLOAD_LENGTH(v) ((v) & 0xffff)
+ #define GET_INTERRUPT(v) (((v) >> 16) & 0x01)
+ #define GET_SKIP(v) (((v) >> 17) & 0x01)
+-#define GET_TAG(v) (((v) >> 18) & 0x02)
+-#define GET_SY(v) (((v) >> 20) & 0x04)
++#define GET_TAG(v) (((v) >> 18) & 0x03)
++#define GET_SY(v) (((v) >> 20) & 0x0f)
+ #define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff)
+
+ static int ioctl_queue_iso(struct client *client, void *buffer)
+@@ -913,7 +913,7 @@ dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
+ return -EFAULT;
+ }
+
+- return 0;
++ return retval;
+ }
+
+ static long
+diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
+index aaff50e..4f73537 100644
+--- a/drivers/firewire/fw-sbp2.c
++++ b/drivers/firewire/fw-sbp2.c
+@@ -172,6 +172,9 @@ struct sbp2_target {
+ int blocked; /* ditto */
+ };
+
++/* Impossible login_id, to detect logout attempt before successful login */
++#define INVALID_LOGIN_ID 0x10000
++
+ /*
+ * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
+ * provided in the config rom. Most devices do provide a value, which
+@@ -791,9 +794,20 @@ static void sbp2_release_target(struct kref *kref)
+ scsi_remove_device(sdev);
+ scsi_device_put(sdev);
+ }
+- sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
+- SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
+-
++ if (lu->login_id != INVALID_LOGIN_ID) {
++ int generation, node_id;
++ /*
++ * tgt->node_id may be obsolete here if we failed
++ * during initial login or after a bus reset where
++ * the topology changed.
++ */
++ generation = device->generation;
++ smp_rmb(); /* node_id vs. generation */
++ node_id = device->node_id;
++ sbp2_send_management_orb(lu, node_id, generation,
++ SBP2_LOGOUT_REQUEST,
++ lu->login_id, NULL);
++ }
+ fw_core_remove_address_handler(&lu->address_handler);
+ list_del(&lu->link);
+ kfree(lu);
+@@ -808,19 +822,20 @@ static void sbp2_release_target(struct kref *kref)
+
+ static struct workqueue_struct *sbp2_wq;
+
++static void sbp2_target_put(struct sbp2_target *tgt)
++{
++ kref_put(&tgt->kref, sbp2_release_target);
++}
++
+ /*
+ * Always get the target's kref when scheduling work on one its units.
+ * Each workqueue job is responsible to call sbp2_target_put() upon return.
+ */
+ static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay)
+ {
+- if (queue_delayed_work(sbp2_wq, &lu->work, delay))
+- kref_get(&lu->tgt->kref);
+-}
+-
+-static void sbp2_target_put(struct sbp2_target *tgt)
+-{
+- kref_put(&tgt->kref, sbp2_release_target);
++ kref_get(&lu->tgt->kref);
++ if (!queue_delayed_work(sbp2_wq, &lu->work, delay))
++ sbp2_target_put(lu->tgt);
+ }
+
+ static void
+@@ -993,6 +1008,7 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
+
+ lu->tgt = tgt;
+ lu->lun = lun_entry & 0xffff;
++ lu->login_id = INVALID_LOGIN_ID;
+ lu->retries = 0;
+ lu->has_sdev = false;
+ lu->blocked = false;
+@@ -1158,7 +1174,7 @@ static int sbp2_probe(struct device *dev)
+
+ /* Do the login in a workqueue so we can easily reschedule retries. */
+ list_for_each_entry(lu, &tgt->lu_list, link)
+- sbp2_queue_work(lu, 0);
++ sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5));
+ return 0;
+
+ fail_tgt_put:
+diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
+index c1b8107..5e20471 100644
+--- a/drivers/firewire/fw-topology.c
++++ b/drivers/firewire/fw-topology.c
+@@ -413,7 +413,7 @@ static void
+ update_tree(struct fw_card *card, struct fw_node *root)
+ {
+ struct list_head list0, list1;
+- struct fw_node *node0, *node1;
++ struct fw_node *node0, *node1, *next1;
+ int i, event;
+
+ INIT_LIST_HEAD(&list0);
+@@ -485,7 +485,9 @@ update_tree(struct fw_card *card, struct fw_node *root)
+ }
+
+ node0 = fw_node(node0->link.next);
+- node1 = fw_node(node1->link.next);
++ next1 = fw_node(node1->link.next);
++ fw_node_put(node1);
++ node1 = next1;
+ }
+ }
+
+diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
+index 2ae1b0d..81b15ba 100644
+--- a/drivers/firewire/fw-transaction.h
++++ b/drivers/firewire/fw-transaction.h
+@@ -248,7 +248,7 @@ struct fw_card {
+ struct fw_node *local_node;
+ struct fw_node *root_node;
+ struct fw_node *irm_node;
+- int color;
++ u8 color; /* must be u8 to match the definition in struct fw_node */
+ int gap_count;
+ bool beta_repeaters_present;
+
+diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
+index b15f882..49144cb 100644
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -247,8 +247,6 @@
+ #define USB_DEVICE_ID_LD_MACHINETEST 0x2040
+
+ #define USB_VENDOR_ID_LOGITECH 0x046d
+-#define USB_DEVICE_ID_LOGITECH_LX3 0xc044
+-#define USB_DEVICE_ID_LOGITECH_V150 0xc047
+ #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
+ #define USB_DEVICE_ID_LOGITECH_HARMONY 0xc110
+ #define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111
+@@ -603,8 +601,6 @@ static const struct hid_blacklist {
+
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
+- { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3, HID_QUIRK_INVERT_HWHEEL },
+- { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150, HID_QUIRK_INVERT_HWHEEL },
+
+ { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS },
+ { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS },
+diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c
+index c3022a0..e4c9853 100644
+--- a/drivers/i2c/busses/scx200_i2c.c
++++ b/drivers/i2c/busses/scx200_i2c.c
+@@ -81,6 +81,7 @@ static struct i2c_algo_bit_data scx200_i2c_data = {
+
+ static struct i2c_adapter scx200_i2c_ops = {
+ .owner = THIS_MODULE,
++ .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
+ .id = I2C_HW_B_SCX200,
+ .algo_data = &scx200_i2c_data,
+ .name = "NatSemi SCx200 I2C",
+diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
+index b1ce10f..e32c24d 100644
+--- a/drivers/input/keyboard/atkbd.c
++++ b/drivers/input/keyboard/atkbd.c
+@@ -834,10 +834,10 @@ static void atkbd_disconnect(struct serio *serio)
+ }
+
+ /*
+- * Most special keys (Fn+F?) on Dell Latitudes do not generate release
++ * Most special keys (Fn+F?) on Dell laptops do not generate release
+ * events so we have to do it ourselves.
+ */
+-static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd)
++static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
+ {
+ const unsigned int forced_release_keys[] = {
+ 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
+@@ -1461,13 +1461,13 @@ static int __init atkbd_setup_fixup(const struct dmi_system_id *id)
+
+ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
+ {
+- .ident = "Dell Latitude series",
++ .ident = "Dell Laptop",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
++ DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
+ },
+ .callback = atkbd_setup_fixup,
+- .driver_data = atkbd_latitude_keymap_fixup,
++ .driver_data = atkbd_dell_laptop_keymap_fixup,
+ },
+ {
+ .ident = "HP 2133",
+diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
+index 2da1a37..a92ee16 100644
+--- a/drivers/media/dvb/frontends/s5h1411.c
++++ b/drivers/media/dvb/frontends/s5h1411.c
+@@ -471,6 +471,20 @@ static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion)
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val);
+ }
+
++static int s5h1411_set_serialmode(struct dvb_frontend *fe, int serial)
++{
++ struct s5h1411_state *state = fe->demodulator_priv;
++ u16 val;
++
++ dprintk("%s(%d)\n", __func__, serial);
++ val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbd) & ~0x100;
++
++ if (serial == 1)
++ val |= 0x100;
++
++ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, val);
++}
++
+ static int s5h1411_enable_modulation(struct dvb_frontend *fe,
+ fe_modulation_t m)
+ {
+@@ -535,7 +549,7 @@ static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable)
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val);
+ }
+
+-static int s5h1411_sleep(struct dvb_frontend *fe, int enable)
++static int s5h1411_set_powerstate(struct dvb_frontend *fe, int enable)
+ {
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+@@ -551,6 +565,11 @@ static int s5h1411_sleep(struct dvb_frontend *fe, int enable)
+ return 0;
+ }
+
++static int s5h1411_sleep(struct dvb_frontend *fe)
++{
++ return s5h1411_set_powerstate(fe, 1);
++}
++
+ static int s5h1411_register_reset(struct dvb_frontend *fe)
+ {
+ struct s5h1411_state *state = fe->demodulator_priv;
+@@ -574,9 +593,6 @@ static int s5h1411_set_frontend(struct dvb_frontend *fe,
+
+ s5h1411_enable_modulation(fe, p->u.vsb.modulation);
+
+- /* Allow the demod to settle */
+- msleep(100);
+-
+ if (fe->ops.tuner_ops.set_params) {
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+@@ -587,6 +603,10 @@ static int s5h1411_set_frontend(struct dvb_frontend *fe,
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+
++ /* Issue a reset to the demod so it knows to resync against the
++ newly tuned frequency */
++ s5h1411_softreset(fe);
++
+ return 0;
+ }
+
+@@ -599,7 +619,7 @@ static int s5h1411_init(struct dvb_frontend *fe)
+
+ dprintk("%s()\n", __func__);
+
+- s5h1411_sleep(fe, 0);
++ s5h1411_set_powerstate(fe, 0);
+ s5h1411_register_reset(fe);
+
+ for (i = 0; i < ARRAY_SIZE(init_tab); i++)
+@@ -612,10 +632,10 @@ static int s5h1411_init(struct dvb_frontend *fe)
+
+ if (state->config->output_mode == S5H1411_SERIAL_OUTPUT)
+ /* Serial */
+- s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1101);
++ s5h1411_set_serialmode(fe, 1);
+ else
+ /* Parallel */
+- s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1001);
++ s5h1411_set_serialmode(fe, 0);
+
+ s5h1411_set_spectralinversion(fe, state->config->inversion);
+ s5h1411_set_if_freq(fe, state->config->vsb_if);
+@@ -863,6 +883,7 @@ static struct dvb_frontend_ops s5h1411_ops = {
+ },
+
+ .init = s5h1411_init,
++ .sleep = s5h1411_sleep,
+ .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl,
+ .set_frontend = s5h1411_set_frontend,
+ .get_frontend = s5h1411_get_frontend,
+diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+index a1252d6..273d2a1 100644
+--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
++++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+@@ -402,6 +402,10 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
+ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0);
+ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0);
+
++ /* prevent the PTSs from slowly drifting away in the generated
++ MPEG stream */
++ ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC, 2, 4, 1);
++
+ return ret;
+ }
+
+diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
+index e23ce77..b46e599 100644
+--- a/drivers/net/atlx/atl1.c
++++ b/drivers/net/atlx/atl1.c
+@@ -2317,7 +2317,8 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
+ 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_buff *skb, struct net_device *netdev)
+ 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);
+diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
+index a5015b1..ffa73fc 100644
+--- 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
+diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
+index b211486..4489e58 100644
+--- a/drivers/net/bonding/bond_alb.c
++++ b/drivers/net/bonding/bond_alb.c
+@@ -167,11 +167,14 @@ static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_
+ /* clear slave from tx_hashtbl */
+ tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;
+
+- index = SLAVE_TLB_INFO(slave).head;
+- while (index != TLB_NULL_INDEX) {
+- u32 next_index = tx_hash_table[index].next;
+- tlb_init_table_entry(&tx_hash_table[index], save_load);
+- index = next_index;
++ /* skip this if we've already freed the tx hash table */
++ if (tx_hash_table) {
++ index = SLAVE_TLB_INFO(slave).head;
++ while (index != TLB_NULL_INDEX) {
++ u32 next_index = tx_hash_table[index].next;
++ tlb_init_table_entry(&tx_hash_table[index], save_load);
++ index = next_index;
++ }
+ }
+
+ tlb_init_slave(slave);
+diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
+index 4b27456..50927ea 100644
+--- 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_descriptor *bss,
+
+ 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);
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 36698e5..bcafbd6 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -219,7 +219,7 @@ static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
+
+ res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;
+
+- if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
++ if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
+ return pci_bar_mem64;
+ return pci_bar_mem32;
+ }
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index b184367..6ad46d7 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -1030,29 +1030,32 @@ static struct platform_driver cmos_platform_driver = {
+
+ static int __init cmos_init(void)
+ {
++ int retval = 0;
++
+ #ifdef CONFIG_PNP
+- if (pnp_platform_devices)
+- return pnp_register_driver(&cmos_pnp_driver);
+- else
+- return platform_driver_probe(&cmos_platform_driver,
+- cmos_platform_probe);
+-#else
+- return platform_driver_probe(&cmos_platform_driver,
+- cmos_platform_probe);
+-#endif /* CONFIG_PNP */
++ pnp_register_driver(&cmos_pnp_driver);
++#endif
++
++ if (!cmos_rtc.dev)
++ retval = platform_driver_probe(&cmos_platform_driver,
++ cmos_platform_probe);
++
++ if (retval == 0)
++ return 0;
++
++#ifdef CONFIG_PNP
++ pnp_unregister_driver(&cmos_pnp_driver);
++#endif
++ return retval;
+ }
+ module_init(cmos_init);
+
+ static void __exit cmos_exit(void)
+ {
+ #ifdef CONFIG_PNP
+- if (pnp_platform_devices)
+- pnp_unregister_driver(&cmos_pnp_driver);
+- else
+- platform_driver_unregister(&cmos_platform_driver);
+-#else
++ pnp_unregister_driver(&cmos_pnp_driver);
++#endif
+ platform_driver_unregister(&cmos_platform_driver);
+-#endif /* CONFIG_PNP */
+ }
+ module_exit(cmos_exit);
+
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index e5e7d78..b7ea69c 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -1047,7 +1047,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
+ 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 *SCpnt)
+ 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);
+diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
+index 706f3e6..7a4ccf5 100644
+--- 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, struct urb *urb, int status)
+ 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_device *udev,
+ 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 */
+diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
+index 2dcde61..9465e70 100644
+--- a/drivers/usb/core/hcd.h
++++ b/drivers/usb/core/hcd.h
+@@ -232,6 +232,7 @@ extern void usb_hcd_flush_endpoint(struct usb_device *udev,
+ 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,
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 875de9a..769f80f 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1349,6 +1349,7 @@ void usb_disconnect(struct usb_device **pdev)
+ */
+ dev_dbg (&udev->dev, "unregistering device\n");
+ usb_disable_device(udev, 0);
++ usb_hcd_synchronize_unlinks(udev);
+
+ usb_unlock_device(udev);
+
+diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
+index 47111e8..db72269 100644
+--- 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)
+ {
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+index cd15547..061df9b 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1745,6 +1745,15 @@ UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201,
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
++/* Reported by Alexandre Oliva <oliva at lsd.ic.unicamp.br>
++ * JMicron responds to USN and several other SCSI ioctls with a
++ * residue that causes subsequent I/O requests to fail. */
++UNUSUAL_DEV( 0x152d, 0x2329, 0x0100, 0x0100,
++ "JMicron",
++ "USB to ATA/ATAPI Bridge",
++ US_SC_DEVICE, US_PR_DEVICE, NULL,
++ US_FL_IGNORE_RESIDUE ),
++
+ /* Reported by Robert Schedel <r.schedel at yahoo.de>
+ * Note: this is a 'super top' device like the above 14cd/6600 device */
+ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
+diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c
+index d128a25..ea30afc 100644
+--- a/fs/hfsplus/bitmap.c
++++ b/fs/hfsplus/bitmap.c
+@@ -32,6 +32,10 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
+ mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
+ mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
+ page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL);
++ if (IS_ERR(page)) {
++ start = size;
++ goto out;
++ }
+ pptr = kmap(page);
+ curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
+ i = offset % 32;
+@@ -73,6 +77,10 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
+ break;
+ page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
+ NULL);
++ if (IS_ERR(page)) {
++ start = size;
++ goto out;
++ }
+ curr = pptr = kmap(page);
+ if ((size ^ offset) / PAGE_CACHE_BITS)
+ end = pptr + PAGE_CACHE_BITS / 32;
+@@ -120,6 +128,10 @@ found:
+ offset += PAGE_CACHE_BITS;
+ page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
+ NULL);
++ if (IS_ERR(page)) {
++ start = size;
++ goto out;
++ }
+ pptr = kmap(page);
+ curr = pptr;
+ end = pptr + PAGE_CACHE_BITS / 32;
+diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
+index ba117c4..f6874ac 100644
+--- a/fs/hfsplus/catalog.c
++++ b/fs/hfsplus/catalog.c
+@@ -168,6 +168,11 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid,
+ return -EIO;
+ }
+
++ if (be16_to_cpu(tmp.thread.nodeName.length) > 255) {
++ printk(KERN_ERR "hfs: catalog name length corrupted\n");
++ return -EIO;
++ }
++
+ hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID),
+ &tmp.thread.nodeName);
+ return hfs_brec_find(fd);
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index 3d9120c..6bfb849 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -1286,7 +1286,9 @@ struct task_struct {
+ atomic_t fs_excl; /* holding fs exclusive resources */
+ struct rcu_head rcu;
+
+- /*
++ struct list_head *scm_work_list;
++
++/*
+ * cache last used pipe for splice
+ */
+ struct pipe_inode_info *splice_pipe;
+diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
+index bb46e76..408f743 100644
+--- a/include/math-emu/op-common.h
++++ b/include/math-emu/op-common.h
+@@ -139,18 +139,27 @@ do { \
+ if (X##_e <= _FP_WFRACBITS_##fs) \
+ { \
+ _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
+- _FP_ROUND(wc, X); \
+ if (_FP_FRAC_HIGH_##fs(X) \
+ & (_FP_OVERFLOW_##fs >> 1)) \
+ { \
+ X##_e = 1; \
+ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+- FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ } \
+ else \
+ { \
+- X##_e = 0; \
+- _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
++ _FP_ROUND(wc, X); \
++ if (_FP_FRAC_HIGH_##fs(X) \
++ & (_FP_OVERFLOW_##fs >> 1)) \
++ { \
++ X##_e = 1; \
++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
++ FP_SET_EXCEPTION(FP_EX_INEXACT); \
++ } \
++ else \
++ { \
++ X##_e = 0; \
++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
++ } \
+ } \
+ if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \
+ (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
+diff --git a/include/net/scm.h b/include/net/scm.h
+index 06df126..33e9986 100644
+--- a/include/net/scm.h
++++ b/include/net/scm.h
+@@ -14,8 +14,9 @@
+
+ struct scm_fp_list
+ {
+- int count;
+- struct file *fp[SCM_MAX_FD];
++ struct list_head list;
++ int count;
++ struct file *fp[SCM_MAX_FD];
+ };
+
+ struct scm_cookie
+diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
+index e8ab096..8178724 100644
+--- a/kernel/sched_clock.c
++++ b/kernel/sched_clock.c
+@@ -118,13 +118,13 @@ static u64 __update_sched_clock(struct sched_clock_data *scd, u64 now)
+
+ /*
+ * scd->clock = clamp(scd->tick_gtod + delta,
+- * max(scd->tick_gtod, scd->clock),
+- * scd->tick_gtod + TICK_NSEC);
++ * max(scd->tick_gtod, scd->clock),
++ * max(scd->clock, scd->tick_gtod + TICK_NSEC));
+ */
+
+ clock = scd->tick_gtod + delta;
+ min_clock = wrap_max(scd->tick_gtod, scd->clock);
+- max_clock = scd->tick_gtod + TICK_NSEC;
++ max_clock = wrap_max(scd->clock, scd->tick_gtod + TICK_NSEC);
+
+ clock = wrap_max(clock, min_clock);
+ clock = wrap_min(clock, max_clock);
+diff --git a/kernel/sched_features.h b/kernel/sched_features.h
+index 9353ca7..c4c88ae 100644
+--- a/kernel/sched_features.h
++++ b/kernel/sched_features.h
+@@ -5,7 +5,7 @@ SCHED_FEAT(START_DEBIT, 1)
+ SCHED_FEAT(AFFINE_WAKEUPS, 1)
+ SCHED_FEAT(CACHE_HOT_BUDDY, 1)
+ SCHED_FEAT(SYNC_WAKEUPS, 1)
+-SCHED_FEAT(HRTICK, 1)
++SCHED_FEAT(HRTICK, 0)
+ SCHED_FEAT(DOUBLE_TICK, 0)
+ SCHED_FEAT(ASYM_GRAN, 1)
+ SCHED_FEAT(LB_BIAS, 1)
+diff --git a/net/core/scm.c b/net/core/scm.c
+index 10f5c65..ab242cc 100644
+--- a/net/core/scm.c
++++ b/net/core/scm.c
+@@ -75,6 +75,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
+ if (!fpl)
+ return -ENOMEM;
+ *fplp = fpl;
++ INIT_LIST_HEAD(&fpl->list);
+ fpl->count = 0;
+ }
+ fpp = &fpl->fp[fpl->count];
+@@ -106,9 +107,25 @@ void __scm_destroy(struct scm_cookie *scm)
+
+ if (fpl) {
+ scm->fp = NULL;
+- for (i=fpl->count-1; i>=0; i--)
+- fput(fpl->fp[i]);
+- kfree(fpl);
++ if (current->scm_work_list) {
++ list_add_tail(&fpl->list, current->scm_work_list);
++ } else {
++ LIST_HEAD(work_list);
++
++ current->scm_work_list = &work_list;
++
++ list_add(&fpl->list, &work_list);
++ while (!list_empty(&work_list)) {
++ fpl = list_first_entry(&work_list, struct scm_fp_list, list);
++
++ list_del(&fpl->list);
++ for (i=fpl->count-1; i>=0; i--)
++ fput(fpl->fp[i]);
++ kfree(fpl);
++ }
++
++ current->scm_work_list = NULL;
++ }
+ }
+ }
+
+@@ -284,6 +301,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
+
+ new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
+ if (new_fpl) {
++ INIT_LIST_HEAD(&new_fpl->list);
+ for (i=fpl->count-1; i>=0; i--)
+ get_file(fpl->fp[i]);
+ memcpy(new_fpl, fpl, sizeof(*fpl));
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 8165f5a..d083f9a 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -357,6 +357,17 @@ struct tcp_out_options {
+ __u32 tsval, tsecr; /* need to include OPTION_TS */
+ };
+
++/* Beware: Something in the Internet is very sensitive to the ordering of
++ * TCP options, we learned this through the hard way, so be careful here.
++ * Luckily we can at least blame others for their non-compliance but from
++ * inter-operatibility perspective it seems that we're somewhat stuck with
++ * the ordering which we have been using if we want to keep working with
++ * those broken things (not that it currently hurts anybody as there isn't
++ * particular reason why the ordering would need to be changed).
++ *
++ * At least SACK_PERM as the first option is known to lead to a disaster
++ * (but it may well be that other scenarios fail similarly).
++ */
+ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
+ const struct tcp_out_options *opts,
+ __u8 **md5_hash) {
+@@ -371,6 +382,12 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
+ *md5_hash = NULL;
+ }
+
++ if (unlikely(opts->mss)) {
++ *ptr++ = htonl((TCPOPT_MSS << 24) |
++ (TCPOLEN_MSS << 16) |
++ opts->mss);
++ }
++
+ if (likely(OPTION_TS & opts->options)) {
+ if (unlikely(OPTION_SACK_ADVERTISE & opts->options)) {
+ *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
+@@ -387,12 +404,6 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
+ *ptr++ = htonl(opts->tsecr);
+ }
+
+- if (unlikely(opts->mss)) {
+- *ptr++ = htonl((TCPOPT_MSS << 24) |
+- (TCPOLEN_MSS << 16) |
+- opts->mss);
+- }
+-
+ if (unlikely(OPTION_SACK_ADVERTISE & opts->options &&
+ !(OPTION_TS & opts->options))) {
+ *ptr++ = htonl((TCPOPT_NOP << 24) |
+@@ -2266,6 +2277,11 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
+ }
+
+ memset(&opts, 0, sizeof(opts));
++#ifdef CONFIG_SYN_COOKIES
++ if (unlikely(req->cookie_ts))
++ TCP_SKB_CB(skb)->when = cookie_init_timestamp(req);
++ else
++#endif
+ TCP_SKB_CB(skb)->when = tcp_time_stamp;
+ tcp_header_size = tcp_synack_options(sk, req,
+ dst_metric(dst, RTAX_ADVMSS),
+@@ -2292,11 +2308,6 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
+
+ /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
+ th->window = htons(min(req->rcv_wnd, 65535U));
+-#ifdef CONFIG_SYN_COOKIES
+- if (unlikely(req->cookie_ts))
+- TCP_SKB_CB(skb)->when = cookie_init_timestamp(req);
+- else
+-#endif
+ tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location);
+ th->doff = (tcp_header_size >> 2);
+ TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 10e22fd..245cbc5 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1087,7 +1087,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
+ *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+ *topt++ = htonl(tcp_time_stamp);
+- *topt = htonl(ts);
++ *topt++ = htonl(ts);
+ }
+
+ #ifdef CONFIG_TCP_MD5SIG
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index ec0a083..700ae9e 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -319,6 +319,7 @@ struct Qdisc_ops noop_qdisc_ops __read_mostly = {
+
+ static struct netdev_queue noop_netdev_queue = {
+ .qdisc = &noop_qdisc,
++ .qdisc_sleeping = &noop_qdisc,
+ };
+
+ struct Qdisc noop_qdisc = {
+@@ -344,6 +345,7 @@ static struct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
+ static struct Qdisc noqueue_qdisc;
+ static struct netdev_queue noqueue_netdev_queue = {
+ .qdisc = &noqueue_qdisc,
++ .qdisc_sleeping = &noqueue_qdisc,
+ };
+
+ static struct Qdisc noqueue_qdisc = {
+diff --git a/scripts/package/mkspec b/scripts/package/mkspec
+index ffd61fe..62c5ffd 100755
+--- 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 ""
+diff --git a/security/commoncap.c b/security/commoncap.c
+index e4c4b3f..378172b 100644
+--- a/security/commoncap.c
++++ b/security/commoncap.c
+@@ -279,10 +279,10 @@ static int get_file_caps(struct linux_binprm *bprm)
+ struct vfs_cap_data vcaps;
+ struct inode *inode;
+
+- if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) {
+- bprm_clear_caps(bprm);
++ bprm_clear_caps(bprm);
++
++ if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)
+ return 0;
+- }
+
+ dentry = dget(bprm->file->f_dentry);
+ inode = dentry->d_inode;
+diff --git a/sound/core/control.c b/sound/core/control.c
+index 281b2e2..236bbb1 100644
+--- a/sound/core/control.c
++++ b/sound/core/control.c
+@@ -1427,12 +1427,12 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
+ cardnum = card->number;
+ snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
+
+- down_read(&card->controls_rwsem);
++ read_lock(&card->ctl_files_rwlock);
+ list_for_each_entry(ctl, &card->ctl_files, list) {
+ wake_up(&ctl->change_sleep);
+ kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
+ }
+- up_read(&card->controls_rwsem);
++ read_unlock(&card->ctl_files_rwlock);
+
+ if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
+ card, -1)) < 0)
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 1c53e33..0f014b1 100644
+--- 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 *pci)
+
+
+ /*
++ * 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 pci_dev *pci,
+ pci_set_drvdata(pci, card);
+ chip->running = 1;
+ power_down_all_codecs(chip);
++ azx_notifier_register(chip);
+
+ dev++;
+ return err;
Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.6
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.6 Sun Nov 16 09:28:39 2008
@@ -0,0 +1,2220 @@
+diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt
+index 8244c64..48d80d9 100644
+--- a/Documentation/cciss.txt
++++ b/Documentation/cciss.txt
+@@ -26,6 +26,8 @@ This driver is known to work with the following cards:
+ * SA P410i
+ * SA P411
+ * SA P812
++ * SA P712m
++ * SA P711m
+
+ Detecting drive failures:
+ -------------------------
+diff --git a/arch/arm/mach-pxa/include/mach/reset.h b/arch/arm/mach-pxa/include/mach/reset.h
+index 9489a48..7b8842c 100644
+--- a/arch/arm/mach-pxa/include/mach/reset.h
++++ b/arch/arm/mach-pxa/include/mach/reset.h
+@@ -10,9 +10,12 @@
+ extern unsigned int reset_status;
+ extern void clear_reset_status(unsigned int mask);
+
+-/*
+- * register GPIO as reset generator
++/**
++ * init_gpio_reset() - register GPIO as reset generator
++ *
++ * @gpio - gpio nr
++ * @output - set gpio as out/low instead of input during normal work
+ */
+-extern int init_gpio_reset(int gpio);
++extern int init_gpio_reset(int gpio, int output);
+
+ #endif /* __ASM_ARCH_RESET_H */
+diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c
+index 9996c61..1b236a6 100644
+--- a/arch/arm/mach-pxa/reset.c
++++ b/arch/arm/mach-pxa/reset.c
+@@ -20,7 +20,7 @@ static void do_hw_reset(void);
+
+ static int reset_gpio = -1;
+
+-int init_gpio_reset(int gpio)
++int init_gpio_reset(int gpio, int output)
+ {
+ int rc;
+
+@@ -30,9 +30,12 @@ int init_gpio_reset(int gpio)
+ goto out;
+ }
+
+- rc = gpio_direction_input(gpio);
++ if (output)
++ rc = gpio_direction_output(gpio, 0);
++ else
++ rc = gpio_direction_input(gpio);
+ if (rc) {
+- printk(KERN_ERR "Can't configure reset_gpio for input\n");
++ printk(KERN_ERR "Can't configure reset_gpio\n");
+ gpio_free(gpio);
+ goto out;
+ }
+diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
+index b569f3b..32cee4c 100644
+--- a/arch/arm/mach-pxa/spitz.c
++++ b/arch/arm/mach-pxa/spitz.c
+@@ -548,7 +548,7 @@ static void spitz_restart(char mode)
+
+ static void __init common_init(void)
+ {
+- init_gpio_reset(SPITZ_GPIO_ON_RESET);
++ init_gpio_reset(SPITZ_GPIO_ON_RESET, 1);
+ pm_power_off = spitz_poweroff;
+ arm_pm_restart = spitz_restart;
+
+diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
+index 9f3ef9e..130e37e 100644
+--- a/arch/arm/mach-pxa/tosa.c
++++ b/arch/arm/mach-pxa/tosa.c
+@@ -781,7 +781,7 @@ static void __init tosa_init(void)
+ gpio_set_wake(MFP_PIN_GPIO1, 1);
+ /* We can't pass to gpio-keys since it will drop the Reset altfunc */
+
+- init_gpio_reset(TOSA_GPIO_ON_RESET);
++ init_gpio_reset(TOSA_GPIO_ON_RESET, 0);
+
+ pm_power_off = tosa_poweroff;
+ arm_pm_restart = tosa_restart;
+diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c
+index 158bd96..99ec030 100644
+--- a/arch/arm/mm/cache-xsc3l2.c
++++ b/arch/arm/mm/cache-xsc3l2.c
+@@ -97,7 +97,7 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
+ /*
+ * Clean and invalidate partial last cache line.
+ */
+- if (end & (CACHE_LINE_SIZE - 1)) {
++ if (start < end && (end & (CACHE_LINE_SIZE - 1))) {
+ xsc3_l2_clean_pa(end & ~(CACHE_LINE_SIZE - 1));
+ xsc3_l2_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
+ end &= ~(CACHE_LINE_SIZE - 1);
+@@ -106,7 +106,7 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
+ /*
+ * Invalidate all full cache lines between 'start' and 'end'.
+ */
+- while (start != end) {
++ while (start < end) {
+ xsc3_l2_inv_pa(start);
+ start += CACHE_LINE_SIZE;
+ }
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index ed92864..552d2b7 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1059,6 +1059,26 @@ config HIGHPTE
+ low memory. Setting this option will put user-space page table
+ entries in high memory.
+
++config X86_RESERVE_LOW_64K
++ bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen"
++ default y
++ help
++ Reserve the first 64K of physical RAM on BIOSes that are known
++ to potentially corrupt that memory range. A numbers of BIOSes are
++ known to utilize this area during suspend/resume, so it must not
++ be used by the kernel.
++
++ Set this to N if you are absolutely sure that you trust the BIOS
++ to get all its memory reservations and usages right.
++
++ If you have doubts about the BIOS (e.g. suspend/resume does not
++ work or there's kernel crashes after certain hardware hotplug
++ events) and it's not AMI or Phoenix, then you might want to enable
++ X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical
++ corruption patterns.
++
++ Say Y if unsure.
++
+ config MATH_EMULATION
+ bool
+ prompt "Math emulation" if X86_32
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index 9838f25..64b5c42 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -578,6 +578,39 @@ static struct x86_quirks default_x86_quirks __initdata;
+
+ struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
+
++static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
++{
++ printk(KERN_NOTICE
++ "%s detected: BIOS may corrupt low RAM, working it around.\n",
++ d->ident);
++
++ e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED);
++ sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
++
++ return 0;
++}
++
++/* List of systems that have known low memory corruption BIOS problems */
++static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
++#ifdef CONFIG_X86_RESERVE_LOW_64K
++ {
++ .callback = dmi_low_memory_corruption,
++ .ident = "AMI BIOS",
++ .matches = {
++ DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
++ },
++ },
++ {
++ .callback = dmi_low_memory_corruption,
++ .ident = "Phoenix BIOS",
++ .matches = {
++ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
++ },
++ },
++#endif
++ {}
++};
++
+ /*
+ * Determine if we were loaded by an EFI loader. If so, then we have also been
+ * passed the efi memmap, systab, etc., so we should use these data structures
+@@ -699,6 +732,10 @@ void __init setup_arch(char **cmdline_p)
+
+ finish_e820_parsing();
+
++ dmi_scan_machine();
++
++ dmi_check_system(bad_bios_dmi_table);
++
+ #ifdef CONFIG_X86_32
+ probe_roms();
+ #endif
+@@ -781,8 +818,6 @@ void __init setup_arch(char **cmdline_p)
+ vsmp_init();
+ #endif
+
+- dmi_scan_machine();
+-
+ io_delay_init();
+
+ /*
+@@ -885,3 +920,5 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+ #endif
+ }
++
++
+diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
+index 8f98e9d..de850e9 100644
+--- a/arch/x86/kernel/tsc.c
++++ b/arch/x86/kernel/tsc.c
+@@ -639,10 +639,6 @@ void __init tsc_init(void)
+ cpu_khz = calibrate_cpu();
+ #endif
+
+- lpj = ((u64)tsc_khz * 1000);
+- do_div(lpj, HZ);
+- lpj_fine = lpj;
+-
+ printk("Detected %lu.%03lu MHz processor.\n",
+ (unsigned long)cpu_khz / 1000,
+ (unsigned long)cpu_khz % 1000);
+@@ -662,6 +658,10 @@ void __init tsc_init(void)
+ /* now allow native_sched_clock() to use rdtsc */
+ tsc_disabled = 0;
+
++ lpj = ((u64)tsc_khz * 1000);
++ do_div(lpj, HZ);
++ lpj_fine = lpj;
++
+ use_tsc_delay();
+ /* Check and install the TSC clocksource */
+ dmi_check_system(bad_tsc_dmi_table);
+diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
+index 7d2edf1..25d2161 100644
+--- a/drivers/acpi/dock.c
++++ b/drivers/acpi/dock.c
+@@ -604,14 +604,17 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
+ static void dock_notify(acpi_handle handle, u32 event, void *data)
+ {
+ struct dock_station *ds = data;
++ struct acpi_device *tmp;
+
+ switch (event) {
+ case ACPI_NOTIFY_BUS_CHECK:
+- if (!dock_in_progress(ds) && dock_present(ds)) {
++ if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
++ &tmp)) {
+ begin_dock(ds);
+ dock(ds);
+ if (!dock_present(ds)) {
+ printk(KERN_ERR PREFIX "Unable to dock!\n");
++ complete_dock(ds);
+ break;
+ }
+ atomic_notifier_call_chain(&dock_notifier_list,
+diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
+index c1db2f2..2c4ccec 100644
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -604,9 +604,6 @@ void ata_scsi_error(struct Scsi_Host *host)
+ if (ata_ncq_enabled(dev))
+ ehc->saved_ncq_enabled |= 1 << devno;
+ }
+-
+- /* set last reset timestamp to some time in the past */
+- ehc->last_reset = jiffies - 60 * HZ;
+ }
+
+ ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS;
+@@ -2209,17 +2206,21 @@ int ata_eh_reset(struct ata_link *link, int classify,
+ if (link->flags & ATA_LFLAG_NO_SRST)
+ softreset = NULL;
+
+- now = jiffies;
+- deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN);
+- if (time_before(now, deadline))
+- schedule_timeout_uninterruptible(deadline - now);
++ /* make sure each reset attemp is at least COOL_DOWN apart */
++ if (ehc->i.flags & ATA_EHI_DID_RESET) {
++ now = jiffies;
++ WARN_ON(time_after(ehc->last_reset, now));
++ deadline = ata_deadline(ehc->last_reset,
++ ATA_EH_RESET_COOL_DOWN);
++ if (time_before(now, deadline))
++ schedule_timeout_uninterruptible(deadline - now);
++ }
+
+ spin_lock_irqsave(ap->lock, flags);
+ ap->pflags |= ATA_PFLAG_RESETTING;
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
+- ehc->last_reset = jiffies;
+
+ ata_link_for_each_dev(dev, link) {
+ /* If we issue an SRST then an ATA drive (not ATAPI)
+@@ -2285,7 +2286,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
+ /*
+ * Perform reset
+ */
+- ehc->last_reset = jiffies;
+ if (ata_is_host_link(link))
+ ata_eh_freeze_port(ap);
+
+@@ -2297,6 +2297,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
+ reset == softreset ? "soft" : "hard");
+
+ /* mark that this EH session started with reset */
++ ehc->last_reset = jiffies;
+ if (reset == hardreset)
+ ehc->i.flags |= ATA_EHI_DID_HARDRESET;
+ else
+@@ -2404,7 +2405,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
+
+ /* reset successful, schedule revalidation */
+ ata_eh_done(link, NULL, ATA_EH_RESET);
+- ehc->last_reset = jiffies;
++ ehc->last_reset = jiffies; /* update to completion time */
+ ehc->i.action |= ATA_EH_REVALIDATE;
+
+ rc = 0;
+diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
+index b73116e..2ac91b8 100644
+--- a/drivers/block/cciss.c
++++ b/drivers/block/cciss.c
+@@ -96,6 +96,8 @@ static const struct pci_device_id cciss_pci_device_id[] = {
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B},
+ {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
+ {0,}
+@@ -133,6 +135,8 @@ static struct board_type products[] = {
+ {0x3245103C, "Smart Array P410i", &SA5_access},
+ {0x3247103C, "Smart Array P411", &SA5_access},
+ {0x3249103C, "Smart Array P812", &SA5_access},
++ {0x324A103C, "Smart Array P712m", &SA5_access},
++ {0x324B103C, "Smart Array P711m", &SA5_access},
+ {0xFFFF103C, "Unknown Smart Array", &SA5_access},
+ };
+
+@@ -1365,6 +1369,7 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
+ disk->first_minor = drv_index << NWD_SHIFT;
+ disk->fops = &cciss_fops;
+ disk->private_data = &h->drv[drv_index];
++ disk->driverfs_dev = &h->pdev->dev;
+
+ /* Set up queue information */
+ blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
+@@ -3403,7 +3408,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
+ int i;
+ int j = 0;
+ int rc;
+- int dac;
++ int dac, return_code;
++ InquiryData_struct *inq_buff = NULL;
+
+ i = alloc_cciss_hba();
+ if (i < 0)
+@@ -3509,6 +3515,25 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
+ /* Turn the interrupts on so we can service requests */
+ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
+
++ /* Get the firmware version */
++ inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL);
++ if (inq_buff == NULL) {
++ printk(KERN_ERR "cciss: out of memory\n");
++ goto clean4;
++ }
++
++ return_code = sendcmd_withirq(CISS_INQUIRY, i, inq_buff,
++ sizeof(InquiryData_struct), 0, 0 , 0, TYPE_CMD);
++ if (return_code == IO_OK) {
++ hba[i]->firm_ver[0] = inq_buff->data_byte[32];
++ hba[i]->firm_ver[1] = inq_buff->data_byte[33];
++ hba[i]->firm_ver[2] = inq_buff->data_byte[34];
++ hba[i]->firm_ver[3] = inq_buff->data_byte[35];
++ } else { /* send command failed */
++ printk(KERN_WARNING "cciss: unable to determine firmware"
++ " version of controller\n");
++ }
++
+ cciss_procinit(i);
+
+ hba[i]->cciss_max_sectors = 2048;
+@@ -3519,6 +3544,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
+ return 1;
+
+ clean4:
++ kfree(inq_buff);
+ #ifdef CONFIG_CISS_SCSI_TAPE
+ kfree(hba[i]->scsi_rejects.complete);
+ #endif
+diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
+index 09c1434..f5d2e54 100644
+--- a/drivers/block/cpqarray.c
++++ b/drivers/block/cpqarray.c
+@@ -567,7 +567,12 @@ static int __init cpqarray_init(void)
+ num_cntlrs_reg++;
+ }
+
+- return(num_cntlrs_reg);
++ if (num_cntlrs_reg)
++ return 0;
++ else {
++ pci_unregister_driver(&cpqarray_pci_driver);
++ return -ENODEV;
++ }
+ }
+
+ /* Function to find the first free pointer into our hba[] array */
+diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c
+index ec249d2..d883e1b 100644
+--- a/drivers/dca/dca-core.c
++++ b/drivers/dca/dca-core.c
+@@ -270,6 +270,6 @@ static void __exit dca_exit(void)
+ dca_sysfs_exit();
+ }
+
+-module_init(dca_init);
++subsys_initcall(dca_init);
+ module_exit(dca_exit);
+
+diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
+index bc8c6e3..3f4db54 100644
+--- a/drivers/dma/ioat_dma.c
++++ b/drivers/dma/ioat_dma.c
+@@ -519,7 +519,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
+ }
+
+ hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+- if (new->async_tx.callback) {
++ if (first->async_tx.callback) {
+ hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
+ if (first != new) {
+ /* move callback into to last desc */
+@@ -611,7 +611,7 @@ static dma_cookie_t ioat2_tx_submit(struct dma_async_tx_descriptor *tx)
+ }
+
+ hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+- if (new->async_tx.callback) {
++ if (first->async_tx.callback) {
+ hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
+ if (first != new) {
+ /* move callback into to last desc */
+@@ -801,6 +801,12 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
+ struct ioat_desc_sw *desc, *_desc;
+ int in_use_descs = 0;
+
++ /* Before freeing channel resources first check
++ * if they have been previously allocated for this channel.
++ */
++ if (ioat_chan->desccount == 0)
++ return;
++
+ tasklet_disable(&ioat_chan->cleanup_task);
+ ioat_dma_memcpy_cleanup(ioat_chan);
+
+@@ -863,6 +869,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
+ ioat_chan->last_completion = ioat_chan->completion_addr = 0;
+ ioat_chan->pending = 0;
+ ioat_chan->dmacount = 0;
++ ioat_chan->desccount = 0;
+ ioat_chan->watchdog_completion = 0;
+ ioat_chan->last_compl_desc_addr_hw = 0;
+ ioat_chan->watchdog_tcp_cookie =
+diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c
+index e763d72..9f6fe46 100644
+--- a/drivers/dma/iovlock.c
++++ b/drivers/dma/iovlock.c
+@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len)
+ int nr_iovecs = 0;
+ int iovec_len_used = 0;
+ int iovec_pages_used = 0;
+- long err;
+
+ /* don't pin down non-user-based iovecs */
+ if (segment_eq(get_fs(), KERNEL_DS))
+@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len)
+ local_list = kmalloc(sizeof(*local_list)
+ + (nr_iovecs * sizeof (struct dma_page_list))
+ + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL);
+- if (!local_list) {
+- err = -ENOMEM;
++ if (!local_list)
+ goto out;
+- }
+
+ /* list of pages starts right after the page list array */
+ pages = (struct page **) &local_list->page_list[nr_iovecs];
+
++ local_list->nr_iovecs = 0;
++
+ for (i = 0; i < nr_iovecs; i++) {
+ struct dma_page_list *page_list = &local_list->page_list[i];
+
+ len -= iov[i].iov_len;
+
+- if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) {
+- err = -EFAULT;
++ if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len))
+ goto unpin;
+- }
+
+ page_list->nr_pages = num_pages_spanned(&iov[i]);
+ page_list->base_address = iov[i].iov_base;
+@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len)
+ NULL);
+ up_read(¤t->mm->mmap_sem);
+
+- if (ret != page_list->nr_pages) {
+- err = -ENOMEM;
++ if (ret != page_list->nr_pages)
+ goto unpin;
+- }
+
+ local_list->nr_iovecs = i + 1;
+ }
+@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len)
+ unpin:
+ dma_unpin_iovec_pages(local_list);
+ out:
+- return ERR_PTR(err);
++ return NULL;
+ }
+
+ void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list)
+diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
+index c40f040..8c030d9 100644
+--- a/drivers/hid/hidraw.c
++++ b/drivers/hid/hidraw.c
+@@ -113,7 +113,7 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t
+ if (!dev->hid_output_raw_report)
+ return -ENODEV;
+
+- if (count > HID_MIN_BUFFER_SIZE) {
++ if (count > HID_MAX_BUFFER_SIZE) {
+ printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
+ task_pid_nr(current));
+ return -EINVAL;
+diff --git a/drivers/md/linear.c b/drivers/md/linear.c
+index b1eebf8..a58a19e 100644
+--- a/drivers/md/linear.c
++++ b/drivers/md/linear.c
+@@ -157,6 +157,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
+
+ min_spacing = conf->array_sectors / 2;
+ sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
++ if (min_spacing == 0)
++ min_spacing = 1;
+
+ /* min_spacing is the minimum spacing that will fit the hash
+ * table in one PAGE. This may be much smaller than needed.
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index e34cd0e..941576d 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1132,7 +1132,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
+ if (!enough(conf))
+ return -EINVAL;
+
+- if (rdev->raid_disk)
++ if (rdev->raid_disk >= 0)
+ first = last = rdev->raid_disk;
+
+ if (rdev->saved_raid_disk >= 0 &&
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index 044d84e..f7284b9 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -280,7 +280,11 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
+ (card->host->ios.clock / 1000);
+
+ if (data->flags & MMC_DATA_WRITE)
+- limit_us = 250000;
++ /*
++ * The limit is really 250 ms, but that is
++ * insufficient for some crappy cards.
++ */
++ limit_us = 300000;
+ else
+ limit_us = 100000;
+
+diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
+index a972cc6..9e7a236 100644
+--- a/drivers/mtd/chips/cfi_cmdset_0002.c
++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
+@@ -362,19 +362,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
+ /* Set the default CFI lock/unlock addresses */
+ cfi->addr_unlock1 = 0x555;
+ cfi->addr_unlock2 = 0x2aa;
+- /* Modify the unlock address if we are in compatibility mode */
+- if ( /* x16 in x8 mode */
+- ((cfi->device_type == CFI_DEVICETYPE_X8) &&
+- (cfi->cfiq->InterfaceDesc ==
+- CFI_INTERFACE_X8_BY_X16_ASYNC)) ||
+- /* x32 in x16 mode */
+- ((cfi->device_type == CFI_DEVICETYPE_X16) &&
+- (cfi->cfiq->InterfaceDesc ==
+- CFI_INTERFACE_X16_BY_X32_ASYNC)))
+- {
+- cfi->addr_unlock1 = 0xaaa;
+- cfi->addr_unlock2 = 0x555;
+- }
+
+ } /* CFI mode */
+ else if (cfi->cfi_mode == CFI_MODE_JEDEC) {
+diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
+index f84ab61..2f3f2f7 100644
+--- a/drivers/mtd/chips/jedec_probe.c
++++ b/drivers/mtd/chips/jedec_probe.c
+@@ -1808,9 +1808,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base,
+ * several first banks can contain 0x7f instead of actual ID
+ */
+ do {
+- uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8),
+- cfi_interleave(cfi),
+- cfi->device_type);
++ uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi);
+ mask = (1 << (cfi->device_type * 8)) - 1;
+ result = map_read(map, base + ofs);
+ bank++;
+@@ -1824,7 +1822,7 @@ static inline u32 jedec_read_id(struct map_info *map, uint32_t base,
+ {
+ map_word result;
+ unsigned long mask;
+- u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type);
++ u32 ofs = cfi_build_cmd_addr(1, map, cfi);
+ mask = (1 << (cfi->device_type * 8)) -1;
+ result = map_read(map, base + ofs);
+ return result.x[0] & mask;
+@@ -2067,8 +2065,8 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
+
+ }
+ /* Ensure the unlock addresses we try stay inside the map */
+- probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, cfi_interleave(cfi), cfi->device_type);
+- probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, cfi_interleave(cfi), cfi->device_type);
++ probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, map, cfi);
++ probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, map, cfi);
+ if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
+ ((base + probe_offset2 + map_bankwidth(map)) >= map->size))
+ goto retry;
+diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
+index 0f6f974..39c17bb 100644
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -370,8 +370,9 @@ struct ring_info {
+ };
+
+ enum features {
+- RTL_FEATURE_WOL = (1 << 0),
+- RTL_FEATURE_MSI = (1 << 1),
++ RTL_FEATURE_WOL = (1 << 0),
++ RTL_FEATURE_MSI = (1 << 1),
++ RTL_FEATURE_GMII = (1 << 2),
+ };
+
+ struct rtl8169_private {
+@@ -406,13 +407,15 @@ struct rtl8169_private {
+ struct vlan_group *vlgrp;
+ #endif
+ int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
+- void (*get_settings)(struct net_device *, struct ethtool_cmd *);
++ int (*get_settings)(struct net_device *, struct ethtool_cmd *);
+ void (*phy_reset_enable)(void __iomem *);
+ void (*hw_start)(struct net_device *);
+ unsigned int (*phy_reset_pending)(void __iomem *);
+ unsigned int (*link_ok)(void __iomem *);
+ struct delayed_work task;
+ unsigned features;
++
++ struct mii_if_info mii;
+ };
+
+ MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev at vger.kernel.org>");
+@@ -482,6 +485,23 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
+ return value;
+ }
+
++static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
++ int val)
++{
++ struct rtl8169_private *tp = netdev_priv(dev);
++ void __iomem *ioaddr = tp->mmio_addr;
++
++ mdio_write(ioaddr, location, val);
++}
++
++static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
++{
++ struct rtl8169_private *tp = netdev_priv(dev);
++ void __iomem *ioaddr = tp->mmio_addr;
++
++ return mdio_read(ioaddr, location);
++}
++
+ static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
+ {
+ RTL_W16(IntrMask, 0x0000);
+@@ -720,9 +740,13 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
+
+ auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+
+- if ((tp->mac_version == RTL_GIGA_MAC_VER_12) ||
+- (tp->mac_version == RTL_GIGA_MAC_VER_17)) {
+- /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */
++ if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
++ (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
++ (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
++ /*
++ * Wake up the PHY.
++ * Vendor specific (0x1f) and reserved (0x0e) MII registers.
++ */
+ mdio_write(ioaddr, 0x1f, 0x0000);
+ mdio_write(ioaddr, 0x0e, 0x0000);
+ }
+@@ -850,7 +874,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
+
+ #endif
+
+-static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
++static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
+@@ -867,65 +891,29 @@ static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
+
+ cmd->speed = SPEED_1000;
+ cmd->duplex = DUPLEX_FULL; /* Always set */
++
++ return 0;
+ }
+
+-static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
++static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+- void __iomem *ioaddr = tp->mmio_addr;
+- u8 status;
+-
+- cmd->supported = SUPPORTED_10baseT_Half |
+- SUPPORTED_10baseT_Full |
+- SUPPORTED_100baseT_Half |
+- SUPPORTED_100baseT_Full |
+- SUPPORTED_1000baseT_Full |
+- SUPPORTED_Autoneg |
+- SUPPORTED_TP;
+-
+- cmd->autoneg = 1;
+- cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
+-
+- if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
+- cmd->advertising |= ADVERTISED_10baseT_Half;
+- if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
+- cmd->advertising |= ADVERTISED_10baseT_Full;
+- if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
+- cmd->advertising |= ADVERTISED_100baseT_Half;
+- if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
+- cmd->advertising |= ADVERTISED_100baseT_Full;
+- if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
+- cmd->advertising |= ADVERTISED_1000baseT_Full;
+-
+- status = RTL_R8(PHYstatus);
+-
+- if (status & _1000bpsF)
+- cmd->speed = SPEED_1000;
+- else if (status & _100bps)
+- cmd->speed = SPEED_100;
+- else if (status & _10bps)
+- cmd->speed = SPEED_10;
+-
+- if (status & TxFlowCtrl)
+- cmd->advertising |= ADVERTISED_Asym_Pause;
+- if (status & RxFlowCtrl)
+- cmd->advertising |= ADVERTISED_Pause;
+-
+- cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
+- DUPLEX_FULL : DUPLEX_HALF;
++
++ return mii_ethtool_gset(&tp->mii, cmd);
+ }
+
+ static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+ unsigned long flags;
++ int rc;
+
+ spin_lock_irqsave(&tp->lock, flags);
+
+- tp->get_settings(dev, cmd);
++ rc = tp->get_settings(dev, cmd);
+
+ spin_unlock_irqrestore(&tp->lock, flags);
+- return 0;
++ return rc;
+ }
+
+ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+@@ -1513,7 +1501,7 @@ static const struct rtl_cfg_info {
+ unsigned int align;
+ u16 intr_event;
+ u16 napi_event;
+- unsigned msi;
++ unsigned features;
+ } rtl_cfg_infos [] = {
+ [RTL_CFG_0] = {
+ .hw_start = rtl_hw_start_8169,
+@@ -1522,7 +1510,7 @@ static const struct rtl_cfg_info {
+ .intr_event = SYSErr | LinkChg | RxOverflow |
+ RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
+ .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
+- .msi = 0
++ .features = RTL_FEATURE_GMII
+ },
+ [RTL_CFG_1] = {
+ .hw_start = rtl_hw_start_8168,
+@@ -1531,7 +1519,7 @@ static const struct rtl_cfg_info {
+ .intr_event = SYSErr | LinkChg | RxOverflow |
+ TxErr | TxOK | RxOK | RxErr,
+ .napi_event = TxErr | TxOK | RxOK | RxOverflow,
+- .msi = RTL_FEATURE_MSI
++ .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
+ },
+ [RTL_CFG_2] = {
+ .hw_start = rtl_hw_start_8101,
+@@ -1540,7 +1528,7 @@ static const struct rtl_cfg_info {
+ .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
+ RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
+ .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
+- .msi = RTL_FEATURE_MSI
++ .features = RTL_FEATURE_MSI
+ }
+ };
+
+@@ -1552,7 +1540,7 @@ static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr,
+ u8 cfg2;
+
+ cfg2 = RTL_R8(Config2) & ~MSIEnable;
+- if (cfg->msi) {
++ if (cfg->features & RTL_FEATURE_MSI) {
+ if (pci_enable_msi(pdev)) {
+ dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
+ } else {
+@@ -1578,6 +1566,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
+ const unsigned int region = cfg->region;
+ struct rtl8169_private *tp;
++ struct mii_if_info *mii;
+ struct net_device *dev;
+ void __iomem *ioaddr;
+ unsigned int i;
+@@ -1602,6 +1591,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ tp->pci_dev = pdev;
+ tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
+
++ mii = &tp->mii;
++ mii->dev = dev;
++ mii->mdio_read = rtl_mdio_read;
++ mii->mdio_write = rtl_mdio_write;
++ mii->phy_id_mask = 0x1f;
++ mii->reg_num_mask = 0x1f;
++ mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
++
+ /* enable device (incl. PCI PM wakeup and hotplug setup) */
+ rc = pci_enable_device(pdev);
+ if (rc < 0) {
+@@ -2099,8 +2096,6 @@ static void rtl_hw_start_8168(struct net_device *dev)
+
+ RTL_R8(IntrMask);
+
+- RTL_W32(RxMissed, 0);
+-
+ rtl_set_rx_mode(dev);
+
+ RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+@@ -2143,8 +2138,6 @@ static void rtl_hw_start_8101(struct net_device *dev)
+
+ RTL_R8(IntrMask);
+
+- RTL_W32(RxMissed, 0);
+-
+ rtl_set_rx_mode(dev);
+
+ RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+@@ -2922,6 +2915,17 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
+ return work_done;
+ }
+
++static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
++{
++ struct rtl8169_private *tp = netdev_priv(dev);
++
++ if (tp->mac_version > RTL_GIGA_MAC_VER_06)
++ return;
++
++ dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
++ RTL_W32(RxMissed, 0);
++}
++
+ static void rtl8169_down(struct net_device *dev)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+@@ -2939,9 +2943,7 @@ core_down:
+
+ rtl8169_asic_down(ioaddr);
+
+- /* Update the error counts. */
+- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
+- RTL_W32(RxMissed, 0);
++ rtl8169_rx_missed(dev, ioaddr);
+
+ spin_unlock_irq(&tp->lock);
+
+@@ -3063,8 +3065,7 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
+
+ if (netif_running(dev)) {
+ spin_lock_irqsave(&tp->lock, flags);
+- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
+- RTL_W32(RxMissed, 0);
++ rtl8169_rx_missed(dev, ioaddr);
+ spin_unlock_irqrestore(&tp->lock, flags);
+ }
+
+@@ -3089,8 +3090,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
+
+ rtl8169_asic_down(ioaddr);
+
+- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
+- RTL_W32(RxMissed, 0);
++ rtl8169_rx_missed(dev, ioaddr);
+
+ spin_unlock_irq(&tp->lock);
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+index 17d4f31..c479ee2 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
++++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+@@ -129,6 +129,13 @@ struct iwl5000_shared {
+ __le32 padding2;
+ } __attribute__ ((packed));
+
++/* calibrations defined for 5000 */
++/* defines the order in which results should be sent to the runtime uCode */
++enum iwl5000_calib {
++ IWL5000_CALIB_LO,
++ IWL5000_CALIB_TX_IQ,
++ IWL5000_CALIB_TX_IQ_PERD,
++};
+
+ #endif /* __iwl_5000_hw_h__ */
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
+index b08036a..79ff288 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
+@@ -445,48 +445,6 @@ static int iwl5000_send_Xtal_calib(struct iwl_priv *priv)
+ sizeof(cal_cmd), &cal_cmd);
+ }
+
+-static int iwl5000_send_calib_results(struct iwl_priv *priv)
+-{
+- int ret = 0;
+-
+- struct iwl_host_cmd hcmd = {
+- .id = REPLY_PHY_CALIBRATION_CMD,
+- .meta.flags = CMD_SIZE_HUGE,
+- };
+-
+- if (priv->calib_results.lo_res) {
+- hcmd.len = priv->calib_results.lo_res_len;
+- hcmd.data = priv->calib_results.lo_res;
+- ret = iwl_send_cmd_sync(priv, &hcmd);
+-
+- if (ret)
+- goto err;
+- }
+-
+- if (priv->calib_results.tx_iq_res) {
+- hcmd.len = priv->calib_results.tx_iq_res_len;
+- hcmd.data = priv->calib_results.tx_iq_res;
+- ret = iwl_send_cmd_sync(priv, &hcmd);
+-
+- if (ret)
+- goto err;
+- }
+-
+- if (priv->calib_results.tx_iq_perd_res) {
+- hcmd.len = priv->calib_results.tx_iq_perd_res_len;
+- hcmd.data = priv->calib_results.tx_iq_perd_res;
+- ret = iwl_send_cmd_sync(priv, &hcmd);
+-
+- if (ret)
+- goto err;
+- }
+-
+- return 0;
+-err:
+- IWL_ERROR("Error %d\n", ret);
+- return ret;
+-}
+-
+ static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
+ {
+ struct iwl5000_calib_cfg_cmd calib_cfg_cmd;
+@@ -511,33 +469,30 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl5000_calib_hdr *hdr = (struct iwl5000_calib_hdr *)pkt->u.raw;
+ int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK;
+-
+- iwl_free_calib_results(priv);
++ int index;
+
+ /* reduce the size of the length field itself */
+ len -= 4;
+
++ /* Define the order in which the results will be sent to the runtime
++ * uCode. iwl_send_calib_results sends them in a row according to their
++ * index. We sort them here */
+ switch (hdr->op_code) {
+ case IWL5000_PHY_CALIBRATE_LO_CMD:
+- priv->calib_results.lo_res = kzalloc(len, GFP_ATOMIC);
+- priv->calib_results.lo_res_len = len;
+- memcpy(priv->calib_results.lo_res, pkt->u.raw, len);
++ index = IWL5000_CALIB_LO;
+ break;
+ case IWL5000_PHY_CALIBRATE_TX_IQ_CMD:
+- priv->calib_results.tx_iq_res = kzalloc(len, GFP_ATOMIC);
+- priv->calib_results.tx_iq_res_len = len;
+- memcpy(priv->calib_results.tx_iq_res, pkt->u.raw, len);
++ index = IWL5000_CALIB_TX_IQ;
+ break;
+ case IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD:
+- priv->calib_results.tx_iq_perd_res = kzalloc(len, GFP_ATOMIC);
+- priv->calib_results.tx_iq_perd_res_len = len;
+- memcpy(priv->calib_results.tx_iq_perd_res, pkt->u.raw, len);
++ index = IWL5000_CALIB_TX_IQ_PERD;
+ break;
+ default:
+ IWL_ERROR("Unknown calibration notification %d\n",
+ hdr->op_code);
+ return;
+ }
++ iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
+ }
+
+ static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
+@@ -832,7 +787,7 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
+ iwl5000_send_Xtal_calib(priv);
+
+ if (priv->ucode_type == UCODE_RT)
+- iwl5000_send_calib_results(priv);
++ iwl_send_calib_results(priv);
+
+ return 0;
+ }
+diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
+index e01f048..72a6743 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
+@@ -2090,7 +2090,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
+ iwl4965_error_recovery(priv);
+
+ iwl_power_update_mode(priv, 1);
+- ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+
+ if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
+ iwl4965_set_mode(priv, priv->iw_mode);
+@@ -2342,6 +2341,7 @@ static void iwl_bg_alive_start(struct work_struct *data)
+ mutex_lock(&priv->mutex);
+ iwl_alive_start(priv);
+ mutex_unlock(&priv->mutex);
++ ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+ }
+
+ static void iwl4965_bg_rf_kill(struct work_struct *work)
+@@ -2486,6 +2486,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
+ if (!priv->vif || !priv->is_open)
+ return;
+
++ iwl_power_cancel_timeout(priv);
+ iwl_scan_cancel_timeout(priv, 200);
+
+ conf = ieee80211_get_hw_conf(priv->hw);
+@@ -2503,8 +2504,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
+
+ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+
+- if (priv->current_ht_config.is_ht)
+- iwl_set_rxon_ht(priv, &priv->current_ht_config);
++ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+
+ iwl_set_rxon_chain(priv);
+ priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
+@@ -2550,10 +2550,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
+ break;
+ }
+
+- /* Enable Rx differential gain and sensitivity calibrations */
+- iwl_chain_noise_reset(priv);
+- priv->start_calib = 1;
+-
+ if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
+ priv->assoc_station_added = 1;
+
+@@ -2561,7 +2557,12 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
+ iwl_activate_qos(priv, 0);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+- iwl_power_update_mode(priv, 0);
++ iwl_power_enable_management(priv);
++
++ /* Enable Rx differential gain and sensitivity calibrations */
++ iwl_chain_noise_reset(priv);
++ priv->start_calib = 1;
++
+ /* we have just associated, don't start scan too early */
+ priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
+ }
+@@ -3212,18 +3213,26 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
+ goto out_unlock;
+ }
+
+- /* we don't schedule scan within next_scan_jiffies period */
++ /* We don't schedule scan within next_scan_jiffies period.
++ * Avoid scanning during possible EAPOL exchange, return
++ * success immediately.
++ */
+ if (priv->next_scan_jiffies &&
+- time_after(priv->next_scan_jiffies, jiffies)) {
+- rc = -EAGAIN;
++ time_after(priv->next_scan_jiffies, jiffies)) {
++ IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
++ queue_work(priv->workqueue, &priv->scan_completed);
++ rc = 0;
+ goto out_unlock;
+ }
+ /* if we just finished scan ask for delay */
+- if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies +
+- IWL_DELAY_NEXT_SCAN, jiffies)) {
+- rc = -EAGAIN;
++ if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
++ time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
++ IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
++ queue_work(priv->workqueue, &priv->scan_completed);
++ rc = 0;
+ goto out_unlock;
+ }
++
+ if (len) {
+ IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
+ iwl_escape_essid(ssid, len), (int)len);
+@@ -3546,6 +3555,16 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
+ /* Per mac80211.h: This is only used in IBSS mode... */
+ if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {
+
++ /* switch to CAM during association period.
++ * the ucode will block any association/authentication
++ * frome during assiciation period if it can not hear
++ * the AP because of PM. the timer enable PM back is
++ * association do not complete
++ */
++ if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
++ IEEE80211_CHAN_RADAR))
++ iwl_power_disable_management(priv, 3000);
++
+ IWL_DEBUG_MAC80211("leave - not in IBSS\n");
+ mutex_unlock(&priv->mutex);
+ return;
+@@ -4083,6 +4102,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
+ /* FIXME : remove when resolved PENDING */
+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
+ iwl_setup_scan_deferred_work(priv);
++ iwl_setup_power_deferred_work(priv);
+
+ if (priv->cfg->ops->lib->setup_deferred_work)
+ priv->cfg->ops->lib->setup_deferred_work(priv);
+@@ -4102,6 +4122,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
+
+ cancel_delayed_work_sync(&priv->init_alive_start);
+ cancel_delayed_work(&priv->scan_check);
++ cancel_delayed_work_sync(&priv->set_power_save);
+ cancel_delayed_work(&priv->alive_start);
+ cancel_work_sync(&priv->beacon_update);
+ del_timer_sync(&priv->statistics_periodic);
+@@ -4204,13 +4225,13 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
+
+ pci_set_master(pdev);
+
+- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
++ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
+ if (!err)
+- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
++ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
+ if (err) {
+- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
++ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ if (!err)
+- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
++ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ /* both attempts failed: */
+ if (err) {
+ printk(KERN_WARNING "%s: No suitable DMA available.\n",
+diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
+index ef49440..35fb4a4 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
++++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
+@@ -66,6 +66,66 @@
+ #include "iwl-core.h"
+ #include "iwl-calib.h"
+
++/*****************************************************************************
++ * INIT calibrations framework
++ *****************************************************************************/
++
++ int iwl_send_calib_results(struct iwl_priv *priv)
++{
++ int ret = 0;
++ int i = 0;
++
++ struct iwl_host_cmd hcmd = {
++ .id = REPLY_PHY_CALIBRATION_CMD,
++ .meta.flags = CMD_SIZE_HUGE,
++ };
++
++ for (i = 0; i < IWL_CALIB_MAX; i++)
++ if (priv->calib_results[i].buf) {
++ hcmd.len = priv->calib_results[i].buf_len;
++ hcmd.data = priv->calib_results[i].buf;
++ ret = iwl_send_cmd_sync(priv, &hcmd);
++ if (ret)
++ goto err;
++ }
++
++ return 0;
++err:
++ IWL_ERROR("Error %d iteration %d\n", ret, i);
++ return ret;
++}
++EXPORT_SYMBOL(iwl_send_calib_results);
++
++int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len)
++{
++ if (res->buf_len != len) {
++ kfree(res->buf);
++ res->buf = kzalloc(len, GFP_ATOMIC);
++ }
++ if (unlikely(res->buf == NULL))
++ return -ENOMEM;
++
++ res->buf_len = len;
++ memcpy(res->buf, buf, len);
++ return 0;
++}
++EXPORT_SYMBOL(iwl_calib_set);
++
++void iwl_calib_free_results(struct iwl_priv *priv)
++{
++ int i;
++
++ for (i = 0; i < IWL_CALIB_MAX; i++) {
++ kfree(priv->calib_results[i].buf);
++ priv->calib_results[i].buf = NULL;
++ priv->calib_results[i].buf_len = 0;
++ }
++}
++
++/*****************************************************************************
++ * RUNTIME calibrations framework
++ *****************************************************************************/
++
+ /* "false alarms" are signals that our DSP tries to lock onto,
+ * but then determines that they are either noise, or transmissions
+ * from a distant wireless network (also "noise", really) that get
+diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
+index 80f2f84..1383fd1 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-core.c
++++ b/drivers/net/wireless/iwlwifi/iwl-core.c
+@@ -646,8 +646,14 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ u32 val;
+
+- if (!ht_info->is_ht)
++ if (!ht_info->is_ht) {
++ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
++ RXON_FLG_CHANNEL_MODE_PURE_40_MSK |
++ RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
++ RXON_FLG_FAT_PROT_MSK |
++ RXON_FLG_HT_PROT_MSK);
+ return;
++ }
+
+ /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */
+ if (iwl_is_fat_tx_allowed(priv, NULL))
+@@ -950,22 +956,6 @@ err:
+ }
+ EXPORT_SYMBOL(iwl_init_drv);
+
+-void iwl_free_calib_results(struct iwl_priv *priv)
+-{
+- kfree(priv->calib_results.lo_res);
+- priv->calib_results.lo_res = NULL;
+- priv->calib_results.lo_res_len = 0;
+-
+- kfree(priv->calib_results.tx_iq_res);
+- priv->calib_results.tx_iq_res = NULL;
+- priv->calib_results.tx_iq_res_len = 0;
+-
+- kfree(priv->calib_results.tx_iq_perd_res);
+- priv->calib_results.tx_iq_perd_res = NULL;
+- priv->calib_results.tx_iq_perd_res_len = 0;
+-}
+-EXPORT_SYMBOL(iwl_free_calib_results);
+-
+ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
+ {
+ int ret = 0;
+@@ -993,10 +983,9 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
+ }
+ EXPORT_SYMBOL(iwl_set_tx_power);
+
+-
+ void iwl_uninit_drv(struct iwl_priv *priv)
+ {
+- iwl_free_calib_results(priv);
++ iwl_calib_free_results(priv);
+ iwlcore_free_geos(priv);
+ iwl_free_channel_map(priv);
+ kfree(priv->scan);
+diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
+index 64f139e..51b36b1 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-core.h
++++ b/drivers/net/wireless/iwlwifi/iwl-core.h
+@@ -186,7 +186,6 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
+ void iwl_hw_detect(struct iwl_priv *priv);
+
+ void iwl_clear_stations_table(struct iwl_priv *priv);
+-void iwl_free_calib_results(struct iwl_priv *priv);
+ void iwl_reset_qos(struct iwl_priv *priv);
+ void iwl_set_rxon_chain(struct iwl_priv *priv);
+ int iwl_set_rxon_channel(struct iwl_priv *priv,
+@@ -291,6 +290,13 @@ int iwl_scan_initiate(struct iwl_priv *priv);
+ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
+ void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+
++/*******************************************************************************
++ * Calibrations - implemented in iwl-calib.c
++ ******************************************************************************/
++int iwl_send_calib_results(struct iwl_priv *priv);
++int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
++void iwl_calib_free_results(struct iwl_priv *priv);
++
+ /*****************************************************
+ * S e n d i n g H o s t C o m m a n d s *
+ *****************************************************/
+diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
+index cdfb343..09bdf8e 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
++++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
+@@ -745,13 +745,10 @@ struct statistics_general_data {
+ u32 beacon_energy_c;
+ };
+
+-struct iwl_calib_results {
+- void *tx_iq_res;
+- void *tx_iq_perd_res;
+- void *lo_res;
+- u32 tx_iq_res_len;
+- u32 tx_iq_perd_res_len;
+- u32 lo_res_len;
++/* Opaque calibration results */
++struct iwl_calib_result {
++ void *buf;
++ size_t buf_len;
+ };
+
+ enum ucode_type {
+@@ -813,6 +810,7 @@ enum {
+
+
+ #define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
++#define IWL_CALIB_MAX 3
+
+ struct iwl_priv {
+
+@@ -857,7 +855,7 @@ struct iwl_priv {
+ s32 last_temperature;
+
+ /* init calibration results */
+- struct iwl_calib_results calib_results;
++ struct iwl_calib_result calib_results[IWL_CALIB_MAX];
+
+ /* Scan related variables */
+ unsigned long last_scan_jiffies;
+@@ -1047,6 +1045,7 @@ struct iwl_priv {
+
+ struct tasklet_struct irq_tasklet;
+
++ struct delayed_work set_power_save;
+ struct delayed_work init_alive_start;
+ struct delayed_work alive_start;
+ struct delayed_work scan_check;
+diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
+index a099c9e..ae60bfd 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-power.c
++++ b/drivers/net/wireless/iwlwifi/iwl-power.c
+@@ -324,7 +324,7 @@ EXPORT_SYMBOL(iwl_power_update_mode);
+ * this will be usefull for rate scale to disable PM during heavy
+ * Tx/Rx activities
+ */
+-int iwl_power_disable_management(struct iwl_priv *priv)
++int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
+ {
+ u16 prev_mode;
+ int ret = 0;
+@@ -337,6 +337,11 @@ int iwl_power_disable_management(struct iwl_priv *priv)
+ ret = iwl_power_update_mode(priv, 0);
+ priv->power_data.power_disabled = 1;
+ priv->power_data.user_power_setting = prev_mode;
++ cancel_delayed_work(&priv->set_power_save);
++ if (ms)
++ queue_delayed_work(priv->workqueue, &priv->set_power_save,
++ msecs_to_jiffies(ms));
++
+
+ return ret;
+ }
+@@ -431,3 +436,35 @@ int iwl_power_temperature_change(struct iwl_priv *priv)
+ return ret;
+ }
+ EXPORT_SYMBOL(iwl_power_temperature_change);
++
++static void iwl_bg_set_power_save(struct work_struct *work)
++{
++ struct iwl_priv *priv = container_of(work,
++ struct iwl_priv, set_power_save.work);
++ IWL_DEBUG(IWL_DL_STATE, "update power\n");
++
++ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
++ return;
++
++ mutex_lock(&priv->mutex);
++
++ /* on starting association we disable power managment
++ * until association, if association failed then this
++ * timer will expire and enable PM again.
++ */
++ if (!iwl_is_associated(priv))
++ iwl_power_enable_management(priv);
++
++ mutex_unlock(&priv->mutex);
++}
++void iwl_setup_power_deferred_work(struct iwl_priv *priv)
++{
++ INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save);
++}
++EXPORT_SYMBOL(iwl_setup_power_deferred_work);
++
++void iwl_power_cancel_timeout(struct iwl_priv *priv)
++{
++ cancel_delayed_work(&priv->set_power_save);
++}
++EXPORT_SYMBOL(iwl_power_cancel_timeout);
+diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
+index abcbbf9..aa99f36 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-power.h
++++ b/drivers/net/wireless/iwlwifi/iwl-power.h
+@@ -78,8 +78,10 @@ struct iwl_power_mgr {
+ u8 power_disabled; /* flag to disable using power saving level */
+ };
+
++void iwl_setup_power_deferred_work(struct iwl_priv *priv);
++void iwl_power_cancel_timeout(struct iwl_priv *priv);
+ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh);
+-int iwl_power_disable_management(struct iwl_priv *priv);
++int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
+ int iwl_power_enable_management(struct iwl_priv *priv);
+ int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
+ int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);
+diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
+index 6c8ac3a..3a90a67 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
++++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
+@@ -464,11 +464,6 @@ void iwl_init_scan_params(struct iwl_priv *priv)
+
+ int iwl_scan_initiate(struct iwl_priv *priv)
+ {
+- if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
+- IWL_ERROR("APs don't scan.\n");
+- return 0;
+- }
+-
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
+ return -EIO;
+@@ -480,8 +475,7 @@ int iwl_scan_initiate(struct iwl_priv *priv)
+ }
+
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+- IWL_DEBUG_SCAN("Scan request while abort pending. "
+- "Queuing.\n");
++ IWL_DEBUG_SCAN("Scan request while abort pending\n");
+ return -EAGAIN;
+ }
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+index b775d5b..752e7f8 100644
+--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+@@ -5761,7 +5761,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
+ if (priv->error_recovering)
+ iwl3945_error_recovery(priv);
+
+- ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+ return;
+
+ restart:
+@@ -6006,6 +6005,7 @@ static void iwl3945_bg_alive_start(struct work_struct *data)
+ mutex_lock(&priv->mutex);
+ iwl3945_alive_start(priv);
+ mutex_unlock(&priv->mutex);
++ ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+ }
+
+ static void iwl3945_bg_rf_kill(struct work_struct *work)
+@@ -6259,6 +6259,11 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
+ direct_mask,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+
++ if (scan->channel_count == 0) {
++ IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
++ goto done;
++ }
++
+ cmd.len += le16_to_cpu(scan->tx_cmd.len) +
+ scan->channel_count * sizeof(struct iwl3945_scan_channel);
+ cmd.data = scan;
+diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
+index a60ae86..a3ccd8c 100644
+--- a/drivers/net/wireless/zd1211rw/zd_usb.c
++++ b/drivers/net/wireless/zd1211rw/zd_usb.c
+@@ -61,6 +61,7 @@ static struct usb_device_id usb_ids[] = {
+ { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 },
+ /* ZD1211B */
+ { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
++ { USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
+@@ -82,6 +83,7 @@ static struct usb_device_id usb_ids[] = {
+ { USB_DEVICE(0x0cde, 0x001a), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
++ { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
+ /* "Driverless" devices that need ejecting */
+ { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
+ { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
+diff --git a/fs/ext3/super.c b/fs/ext3/super.c
+index f38a5af..810bf7c 100644
+--- a/fs/ext3/super.c
++++ b/fs/ext3/super.c
+@@ -2365,13 +2365,12 @@ static void ext3_write_super (struct super_block * sb)
+
+ static int ext3_sync_fs(struct super_block *sb, int wait)
+ {
+- tid_t target;
+-
+ sb->s_dirt = 0;
+- if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
+- if (wait)
+- log_wait_commit(EXT3_SB(sb)->s_journal, target);
+- }
++ if (wait)
++ ext3_force_commit(sb);
++ else
++ journal_start_commit(EXT3_SB(sb)->s_journal, NULL);
++
+ return 0;
+ }
+
+diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c
+index ba85157..6d98f11 100644
+--- a/fs/hfs/catalog.c
++++ b/fs/hfs/catalog.c
+@@ -190,6 +190,10 @@ int hfs_cat_find_brec(struct super_block *sb, u32 cnid,
+
+ fd->search_key->cat.ParID = rec.thread.ParID;
+ len = fd->search_key->cat.CName.len = rec.thread.CName.len;
++ if (len > HFS_NAMELEN) {
++ printk(KERN_ERR "hfs: bad catalog namelength\n");
++ return -EIO;
++ }
+ memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len);
+ return hfs_brec_find(fd);
+ }
+diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
+index 8adebd3..0fd792b 100644
+--- a/fs/jffs2/background.c
++++ b/fs/jffs2/background.c
+@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread(void *_c)
+ for (;;) {
+ allow_signal(SIGHUP);
+ again:
++ spin_lock(&c->erase_completion_lock);
+ if (!jffs2_thread_should_wake(c)) {
+ set_current_state (TASK_INTERRUPTIBLE);
++ spin_unlock(&c->erase_completion_lock);
+ D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
+- /* Yes, there's a race here; we checked jffs2_thread_should_wake()
+- before setting current->state to TASK_INTERRUPTIBLE. But it doesn't
+- matter - We don't care if we miss a wakeup, because the GC thread
+- is only an optimisation anyway. */
+ schedule();
+- }
++ } else
++ spin_unlock(&c->erase_completion_lock);
++
+
+ /* This thread is purely an optimisation. But if it runs when
+ other things could be running, it actually makes things a
+diff --git a/fs/jffs2/compr_lzo.c b/fs/jffs2/compr_lzo.c
+index 47b0457..90cb60d 100644
+--- a/fs/jffs2/compr_lzo.c
++++ b/fs/jffs2/compr_lzo.c
+@@ -19,7 +19,7 @@
+
+ static void *lzo_mem;
+ static void *lzo_compress_buf;
+-static DEFINE_MUTEX(deflate_mutex);
++static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */
+
+ static void free_workspace(void)
+ {
+@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out,
+
+ mutex_lock(&deflate_mutex);
+ ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem);
+- mutex_unlock(&deflate_mutex);
+-
+ if (ret != LZO_E_OK)
+- return -1;
++ goto fail;
+
+ if (compress_size > *dstlen)
+- return -1;
++ goto fail;
+
+ memcpy(cpage_out, lzo_compress_buf, compress_size);
+- *dstlen = compress_size;
++ mutex_unlock(&deflate_mutex);
+
++ *dstlen = compress_size;
+ return 0;
++
++ fail:
++ mutex_unlock(&deflate_mutex);
++ return -1;
+ }
+
+ static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
+diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
+index ae060c6..18546d8 100644
+--- a/include/asm-generic/memory_model.h
++++ b/include/asm-generic/memory_model.h
+@@ -34,7 +34,7 @@
+
+ #define __pfn_to_page(pfn) \
+ ({ unsigned long __pfn = (pfn); \
+- unsigned long __nid = arch_pfn_to_nid(pfn); \
++ unsigned long __nid = arch_pfn_to_nid(__pfn); \
+ NODE_DATA(__nid)->node_mem_map + arch_local_page_offset(__pfn, __nid);\
+ })
+
+diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
+index d6fb115..3a16bea 100644
+--- a/include/linux/mtd/cfi.h
++++ b/include/linux/mtd/cfi.h
+@@ -281,9 +281,25 @@ struct cfi_private {
+ /*
+ * Returns the command address according to the given geometry.
+ */
+-static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int type)
++static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs,
++ struct map_info *map, struct cfi_private *cfi)
+ {
+- return (cmd_ofs * type) * interleave;
++ unsigned bankwidth = map_bankwidth(map);
++ unsigned interleave = cfi_interleave(cfi);
++ unsigned type = cfi->device_type;
++ uint32_t addr;
++
++ addr = (cmd_ofs * type) * interleave;
++
++ /* Modify the unlock address if we are in compatiblity mode.
++ * For 16bit devices on 8 bit busses
++ * and 32bit devices on 16 bit busses
++ * set the low bit of the alternating bit sequence of the address.
++ */
++ if (((type * interleave) > bankwidth) && ((uint8_t)cmd_ofs == 0xaa))
++ addr |= (type >> 1)*interleave;
++
++ return addr;
+ }
+
+ /*
+@@ -429,7 +445,7 @@ static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t
+ int type, map_word *prev_val)
+ {
+ map_word val;
+- uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type);
++ uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, map, cfi);
+
+ val = cfi_build_cmd(cmd, map, cfi);
+
+diff --git a/include/net/af_unix.h b/include/net/af_unix.h
+index 7dd29b7..c29ff1d 100644
+--- a/include/net/af_unix.h
++++ b/include/net/af_unix.h
+@@ -54,6 +54,7 @@ struct unix_sock {
+ atomic_long_t inflight;
+ spinlock_t lock;
+ unsigned int gc_candidate : 1;
++ unsigned int gc_maybe_cycle : 1;
+ wait_queue_head_t peer_wait;
+ };
+ #define unix_sk(__sk) ((struct unix_sock *)__sk)
+diff --git a/kernel/cgroup.c b/kernel/cgroup.c
+index a0123d7..d68bf2b 100644
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -2443,7 +2443,6 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
+ list_del(&cgrp->sibling);
+ spin_lock(&cgrp->dentry->d_lock);
+ d = dget(cgrp->dentry);
+- cgrp->dentry = NULL;
+ spin_unlock(&d->d_lock);
+
+ cgroup_d_remove_dir(d);
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 67a7119..77427c8 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -353,11 +353,26 @@ static int vma_has_reserves(struct vm_area_struct *vma)
+ return 0;
+ }
+
++static void clear_gigantic_page(struct page *page,
++ unsigned long addr, unsigned long sz)
++{
++ int i;
++ struct page *p = page;
++
++ might_sleep();
++ for (i = 0; i < sz/PAGE_SIZE; i++, p = mem_map_next(p, page, i)) {
++ cond_resched();
++ clear_user_highpage(p, addr + i * PAGE_SIZE);
++ }
++}
+ static void clear_huge_page(struct page *page,
+ unsigned long addr, unsigned long sz)
+ {
+ int i;
+
++ if (unlikely(sz > MAX_ORDER_NR_PAGES))
++ return clear_gigantic_page(page, addr, sz);
++
+ might_sleep();
+ for (i = 0; i < sz/PAGE_SIZE; i++) {
+ cond_resched();
+@@ -365,12 +380,32 @@ static void clear_huge_page(struct page *page,
+ }
+ }
+
++static void copy_gigantic_page(struct page *dst, struct page *src,
++ unsigned long addr, struct vm_area_struct *vma)
++{
++ int i;
++ struct hstate *h = hstate_vma(vma);
++ struct page *dst_base = dst;
++ struct page *src_base = src;
++ might_sleep();
++ for (i = 0; i < pages_per_huge_page(h); ) {
++ cond_resched();
++ copy_user_highpage(dst, src, addr + i*PAGE_SIZE, vma);
++
++ i++;
++ dst = mem_map_next(dst, dst_base, i);
++ src = mem_map_next(src, src_base, i);
++ }
++}
+ static void copy_huge_page(struct page *dst, struct page *src,
+ unsigned long addr, struct vm_area_struct *vma)
+ {
+ int i;
+ struct hstate *h = hstate_vma(vma);
+
++ if (unlikely(pages_per_huge_page(h) > MAX_ORDER_NR_PAGES))
++ return copy_gigantic_page(dst, src, addr, vma);
++
+ might_sleep();
+ for (i = 0; i < pages_per_huge_page(h); i++) {
+ cond_resched();
+@@ -455,6 +490,8 @@ static void update_and_free_page(struct hstate *h, struct page *page)
+ {
+ int i;
+
++ VM_BUG_ON(h->order >= MAX_ORDER);
++
+ h->nr_huge_pages--;
+ h->nr_huge_pages_node[page_to_nid(page)]--;
+ for (i = 0; i < pages_per_huge_page(h); i++) {
+@@ -969,6 +1006,14 @@ found:
+ return 1;
+ }
+
++static void prep_compound_huge_page(struct page *page, int order)
++{
++ if (unlikely(order > (MAX_ORDER - 1)))
++ prep_compound_gigantic_page(page, order);
++ else
++ prep_compound_page(page, order);
++}
++
+ /* Put bootmem huge pages into the standard lists after mem_map is up */
+ static void __init gather_bootmem_prealloc(void)
+ {
+@@ -979,7 +1024,7 @@ static void __init gather_bootmem_prealloc(void)
+ struct hstate *h = m->hstate;
+ __ClearPageReserved(page);
+ WARN_ON(page_count(page) != 1);
+- prep_compound_page(page, h->order);
++ prep_compound_huge_page(page, h->order);
+ prep_new_huge_page(h, page, page_to_nid(page));
+ }
+ }
+@@ -2103,7 +2148,7 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ same_page:
+ if (pages) {
+ get_page(page);
+- pages[i] = page + pfn_offset;
++ pages[i] = mem_map_offset(page, pfn_offset);
+ }
+
+ if (vmas)
+diff --git a/mm/internal.h b/mm/internal.h
+index 1f43f74..92729ea 100644
+--- a/mm/internal.h
++++ b/mm/internal.h
+@@ -17,6 +17,7 @@ void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
+ unsigned long floor, unsigned long ceiling);
+
+ extern void prep_compound_page(struct page *page, unsigned long order);
++extern void prep_compound_gigantic_page(struct page *page, unsigned long order);
+
+ static inline void set_page_count(struct page *page, int v)
+ {
+@@ -53,6 +54,34 @@ static inline unsigned long page_order(struct page *page)
+ }
+
+ /*
++ * Return the mem_map entry representing the 'offset' subpage within
++ * the maximally aligned gigantic page 'base'. Handle any discontiguity
++ * in the mem_map at MAX_ORDER_NR_PAGES boundaries.
++ */
++static inline struct page *mem_map_offset(struct page *base, int offset)
++{
++ if (unlikely(offset >= MAX_ORDER_NR_PAGES))
++ return pfn_to_page(page_to_pfn(base) + offset);
++ return base + offset;
++}
++
++/*
++ * Iterator over all subpages withing the maximally aligned gigantic
++ * page 'base'. Handle any discontiguity in the mem_map.
++ */
++static inline struct page *mem_map_next(struct page *iter,
++ struct page *base, int offset)
++{
++ if (unlikely((offset & (MAX_ORDER_NR_PAGES - 1)) == 0)) {
++ unsigned long pfn = page_to_pfn(base) + offset;
++ if (!pfn_valid(pfn))
++ return NULL;
++ return pfn_to_page(pfn);
++ }
++ return iter + 1;
++}
++
++/*
+ * FLATMEM and DISCONTIGMEM configurations use alloc_bootmem_node,
+ * so all functions starting at paging_init should be marked __init
+ * in those cases. SPARSEMEM, however, allows for memory hotplug,
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 27b8681..ed5cdae 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -268,24 +268,39 @@ void prep_compound_page(struct page *page, unsigned long order)
+ {
+ int i;
+ int nr_pages = 1 << order;
++
++ set_compound_page_dtor(page, free_compound_page);
++ set_compound_order(page, order);
++ __SetPageHead(page);
++ for (i = 1; i < nr_pages; i++) {
++ struct page *p = page + i;
++
++ __SetPageTail(p);
++ p->first_page = page;
++ }
++}
++
++#ifdef CONFIG_HUGETLBFS
++void prep_compound_gigantic_page(struct page *page, unsigned long order)
++{
++ int i;
++ int nr_pages = 1 << order;
+ struct page *p = page + 1;
+
+ set_compound_page_dtor(page, free_compound_page);
+ set_compound_order(page, order);
+ __SetPageHead(page);
+- for (i = 1; i < nr_pages; i++, p++) {
+- if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0))
+- p = pfn_to_page(page_to_pfn(page) + i);
++ for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
+ __SetPageTail(p);
+ p->first_page = page;
+ }
+ }
++#endif
+
+ static void destroy_compound_page(struct page *page, unsigned long order)
+ {
+ int i;
+ int nr_pages = 1 << order;
+- struct page *p = page + 1;
+
+ if (unlikely(compound_order(page) != order))
+ bad_page(page);
+@@ -293,9 +308,8 @@ static void destroy_compound_page(struct page *page, unsigned long order)
+ if (unlikely(!PageHead(page)))
+ bad_page(page);
+ __ClearPageHead(page);
+- for (i = 1; i < nr_pages; i++, p++) {
+- if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0))
+- p = pfn_to_page(page_to_pfn(page) + i);
++ for (i = 1; i < nr_pages; i++) {
++ struct page *p = page + i;
+
+ if (unlikely(!PageTail(p) |
+ (p->first_page != page)))
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 015606b..8bde9bf 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1300,14 +1300,23 @@ static void unix_destruct_fds(struct sk_buff *skb)
+ sock_wfree(skb);
+ }
+
+-static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
++static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+ {
+ int i;
++
++ /*
++ * Need to duplicate file references for the sake of garbage
++ * collection. Otherwise a socket in the fps might become a
++ * candidate for GC while the skb is not yet queued.
++ */
++ UNIXCB(skb).fp = scm_fp_dup(scm->fp);
++ if (!UNIXCB(skb).fp)
++ return -ENOMEM;
++
+ for (i=scm->fp->count-1; i>=0; i--)
+ unix_inflight(scm->fp->fp[i]);
+- UNIXCB(skb).fp = scm->fp;
+ skb->destructor = unix_destruct_fds;
+- scm->fp = NULL;
++ return 0;
+ }
+
+ /*
+@@ -1366,8 +1375,11 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
+ goto out;
+
+ memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
+- if (siocb->scm->fp)
+- unix_attach_fds(siocb->scm, skb);
++ if (siocb->scm->fp) {
++ err = unix_attach_fds(siocb->scm, skb);
++ if (err)
++ goto out_free;
++ }
+ unix_get_secdata(siocb->scm, skb);
+
+ skb_reset_transport_header(skb);
+@@ -1536,8 +1548,13 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
+ size = min_t(int, size, skb_tailroom(skb));
+
+ memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
+- if (siocb->scm->fp)
+- unix_attach_fds(siocb->scm, skb);
++ if (siocb->scm->fp) {
++ err = unix_attach_fds(siocb->scm, skb);
++ if (err) {
++ kfree_skb(skb);
++ goto out_err;
++ }
++ }
+
+ if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) {
+ kfree_skb(skb);
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 2a27b84..6d4a9a8 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -186,8 +186,17 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
+ */
+ struct sock *sk = unix_get_socket(*fp++);
+ if (sk) {
+- hit = true;
+- func(unix_sk(sk));
++ struct unix_sock *u = unix_sk(sk);
++
++ /*
++ * Ignore non-candidates, they could
++ * have been added to the queues after
++ * starting the garbage collection
++ */
++ if (u->gc_candidate) {
++ hit = true;
++ func(u);
++ }
+ }
+ }
+ if (hit && hitlist != NULL) {
+@@ -249,11 +258,11 @@ static void inc_inflight_move_tail(struct unix_sock *u)
+ {
+ atomic_long_inc(&u->inflight);
+ /*
+- * If this is still a candidate, move it to the end of the
+- * list, so that it's checked even if it was already passed
+- * over
++ * If this still might be part of a cycle, move it to the end
++ * of the list, so that it's checked even if it was already
++ * passed over
+ */
+- if (u->gc_candidate)
++ if (u->gc_maybe_cycle)
+ list_move_tail(&u->link, &gc_candidates);
+ }
+
+@@ -267,6 +276,7 @@ void unix_gc(void)
+ struct unix_sock *next;
+ struct sk_buff_head hitlist;
+ struct list_head cursor;
++ LIST_HEAD(not_cycle_list);
+
+ spin_lock(&unix_gc_lock);
+
+@@ -282,10 +292,14 @@ void unix_gc(void)
+ *
+ * Holding unix_gc_lock will protect these candidates from
+ * being detached, and hence from gaining an external
+- * reference. This also means, that since there are no
+- * possible receivers, the receive queues of these sockets are
+- * static during the GC, even though the dequeue is done
+- * before the detach without atomicity guarantees.
++ * reference. Since there are no possible receivers, all
++ * buffers currently on the candidates' queues stay there
++ * during the garbage collection.
++ *
++ * We also know that no new candidate can be added onto the
++ * receive queues. Other, non candidate sockets _can_ be
++ * added to queue, so we must make sure only to touch
++ * candidates.
+ */
+ list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
+ long total_refs;
+@@ -299,6 +313,7 @@ void unix_gc(void)
+ if (total_refs == inflight_refs) {
+ list_move_tail(&u->link, &gc_candidates);
+ u->gc_candidate = 1;
++ u->gc_maybe_cycle = 1;
+ }
+ }
+
+@@ -325,14 +340,24 @@ void unix_gc(void)
+ list_move(&cursor, &u->link);
+
+ if (atomic_long_read(&u->inflight) > 0) {
+- list_move_tail(&u->link, &gc_inflight_list);
+- u->gc_candidate = 0;
++ list_move_tail(&u->link, ¬_cycle_list);
++ u->gc_maybe_cycle = 0;
+ scan_children(&u->sk, inc_inflight_move_tail, NULL);
+ }
+ }
+ list_del(&cursor);
+
+ /*
++ * not_cycle_list contains those sockets which do not make up a
++ * cycle. Restore these to the inflight list.
++ */
++ while (!list_empty(¬_cycle_list)) {
++ u = list_entry(not_cycle_list.next, struct unix_sock, link);
++ u->gc_candidate = 0;
++ list_move_tail(&u->link, &gc_inflight_list);
++ }
++
++ /*
+ * Now gc_candidates contains only garbage. Restore original
+ * inflight counters for these as well, and remove the skbuffs
+ * which are creating the cycle(s).
+diff --git a/security/keys/internal.h b/security/keys/internal.h
+index b39f5c2..239098f 100644
+--- a/security/keys/internal.h
++++ b/security/keys/internal.h
+@@ -107,6 +107,7 @@ extern key_ref_t search_process_keyrings(struct key_type *type,
+
+ extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
+
++extern int install_user_keyrings(struct task_struct *tsk);
+ extern int install_thread_keyring(struct task_struct *tsk);
+ extern int install_process_keyring(struct task_struct *tsk);
+
+diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
+index 5be6d01..45b240a 100644
+--- a/security/keys/process_keys.c
++++ b/security/keys/process_keys.c
+@@ -40,7 +40,7 @@ struct key_user root_key_user = {
+ /*
+ * install user and user session keyrings for a particular UID
+ */
+-static int install_user_keyrings(struct task_struct *tsk)
++int install_user_keyrings(struct task_struct *tsk)
+ {
+ struct user_struct *user = tsk->user;
+ struct key *uid_keyring, *session_keyring;
+diff --git a/security/keys/request_key.c b/security/keys/request_key.c
+index ba32ca6..abea08f 100644
+--- a/security/keys/request_key.c
++++ b/security/keys/request_key.c
+@@ -74,6 +74,10 @@ static int call_sbin_request_key(struct key_construction *cons,
+
+ kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
+
++ ret = install_user_keyrings(tsk);
++ if (ret < 0)
++ goto error_alloc;
++
+ /* allocate a new session keyring */
+ sprintf(desc, "_req.%u", key->serial);
+
+diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
+index f3da621..732ce13 100644
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -67,6 +67,7 @@ enum {
+ enum {
+ STAC_92HD73XX_REF,
+ STAC_DELL_M6,
++ STAC_DELL_EQ,
+ STAC_92HD73XX_MODELS
+ };
+
+@@ -560,9 +561,7 @@ static struct hda_verb dell_eq_core_init[] = {
+ };
+
+ static struct hda_verb dell_m6_core_init[] = {
+- /* set master volume to max value without distortion
+- * and direct control */
+- { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
++ { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
+ /* setup audio connections */
+ { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
+ { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
+@@ -1297,11 +1296,13 @@ static unsigned int dell_m6_pin_configs[13] = {
+ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
+ [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
+ [STAC_DELL_M6] = dell_m6_pin_configs,
++ [STAC_DELL_EQ] = dell_m6_pin_configs,
+ };
+
+ static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
+ [STAC_92HD73XX_REF] = "ref",
+ [STAC_DELL_M6] = "dell-m6",
++ [STAC_DELL_EQ] = "dell-eq",
+ };
+
+ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
+@@ -3560,8 +3561,12 @@ again:
+ spec->gpio_data = 0x01;
+
+ switch (spec->board_config) {
+- case STAC_DELL_M6:
++ case STAC_DELL_EQ:
+ spec->init = dell_eq_core_init;
++ /* fallthru */
++ case STAC_DELL_M6:
++ if (!spec->init)
++ spec->init = dell_m6_core_init;
+ switch (codec->subsystem_id) {
+ case 0x1028025e: /* Analog Mics */
+ case 0x1028025f:
+@@ -3570,8 +3575,6 @@ again:
+ break;
+ case 0x10280271: /* Digital Mics */
+ case 0x10280272:
+- spec->init = dell_m6_core_init;
+- /* fall-through */
+ case 0x10280254:
+ case 0x10280255:
+ stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.1 (original)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.1 Sun Nov 16 09:28:39 2008
@@ -25,3 +25,9 @@
+ bugfix/fix-hifn_795X-divdi3.patch
+ bugfix/powerpc/mm-mol.patch
#+ bugfix/powerpc/lpar-console.patch
++ bugfix/all/stable/patch-2.6.27.1
++ bugfix/all/stable/patch-2.6.27.2
++ bugfix/all/stable/patch-2.6.27.3
++ bugfix/all/stable/patch-2.6.27.4
++ bugfix/all/stable/patch-2.6.27.5
++ bugfix/all/stable/patch-2.6.27.6
More information about the Kernel-svn-changes
mailing list