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. ;) svn path=/dists/trunk/linux-2.6/; revision=12385
This commit is contained in:
parent
12ae86bf23
commit
85b9d39839
|
@ -13,6 +13,7 @@ linux-2.6 (2.6.27-1~experimental.1) UNRELEASED; urgency=low
|
|||
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.
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue