]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
some last .22 patches.
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 6 Feb 2008 22:50:59 +0000 (14:50 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 6 Feb 2008 22:50:59 +0000 (14:50 -0800)
queue-2.6.22/pci-fix-fakephp-deadlock.patch [new file with mode: 0644]
queue-2.6.22/quicklists-do-not-release-off-node-pages-early.patch [new file with mode: 0644]
queue-2.6.22/sata_promise-asic-prd-table-bug-workaround.patch [new file with mode: 0644]
queue-2.6.22/sata_promise-fasttrack-tx4200-is-a-second-generation-chip.patch [new file with mode: 0644]
queue-2.6.22/series [new file with mode: 0644]

diff --git a/queue-2.6.22/pci-fix-fakephp-deadlock.patch b/queue-2.6.22/pci-fix-fakephp-deadlock.patch
new file mode 100644 (file)
index 0000000..6fe26fc
--- /dev/null
@@ -0,0 +1,138 @@
+From stable-bounces@linux.kernel.org Mon Feb  4 05:57:09 2008
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Mon, 04 Feb 2008 13:56:36 +0000
+Subject: PCI: Fix fakephp deadlock
+To: stable@kernel.org
+Cc: linux-pci@atrey.karlin.mff.cuni.cz, linux-kernel@vger.kernel.org
+Message-ID: <47A71994.3050409@mev.co.uk>
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+This patch works around a problem in the fakephp driver when a process
+writing "0" to a "power" sysfs file to fake removal of a PCI device ends
+up deadlocking itself in the sysfs code.
+
+The patch is functionally identical to the one in Linus' tree post 2.6.24:
+http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=5c796ae7a7ebe56967ed9b9963d7c16d733635ff
+
+I have tested it on a 2.6.22 kernel.
+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/hotplug/fakephp.c |   39 +++++++++++++++++++++++++++++++++++----
+ 1 file changed, 35 insertions(+), 4 deletions(-)
+
+--- a/drivers/pci/hotplug/fakephp.c
++++ b/drivers/pci/hotplug/fakephp.c
+@@ -39,6 +39,7 @@
+ #include <linux/init.h>
+ #include <linux/string.h>
+ #include <linux/slab.h>
++#include <linux/workqueue.h>
+ #include "../pci.h"
+ #if !defined(MODULE)
+@@ -63,10 +64,16 @@ struct dummy_slot {
+       struct list_head node;
+       struct hotplug_slot *slot;
+       struct pci_dev *dev;
++      struct work_struct remove_work;
++      unsigned long removed;
+ };
+ static int debug;
+ static LIST_HEAD(slot_list);
++static struct workqueue_struct *dummyphp_wq;
++
++static void pci_rescan_worker(struct work_struct *work);
++static DECLARE_WORK(pci_rescan_work, pci_rescan_worker);
+ static int enable_slot (struct hotplug_slot *slot);
+ static int disable_slot (struct hotplug_slot *slot);
+@@ -109,7 +116,7 @@ static int add_slot(struct pci_dev *dev)
+       slot->name = &dev->dev.bus_id[0];
+       dbg("slot->name = %s\n", slot->name);
+-      dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL);
++      dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
+       if (!dslot)
+               goto error_info;
+@@ -164,6 +171,14 @@ static void remove_slot(struct dummy_slo
+               err("Problem unregistering a slot %s\n", dslot->slot->name);
+ }
++/* called from the single-threaded workqueue handler to remove a slot */
++static void remove_slot_worker(struct work_struct *work)
++{
++      struct dummy_slot *dslot =
++              container_of(work, struct dummy_slot, remove_work);
++      remove_slot(dslot);
++}
++
+ /**
+  * Rescan slot.
+  * Tries hard not to re-enable already existing devices
+@@ -267,11 +282,17 @@ static inline void pci_rescan(void) {
+       pci_rescan_buses(&pci_root_buses);
+ }
++/* called from the single-threaded workqueue handler to rescan all pci buses */
++static void pci_rescan_worker(struct work_struct *work)
++{
++      pci_rescan();
++}
+ static int enable_slot(struct hotplug_slot *hotplug_slot)
+ {
+       /* mis-use enable_slot for rescanning of the pci bus */
+-      pci_rescan();
++      cancel_work_sync(&pci_rescan_work);
++      queue_work(dummyphp_wq, &pci_rescan_work);
+       return -ENODEV;
+ }
+@@ -306,6 +327,10 @@ static int disable_slot(struct hotplug_s
+               err("Can't remove PCI devices with other PCI devices behind it yet.\n");
+               return -ENODEV;
+       }
++      if (test_and_set_bit(0, &dslot->removed)) {
++              dbg("Slot already scheduled for removal\n");
++              return -ENODEV;
++      }
+       /* search for subfunctions and disable them first */
+       if (!(dslot->dev->devfn & 7)) {
+               for (func = 1; func < 8; func++) {
+@@ -328,8 +353,9 @@ static int disable_slot(struct hotplug_s
+       /* remove the device from the pci core */
+       pci_remove_bus_device(dslot->dev);
+-      /* blow away this sysfs entry and other parts. */
+-      remove_slot(dslot);
++      /* queue work item to blow away this sysfs entry and other parts. */
++      INIT_WORK(&dslot->remove_work, remove_slot_worker);
++      queue_work(dummyphp_wq, &dslot->remove_work);
+       return 0;
+ }
+@@ -340,6 +366,7 @@ static void cleanup_slots (void)
+       struct list_head *next;
+       struct dummy_slot *dslot;
++      destroy_workqueue(dummyphp_wq);
+       list_for_each_safe (tmp, next, &slot_list) {
+               dslot = list_entry (tmp, struct dummy_slot, node);
+               remove_slot(dslot);
+@@ -351,6 +378,10 @@ static int __init dummyphp_init(void)
+ {
+       info(DRIVER_DESC "\n");
++      dummyphp_wq = create_singlethread_workqueue(MY_NAME);
++      if (!dummyphp_wq)
++              return -ENOMEM;
++
+       return pci_scan_buses();
+ }
diff --git a/queue-2.6.22/quicklists-do-not-release-off-node-pages-early.patch b/queue-2.6.22/quicklists-do-not-release-off-node-pages-early.patch
new file mode 100644 (file)
index 0000000..355a5de
--- /dev/null
@@ -0,0 +1,46 @@
+From stable-bounces@linux.kernel.org Tue Feb  5 13:06:37 2008
+From: Christoph Lameter <clameter@sgi.com>
+Date: Sat, 22 Dec 2007 14:03:23 -0800
+Subject: quicklists: do not release off node pages early
+To: torvalds@linux-foundation.org
+Cc: stable@kernel.org, akpm@linux-foundation.org,
+dhaval@linux.vnet.ibm.com, clameter@sgi.com
+Message-ID: <200712222203.lBMM3Nsk021922@imap1.linux-foundation.org>
+
+
+From: Christoph Lameter <clameter@sgi.com>
+
+patch ed367fc3a7349b17354c7acef551533337764859 in mainline.
+
+quicklists must keep even off node pages on the quicklists until the TLB
+flush has been completed.
+
+Signed-off-by: Christoph Lameter <clameter@sgi.com>
+Cc: Dhaval Giani <dhaval@linux.vnet.ibm.com>
+Cc: Oliver Pinter <oliver.pntr@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ include/linux/quicklist.h |    8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/include/linux/quicklist.h
++++ b/include/linux/quicklist.h
+@@ -56,14 +56,6 @@ static inline void __quicklist_free(int 
+       struct page *page)
+ {
+       struct quicklist *q;
+-      int nid = page_to_nid(page);
+-
+-      if (unlikely(nid != numa_node_id())) {
+-              if (dtor)
+-                      dtor(p);
+-              __free_page(page);
+-              return;
+-      }
+       q = &get_cpu_var(quicklist)[nr];
+       *(void **)p = q->page;
diff --git a/queue-2.6.22/sata_promise-asic-prd-table-bug-workaround.patch b/queue-2.6.22/sata_promise-asic-prd-table-bug-workaround.patch
new file mode 100644 (file)
index 0000000..fb598d1
--- /dev/null
@@ -0,0 +1,163 @@
+From stable-bounces@linux.kernel.org Wed Jan 16 01:32:59 2008
+From: Mikael Pettersson <mikpe@it.uu.se>
+Date: Wed, 16 Jan 2008 10:32:17 +0100 (MET)
+Subject: sata_promise: ASIC PRD table bug workaround
+To: stable@kernel.org
+Cc: Jeff Garzik <jeff@garzik.org>
+Message-ID: <200801160932.m0G9WHjG029881@harpo.it.uu.se>
+
+From: Mikael Pettersson <mikpe@it.uu.se>
+
+patch b9ccd4a90bbb964506f01b4bdcff4f50f8d5d334 in mainline.
+
+Second-generation Promise SATA controllers have an ASIC bug
+which can trigger if the last PRD entry is larger than 164 bytes,
+resulting in intermittent errors and possible data corruption.
+
+Work around this by replacing calls to ata_qc_prep() with a
+private version that fills the PRD, checks the size of the
+last entry, and if necessary splits it to avoid the bug.
+Also reduce sg_tablesize by 1 to accommodate the new entry.
+
+Tested on the second-generation SATA300 TX4 and SATA300 TX2plus,
+and the first-generation PDC20378.
+
+Thanks to Alexander Sabourenkov for verifying the bug by
+studying the vendor driver, and for writing the initial patch
+upon which this one is based.
+
+Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
+Cc: Jeff Garzik <jeff@garzik.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ata/sata_promise.c |   87 ++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 83 insertions(+), 4 deletions(-)
+
+--- a/drivers/ata/sata_promise.c
++++ b/drivers/ata/sata_promise.c
+@@ -51,6 +51,7 @@
+ enum {
+       PDC_MAX_PORTS           = 4,
+       PDC_MMIO_BAR            = 3,
++      PDC_MAX_PRD             = LIBATA_MAX_PRD - 1, /* -1 for ASIC PRD bug workaround */
+       /* register offsets */
+       PDC_FEATURE             = 0x04, /* Feature/Error reg (per port) */
+@@ -157,7 +158,7 @@ static struct scsi_host_template pdc_ata
+       .queuecommand           = ata_scsi_queuecmd,
+       .can_queue              = ATA_DEF_QUEUE,
+       .this_id                = ATA_SHT_THIS_ID,
+-      .sg_tablesize           = LIBATA_MAX_PRD,
++      .sg_tablesize           = PDC_MAX_PRD,
+       .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
+       .emulated               = ATA_SHT_EMULATED,
+       .use_clustering         = ATA_SHT_USE_CLUSTERING,
+@@ -531,6 +532,84 @@ static void pdc_atapi_pkt(struct ata_que
+       memcpy(buf+31, cdb, cdb_len);
+ }
++/**
++ *    pdc_fill_sg - Fill PCI IDE PRD table
++ *    @qc: Metadata associated with taskfile to be transferred
++ *
++ *    Fill PCI IDE PRD (scatter-gather) table with segments
++ *    associated with the current disk command.
++ *    Make sure hardware does not choke on it.
++ *
++ *    LOCKING:
++ *    spin_lock_irqsave(host lock)
++ *
++ */
++static void pdc_fill_sg(struct ata_queued_cmd *qc)
++{
++      struct ata_port *ap = qc->ap;
++      struct scatterlist *sg;
++      unsigned int idx;
++      const u32 SG_COUNT_ASIC_BUG = 41*4;
++
++      if (!(qc->flags & ATA_QCFLAG_DMAMAP))
++              return;
++
++      WARN_ON(qc->__sg == NULL);
++      WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
++
++      idx = 0;
++      ata_for_each_sg(sg, qc) {
++              u32 addr, offset;
++              u32 sg_len, len;
++
++              /* determine if physical DMA addr spans 64K boundary.
++               * Note h/w doesn't support 64-bit, so we unconditionally
++               * truncate dma_addr_t to u32.
++               */
++              addr = (u32) sg_dma_address(sg);
++              sg_len = sg_dma_len(sg);
++
++              while (sg_len) {
++                      offset = addr & 0xffff;
++                      len = sg_len;
++                      if ((offset + sg_len) > 0x10000)
++                              len = 0x10000 - offset;
++
++                      ap->prd[idx].addr = cpu_to_le32(addr);
++                      ap->prd[idx].flags_len = cpu_to_le32(len & 0xffff);
++                      VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
++
++                      idx++;
++                      sg_len -= len;
++                      addr += len;
++              }
++      }
++
++      if (idx) {
++              u32 len = le32_to_cpu(ap->prd[idx - 1].flags_len);
++
++              if (len > SG_COUNT_ASIC_BUG) {
++                      u32 addr;
++
++                      VPRINTK("Splitting last PRD.\n");
++
++                      addr = le32_to_cpu(ap->prd[idx - 1].addr);
++                      ap->prd[idx - 1].flags_len = cpu_to_le32(len - SG_COUNT_ASIC_BUG);
++                      VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx - 1, addr, SG_COUNT_ASIC_BUG);
++
++                      addr = addr + len - SG_COUNT_ASIC_BUG;
++                      len = SG_COUNT_ASIC_BUG;
++                      ap->prd[idx].addr = cpu_to_le32(addr);
++                      ap->prd[idx].flags_len = cpu_to_le32(len);
++                      VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
++
++                      idx++;
++              }
++
++              ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
++      }
++}
++
+ static void pdc_qc_prep(struct ata_queued_cmd *qc)
+ {
+       struct pdc_port_priv *pp = qc->ap->private_data;
+@@ -540,7 +619,7 @@ static void pdc_qc_prep(struct ata_queue
+       switch (qc->tf.protocol) {
+       case ATA_PROT_DMA:
+-              ata_qc_prep(qc);
++              pdc_fill_sg(qc);
+               /* fall through */
+       case ATA_PROT_NODATA:
+@@ -556,11 +635,11 @@ static void pdc_qc_prep(struct ata_queue
+               break;
+       case ATA_PROT_ATAPI:
+-              ata_qc_prep(qc);
++              pdc_fill_sg(qc);
+               break;
+       case ATA_PROT_ATAPI_DMA:
+-              ata_qc_prep(qc);
++              pdc_fill_sg(qc);
+               /*FALLTHROUGH*/
+       case ATA_PROT_ATAPI_NODATA:
+               pdc_atapi_pkt(qc);
diff --git a/queue-2.6.22/sata_promise-fasttrack-tx4200-is-a-second-generation-chip.patch b/queue-2.6.22/sata_promise-fasttrack-tx4200-is-a-second-generation-chip.patch
new file mode 100644 (file)
index 0000000..66a01f2
--- /dev/null
@@ -0,0 +1,45 @@
+From stable-bounces@linux.kernel.org Wed Jan 16 02:34:27 2008
+From: Mikael Pettersson <mikpe@it.uu.se>
+Date: Wed, 16 Jan 2008 10:31:22 +0100 (MET)
+Subject: sata_promise: FastTrack TX4200 is a second-generation chip
+To: stable@kernel.org
+Cc: Jeff Garzik <jeff@garzik.org>
+Message-ID: <200801160931.m0G9VMOw029868@harpo.it.uu.se>
+
+From: Mikael Pettersson <mikpe@it.uu.se>
+
+patch 7f9992a23190418592f0810900e4f91546ec41da in mainline.
+
+This patch corrects sata_promise to classify FastTrack TX4200
+(DID 3515/3519) as a second-generation chip. Promise's partial-
+source FT TX4200 driver confirms this classification.
+
+Treating it as a first-generation chip causes several problems:
+1. Detection failures. This is a recent regression triggered by
+   the hotplug-enabling changes in 2.6.23-rc1.
+2. Various "failed to resume link for reset" warnings.
+
+This patch fixes <http://bugzilla.kernel.org/show_bug.cgi?id=8936>.
+
+Thanks to Stephen Ziemba for reporting the bug and for testing the fix.
+
+Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ata/sata_promise.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/ata/sata_promise.c
++++ b/drivers/ata/sata_promise.c
+@@ -330,8 +330,8 @@ static const struct pci_device_id pdc_at
+       { PCI_VDEVICE(PROMISE, 0x3318), board_20319 },
+       { PCI_VDEVICE(PROMISE, 0x3319), board_20319 },
+-      { PCI_VDEVICE(PROMISE, 0x3515), board_20319 },
+-      { PCI_VDEVICE(PROMISE, 0x3519), board_20319 },
++      { PCI_VDEVICE(PROMISE, 0x3515), board_40518 },
++      { PCI_VDEVICE(PROMISE, 0x3519), board_40518 },
+       { PCI_VDEVICE(PROMISE, 0x3d17), board_40518 },
+       { PCI_VDEVICE(PROMISE, 0x3d18), board_40518 },
diff --git a/queue-2.6.22/series b/queue-2.6.22/series
new file mode 100644 (file)
index 0000000..f6f31c1
--- /dev/null
@@ -0,0 +1,4 @@
+sata_promise-fasttrack-tx4200-is-a-second-generation-chip.patch
+sata_promise-asic-prd-table-bug-workaround.patch
+pci-fix-fakephp-deadlock.patch
+quicklists-do-not-release-off-node-pages-early.patch