[kernel] r19613 - in dists/squeeze/linux-2.6/debian: . patches/features/all/hpsa patches/series

Ben Hutchings benh at alioth.debian.org
Sun Dec 16 22:30:48 UTC 2012


Author: benh
Date: Sun Dec 16 22:30:47 2012
New Revision: 19613

Log:
hpsa: Backport changes up to Linux 3.2.35 (Closes: #690100)

Added:
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0080-hpsa-defend-against-zero-sized-buffers-in-passthru-i.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0081-hpsa-fixup-DMA-address-before-freeing.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0082-hpsa-Remove-duplicate-defines-of-DIRECT_LOOKUP_-cons.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0083-hpsa-fix-board-status-waiting-code.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0084-hpsa-Use-kernel-provided-PCI-state-save-and-restore-.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0085-hpsa-limit-commands-allocated-on-reset_devices.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0086-hpsa-do-not-reset-unknown-boards-on-reset_devices.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0087-hpsa-take-the-adapter-lock-in-hpsa_wait_for_mode_cha.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0088-hpsa-allow-driver-to-put-controller-in-either-simple.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0089-hpsa-Add-a-per-controller-commands_outstanding-entry.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0090-hpsa-fix-use-of-uninitialized-variable-in-hpsa_add_m.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0091-hpsa-Fix-problem-that-CMD_UNABORTABLE-command-status.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0092-hpsa-avoid-leaking-stack-contents-to-userland.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0093-hpsa-do-not-re-order-commands-in-internal-queues.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0094-hpsa-make-hpsa.hpsa_simple_mode-1-module-parameter-a.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0095-hpsa-Add-transport_mode-host-attribute-in-sys.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0096-hpsa-Inform-controller-we-are-using-32-bit-tags.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0097-hpsa-Do-not-attempt-kdump-if-we-detect-resetting-con.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0098-hpsa-fix-bad-comparison.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0099-hpsa-fix-incorrect-PCI-IDs-and-add-two-new-ones-2nd-.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0100-hpsa-move-device-attributes-to-avoid-forward-declara.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0101-hpsa-export-resettable-host-attribute.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0102-hpsa-do-readl-after-writel-in-main-i-o-path-to-ensur.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0103-hpsa-add-readl-after-writel-in-interrupt-mask-settin.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0104-hpsa-remove-unused-parameter-from-hpsa_complete_scsi.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0105-hpsa-delete-old-unused-padding-garbage.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0106-hpsa-do-a-better-job-of-detecting-controller-reset-f.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0107-hpsa-wait-longer-for-no-op-to-complete-after-resetti.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0108-hpsa-factor-out-cmd-pool-allocation-functions.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0109-hpsa-factor-out-irq-request-code.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0110-hpsa-increase-time-to-wait-for-board-reset.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0111-hpsa-clarify-messages-around-reset-behavior.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0112-hpsa-remove-atrophied-hpsa_scsi_setup-function.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0113-hpsa-use-new-doorbell-bit-5-reset-method.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0114-hpsa-do-soft-reset-if-hard-reset-is-broken.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0115-hpsa-remove-superfluous-sleeps-around-reset-code.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0116-hpsa-do-not-attempt-PCI-power-management-reset-metho.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0117-hpsa-add-P2000-to-list-of-shared-SAS-devices.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0118-hpsa-Change-memset-using-sizeof-ptr-to-sizeof-ptr.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0119-hpsa-fix-dma-unmap-error-in-hpsa_passthru_ioctl.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0120-hpsa-fix-potential-overrun-while-memcpy-ing-sense-da.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0121-hpsa-do-not-attempt-to-read-from-a-write-only-regist.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0122-hpsa-retry-commands-completing-with-status-of-UNSOLI.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0123-hpsa-fix-problem-that-OBDR-devices-are-not-detected.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0124-hpsa-fix-physical-device-lun-and-target-numbering-pr.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0125-hpsa-change-confusing-message-to-be-more-clear.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0126-hpsa-add-small-delay-when-using-PCI-Power-Management.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0127-hpsa-set-max-sectors-instead-of-taking-the-default.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0128-hpsa-remove-unused-busy_initializing-and-busy_scanni.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0129-hpsa-rename-HPSA_MAX_SCSI_DEVS_PER_HBA.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0130-hpsa-fix-potential-array-overflow-in-hpsa_update_scs.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0131-hpsa-fix-flush-cache-transfer-length.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0132-hpsa-detect-controller-lockup.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0133-hpsa-Disable-ASPM.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0134-hpsa-Fix-problem-with-MSA2xxx-devices.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0135-hpsa-Add-IRQF_SHARED-back-in-for-the-non-MSI-X-inter.patch
   dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0136-hpsa-fix-handling-of-protocol-error.patch
Modified:
   dists/squeeze/linux-2.6/debian/changelog
   dists/squeeze/linux-2.6/debian/patches/series/47

Modified: dists/squeeze/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze/linux-2.6/debian/changelog	Sun Dec 16 19:30:35 2012	(r19612)
+++ dists/squeeze/linux-2.6/debian/changelog	Sun Dec 16 22:30:47 2012	(r19613)
@@ -6,6 +6,7 @@
     (Closes: #689928)
   * header: fix broken headers for user space (Closes: #692133)
   * nfsv4: Fix kernel panic when mounting NFSv4 (Closes: #695872)
+  * hpsa: Backport changes up to Linux 3.2.35 (Closes: #690100)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Mon, 08 Oct 2012 00:26:11 +0100
 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0080-hpsa-defend-against-zero-sized-buffers-in-passthru-i.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0080-hpsa-defend-against-zero-sized-buffers-in-passthru-i.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,90 @@
+From f9fe8698b191d79e9a4e78013f52453c8f6a317d Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Thu, 6 Jan 2011 14:47:48 -0600
+Subject: [PATCH 080/136] hpsa: defend against zero sized buffers in passthru
+ ioctls
+
+commit b03a7771c81a0d5f026250c8cd4091d9ee767fdc upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   36 ++++++++++++++++--------------------
+ 1 file changed, 16 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 3c7c9a7..eb7ace9 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -2405,15 +2405,17 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+ 		buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
+ 		if (buff == NULL)
+ 			return -EFAULT;
+-	}
+-	if (iocommand.Request.Type.Direction == XFER_WRITE) {
+-		/* Copy the data into the buffer we created */
+-		if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) {
+-			kfree(buff);
+-			return -EFAULT;
++		if (iocommand.Request.Type.Direction == XFER_WRITE) {
++			/* Copy the data into the buffer we created */
++			if (copy_from_user(buff, iocommand.buf,
++				iocommand.buf_size)) {
++				kfree(buff);
++				return -EFAULT;
++			}
++		} else {
++			memset(buff, 0, iocommand.buf_size);
+ 		}
+-	} else
+-		memset(buff, 0, iocommand.buf_size);
++	}
+ 	c = cmd_special_alloc(h);
+ 	if (c == NULL) {
+ 		kfree(buff);
+@@ -2459,8 +2461,8 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+ 		cmd_special_free(h, c);
+ 		return -EFAULT;
+ 	}
+-
+-	if (iocommand.Request.Type.Direction == XFER_READ) {
++	if (iocommand.Request.Type.Direction == XFER_READ &&
++		iocommand.buf_size > 0) {
+ 		/* Copy the data out of the buffer we created */
+ 		if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) {
+ 			kfree(buff);
+@@ -2553,14 +2555,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+ 	}
+ 	c->cmd_type = CMD_IOCTL_PEND;
+ 	c->Header.ReplyQueue = 0;
+-
+-	if (ioc->buf_size > 0) {
+-		c->Header.SGList = sg_used;
+-		c->Header.SGTotal = sg_used;
+-	} else {
+-		c->Header.SGList = 0;
+-		c->Header.SGTotal = 0;
+-	}
++	c->Header.SGList = c->Header.SGTotal = sg_used;
+ 	memcpy(&c->Header.LUN, &ioc->LUN_info, sizeof(c->Header.LUN));
+ 	c->Header.Tag.lower = c->busaddr;
+ 	memcpy(&c->Request, &ioc->Request, sizeof(c->Request));
+@@ -2577,7 +2572,8 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+ 		}
+ 	}
+ 	hpsa_scsi_do_simple_cmd_core(h, c);
+-	hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL);
++	if (sg_used)
++		hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL);
+ 	check_ioctl_unit_attention(h, c);
+ 	/* Copy the error information out */
+ 	memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info));
+@@ -2586,7 +2582,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+ 		status = -EFAULT;
+ 		goto cleanup1;
+ 	}
+-	if (ioc->Request.Type.Direction == XFER_READ) {
++	if (ioc->Request.Type.Direction == XFER_READ && ioc->buf_size > 0) {
+ 		/* Copy the data out of the buffer we created */
+ 		BYTE __user *ptr = ioc->buf;
+ 		for (i = 0; i < sg_used; i++) {

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0081-hpsa-fixup-DMA-address-before-freeing.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0081-hpsa-fixup-DMA-address-before-freeing.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,49 @@
+From 5c17c7e0af831bdb5d5b2e27909f697d3bd898b6 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <StephenM.Cameron>
+Date: Thu, 6 Jan 2011 14:47:53 -0600
+Subject: [PATCH 081/136] hpsa: fixup DMA address before freeing.
+
+commit d896f3f3d129f1e2fbb4e3824242bc0dc2fb1a07 upstream.
+
+Some low bits might have been set by the driver, causing
+a message like this to come out:
+
+ [   13.288062] ------------[ cut here ]------------
+ [   13.293211] WARNING: at lib/dma-debug.c:803 check_unmap+0x1a1/0x654()
+ [   13.300387] Hardware name: ProLiant DL180 G6
+ [   13.305335] hpsa 0000:06:00.0: DMA-API: device driver tries to free
+ DMA memory it has not allocated [device address=0x000000007f81e001]
+ [size=640 bytes]
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c     |    2 +-
+ drivers/scsi/hpsa_cmd.h |    1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index eb7ace9..f6f53e5 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -2239,7 +2239,7 @@ static void cmd_special_free(struct ctlr_info *h, struct CommandList *c)
+ 	pci_free_consistent(h->pdev, sizeof(*c->err_info),
+ 			    c->err_info, (dma_addr_t) temp64.val);
+ 	pci_free_consistent(h->pdev, sizeof(*c),
+-			    c, (dma_addr_t) c->busaddr);
++			    c, (dma_addr_t) (c->busaddr & DIRECT_LOOKUP_MASK));
+ }
+ 
+ #ifdef CONFIG_COMPAT
+diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
+index f5c4c3c..7910c14 100644
+--- a/drivers/scsi/hpsa_cmd.h
++++ b/drivers/scsi/hpsa_cmd.h
+@@ -265,6 +265,7 @@ struct ErrorInfo {
+ 
+ #define DIRECT_LOOKUP_SHIFT 5
+ #define DIRECT_LOOKUP_BIT 0x10
++#define DIRECT_LOOKUP_MASK (~((1 << DIRECT_LOOKUP_SHIFT) - 1))
+ 
+ #define HPSA_ERROR_BIT          0x02
+ struct ctlr_info; /* defined in hpsa.h */

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0082-hpsa-Remove-duplicate-defines-of-DIRECT_LOOKUP_-cons.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0082-hpsa-Remove-duplicate-defines-of-DIRECT_LOOKUP_-cons.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,34 @@
+From 1d59adeeba7f7e2b0228888e19d2d2dea5e6637e Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <StephenM.Cameron>
+Date: Thu, 6 Jan 2011 14:47:58 -0600
+Subject: [PATCH 082/136] hpsa: Remove duplicate defines of DIRECT_LOOKUP_
+ constants
+
+commit 922a9e4da34270d81e216728f929c6e11e169794 upstream.
+
+They are defined in hpsa_cmd.h
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index f6f53e5..61fc7e8 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -2835,13 +2835,11 @@ static inline void finish_cmd(struct CommandList *c, u32 raw_tag)
+ 
+ static inline u32 hpsa_tag_contains_index(u32 tag)
+ {
+-#define DIRECT_LOOKUP_BIT 0x10
+ 	return tag & DIRECT_LOOKUP_BIT;
+ }
+ 
+ static inline u32 hpsa_tag_to_index(u32 tag)
+ {
+-#define DIRECT_LOOKUP_SHIFT 5
+ 	return tag >> DIRECT_LOOKUP_SHIFT;
+ }
+ 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0083-hpsa-fix-board-status-waiting-code.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0083-hpsa-fix-board-status-waiting-code.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,123 @@
+From 2f25d644826dd5b85ec8634328b58b3107ca8399 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Thu, 6 Jan 2011 14:48:03 -0600
+Subject: [PATCH 083/136] hpsa: fix board status waiting code
+
+commit fe5389c87f13c16cd77d976801c93422d0c05a49 upstream.
+
+After a reset, we should first wait for the board to become "not ready",
+and then wait for it to become "ready", instead of immediately
+waiting for it to become "ready", and do this waiting *after*
+restoring PCI config space registers.  Also, only wait 10 secs
+for board to become "not ready" after a reset (it should quickly
+become not ready.)
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   44 ++++++++++++++++++++++++++++++++++++--------
+ drivers/scsi/hpsa.h |    4 ++++
+ 2 files changed, 40 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 61fc7e8..053ecce 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -165,6 +165,10 @@ static int __devinit hpsa_find_cfg_addrs(struct pci_dev *pdev,
+ static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev,
+ 	unsigned long *memory_bar);
+ static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id);
++static int __devinit hpsa_wait_for_board_state(struct pci_dev *pdev,
++	void __iomem *vaddr, int wait_for_ready);
++#define BOARD_NOT_READY 0
++#define BOARD_READY 1
+ 
+ static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
+ static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL);
+@@ -3209,6 +3213,20 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	   need a little pause here */
+ 	msleep(HPSA_POST_RESET_PAUSE_MSECS);
+ 
++	/* Wait for board to become not ready, then ready. */
++	dev_info(&pdev->dev, "Waiting for board to become ready.\n");
++	rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY);
++	if (rc)
++		dev_warn(&pdev->dev,
++			"failed waiting for board to become not ready\n");
++	rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_READY);
++	if (rc) {
++		dev_warn(&pdev->dev,
++			"failed waiting for board to become ready\n");
++		goto unmap_cfgtable;
++	}
++	dev_info(&pdev->dev, "board ready.\n");
++
+ 	/* Controller should be in simple mode at this point.  If it's not,
+ 	 * It means we're on one of those controllers which doesn't support
+ 	 * the doorbell reset method and on which the PCI power management reset
+@@ -3404,18 +3422,28 @@ static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev,
+ 	return -ENODEV;
+ }
+ 
+-static int __devinit hpsa_wait_for_board_ready(struct ctlr_info *h)
++static int __devinit hpsa_wait_for_board_state(struct pci_dev *pdev,
++	void __iomem *vaddr, int wait_for_ready)
+ {
+-	int i;
++	int i, iterations;
+ 	u32 scratchpad;
++	if (wait_for_ready)
++		iterations = HPSA_BOARD_READY_ITERATIONS;
++	else
++		iterations = HPSA_BOARD_NOT_READY_ITERATIONS;
+ 
+-	for (i = 0; i < HPSA_BOARD_READY_ITERATIONS; i++) {
+-		scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
+-		if (scratchpad == HPSA_FIRMWARE_READY)
+-			return 0;
++	for (i = 0; i < iterations; i++) {
++		scratchpad = readl(vaddr + SA5_SCRATCHPAD_OFFSET);
++		if (wait_for_ready) {
++			if (scratchpad == HPSA_FIRMWARE_READY)
++				return 0;
++		} else {
++			if (scratchpad != HPSA_FIRMWARE_READY)
++				return 0;
++		}
+ 		msleep(HPSA_BOARD_READY_POLL_INTERVAL_MSECS);
+ 	}
+-	dev_warn(&h->pdev->dev, "board not ready, timed out.\n");
++	dev_warn(&pdev->dev, "board not ready, timed out.\n");
+ 	return -ENODEV;
+ }
+ 
+@@ -3607,7 +3635,7 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h)
+ 		err = -ENOMEM;
+ 		goto err_out_free_res;
+ 	}
+-	err = hpsa_wait_for_board_ready(h);
++	err = hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY);
+ 	if (err)
+ 		goto err_out_free_res;
+ 	err = hpsa_find_cfgtables(h);
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 19586e1..074d237 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -154,12 +154,16 @@ struct ctlr_info {
+  * HPSA_BOARD_READY_ITERATIONS are derived from those.
+  */
+ #define HPSA_BOARD_READY_WAIT_SECS (120)
++#define HPSA_BOARD_NOT_READY_WAIT_SECS (10)
+ #define HPSA_BOARD_READY_POLL_INTERVAL_MSECS (100)
+ #define HPSA_BOARD_READY_POLL_INTERVAL \
+ 	((HPSA_BOARD_READY_POLL_INTERVAL_MSECS * HZ) / 1000)
+ #define HPSA_BOARD_READY_ITERATIONS \
+ 	((HPSA_BOARD_READY_WAIT_SECS * 1000) / \
+ 		HPSA_BOARD_READY_POLL_INTERVAL_MSECS)
++#define HPSA_BOARD_NOT_READY_ITERATIONS \
++	((HPSA_BOARD_NOT_READY_WAIT_SECS * 1000) / \
++		HPSA_BOARD_READY_POLL_INTERVAL_MSECS)
+ #define HPSA_POST_RESET_PAUSE_MSECS (3000)
+ #define HPSA_POST_RESET_NOOP_RETRIES (12)
+ 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0084-hpsa-Use-kernel-provided-PCI-state-save-and-restore-.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0084-hpsa-Use-kernel-provided-PCI-state-save-and-restore-.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,159 @@
+From c9b2fbc21a082f18582b75e4791ae1391c37d308 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Thu, 6 Jan 2011 14:48:08 -0600
+Subject: [PATCH 084/136] hpsa: Use kernel provided PCI state save and restore
+ functions
+
+commit 270d05de2b8d82df4ed19955f6c0c7400f6ffbf5 upstream.
+
+and use the doorbell reset method if available (which doesn't
+lock up the controller if you properly save and restore all
+the PCI registers that you're supposed to.)
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   81 ++++++++++-----------------------------------------
+ 1 file changed, 15 insertions(+), 66 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 053ecce..c5dae04 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3025,38 +3025,6 @@ static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
+ #define hpsa_soft_reset_controller(p) hpsa_message(p, 1, 0)
+ #define hpsa_noop(p) hpsa_message(p, 3, 0)
+ 
+-static __devinit int hpsa_reset_msi(struct pci_dev *pdev)
+-{
+-/* the #defines are stolen from drivers/pci/msi.h. */
+-#define msi_control_reg(base)		(base + PCI_MSI_FLAGS)
+-#define PCI_MSIX_FLAGS_ENABLE		(1 << 15)
+-
+-	int pos;
+-	u16 control = 0;
+-
+-	pos = pci_find_capability(pdev, PCI_CAP_ID_MSI);
+-	if (pos) {
+-		pci_read_config_word(pdev, msi_control_reg(pos), &control);
+-		if (control & PCI_MSI_FLAGS_ENABLE) {
+-			dev_info(&pdev->dev, "resetting MSI\n");
+-			pci_write_config_word(pdev, msi_control_reg(pos),
+-					control & ~PCI_MSI_FLAGS_ENABLE);
+-		}
+-	}
+-
+-	pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
+-	if (pos) {
+-		pci_read_config_word(pdev, msi_control_reg(pos), &control);
+-		if (control & PCI_MSIX_FLAGS_ENABLE) {
+-			dev_info(&pdev->dev, "resetting MSI-X\n");
+-			pci_write_config_word(pdev, msi_control_reg(pos),
+-					control & ~PCI_MSIX_FLAGS_ENABLE);
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
+ 	void * __iomem vaddr, bool use_doorbell)
+ {
+@@ -3112,17 +3080,17 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
+  */
+ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ {
+-	u16 saved_config_space[32];
+ 	u64 cfg_offset;
+ 	u32 cfg_base_addr;
+ 	u64 cfg_base_addr_index;
+ 	void __iomem *vaddr;
+ 	unsigned long paddr;
+ 	u32 misc_fw_support, active_transport;
+-	int rc, i;
++	int rc;
+ 	struct CfgTable __iomem *cfgtable;
+ 	bool use_doorbell;
+ 	u32 board_id;
++	u16 command_register;
+ 
+ 	/* For controllers as old as the P600, this is very nearly
+ 	 * the same thing as
+@@ -3132,14 +3100,6 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	 * pci_set_power_state(pci_dev, PCI_D0);
+ 	 * pci_restore_state(pci_dev);
+ 	 *
+-	 * but we can't use these nice canned kernel routines on
+-	 * kexec, because they also check the MSI/MSI-X state in PCI
+-	 * configuration space and do the wrong thing when it is
+-	 * set/cleared.  Also, the pci_save/restore_state functions
+-	 * violate the ordering requirements for restoring the
+-	 * configuration space from the CCISS document (see the
+-	 * comment below).  So we roll our own ....
+-	 *
+ 	 * For controllers newer than the P600, the pci power state
+ 	 * method of resetting doesn't work so we have another way
+ 	 * using the doorbell register.
+@@ -3156,9 +3116,13 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	if (board_id == 0x409C0E11 || board_id == 0x409D0E11)
+ 		return -ENOTSUPP;
+ 
+-	for (i = 0; i < 32; i++)
+-		pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
+-
++	/* Save the PCI command register */
++	pci_read_config_word(pdev, 4, &command_register);
++	/* Turn the board off.  This is so that later pci_restore_state()
++	 * won't turn the board on before the rest of config space is ready.
++	 */
++	pci_disable_device(pdev);
++	pci_save_state(pdev);
+ 
+ 	/* find the first memory BAR, so we can find the cfg table */
+ 	rc = hpsa_pci_find_memory_BAR(pdev, &paddr);
+@@ -3184,30 +3148,17 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	misc_fw_support = readl(&cfgtable->misc_fw_support);
+ 	use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
+ 
+-	/* The doorbell reset seems to cause lockups on some Smart
+-	 * Arrays (e.g. P410, P410i, maybe others).  Until this is
+-	 * fixed or at least isolated, avoid the doorbell reset.
+-	 */
+-	use_doorbell = 0;
+-
+ 	rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell);
+ 	if (rc)
+ 		goto unmap_cfgtable;
+ 
+-	/* Restore the PCI configuration space.  The Open CISS
+-	 * Specification says, "Restore the PCI Configuration
+-	 * Registers, offsets 00h through 60h. It is important to
+-	 * restore the command register, 16-bits at offset 04h,
+-	 * last. Do not restore the configuration status register,
+-	 * 16-bits at offset 06h."  Note that the offset is 2*i.
+-	 */
+-	for (i = 0; i < 32; i++) {
+-		if (i == 2 || i == 3)
+-			continue;
+-		pci_write_config_word(pdev, 2*i, saved_config_space[i]);
++	pci_restore_state(pdev);
++	rc = pci_enable_device(pdev);
++	if (rc) {
++		dev_warn(&pdev->dev, "failed to enable device.\n");
++		goto unmap_cfgtable;
+ 	}
+-	wmb();
+-	pci_write_config_word(pdev, 4, saved_config_space[2]);
++	pci_write_config_word(pdev, 4, command_register);
+ 
+ 	/* Some devices (notably the HP Smart Array 5i Controller)
+ 	   need a little pause here */
+@@ -3704,8 +3655,6 @@ static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev)
+ 		return 0; /* just try to do the kdump anyhow. */
+ 	if (rc)
+ 		return -ENODEV;
+-	if (hpsa_reset_msi(pdev))
+-		return -ENODEV;
+ 
+ 	/* Now try to get the controller to respond to a no-op */
+ 	for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) {

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0085-hpsa-limit-commands-allocated-on-reset_devices.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0085-hpsa-limit-commands-allocated-on-reset_devices.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,31 @@
+From 49dd47ee22a6d53e7583fea7db49b837c5cb7107 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Thu, 6 Jan 2011 14:48:13 -0600
+Subject: [PATCH 085/136] hpsa: limit commands allocated on reset_devices
+
+commit 72ceeaecb748dff3d35b10d7518bed651b895f3e upstream.
+
+This is to conserve memory in a memory-limited kdump scenario
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index c5dae04..ce422d2 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3442,6 +3442,11 @@ static int __devinit hpsa_find_cfgtables(struct ctlr_info *h)
+ static void __devinit hpsa_get_max_perf_mode_cmds(struct ctlr_info *h)
+ {
+ 	h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
++
++	/* Limit commands in memory limited kdump scenario. */
++	if (reset_devices && h->max_commands > 32)
++		h->max_commands = 32;
++
+ 	if (h->max_commands < 16) {
+ 		dev_warn(&h->pdev->dev, "Controller reports "
+ 			"max supported commands of %d, an obvious lie. "

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0086-hpsa-do-not-reset-unknown-boards-on-reset_devices.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0086-hpsa-do-not-reset-unknown-boards-on-reset_devices.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,33 @@
+From fc59111199675969a6a3804e0cd2c896534ceafe Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Thu, 6 Jan 2011 14:48:18 -0600
+Subject: [PATCH 086/136] hpsa: do not reset unknown boards on reset_devices
+
+commit 25c1e56a04e60af2414f8d81eda0fd10b8e7b961 upstream.
+
+This is to prevent hpsa from resetting older boards
+which the cciss driver may be controlling.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index ce422d2..be9540a 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3112,7 +3112,11 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	 * likely not be happy.  Just forbid resetting this conjoined mess.
+ 	 * The 640x isn't really supported by hpsa anyway.
+ 	 */
+-	hpsa_lookup_board_id(pdev, &board_id);
++	rc = hpsa_lookup_board_id(pdev, &board_id);
++	if (rc < 0) {
++		dev_warn(&pdev->dev, "Not resetting device.\n");
++		return -ENODEV;
++	}
+ 	if (board_id == 0x409C0E11 || board_id == 0x409D0E11)
+ 		return -ENOTSUPP;
+ 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0087-hpsa-take-the-adapter-lock-in-hpsa_wait_for_mode_cha.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0087-hpsa-take-the-adapter-lock-in-hpsa_wait_for_mode_cha.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,59 @@
+From 4fd0ada1b0a83466ba65155431dba7ec4ae301b1 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Thu, 6 Jan 2011 14:48:24 -0600
+Subject: [PATCH 087/136] hpsa: take the adapter lock in
+ hpsa_wait_for_mode_change_ack
+
+commit 6eaf46fdc719991a3ccda1e14b274e9adb515978 upstream.
+
+Need to take the lock while accessing the register to check to
+see if config table changes have taken effect.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index be9540a..76f34d9 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3525,13 +3525,18 @@ static inline void hpsa_p600_dma_prefetch_quirk(struct ctlr_info *h)
+ static void __devinit hpsa_wait_for_mode_change_ack(struct ctlr_info *h)
+ {
+ 	int i;
++	u32 doorbell_value;
++	unsigned long flags;
+ 
+ 	/* under certain very rare conditions, this can take awhile.
+ 	 * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right
+ 	 * as we enter this code.)
+ 	 */
+ 	for (i = 0; i < MAX_CONFIG_WAIT; i++) {
+-		if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
++		spin_lock_irqsave(&h->lock, flags);
++		doorbell_value = readl(h->vaddr + SA5_DOORBELL);
++		spin_unlock_irqrestore(&h->lock, flags);
++		if (!doorbell_value & CFGTBL_ChangeReq)
+ 			break;
+ 		/* delay and try again */
+ 		msleep(10);
+@@ -3703,6 +3708,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 	h->busy_initializing = 1;
+ 	INIT_HLIST_HEAD(&h->cmpQ);
+ 	INIT_HLIST_HEAD(&h->reqQ);
++	spin_lock_init(&h->lock);
++	spin_lock_init(&h->scan_lock);
+ 	rc = hpsa_pci_init(h);
+ 	if (rc != 0)
+ 		goto clean1;
+@@ -3762,8 +3769,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 	}
+ 	if (hpsa_allocate_sg_chain_blocks(h))
+ 		goto clean4;
+-	spin_lock_init(&h->lock);
+-	spin_lock_init(&h->scan_lock);
+ 	init_waitqueue_head(&h->scan_wait_queue);
+ 	h->scan_finished = 1; /* no scan currently in progress */
+ 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0088-hpsa-allow-driver-to-put-controller-in-either-simple.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0088-hpsa-allow-driver-to-put-controller-in-either-simple.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,39 @@
+From eed7e66b40b1c85ad0a389163e5d1bc03d406d2e Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Thu, 6 Jan 2011 14:48:29 -0600
+Subject: [PATCH 088/136] hpsa: allow driver to put controller in either
+ simple or performant mode
+
+commit 02ec19c82e87e3748d326ca5e15e7ddb18c73476 upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 76f34d9..7f488db 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -74,6 +74,10 @@ static int hpsa_allow_any;
+ module_param(hpsa_allow_any, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(hpsa_allow_any,
+ 		"Allow hpsa driver to access unknown HP Smart Array hardware");
++static int hpsa_simple_mode;
++module_param(hpsa_simple_mode, int, S_IRUGO|S_IWUSR);
++MODULE_PARM_DESC(hpsa_simple_mode,
++	"Use 'simple mode' rather than 'performant mode'");
+ 
+ /* define the PCI info for the cards we can control */
+ static const struct pci_device_id hpsa_pci_device_id[] = {
+@@ -4010,6 +4014,9 @@ static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
+ {
+ 	u32 trans_support;
+ 
++	if (hpsa_simple_mode)
++		return;
++
+ 	trans_support = readl(&(h->cfgtable->TransportSupport));
+ 	if (!(trans_support & PERFORMANT_MODE))
+ 		return;

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0089-hpsa-Add-a-per-controller-commands_outstanding-entry.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0089-hpsa-Add-a-per-controller-commands_outstanding-entry.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,60 @@
+From 48f6a79fe7ded6d8f2331c16f6c79679b11ae5ce Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Thu, 6 Jan 2011 14:48:39 -0600
+Subject: [PATCH 089/136] hpsa: Add a per controller commands_outstanding
+ entry in /sys
+
+commit 94a136495a3fbe59b960c46fba3574b1159e8489 upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 7f488db..fef7931 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -151,6 +151,8 @@ static ssize_t unique_id_show(struct device *dev,
+ 	struct device_attribute *attr, char *buf);
+ static ssize_t host_show_firmware_revision(struct device *dev,
+ 	     struct device_attribute *attr, char *buf);
++static ssize_t host_show_commands_outstanding(struct device *dev,
++	     struct device_attribute *attr, char *buf);
+ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno);
+ static ssize_t host_store_rescan(struct device *dev,
+ 	 struct device_attribute *attr, const char *buf, size_t count);
+@@ -180,6 +182,8 @@ static DEVICE_ATTR(unique_id, S_IRUGO, unique_id_show, NULL);
+ static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
+ static DEVICE_ATTR(firmware_revision, S_IRUGO,
+ 	host_show_firmware_revision, NULL);
++static DEVICE_ATTR(commands_outstanding, S_IRUGO,
++	host_show_commands_outstanding, NULL);
+ 
+ static struct device_attribute *hpsa_sdev_attrs[] = {
+ 	&dev_attr_raid_level,
+@@ -191,6 +195,7 @@ static struct device_attribute *hpsa_sdev_attrs[] = {
+ static struct device_attribute *hpsa_shost_attrs[] = {
+ 	&dev_attr_rescan,
+ 	&dev_attr_firmware_revision,
++	&dev_attr_commands_outstanding,
+ 	NULL,
+ };
+ 
+@@ -290,6 +295,15 @@ static ssize_t host_show_firmware_revision(struct device *dev,
+ 		fwrev[0], fwrev[1], fwrev[2], fwrev[3]);
+ }
+ 
++static ssize_t host_show_commands_outstanding(struct device *dev,
++	     struct device_attribute *attr, char *buf)
++{
++	struct Scsi_Host *shost = class_to_shost(dev);
++	struct ctlr_info *h = shost_to_hba(shost);
++
++	return snprintf(buf, 20, "%d\n", h->commands_outstanding);
++}
++
+ /* Enqueuing and dequeuing functions for cmdlists. */
+ static inline void addQ(struct hlist_head *list, struct CommandList *c)
+ {

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0090-hpsa-fix-use-of-uninitialized-variable-in-hpsa_add_m.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0090-hpsa-fix-use-of-uninitialized-variable-in-hpsa_add_m.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,38 @@
+From 57bb0a0b5b6ae6fb87df50877c317925ec320c74 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Fri, 7 Jan 2011 10:55:43 -0600
+Subject: [PATCH 090/136] hpsa: fix use of uninitialized variable in
+ hpsa_add_msa2xxx_enclosure_device()
+
+commit c4f8a299d04bd083643ba93e982ab910219dd1f0 upstream.
+
+Thanks to Scott Teel for noticing this.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index fef7931..3ae6f3b 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1608,6 +1608,8 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
+ 	if (lun == 0) /* if lun is 0, then obviously we have a lun 0. */
+ 		return 0;
+ 
++	memset(scsi3addr, 0, 8);
++	scsi3addr[3] = target;
+ 	if (is_hba_lunid(scsi3addr))
+ 		return 0; /* Don't add the RAID controller here. */
+ 
+@@ -1622,8 +1624,6 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
+ 		return 0;
+ 	}
+ 
+-	memset(scsi3addr, 0, 8);
+-	scsi3addr[3] = target;
+ 	if (hpsa_update_device_info(h, scsi3addr, this_device))
+ 		return 0;
+ 	(*nmsa2xxx_enclosures)++;

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0091-hpsa-Fix-problem-that-CMD_UNABORTABLE-command-status.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0091-hpsa-Fix-problem-that-CMD_UNABORTABLE-command-status.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,39 @@
+From d27d3c0d4aa3ad016886557f9f9fbd4e3e2f6c95 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <StephenM.Cameron>
+Date: Fri, 7 Jan 2011 10:55:48 -0600
+Subject: [PATCH 091/136] hpsa: Fix problem that CMD_UNABORTABLE command
+ status was treated as unknown
+
+commit 1d5e2ed0805bf426226b7daa54b3e60af78baa10 upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 3ae6f3b..51acff6 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1143,6 +1143,10 @@ static void complete_scsi_command(struct CommandList *cp,
+ 		cmd->result = DID_TIME_OUT << 16;
+ 		dev_warn(&h->pdev->dev, "cp %p timedout\n", cp);
+ 		break;
++	case CMD_UNABORTABLE:
++		cmd->result = DID_ERROR << 16;
++		dev_warn(&h->pdev->dev, "Command unabortable\n");
++		break;
+ 	default:
+ 		cmd->result = DID_ERROR << 16;
+ 		dev_warn(&h->pdev->dev, "cp %p returned unknown status %x\n",
+@@ -1308,6 +1312,9 @@ static void hpsa_scsi_interpret_error(struct CommandList *cp)
+ 	case CMD_TIMEOUT:
+ 		dev_warn(d, "cp %p timed out\n", cp);
+ 		break;
++	case CMD_UNABORTABLE:
++		dev_warn(d, "Command unabortable\n");
++		break;
+ 	default:
+ 		dev_warn(d, "cp %p returned unknown status %x\n", cp,
+ 				ei->CommandStatus);

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0092-hpsa-avoid-leaking-stack-contents-to-userland.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0092-hpsa-avoid-leaking-stack-contents-to-userland.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,37 @@
+From c6bda971d4c6d0b2d4f71ae74d4afa39d7359c5e Mon Sep 17 00:00:00 2001
+From: Vasiliy Kulikov <segooon at gmail.com>
+Date: Fri, 7 Jan 2011 10:55:53 -0600
+Subject: [PATCH 092/136] hpsa: avoid leaking stack contents to userland
+
+commit 938abd8449c27fc67203e1a7c350199cea1158da upstream.
+
+memset arg64 to zero in the passthrough ioctls to avoid leaking contents
+of kernel stack memory to userland via uninitialized padding fields
+inserted by the compiler for alignment reasons.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 51acff6..2043392 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -2282,6 +2282,7 @@ static int hpsa_ioctl32_passthru(struct scsi_device *dev, int cmd, void *arg)
+ 	int err;
+ 	u32 cp;
+ 
++	memset(&arg64, 0, sizeof(arg64));
+ 	err = 0;
+ 	err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
+ 			   sizeof(arg64.LUN_info));
+@@ -2318,6 +2319,7 @@ static int hpsa_ioctl32_big_passthru(struct scsi_device *dev,
+ 	int err;
+ 	u32 cp;
+ 
++	memset(&arg64, 0, sizeof(arg64));
+ 	err = 0;
+ 	err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
+ 			   sizeof(arg64.LUN_info));

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0093-hpsa-do-not-re-order-commands-in-internal-queues.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0093-hpsa-do-not-re-order-commands-in-internal-queues.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,126 @@
+From 366de2b726f4a6237f2dcc4856baaf8fc43dee7d Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 15 Feb 2011 15:32:48 -0600
+Subject: [PATCH 093/136] hpsa: do not re-order commands in internal queues
+
+commit 9e0fc764eaec082cd2ffcf82568dfdd086935934 upstream.
+
+Driver's internal queues should be FIFO, not LIFO.
+This is a port of an almost identical patch from cciss by Jens Axboe.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c     |   23 +++++++++++------------
+ drivers/scsi/hpsa.h     |    4 ++--
+ drivers/scsi/hpsa_cmd.h |    2 +-
+ 3 files changed, 14 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 2043392..5a62a0f 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -305,9 +305,9 @@ static ssize_t host_show_commands_outstanding(struct device *dev,
+ }
+ 
+ /* Enqueuing and dequeuing functions for cmdlists. */
+-static inline void addQ(struct hlist_head *list, struct CommandList *c)
++static inline void addQ(struct list_head *list, struct CommandList *c)
+ {
+-	hlist_add_head(&c->list, list);
++	list_add_tail(&c->list, list);
+ }
+ 
+ static inline u32 next_command(struct ctlr_info *h)
+@@ -357,9 +357,9 @@ static void enqueue_cmd_and_start_io(struct ctlr_info *h,
+ 
+ static inline void removeQ(struct CommandList *c)
+ {
+-	if (WARN_ON(hlist_unhashed(&c->list)))
++	if (WARN_ON(list_empty(&c->list)))
+ 		return;
+-	hlist_del_init(&c->list);
++	list_del_init(&c->list);
+ }
+ 
+ static inline int is_hba_lunid(unsigned char scsi3addr[])
+@@ -2200,7 +2200,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
+ 
+ 	c->cmdindex = i;
+ 
+-	INIT_HLIST_NODE(&c->list);
++	INIT_LIST_HEAD(&c->list);
+ 	c->busaddr = (u32) cmd_dma_handle;
+ 	temp64.val = (u64) err_dma_handle;
+ 	c->ErrDesc.Addr.lower = temp64.val32.lower;
+@@ -2238,7 +2238,7 @@ static struct CommandList *cmd_special_alloc(struct ctlr_info *h)
+ 	}
+ 	memset(c->err_info, 0, sizeof(*c->err_info));
+ 
+-	INIT_HLIST_NODE(&c->list);
++	INIT_LIST_HEAD(&c->list);
+ 	c->busaddr = (u32) cmd_dma_handle;
+ 	temp64.val = (u64) err_dma_handle;
+ 	c->ErrDesc.Addr.lower = temp64.val32.lower;
+@@ -2809,8 +2809,8 @@ static void start_io(struct ctlr_info *h)
+ {
+ 	struct CommandList *c;
+ 
+-	while (!hlist_empty(&h->reqQ)) {
+-		c = hlist_entry(h->reqQ.first, struct CommandList, list);
++	while (!list_empty(&h->reqQ)) {
++		c = list_entry(h->reqQ.next, struct CommandList, list);
+ 		/* can't do anything if fifo is full */
+ 		if ((h->access.fifo_full(h))) {
+ 			dev_warn(&h->pdev->dev, "fifo full\n");
+@@ -2901,10 +2901,9 @@ static inline u32 process_nonindexed_cmd(struct ctlr_info *h,
+ {
+ 	u32 tag;
+ 	struct CommandList *c = NULL;
+-	struct hlist_node *tmp;
+ 
+ 	tag = hpsa_tag_discard_error_bits(raw_tag);
+-	hlist_for_each_entry(c, tmp, &h->cmpQ, list) {
++	list_for_each_entry(c, &h->cmpQ, list) {
+ 		if ((c->busaddr & 0xFFFFFFE0) == (tag & 0xFFFFFFE0)) {
+ 			finish_cmd(c, raw_tag);
+ 			return next_command(h);
+@@ -3733,8 +3732,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 
+ 	h->pdev = pdev;
+ 	h->busy_initializing = 1;
+-	INIT_HLIST_HEAD(&h->cmpQ);
+-	INIT_HLIST_HEAD(&h->reqQ);
++	INIT_LIST_HEAD(&h->cmpQ);
++	INIT_LIST_HEAD(&h->reqQ);
+ 	spin_lock_init(&h->lock);
+ 	spin_lock_init(&h->scan_lock);
+ 	rc = hpsa_pci_init(h);
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 074d237..e898193 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -75,8 +75,8 @@ struct ctlr_info {
+ 	struct access_method access;
+ 
+ 	/* queue and queue Info */
+-	struct hlist_head reqQ;
+-	struct hlist_head cmpQ;
++	struct list_head reqQ;
++	struct list_head cmpQ;
+ 	unsigned int Qdepth;
+ 	unsigned int maxQsinceinit;
+ 	unsigned int maxSG;
+diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
+index 7910c14..785abdd 100644
+--- a/drivers/scsi/hpsa_cmd.h
++++ b/drivers/scsi/hpsa_cmd.h
+@@ -292,7 +292,7 @@ struct CommandList {
+ 	struct ctlr_info	   *h;
+ 	int			   cmd_type;
+ 	long			   cmdindex;
+-	struct hlist_node list;
++	struct list_head list;
+ 	struct request *rq;
+ 	struct completion *waiting;
+ 	void   *scsi_cmd;

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0094-hpsa-make-hpsa.hpsa_simple_mode-1-module-parameter-a.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0094-hpsa-make-hpsa.hpsa_simple_mode-1-module-parameter-a.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,155 @@
+From b7e25a46a70a9dd756b5a144a52a07e030b5121c Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 15 Feb 2011 15:32:53 -0600
+Subject: [PATCH 094/136] hpsa: make hpsa.hpsa_simple_mode=1 module parameter
+ actually work
+
+commit a9a3a2739a44fc05dcaba0d4d36e52dc444c294f upstream.
+
+It's not enough to simple avoid putting the board into performant
+mode, as we have to set up the interrupts differently, etc.  When
+I originally tested this module parameter, I tested it incorrectly
+without realizing it, and the driver was running in performant mode
+the whole time unbeknownst to me.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   37 +++++++++++++++++++++++--------------
+ drivers/scsi/hpsa.h |    1 +
+ 2 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 5a62a0f..dc00910 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1177,7 +1177,7 @@ static int hpsa_scsi_detect(struct ctlr_info *h)
+ 	sh->sg_tablesize = h->maxsgentries;
+ 	h->scsi_host = sh;
+ 	sh->hostdata[0] = (unsigned long) h;
+-	sh->irq = h->intr[PERF_MODE_INT];
++	sh->irq = h->intr[h->intr_mode];
+ 	sh->unique_id = sh->irq;
+ 	error = scsi_add_host(sh, &h->pdev->dev);
+ 	if (error)
+@@ -2874,10 +2874,14 @@ static inline u32 hpsa_tag_to_index(u32 tag)
+ 	return tag >> DIRECT_LOOKUP_SHIFT;
+ }
+ 
+-static inline u32 hpsa_tag_discard_error_bits(u32 tag)
++
++static inline u32 hpsa_tag_discard_error_bits(struct ctlr_info *h, u32 tag)
+ {
+-#define HPSA_ERROR_BITS 0x03
+-	return tag & ~HPSA_ERROR_BITS;
++#define HPSA_PERF_ERROR_BITS ((1 << DIRECT_LOOKUP_SHIFT) - 1)
++#define HPSA_SIMPLE_ERROR_BITS 0x03
++	if (unlikely(h->transMethod != CFGTBL_Trans_Performant))
++		return tag & ~HPSA_SIMPLE_ERROR_BITS;
++	return tag & ~HPSA_PERF_ERROR_BITS;
+ }
+ 
+ /* process completion of an indexed ("direct lookup") command */
+@@ -2902,7 +2906,7 @@ static inline u32 process_nonindexed_cmd(struct ctlr_info *h,
+ 	u32 tag;
+ 	struct CommandList *c = NULL;
+ 
+-	tag = hpsa_tag_discard_error_bits(raw_tag);
++	tag = hpsa_tag_discard_error_bits(h, raw_tag);
+ 	list_for_each_entry(c, &h->cmpQ, list) {
+ 		if ((c->busaddr & 0xFFFFFFE0) == (tag & 0xFFFFFFE0)) {
+ 			finish_cmd(c, raw_tag);
+@@ -2953,7 +2957,10 @@ static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id)
+ 	return IRQ_HANDLED;
+ }
+ 
+-/* Send a message CDB to the firmware. */
++/* Send a message CDB to the firmware. Careful, this only works
++ * in simple mode, not performant mode due to the tag lookup.
++ * We only ever use this immediately after a controller reset.
++ */
+ static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
+ 						unsigned char type)
+ {
+@@ -3019,7 +3026,7 @@ static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
+ 
+ 	for (i = 0; i < HPSA_MSG_SEND_RETRY_LIMIT; i++) {
+ 		tag = readl(vaddr + SA5_REPLY_PORT_OFFSET);
+-		if (hpsa_tag_discard_error_bits(tag) == paddr32)
++		if ((tag & ~HPSA_SIMPLE_ERROR_BITS) == paddr32)
+ 			break;
+ 		msleep(HPSA_MSG_SEND_RETRY_INTERVAL_MSECS);
+ 	}
+@@ -3351,7 +3358,7 @@ static void __devinit hpsa_interrupt_mode(struct ctlr_info *h)
+ default_int_mode:
+ #endif				/* CONFIG_PCI_MSI */
+ 	/* if we get here we're going to use the default interrupt mode */
+-	h->intr[PERF_MODE_INT] = h->pdev->irq;
++	h->intr[h->intr_mode] = h->pdev->irq;
+ }
+ 
+ static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id)
+@@ -3732,6 +3739,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 
+ 	h->pdev = pdev;
+ 	h->busy_initializing = 1;
++	h->intr_mode = hpsa_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
++	printk(KERN_WARNING "hpsa_simple_mode is %d\n", hpsa_simple_mode);
+ 	INIT_LIST_HEAD(&h->cmpQ);
+ 	INIT_LIST_HEAD(&h->reqQ);
+ 	spin_lock_init(&h->lock);
+@@ -3762,20 +3771,20 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 	h->access.set_intr_mask(h, HPSA_INTR_OFF);
+ 
+ 	if (h->msix_vector || h->msi_vector)
+-		rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr_msi,
++		rc = request_irq(h->intr[h->intr_mode], do_hpsa_intr_msi,
+ 				IRQF_DISABLED, h->devname, h);
+ 	else
+-		rc = request_irq(h->intr[PERF_MODE_INT], do_hpsa_intr_intx,
++		rc = request_irq(h->intr[h->intr_mode], do_hpsa_intr_intx,
+ 				IRQF_DISABLED, h->devname, h);
+ 	if (rc) {
+ 		dev_err(&pdev->dev, "unable to get irq %d for %s\n",
+-		       h->intr[PERF_MODE_INT], h->devname);
++		       h->intr[h->intr_mode], h->devname);
+ 		goto clean2;
+ 	}
+ 
+ 	dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
+ 	       h->devname, pdev->device,
+-	       h->intr[PERF_MODE_INT], dac ? "" : " not");
++	       h->intr[h->intr_mode], dac ? "" : " not");
+ 
+ 	h->cmd_pool_bits =
+ 	    kmalloc(((h->nr_cmds + BITS_PER_LONG -
+@@ -3826,7 +3835,7 @@ clean4:
+ 			    h->nr_cmds * sizeof(struct ErrorInfo),
+ 			    h->errinfo_pool,
+ 			    h->errinfo_pool_dhandle);
+-	free_irq(h->intr[PERF_MODE_INT], h);
++	free_irq(h->intr[h->intr_mode], h);
+ clean2:
+ clean1:
+ 	h->busy_initializing = 0;
+@@ -3870,7 +3879,7 @@ static void hpsa_shutdown(struct pci_dev *pdev)
+ 	 */
+ 	hpsa_flush_cache(h);
+ 	h->access.set_intr_mask(h, HPSA_INTR_OFF);
+-	free_irq(h->intr[PERF_MODE_INT], h);
++	free_irq(h->intr[h->intr_mode], h);
+ #ifdef CONFIG_PCI_MSI
+ 	if (h->msix_vector)
+ 		pci_disable_msix(h->pdev);
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index e898193..621a153 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -72,6 +72,7 @@ struct ctlr_info {
+ 	unsigned int intr[4];
+ 	unsigned int msix_vector;
+ 	unsigned int msi_vector;
++	int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */
+ 	struct access_method access;
+ 
+ 	/* queue and queue Info */

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0095-hpsa-Add-transport_mode-host-attribute-in-sys.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0095-hpsa-Add-transport_mode-host-attribute-in-sys.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,70 @@
+From a0fde39e480c3d4ee24cbb859b6ce1edcd81d773 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 15 Feb 2011 15:32:58 -0600
+Subject: [PATCH 095/136] hpsa: Add transport_mode host attribute in /sys
+
+commit 745a7a25bc0f6dc77db72656b7bc8d17b6ee8e53 upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index dc00910..c1e2319 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -153,6 +153,8 @@ static ssize_t host_show_firmware_revision(struct device *dev,
+ 	     struct device_attribute *attr, char *buf);
+ static ssize_t host_show_commands_outstanding(struct device *dev,
+ 	     struct device_attribute *attr, char *buf);
++static ssize_t host_show_transport_mode(struct device *dev,
++	struct device_attribute *attr, char *buf);
+ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno);
+ static ssize_t host_store_rescan(struct device *dev,
+ 	 struct device_attribute *attr, const char *buf, size_t count);
+@@ -184,6 +186,8 @@ static DEVICE_ATTR(firmware_revision, S_IRUGO,
+ 	host_show_firmware_revision, NULL);
+ static DEVICE_ATTR(commands_outstanding, S_IRUGO,
+ 	host_show_commands_outstanding, NULL);
++static DEVICE_ATTR(transport_mode, S_IRUGO,
++	host_show_transport_mode, NULL);
+ 
+ static struct device_attribute *hpsa_sdev_attrs[] = {
+ 	&dev_attr_raid_level,
+@@ -196,6 +200,7 @@ static struct device_attribute *hpsa_shost_attrs[] = {
+ 	&dev_attr_rescan,
+ 	&dev_attr_firmware_revision,
+ 	&dev_attr_commands_outstanding,
++	&dev_attr_transport_mode,
+ 	NULL,
+ };
+ 
+@@ -304,6 +309,18 @@ static ssize_t host_show_commands_outstanding(struct device *dev,
+ 	return snprintf(buf, 20, "%d\n", h->commands_outstanding);
+ }
+ 
++static ssize_t host_show_transport_mode(struct device *dev,
++	struct device_attribute *attr, char *buf)
++{
++	struct ctlr_info *h;
++	struct Scsi_Host *shost = class_to_shost(dev);
++
++	h = shost_to_hba(shost);
++	return snprintf(buf, 20, "%s\n",
++		h->transMethod == CFGTBL_Trans_Performant ?
++			"performant" : "simple");
++}
++
+ /* Enqueuing and dequeuing functions for cmdlists. */
+ static inline void addQ(struct list_head *list, struct CommandList *c)
+ {
+@@ -3740,7 +3757,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 	h->pdev = pdev;
+ 	h->busy_initializing = 1;
+ 	h->intr_mode = hpsa_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
+-	printk(KERN_WARNING "hpsa_simple_mode is %d\n", hpsa_simple_mode);
+ 	INIT_LIST_HEAD(&h->cmpQ);
+ 	INIT_LIST_HEAD(&h->reqQ);
+ 	spin_lock_init(&h->lock);

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0096-hpsa-Inform-controller-we-are-using-32-bit-tags.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0096-hpsa-Inform-controller-we-are-using-32-bit-tags.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,122 @@
+From 8672b6f8e803d0c1394ccd0a7030da3e7fbca512 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 15 Feb 2011 15:33:03 -0600
+Subject: [PATCH 096/136] hpsa: Inform controller we are using 32-bit tags.
+
+commit 960a30e7a73affcc441b9ceaff3b1b9e73e99c1f upstream.
+
+Controller will transfer only 32-bits on completion if it
+knows we are only using 32-bit tags.  Also, some newer controllers
+apparently (and erroneously) require that we only use 32-bit tags,
+and that we inform the controller of this.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c     |   24 +++++++++++++-----------
+ drivers/scsi/hpsa_cmd.h |    1 +
+ 2 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index c1e2319..747c31b 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -317,7 +317,7 @@ static ssize_t host_show_transport_mode(struct device *dev,
+ 
+ 	h = shost_to_hba(shost);
+ 	return snprintf(buf, 20, "%s\n",
+-		h->transMethod == CFGTBL_Trans_Performant ?
++		h->transMethod & CFGTBL_Trans_Performant ?
+ 			"performant" : "simple");
+ }
+ 
+@@ -331,7 +331,7 @@ static inline u32 next_command(struct ctlr_info *h)
+ {
+ 	u32 a;
+ 
+-	if (unlikely(h->transMethod != CFGTBL_Trans_Performant))
++	if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant)))
+ 		return h->access.command_completed(h);
+ 
+ 	if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
+@@ -355,7 +355,7 @@ static inline u32 next_command(struct ctlr_info *h)
+  */
+ static void set_performant_mode(struct ctlr_info *h, struct CommandList *c)
+ {
+-	if (likely(h->transMethod == CFGTBL_Trans_Performant))
++	if (likely(h->transMethod & CFGTBL_Trans_Performant))
+ 		c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1);
+ }
+ 
+@@ -2896,7 +2896,7 @@ static inline u32 hpsa_tag_discard_error_bits(struct ctlr_info *h, u32 tag)
+ {
+ #define HPSA_PERF_ERROR_BITS ((1 << DIRECT_LOOKUP_SHIFT) - 1)
+ #define HPSA_SIMPLE_ERROR_BITS 0x03
+-	if (unlikely(h->transMethod != CFGTBL_Trans_Performant))
++	if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant)))
+ 		return tag & ~HPSA_SIMPLE_ERROR_BITS;
+ 	return tag & ~HPSA_PERF_ERROR_BITS;
+ }
+@@ -3612,6 +3612,7 @@ static int __devinit hpsa_enter_simple_mode(struct ctlr_info *h)
+ 			"unable to get board into simple mode\n");
+ 		return -ENODEV;
+ 	}
++	h->transMethod = CFGTBL_Trans_Simple;
+ 	return 0;
+ }
+ 
+@@ -3997,7 +3998,8 @@ static void  calc_bucket_map(int bucket[], int num_buckets,
+ 	}
+ }
+ 
+-static __devinit void hpsa_enter_performant_mode(struct ctlr_info *h)
++static __devinit void hpsa_enter_performant_mode(struct ctlr_info *h,
++	u32 use_short_tags)
+ {
+ 	int i;
+ 	unsigned long register_value;
+@@ -4045,7 +4047,7 @@ static __devinit void hpsa_enter_performant_mode(struct ctlr_info *h)
+ 	writel(0, &h->transtable->RepQCtrAddrHigh32);
+ 	writel(h->reply_pool_dhandle, &h->transtable->RepQAddr0Low32);
+ 	writel(0, &h->transtable->RepQAddr0High32);
+-	writel(CFGTBL_Trans_Performant,
++	writel(CFGTBL_Trans_Performant | use_short_tags,
+ 		&(h->cfgtable->HostWrite.TransportRequest));
+ 	writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+ 	hpsa_wait_for_mode_change_ack(h);
+@@ -4055,6 +4057,9 @@ static __devinit void hpsa_enter_performant_mode(struct ctlr_info *h)
+ 					" performant mode\n");
+ 		return;
+ 	}
++	/* Change the access methods to the performant access methods */
++	h->access = SA5_performant_access;
++	h->transMethod = CFGTBL_Trans_Performant;
+ }
+ 
+ static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
+@@ -4083,11 +4088,8 @@ static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
+ 		|| (h->blockFetchTable == NULL))
+ 		goto clean_up;
+ 
+-	hpsa_enter_performant_mode(h);
+-
+-	/* Change the access methods to the performant access methods */
+-	h->access = SA5_performant_access;
+-	h->transMethod = CFGTBL_Trans_Performant;
++	hpsa_enter_performant_mode(h,
++		trans_support & CFGTBL_Trans_use_short_tags);
+ 
+ 	return;
+ 
+diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
+index 785abdd..1846490 100644
+--- a/drivers/scsi/hpsa_cmd.h
++++ b/drivers/scsi/hpsa_cmd.h
+@@ -104,6 +104,7 @@
+ 
+ #define CFGTBL_Trans_Simple     0x00000002l
+ #define CFGTBL_Trans_Performant 0x00000004l
++#define CFGTBL_Trans_use_short_tags 0x20000000l
+ 
+ #define CFGTBL_BusType_Ultra2   0x00000001l
+ #define CFGTBL_BusType_Ultra3   0x00000002l

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0097-hpsa-Do-not-attempt-kdump-if-we-detect-resetting-con.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0097-hpsa-Do-not-attempt-kdump-if-we-detect-resetting-con.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,39 @@
+From 6d2736e5d6e72c2b2d9b01c9035c4a140228b229 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 15 Feb 2011 15:33:08 -0600
+Subject: [PATCH 097/136] hpsa: Do not attempt kdump if we detect resetting
+ controller failed.
+
+commit ba95e2ac6bfeb9af92153058a353fc47e1addc02 upstream.
+
+We can get completions left over from before the attempted reset which
+will interfere with the kdump.  Better to just not make the attempt in
+that case.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 747c31b..087a77b 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3236,13 +3236,13 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	 * It means we're on one of those controllers which doesn't support
+ 	 * the doorbell reset method and on which the PCI power management reset
+ 	 * method doesn't work (P800, for example.)
+-	 * In those cases, pretend the reset worked and hope for the best.
++	 * In those cases, don't try to proceed, as it generally doesn't work.
+ 	 */
+ 	active_transport = readl(&cfgtable->TransportActive);
+ 	if (active_transport & PERFORMANT_MODE) {
+ 		dev_warn(&pdev->dev, "Unable to successfully reset controller,"
+-			" proceeding anyway.\n");
+-		rc = -ENOTSUPP;
++			" Ignoring controller.\n");
++		rc = -ENODEV;
+ 	}
+ 
+ unmap_cfgtable:

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0098-hpsa-fix-bad-comparison.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0098-hpsa-fix-bad-comparison.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,30 @@
+From 82544351c81e6bb64eee4a7c8a76784de854ea2a Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <error27 at gmail.com>
+Date: Tue, 15 Feb 2011 15:33:13 -0600
+Subject: [PATCH 098/136] hpsa: fix bad comparison
+
+commit 382be668c5a284844f9dcbb5b1cb8ffba2386d80 upstream.
+
+'!' has higher precedence than '&'.  CFGTBL_ChangeReq is 0x1 so the
+original code is equivelent to if (!doorbell_value) {...
+
+Signed-off-by: Dan Carpenter <error27 at gmail.com>
+Acked-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 087a77b..0f5979a 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3586,7 +3586,7 @@ static void __devinit hpsa_wait_for_mode_change_ack(struct ctlr_info *h)
+ 		spin_lock_irqsave(&h->lock, flags);
+ 		doorbell_value = readl(h->vaddr + SA5_DOORBELL);
+ 		spin_unlock_irqrestore(&h->lock, flags);
+-		if (!doorbell_value & CFGTBL_ChangeReq)
++		if (!(doorbell_value & CFGTBL_ChangeReq))
+ 			break;
+ 		/* delay and try again */
+ 		msleep(10);

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0099-hpsa-fix-incorrect-PCI-IDs-and-add-two-new-ones-2nd-.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0099-hpsa-fix-incorrect-PCI-IDs-and-add-two-new-ones-2nd-.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,74 @@
+From 7cab8a9728ccfb9c0843d2f64e1d544389ba9888 Mon Sep 17 00:00:00 2001
+From: "scameron at beardog.cce.hp.com" <scameron at beardog.cce.hp.com>
+Date: Mon, 7 Mar 2011 10:44:16 -0600
+Subject: [PATCH 099/136] hpsa: fix incorrect PCI IDs and add two new ones
+ (2nd try)
+
+commit 9143a9612277abc6e4ddced2bc54a120734834c6 upstream.
+
+My first attempt was botched, got the wrong PCI Device ID
+(used PCI_DEVICE_ID_HP_CISSE, should have been PCI_DEVICE_ID_HP_CISSF)
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+[bwh: Backported to 2.6.32: also add the device ID to <linux/pci_ids.h>,
+ added upstream in commit 6362beea8914cbd4630ccde3617d944aeca2d48f]
+---
+ drivers/scsi/hpsa.c     |   24 ++++++++++++++----------
+ include/linux/pci_ids.h |    1 +
+ 2 files changed, 15 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 0f5979a..a410aca 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -82,11 +82,13 @@ MODULE_PARM_DESC(hpsa_simple_mode,
+ /* define the PCI info for the cards we can control */
+ static const struct pci_device_id hpsa_pci_device_id[] = {
+ 	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3233},
+-	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3250},
+-	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3251},
+-	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3252},
+-	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3253},
+-	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3254},
++	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3350},
++	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3351},
++	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3352},
++	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3353},
++	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3354},
++	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3355},
++	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3356},
+ 	{PCI_VENDOR_ID_HP,     PCI_ANY_ID,	PCI_ANY_ID, PCI_ANY_ID,
+ 		PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
+ 	{0,}
+@@ -106,11 +108,13 @@ static struct board_type products[] = {
+ 	{0x3249103C, "Smart Array P812", &SA5_access},
+ 	{0x324a103C, "Smart Array P712m", &SA5_access},
+ 	{0x324b103C, "Smart Array P711m", &SA5_access},
+-	{0x3250103C, "Smart Array", &SA5_access},
+-	{0x3250113C, "Smart Array", &SA5_access},
+-	{0x3250123C, "Smart Array", &SA5_access},
+-	{0x3250133C, "Smart Array", &SA5_access},
+-	{0x3250143C, "Smart Array", &SA5_access},
++	{0x3350103C, "Smart Array", &SA5_access},
++	{0x3351103C, "Smart Array", &SA5_access},
++	{0x3352103C, "Smart Array", &SA5_access},
++	{0x3353103C, "Smart Array", &SA5_access},
++	{0x3354103C, "Smart Array", &SA5_access},
++	{0x3355103C, "Smart Array", &SA5_access},
++	{0x3356103C, "Smart Array", &SA5_access},
+ 	{0xFFFF103C, "Unknown Smart Array", &SA5_access},
+ };
+ 
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
+index 96077a5..b987a66 100644
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -744,6 +744,7 @@
+ #define PCI_DEVICE_ID_HP_CISSC		0x3230
+ #define PCI_DEVICE_ID_HP_CISSD		0x3238
+ #define PCI_DEVICE_ID_HP_CISSE		0x323a
++#define PCI_DEVICE_ID_HP_CISSF		0x323b
+ #define PCI_DEVICE_ID_HP_ZX2_IOC	0x4031
+ 
+ #define PCI_VENDOR_ID_PCTECH		0x1042

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0100-hpsa-move-device-attributes-to-avoid-forward-declara.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0100-hpsa-move-device-attributes-to-avoid-forward-declara.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,304 @@
+From aa98bec461822222293c009fd7a3ef3d712968d0 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Wed, 9 Mar 2011 17:00:01 -0600
+Subject: [PATCH 100/136] hpsa: move device attributes to avoid forward
+ declarations
+
+commit 3f5eac3a040a2ea61a575f713aabedecdd23c3f8 upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+[bwh: Backported to 2.6.32: no scsi_host_template::change_queue_depth]
+---
+ drivers/scsi/hpsa.c |  251 ++++++++++++++++++++++++---------------------------
+ 1 file changed, 119 insertions(+), 132 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index a410aca..3eb21da 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -147,21 +147,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
+ static int hpsa_slave_alloc(struct scsi_device *sdev);
+ static void hpsa_slave_destroy(struct scsi_device *sdev);
+ 
+-static ssize_t raid_level_show(struct device *dev,
+-	struct device_attribute *attr, char *buf);
+-static ssize_t lunid_show(struct device *dev,
+-	struct device_attribute *attr, char *buf);
+-static ssize_t unique_id_show(struct device *dev,
+-	struct device_attribute *attr, char *buf);
+-static ssize_t host_show_firmware_revision(struct device *dev,
+-	     struct device_attribute *attr, char *buf);
+-static ssize_t host_show_commands_outstanding(struct device *dev,
+-	     struct device_attribute *attr, char *buf);
+-static ssize_t host_show_transport_mode(struct device *dev,
+-	struct device_attribute *attr, char *buf);
+ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno);
+-static ssize_t host_store_rescan(struct device *dev,
+-	 struct device_attribute *attr, const char *buf, size_t count);
+ static int check_for_unit_attention(struct ctlr_info *h,
+ 	struct CommandList *c);
+ static void check_ioctl_unit_attention(struct ctlr_info *h,
+@@ -182,52 +168,6 @@ static int __devinit hpsa_wait_for_board_state(struct pci_dev *pdev,
+ #define BOARD_NOT_READY 0
+ #define BOARD_READY 1
+ 
+-static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
+-static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL);
+-static DEVICE_ATTR(unique_id, S_IRUGO, unique_id_show, NULL);
+-static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
+-static DEVICE_ATTR(firmware_revision, S_IRUGO,
+-	host_show_firmware_revision, NULL);
+-static DEVICE_ATTR(commands_outstanding, S_IRUGO,
+-	host_show_commands_outstanding, NULL);
+-static DEVICE_ATTR(transport_mode, S_IRUGO,
+-	host_show_transport_mode, NULL);
+-
+-static struct device_attribute *hpsa_sdev_attrs[] = {
+-	&dev_attr_raid_level,
+-	&dev_attr_lunid,
+-	&dev_attr_unique_id,
+-	NULL,
+-};
+-
+-static struct device_attribute *hpsa_shost_attrs[] = {
+-	&dev_attr_rescan,
+-	&dev_attr_firmware_revision,
+-	&dev_attr_commands_outstanding,
+-	&dev_attr_transport_mode,
+-	NULL,
+-};
+-
+-static struct scsi_host_template hpsa_driver_template = {
+-	.module			= THIS_MODULE,
+-	.name			= "hpsa",
+-	.proc_name		= "hpsa",
+-	.queuecommand		= hpsa_scsi_queue_command,
+-	.scan_start		= hpsa_scan_start,
+-	.scan_finished		= hpsa_scan_finished,
+-	.this_id		= -1,
+-	.use_clustering		= ENABLE_CLUSTERING,
+-	.eh_device_reset_handler = hpsa_eh_device_reset_handler,
+-	.ioctl			= hpsa_ioctl,
+-	.slave_alloc		= hpsa_slave_alloc,
+-	.slave_destroy		= hpsa_slave_destroy,
+-#ifdef CONFIG_COMPAT
+-	.compat_ioctl		= hpsa_compat_ioctl,
+-#endif
+-	.sdev_attrs = hpsa_sdev_attrs,
+-	.shost_attrs = hpsa_shost_attrs,
+-};
+-
+ static inline struct ctlr_info *sdev_to_hba(struct scsi_device *sdev)
+ {
+ 	unsigned long *priv = shost_priv(sdev->host);
+@@ -325,83 +265,11 @@ static ssize_t host_show_transport_mode(struct device *dev,
+ 			"performant" : "simple");
+ }
+ 
+-/* Enqueuing and dequeuing functions for cmdlists. */
+-static inline void addQ(struct list_head *list, struct CommandList *c)
+-{
+-	list_add_tail(&c->list, list);
+-}
+-
+-static inline u32 next_command(struct ctlr_info *h)
+-{
+-	u32 a;
+-
+-	if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant)))
+-		return h->access.command_completed(h);
+-
+-	if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
+-		a = *(h->reply_pool_head); /* Next cmd in ring buffer */
+-		(h->reply_pool_head)++;
+-		h->commands_outstanding--;
+-	} else {
+-		a = FIFO_EMPTY;
+-	}
+-	/* Check for wraparound */
+-	if (h->reply_pool_head == (h->reply_pool + h->max_commands)) {
+-		h->reply_pool_head = h->reply_pool;
+-		h->reply_pool_wraparound ^= 1;
+-	}
+-	return a;
+-}
+-
+-/* set_performant_mode: Modify the tag for cciss performant
+- * set bit 0 for pull model, bits 3-1 for block fetch
+- * register number
+- */
+-static void set_performant_mode(struct ctlr_info *h, struct CommandList *c)
+-{
+-	if (likely(h->transMethod & CFGTBL_Trans_Performant))
+-		c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1);
+-}
+-
+-static void enqueue_cmd_and_start_io(struct ctlr_info *h,
+-	struct CommandList *c)
+-{
+-	unsigned long flags;
+-
+-	set_performant_mode(h, c);
+-	spin_lock_irqsave(&h->lock, flags);
+-	addQ(&h->reqQ, c);
+-	h->Qdepth++;
+-	start_io(h);
+-	spin_unlock_irqrestore(&h->lock, flags);
+-}
+-
+-static inline void removeQ(struct CommandList *c)
+-{
+-	if (WARN_ON(list_empty(&c->list)))
+-		return;
+-	list_del_init(&c->list);
+-}
+-
+-static inline int is_hba_lunid(unsigned char scsi3addr[])
+-{
+-	return memcmp(scsi3addr, RAID_CTLR_LUNID, 8) == 0;
+-}
+-
+ static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[])
+ {
+ 	return (scsi3addr[3] & 0xC0) == 0x40;
+ }
+ 
+-static inline int is_scsi_rev_5(struct ctlr_info *h)
+-{
+-	if (!h->hba_inquiry_data)
+-		return 0;
+-	if ((h->hba_inquiry_data[2] & 0x07) == 5)
+-		return 1;
+-	return 0;
+-}
+-
+ static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
+ 	"UNKNOWN"
+ };
+@@ -493,6 +361,125 @@ static ssize_t unique_id_show(struct device *dev,
+ 			sn[12], sn[13], sn[14], sn[15]);
+ }
+ 
++static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
++static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL);
++static DEVICE_ATTR(unique_id, S_IRUGO, unique_id_show, NULL);
++static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
++static DEVICE_ATTR(firmware_revision, S_IRUGO,
++	host_show_firmware_revision, NULL);
++static DEVICE_ATTR(commands_outstanding, S_IRUGO,
++	host_show_commands_outstanding, NULL);
++static DEVICE_ATTR(transport_mode, S_IRUGO,
++	host_show_transport_mode, NULL);
++
++static struct device_attribute *hpsa_sdev_attrs[] = {
++	&dev_attr_raid_level,
++	&dev_attr_lunid,
++	&dev_attr_unique_id,
++	NULL,
++};
++
++static struct device_attribute *hpsa_shost_attrs[] = {
++	&dev_attr_rescan,
++	&dev_attr_firmware_revision,
++	&dev_attr_commands_outstanding,
++	&dev_attr_transport_mode,
++	NULL,
++};
++
++static struct scsi_host_template hpsa_driver_template = {
++	.module			= THIS_MODULE,
++	.name			= "hpsa",
++	.proc_name		= "hpsa",
++	.queuecommand		= hpsa_scsi_queue_command,
++	.scan_start		= hpsa_scan_start,
++	.scan_finished		= hpsa_scan_finished,
++	.this_id		= -1,
++	.use_clustering		= ENABLE_CLUSTERING,
++	.eh_device_reset_handler = hpsa_eh_device_reset_handler,
++	.ioctl			= hpsa_ioctl,
++	.slave_alloc		= hpsa_slave_alloc,
++	.slave_destroy		= hpsa_slave_destroy,
++#ifdef CONFIG_COMPAT
++	.compat_ioctl		= hpsa_compat_ioctl,
++#endif
++	.sdev_attrs = hpsa_sdev_attrs,
++	.shost_attrs = hpsa_shost_attrs,
++};
++
++
++/* Enqueuing and dequeuing functions for cmdlists. */
++static inline void addQ(struct list_head *list, struct CommandList *c)
++{
++	list_add_tail(&c->list, list);
++}
++
++static inline u32 next_command(struct ctlr_info *h)
++{
++	u32 a;
++
++	if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant)))
++		return h->access.command_completed(h);
++
++	if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
++		a = *(h->reply_pool_head); /* Next cmd in ring buffer */
++		(h->reply_pool_head)++;
++		h->commands_outstanding--;
++	} else {
++		a = FIFO_EMPTY;
++	}
++	/* Check for wraparound */
++	if (h->reply_pool_head == (h->reply_pool + h->max_commands)) {
++		h->reply_pool_head = h->reply_pool;
++		h->reply_pool_wraparound ^= 1;
++	}
++	return a;
++}
++
++/* set_performant_mode: Modify the tag for cciss performant
++ * set bit 0 for pull model, bits 3-1 for block fetch
++ * register number
++ */
++static void set_performant_mode(struct ctlr_info *h, struct CommandList *c)
++{
++	if (likely(h->transMethod & CFGTBL_Trans_Performant))
++		c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1);
++}
++
++static void enqueue_cmd_and_start_io(struct ctlr_info *h,
++	struct CommandList *c)
++{
++	unsigned long flags;
++
++	set_performant_mode(h, c);
++	spin_lock_irqsave(&h->lock, flags);
++	addQ(&h->reqQ, c);
++	h->Qdepth++;
++	start_io(h);
++	spin_unlock_irqrestore(&h->lock, flags);
++}
++
++static inline void removeQ(struct CommandList *c)
++{
++	if (WARN_ON(list_empty(&c->list)))
++		return;
++	list_del_init(&c->list);
++}
++
++static inline int is_hba_lunid(unsigned char scsi3addr[])
++{
++	return memcmp(scsi3addr, RAID_CTLR_LUNID, 8) == 0;
++}
++
++static inline int is_scsi_rev_5(struct ctlr_info *h)
++{
++	if (!h->hba_inquiry_data)
++		return 0;
++	if ((h->hba_inquiry_data[2] & 0x07) == 5)
++		return 1;
++	return 0;
++}
++
+ static int hpsa_find_target_lun(struct ctlr_info *h,
+ 	unsigned char scsi3addr[], int bus, int *target, int *lun)
+ {

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0101-hpsa-export-resettable-host-attribute.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0101-hpsa-export-resettable-host-attribute.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,86 @@
+From 9910b190678f5204ff108439a77f86172f632595 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Wed, 9 Mar 2011 17:00:06 -0600
+Subject: [PATCH 101/136] hpsa: export resettable host attribute
+
+commit 941b1cdae83039c99fc5c1884a98d2afd39760e5 upstream.
+
+This attribute, requested by Redhat, allows kexec-tools to know
+whether the controller can honor the reset_devices kernel parameter
+and actually reset the controller.  For kdump to work properly it
+is necessary that the reset_devices parameter be honored.  This
+attribute enables kexec-tools to warn the user if they attempt to
+designate a non-resettable controller as the dump device.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   41 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 3eb21da..fa52ad9 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -265,6 +265,44 @@ static ssize_t host_show_transport_mode(struct device *dev,
+ 			"performant" : "simple");
+ }
+ 
++/* List of controllers which cannot be reset on kexec with reset_devices */
++static u32 unresettable_controller[] = {
++	0x324a103C, /* Smart Array P712m */
++	0x324b103C, /* SmartArray P711m */
++	0x3223103C, /* Smart Array P800 */
++	0x3234103C, /* Smart Array P400 */
++	0x3235103C, /* Smart Array P400i */
++	0x3211103C, /* Smart Array E200i */
++	0x3212103C, /* Smart Array E200 */
++	0x3213103C, /* Smart Array E200i */
++	0x3214103C, /* Smart Array E200i */
++	0x3215103C, /* Smart Array E200i */
++	0x3237103C, /* Smart Array E500 */
++	0x323D103C, /* Smart Array P700m */
++	0x409C0E11, /* Smart Array 6400 */
++	0x409D0E11, /* Smart Array 6400 EM */
++};
++
++static int ctlr_is_resettable(struct ctlr_info *h)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++)
++		if (unresettable_controller[i] == h->board_id)
++			return 0;
++	return 1;
++}
++
++static ssize_t host_show_resettable(struct device *dev,
++	struct device_attribute *attr, char *buf)
++{
++	struct ctlr_info *h;
++	struct Scsi_Host *shost = class_to_shost(dev);
++
++	h = shost_to_hba(shost);
++	return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h));
++}
++
+ static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[])
+ {
+ 	return (scsi3addr[3] & 0xC0) == 0x40;
+@@ -371,6 +409,8 @@ static DEVICE_ATTR(commands_outstanding, S_IRUGO,
+ 	host_show_commands_outstanding, NULL);
+ static DEVICE_ATTR(transport_mode, S_IRUGO,
+ 	host_show_transport_mode, NULL);
++static DEVICE_ATTR(resettable, S_IRUGO,
++	host_show_resettable, NULL);
+ 
+ static struct device_attribute *hpsa_sdev_attrs[] = {
+ 	&dev_attr_raid_level,
+@@ -384,6 +424,7 @@ static struct device_attribute *hpsa_shost_attrs[] = {
+ 	&dev_attr_firmware_revision,
+ 	&dev_attr_commands_outstanding,
+ 	&dev_attr_transport_mode,
++	&dev_attr_resettable,
+ 	NULL,
+ };
+ 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0102-hpsa-do-readl-after-writel-in-main-i-o-path-to-ensur.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0102-hpsa-do-readl-after-writel-in-main-i-o-path-to-ensur.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,30 @@
+From bebca693eb5bde267011b46fbcca723047b0c1b4 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:58:49 -0500
+Subject: [PATCH 102/136] hpsa: do readl after writel in main i/o path to
+ ensure commands don't get lost.
+
+commit d0be5ec8693944c2e2fc0de70fda9dbc1b93bd7d upstream.
+
+Apparently we've been doin it rong for a decade, but only lately do we
+run into problems.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 621a153..98c97ca 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -212,6 +212,7 @@ static void SA5_submit_command(struct ctlr_info *h,
+ 	dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr,
+ 		c->Header.Tag.lower);
+ 	writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
++	(void) readl(h->vaddr + SA5_REQUEST_PORT_OFFSET);
+ 	h->commands_outstanding++;
+ 	if (h->commands_outstanding > h->max_outstanding)
+ 		h->max_outstanding = h->commands_outstanding;

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0103-hpsa-add-readl-after-writel-in-interrupt-mask-settin.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0103-hpsa-add-readl-after-writel-in-interrupt-mask-settin.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,48 @@
+From 6cdd7154301c0975c5c4c41ed0b37b313355f01a Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:58:55 -0500
+Subject: [PATCH 103/136] hpsa: add readl after writel in interrupt mask
+ setting code
+
+commit 8cd21da71c952843f9cc215436286cf7f991cc6e upstream.
+
+This is to ensure the board interrupts are really off when
+these functions return.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.h |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 98c97ca..7eec397 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -228,10 +228,12 @@ static void SA5_intr_mask(struct ctlr_info *h, unsigned long val)
+ 	if (val) { /* Turn interrupts on */
+ 		h->interrupts_enabled = 1;
+ 		writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
++		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+ 	} else { /* Turn them off */
+ 		h->interrupts_enabled = 0;
+ 		writel(SA5_INTR_OFF,
+ 			h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
++		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+ 	}
+ }
+ 
+@@ -240,10 +242,12 @@ static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val)
+ 	if (val) { /* turn on interrupts */
+ 		h->interrupts_enabled = 1;
+ 		writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
++		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+ 	} else {
+ 		h->interrupts_enabled = 0;
+ 		writel(SA5_PERF_INTR_OFF,
+ 			h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
++		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+ 	}
+ }
+ 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0104-hpsa-remove-unused-parameter-from-hpsa_complete_scsi.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0104-hpsa-remove-unused-parameter-from-hpsa_complete_scsi.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,38 @@
+From 73be737a0b5e3de570dfecc9fd43fa9dda590eca Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:00 -0500
+Subject: [PATCH 104/136] hpsa: remove unused parameter from
+ hpsa_complete_scsi_command()
+
+commit 1fb011fb05b6bac4fb8eabd324a6983116f7594d upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index fa52ad9..a5b47a9 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -997,8 +997,7 @@ static void hpsa_unmap_sg_chain_block(struct ctlr_info *h,
+ 	pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE);
+ }
+ 
+-static void complete_scsi_command(struct CommandList *cp,
+-	int timeout, u32 tag)
++static void complete_scsi_command(struct CommandList *cp)
+ {
+ 	struct scsi_cmnd *cmd;
+ 	struct ctlr_info *h;
+@@ -2908,7 +2907,7 @@ static inline void finish_cmd(struct CommandList *c, u32 raw_tag)
+ {
+ 	removeQ(c);
+ 	if (likely(c->cmd_type == CMD_SCSI))
+-		complete_scsi_command(c, 0, raw_tag);
++		complete_scsi_command(c);
+ 	else if (c->cmd_type == CMD_IOCTL_PEND)
+ 		complete(c->waiting);
+ }

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0105-hpsa-delete-old-unused-padding-garbage.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0105-hpsa-delete-old-unused-padding-garbage.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,33 @@
+From eee0ac89f0ce7c0f30cdf2c094c2bd3081f68082 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:05 -0500
+Subject: [PATCH 105/136] hpsa: delete old unused padding garbage
+
+commit a2a431a4fd3b11c6808933ca1bdb2d28a8fa0634 upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa_cmd.h |    8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
+index 1846490..0500740 100644
+--- a/drivers/scsi/hpsa_cmd.h
++++ b/drivers/scsi/hpsa_cmd.h
+@@ -256,14 +256,6 @@ struct ErrorInfo {
+ #define CMD_IOCTL_PEND  0x01
+ #define CMD_SCSI	0x03
+ 
+-/* This structure needs to be divisible by 32 for new
+- * indexing method and performant mode.
+- */
+-#define PAD32 32
+-#define PAD64DIFF 0
+-#define USEEXTRA ((sizeof(void *) - 4)/4)
+-#define PADSIZE (PAD32 + PAD64DIFF * USEEXTRA)
+-
+ #define DIRECT_LOOKUP_SHIFT 5
+ #define DIRECT_LOOKUP_BIT 0x10
+ #define DIRECT_LOOKUP_MASK (~((1 << DIRECT_LOOKUP_SHIFT) - 1))

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0106-hpsa-do-a-better-job-of-detecting-controller-reset-f.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0106-hpsa-do-a-better-job-of-detecting-controller-reset-f.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,154 @@
+From 66c1eae0fb9d6eba75effd5aeb23a7431ef4176f Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:10 -0500
+Subject: [PATCH 106/136] hpsa: do a better job of detecting controller reset
+ failure
+
+commit 580ada3c1e2f23b4b0f3c254cae3eb278f92d494 upstream.
+
+Detect failure of controller reset by noticing if the 32 bytes of
+"driver version" we store on the hardware in the config table
+fail to get zeroed out.  Previously we noticed if the controller
+did not transition to "simple mode", but this did not detect reset
+failure if the controller was already in simple mode prior to
+the reset attempt (e.g. due to module parameter hpsa_simple_mode=1).
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c     |   76 ++++++++++++++++++++++++++++++++++++++++-------
+ drivers/scsi/hpsa_cmd.h |    1 +
+ 2 files changed, 67 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index a5b47a9..dcdf55a 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3156,6 +3156,59 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
+ 	return 0;
+ }
+ 
++static __devinit void init_driver_version(char *driver_version, int len)
++{
++	memset(driver_version, 0, len);
++	strncpy(driver_version, "hpsa " HPSA_DRIVER_VERSION, len - 1);
++}
++
++static __devinit int write_driver_ver_to_cfgtable(
++	struct CfgTable __iomem *cfgtable)
++{
++	char *driver_version;
++	int i, size = sizeof(cfgtable->driver_version);
++
++	driver_version = kmalloc(size, GFP_KERNEL);
++	if (!driver_version)
++		return -ENOMEM;
++
++	init_driver_version(driver_version, size);
++	for (i = 0; i < size; i++)
++		writeb(driver_version[i], &cfgtable->driver_version[i]);
++	kfree(driver_version);
++	return 0;
++}
++
++static __devinit void read_driver_ver_from_cfgtable(
++	struct CfgTable __iomem *cfgtable, unsigned char *driver_ver)
++{
++	int i;
++
++	for (i = 0; i < sizeof(cfgtable->driver_version); i++)
++		driver_ver[i] = readb(&cfgtable->driver_version[i]);
++}
++
++static __devinit int controller_reset_failed(
++	struct CfgTable __iomem *cfgtable)
++{
++
++	char *driver_ver, *old_driver_ver;
++	int rc, size = sizeof(cfgtable->driver_version);
++
++	old_driver_ver = kmalloc(2 * size, GFP_KERNEL);
++	if (!old_driver_ver)
++		return -ENOMEM;
++	driver_ver = old_driver_ver + size;
++
++	/* After a reset, the 32 bytes of "driver version" in the cfgtable
++	 * should have been changed, otherwise we know the reset failed.
++	 */
++	init_driver_version(old_driver_ver, size);
++	read_driver_ver_from_cfgtable(cfgtable, driver_ver);
++	rc = !memcmp(driver_ver, old_driver_ver, size);
++	kfree(old_driver_ver);
++	return rc;
++}
+ /* This does a hard reset of the controller using PCI power management
+  * states or the using the doorbell register.
+  */
+@@ -3166,7 +3219,7 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	u64 cfg_base_addr_index;
+ 	void __iomem *vaddr;
+ 	unsigned long paddr;
+-	u32 misc_fw_support, active_transport;
++	u32 misc_fw_support;
+ 	int rc;
+ 	struct CfgTable __iomem *cfgtable;
+ 	bool use_doorbell;
+@@ -3228,6 +3281,9 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 		rc = -ENOMEM;
+ 		goto unmap_vaddr;
+ 	}
++	rc = write_driver_ver_to_cfgtable(cfgtable);
++	if (rc)
++		goto unmap_vaddr;
+ 
+ 	/* If reset via doorbell register is supported, use that. */
+ 	misc_fw_support = readl(&cfgtable->misc_fw_support);
+@@ -3261,19 +3317,16 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 			"failed waiting for board to become ready\n");
+ 		goto unmap_cfgtable;
+ 	}
+-	dev_info(&pdev->dev, "board ready.\n");
+ 
+-	/* Controller should be in simple mode at this point.  If it's not,
+-	 * It means we're on one of those controllers which doesn't support
+-	 * the doorbell reset method and on which the PCI power management reset
+-	 * method doesn't work (P800, for example.)
+-	 * In those cases, don't try to proceed, as it generally doesn't work.
+-	 */
+-	active_transport = readl(&cfgtable->TransportActive);
+-	if (active_transport & PERFORMANT_MODE) {
++	rc = controller_reset_failed(vaddr);
++	if (rc < 0)
++		goto unmap_cfgtable;
++	if (rc) {
+ 		dev_warn(&pdev->dev, "Unable to successfully reset controller,"
+ 			" Ignoring controller.\n");
+ 		rc = -ENODEV;
++	} else {
++		dev_info(&pdev->dev, "board ready.\n");
+ 	}
+ 
+ unmap_cfgtable:
+@@ -3514,6 +3567,9 @@ static int __devinit hpsa_find_cfgtables(struct ctlr_info *h)
+ 		       cfg_base_addr_index) + cfg_offset, sizeof(*h->cfgtable));
+ 	if (!h->cfgtable)
+ 		return -ENOMEM;
++	rc = write_driver_ver_to_cfgtable(h->cfgtable);
++	if (rc)
++		return rc;
+ 	/* Find performant mode table. */
+ 	trans_offset = readl(&h->cfgtable->TransMethodOffset);
+ 	h->transtable = remap_pci_mem(pci_resource_start(h->pdev,
+diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
+index 0500740..8fd35a7 100644
+--- a/drivers/scsi/hpsa_cmd.h
++++ b/drivers/scsi/hpsa_cmd.h
+@@ -337,6 +337,7 @@ struct CfgTable {
+ 	u8		reserved[0x78 - 0x58];
+ 	u32		misc_fw_support; /* offset 0x78 */
+ #define			MISC_FW_DOORBELL_RESET (0x02)
++	u8		driver_version[32];
+ };
+ 
+ #define NUM_BLOCKFETCH_ENTRIES 8

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0107-hpsa-wait-longer-for-no-op-to-complete-after-resetti.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0107-hpsa-wait-longer-for-no-op-to-complete-after-resetti.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,31 @@
+From cab8825b8a2cb4fd848a4e5bf9d0c952a1801b53 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:15 -0500
+Subject: [PATCH 107/136] hpsa: wait longer for no-op to complete after
+ resetting controller
+
+commit 516fda49e8596904a741693059c8746f11ce579c upstream.
+
+This is to avoid the usual two or three messages about the command
+timing out.  We're obviously not waiting long enough.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 7eec397..7a4ee73 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -130,7 +130,7 @@ struct ctlr_info {
+ #define HPSA_BUS_RESET_MSG 2
+ #define HPSA_HOST_RESET_MSG 3
+ #define HPSA_MSG_SEND_RETRY_LIMIT 10
+-#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS 1000
++#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS (10000)
+ 
+ /* Maximum time in seconds driver will wait for command completions
+  * when polling before giving up.

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0108-hpsa-factor-out-cmd-pool-allocation-functions.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0108-hpsa-factor-out-cmd-pool-allocation-functions.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,112 @@
+From 65214eeec0a7660174f59dbd1e2bcc9173c5c9c7 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:20 -0500
+Subject: [PATCH 108/136] hpsa: factor out cmd pool allocation functions
+
+commit 2e9d1b3626c4383362df30bb853a1b57c2798300 upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   66 ++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 36 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index dcdf55a..385fddd 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3819,6 +3819,40 @@ static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev)
+ 	return 0;
+ }
+ 
++static __devinit int hpsa_allocate_cmd_pool(struct ctlr_info *h)
++{
++	h->cmd_pool_bits = kzalloc(
++		DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG) *
++		sizeof(unsigned long), GFP_KERNEL);
++	h->cmd_pool = pci_alloc_consistent(h->pdev,
++		    h->nr_cmds * sizeof(*h->cmd_pool),
++		    &(h->cmd_pool_dhandle));
++	h->errinfo_pool = pci_alloc_consistent(h->pdev,
++		    h->nr_cmds * sizeof(*h->errinfo_pool),
++		    &(h->errinfo_pool_dhandle));
++	if ((h->cmd_pool_bits == NULL)
++	    || (h->cmd_pool == NULL)
++	    || (h->errinfo_pool == NULL)) {
++		dev_err(&h->pdev->dev, "out of memory in %s", __func__);
++		return -ENOMEM;
++	}
++	return 0;
++}
++
++static void hpsa_free_cmd_pool(struct ctlr_info *h)
++{
++	kfree(h->cmd_pool_bits);
++	if (h->cmd_pool)
++		pci_free_consistent(h->pdev,
++			    h->nr_cmds * sizeof(struct CommandList),
++			    h->cmd_pool, h->cmd_pool_dhandle);
++	if (h->errinfo_pool)
++		pci_free_consistent(h->pdev,
++			    h->nr_cmds * sizeof(struct ErrorInfo),
++			    h->errinfo_pool,
++			    h->errinfo_pool_dhandle);
++}
++
+ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 				    const struct pci_device_id *ent)
+ {
+@@ -3889,33 +3923,14 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 	dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
+ 	       h->devname, pdev->device,
+ 	       h->intr[h->intr_mode], dac ? "" : " not");
+-
+-	h->cmd_pool_bits =
+-	    kmalloc(((h->nr_cmds + BITS_PER_LONG -
+-		      1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL);
+-	h->cmd_pool = pci_alloc_consistent(h->pdev,
+-		    h->nr_cmds * sizeof(*h->cmd_pool),
+-		    &(h->cmd_pool_dhandle));
+-	h->errinfo_pool = pci_alloc_consistent(h->pdev,
+-		    h->nr_cmds * sizeof(*h->errinfo_pool),
+-		    &(h->errinfo_pool_dhandle));
+-	if ((h->cmd_pool_bits == NULL)
+-	    || (h->cmd_pool == NULL)
+-	    || (h->errinfo_pool == NULL)) {
+-		dev_err(&pdev->dev, "out of memory");
+-		rc = -ENOMEM;
++	if (hpsa_allocate_cmd_pool(h))
+ 		goto clean4;
+-	}
+ 	if (hpsa_allocate_sg_chain_blocks(h))
+ 		goto clean4;
+ 	init_waitqueue_head(&h->scan_wait_queue);
+ 	h->scan_finished = 1; /* no scan currently in progress */
+ 
+ 	pci_set_drvdata(pdev, h);
+-	memset(h->cmd_pool_bits, 0,
+-	       ((h->nr_cmds + BITS_PER_LONG -
+-		 1) / BITS_PER_LONG) * sizeof(unsigned long));
+-
+ 	hpsa_scsi_setup(h);
+ 
+ 	/* Turn the interrupts on so we can service requests */
+@@ -3929,16 +3944,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 
+ clean4:
+ 	hpsa_free_sg_chain_blocks(h);
+-	kfree(h->cmd_pool_bits);
+-	if (h->cmd_pool)
+-		pci_free_consistent(h->pdev,
+-			    h->nr_cmds * sizeof(struct CommandList),
+-			    h->cmd_pool, h->cmd_pool_dhandle);
+-	if (h->errinfo_pool)
+-		pci_free_consistent(h->pdev,
+-			    h->nr_cmds * sizeof(struct ErrorInfo),
+-			    h->errinfo_pool,
+-			    h->errinfo_pool_dhandle);
++	hpsa_free_cmd_pool(h);
+ 	free_irq(h->intr[h->intr_mode], h);
+ clean2:
+ clean1:

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0109-hpsa-factor-out-irq-request-code.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0109-hpsa-factor-out-irq-request-code.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,65 @@
+From cbe6b1e444cd01e6e30fe84af46c0d06718899e9 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:25 -0500
+Subject: [PATCH 109/136] hpsa: factor out irq request code
+
+commit 0ae01a32cb4a89ef0ed49bb6f49bd5830b13ab3e upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   32 +++++++++++++++++++++-----------
+ 1 file changed, 21 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 385fddd..af883b6 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3853,6 +3853,26 @@ static void hpsa_free_cmd_pool(struct ctlr_info *h)
+ 			    h->errinfo_pool_dhandle);
+ }
+ 
++static int hpsa_request_irq(struct ctlr_info *h,
++	irqreturn_t (*msixhandler)(int, void *),
++	irqreturn_t (*intxhandler)(int, void *))
++{
++	int rc;
++
++	if (h->msix_vector || h->msi_vector)
++		rc = request_irq(h->intr[h->intr_mode], msixhandler,
++				IRQF_DISABLED, h->devname, h);
++	else
++		rc = request_irq(h->intr[h->intr_mode], intxhandler,
++				IRQF_DISABLED, h->devname, h);
++	if (rc) {
++		dev_err(&h->pdev->dev, "unable to get irq %d for %s\n",
++		       h->intr[h->intr_mode], h->devname);
++		return -ENODEV;
++	}
++	return 0;
++}
++
+ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 				    const struct pci_device_id *ent)
+ {
+@@ -3908,18 +3928,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 	/* make sure the board interrupts are off */
+ 	h->access.set_intr_mask(h, HPSA_INTR_OFF);
+ 
+-	if (h->msix_vector || h->msi_vector)
+-		rc = request_irq(h->intr[h->intr_mode], do_hpsa_intr_msi,
+-				IRQF_DISABLED, h->devname, h);
+-	else
+-		rc = request_irq(h->intr[h->intr_mode], do_hpsa_intr_intx,
+-				IRQF_DISABLED, h->devname, h);
+-	if (rc) {
+-		dev_err(&pdev->dev, "unable to get irq %d for %s\n",
+-		       h->intr[h->intr_mode], h->devname);
++	if (hpsa_request_irq(h, do_hpsa_intr_msi, do_hpsa_intr_intx))
+ 		goto clean2;
+-	}
+-
+ 	dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
+ 	       h->devname, pdev->device,
+ 	       h->intr[h->intr_mode], dac ? "" : " not");

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0110-hpsa-increase-time-to-wait-for-board-reset.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0110-hpsa-increase-time-to-wait-for-board-reset.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,27 @@
+From cf37da8207b8daf6830e81d803e9c04e7fae0e5d Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:31 -0500
+Subject: [PATCH 110/136] hpsa: increase time to wait for board reset
+
+commit 2ed7127bceb10a6a7d5a38c30ab65176d4e4bc0f upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 7a4ee73..b1412a7 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -155,7 +155,7 @@ struct ctlr_info {
+  * HPSA_BOARD_READY_ITERATIONS are derived from those.
+  */
+ #define HPSA_BOARD_READY_WAIT_SECS (120)
+-#define HPSA_BOARD_NOT_READY_WAIT_SECS (10)
++#define HPSA_BOARD_NOT_READY_WAIT_SECS (100)
+ #define HPSA_BOARD_READY_POLL_INTERVAL_MSECS (100)
+ #define HPSA_BOARD_READY_POLL_INTERVAL \
+ 	((HPSA_BOARD_READY_POLL_INTERVAL_MSECS * HZ) / 1000)

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0111-hpsa-clarify-messages-around-reset-behavior.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0111-hpsa-clarify-messages-around-reset-behavior.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,47 @@
+From 943f2a951a285ef8affdab4fb237e1b6bbc6ceca Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:36 -0500
+Subject: [PATCH 111/136] hpsa: clarify messages around reset behavior
+
+commit 2b870cb30000477e425666f9c6d83cca8fddc7c0 upstream.
+
+When waiting for the board to become "not ready"
+don't print a message saying "waiting for board to
+become ready" (possibly followed by a message saying
+"failed waiting for board to become not ready".  Instead,
+it should be "waiting for board to reset" and "failed
+waiting for board to reset."
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index af883b6..c9e26a5 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3306,11 +3306,11 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	msleep(HPSA_POST_RESET_PAUSE_MSECS);
+ 
+ 	/* Wait for board to become not ready, then ready. */
+-	dev_info(&pdev->dev, "Waiting for board to become ready.\n");
++	dev_info(&pdev->dev, "Waiting for board to reset.\n");
+ 	rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY);
+ 	if (rc)
+ 		dev_warn(&pdev->dev,
+-			"failed waiting for board to become not ready\n");
++			"failed waiting for board to reset\n");
+ 	rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_READY);
+ 	if (rc) {
+ 		dev_warn(&pdev->dev,
+@@ -3809,6 +3809,7 @@ static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev)
+ 		return -ENODEV;
+ 
+ 	/* Now try to get the controller to respond to a no-op */
++	dev_warn(&pdev->dev, "Waiting for controller to respond to no-op\n");
+ 	for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) {
+ 		if (hpsa_noop(pdev) == 0)
+ 			break;

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0112-hpsa-remove-atrophied-hpsa_scsi_setup-function.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0112-hpsa-remove-atrophied-hpsa_scsi_setup-function.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,46 @@
+From 014dd58b2c620e56b168ec767427bd6a83a15886 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:41 -0500
+Subject: [PATCH 112/136] hpsa: remove atrophied hpsa_scsi_setup function
+
+commit 9a41338e5b474add499a7ca2a5a76148e5076805 upstream.
+
+hpsa_scsi_setup at one time contained enough code to justify
+its existence, but that time has passed.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index c9e26a5..dd30bfd 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -920,13 +920,6 @@ static void hpsa_slave_destroy(struct scsi_device *sdev)
+ 	/* nothing to do. */
+ }
+ 
+-static void hpsa_scsi_setup(struct ctlr_info *h)
+-{
+-	h->ndevices = 0;
+-	h->scsi_host = NULL;
+-	spin_lock_init(&h->devlock);
+-}
+-
+ static void hpsa_free_sg_chain_blocks(struct ctlr_info *h)
+ {
+ 	int i;
+@@ -3942,7 +3935,9 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 	h->scan_finished = 1; /* no scan currently in progress */
+ 
+ 	pci_set_drvdata(pdev, h);
+-	hpsa_scsi_setup(h);
++	h->ndevices = 0;
++	h->scsi_host = NULL;
++	spin_lock_init(&h->devlock);
+ 
+ 	/* Turn the interrupts on so we can service requests */
+ 	h->access.set_intr_mask(h, HPSA_INTR_ON);

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0113-hpsa-use-new-doorbell-bit-5-reset-method.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0113-hpsa-use-new-doorbell-bit-5-reset-method.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,99 @@
+From 10d448eedfaf5e81e3298e2804449932f1dabb8f Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:46 -0500
+Subject: [PATCH 113/136] hpsa: use new doorbell-bit-5 reset method
+
+commit cf0b08d0cd87ada9d284925834d08fb8026da888 upstream.
+
+The bit-2-doorbell reset method seemed to cause (survivable) NMIs
+on some systems and (unsurvivable) IOCK NMIs on some G7 servers.
+Firmware guys implemented a new doorbell method to alleviate these
+problems triggered by bit 5 of the doorbell register.  We want to
+use it if it's available.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c     |   25 ++++++++++++++++++++-----
+ drivers/scsi/hpsa_cmd.h |    2 ++
+ 2 files changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index dd30bfd..eece647 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3100,7 +3100,7 @@ static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
+ #define hpsa_noop(p) hpsa_message(p, 3, 0)
+ 
+ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
+-	void * __iomem vaddr, bool use_doorbell)
++	void * __iomem vaddr, u32 use_doorbell)
+ {
+ 	u16 pmcsr;
+ 	int pos;
+@@ -3111,7 +3111,7 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
+ 		 * other way using the doorbell register.
+ 		 */
+ 		dev_info(&pdev->dev, "using doorbell to reset controller\n");
+-		writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL);
++		writel(use_doorbell, vaddr + SA5_DOORBELL);
+ 		msleep(1000);
+ 	} else { /* Try to do it the PCI power state way */
+ 
+@@ -3215,7 +3215,7 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	u32 misc_fw_support;
+ 	int rc;
+ 	struct CfgTable __iomem *cfgtable;
+-	bool use_doorbell;
++	u32 use_doorbell;
+ 	u32 board_id;
+ 	u16 command_register;
+ 
+@@ -3278,9 +3278,24 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	if (rc)
+ 		goto unmap_vaddr;
+ 
+-	/* If reset via doorbell register is supported, use that. */
++	/* If reset via doorbell register is supported, use that.
++	 * There are two such methods.  Favor the newest method.
++	 */
+ 	misc_fw_support = readl(&cfgtable->misc_fw_support);
+-	use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
++	use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET2;
++	if (use_doorbell) {
++		use_doorbell = DOORBELL_CTLR_RESET2;
++	} else {
++		use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
++		if (use_doorbell) {
++			dev_warn(&pdev->dev, "Controller claims that "
++				"'Bit 2 doorbell reset' is "
++				"supported, but not 'bit 5 doorbell reset'.  "
++				"Firmware update is recommended.\n");
++			rc = -ENODEV;
++			goto unmap_cfgtable;
++		}
++	}
+ 
+ 	rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell);
+ 	if (rc)
+diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
+index 8fd35a7..55d741b 100644
+--- a/drivers/scsi/hpsa_cmd.h
++++ b/drivers/scsi/hpsa_cmd.h
+@@ -101,6 +101,7 @@
+ #define CFGTBL_ChangeReq        0x00000001l
+ #define CFGTBL_AccCmds          0x00000001l
+ #define DOORBELL_CTLR_RESET	0x00000004l
++#define DOORBELL_CTLR_RESET2	0x00000020l
+ 
+ #define CFGTBL_Trans_Simple     0x00000002l
+ #define CFGTBL_Trans_Performant 0x00000004l
+@@ -337,6 +338,7 @@ struct CfgTable {
+ 	u8		reserved[0x78 - 0x58];
+ 	u32		misc_fw_support; /* offset 0x78 */
+ #define			MISC_FW_DOORBELL_RESET (0x02)
++#define			MISC_FW_DOORBELL_RESET2 (0x010)
+ 	u8		driver_version[32];
+ };
+ 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0114-hpsa-do-soft-reset-if-hard-reset-is-broken.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0114-hpsa-do-soft-reset-if-hard-reset-is-broken.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,361 @@
+From 679d87a9511524282791dd411777a13a14ee5581 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:51 -0500
+Subject: [PATCH 114/136] hpsa: do soft reset if hard reset is broken
+
+commit 64670ac8702ec37a00ad6e479f3cacbde0fd4efa upstream.
+
+on driver load, if reset_devices is set, and the hard reset
+attempts fail, try to bring up the controller to the point that
+a command can be sent, and send it a soft reset command, then
+after the reset undo whatever driver initialization was done to get
+it to the point to take a command, and re-do it after the reset.
+
+This is to get kdump to work on all the "non-resettable" controllers
+(except 64xx controllers which can't be reset due to the potentially
+shared cache module.)
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |  226 +++++++++++++++++++++++++++++++++++++++++++++++----
+ drivers/scsi/hpsa.h |    6 +-
+ 2 files changed, 216 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index eece647..71389ed 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -2715,6 +2715,26 @@ static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg)
+ 	}
+ }
+ 
++static int __devinit hpsa_send_host_reset(struct ctlr_info *h,
++	unsigned char *scsi3addr, u8 reset_type)
++{
++	struct CommandList *c;
++
++	c = cmd_alloc(h);
++	if (!c)
++		return -ENOMEM;
++	fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0,
++		RAID_CTLR_LUNID, TYPE_MSG);
++	c->Request.CDB[1] = reset_type; /* fill_cmd defaults to target reset */
++	c->waiting = NULL;
++	enqueue_cmd_and_start_io(h, c);
++	/* Don't wait for completion, the reset won't complete.  Don't free
++	 * the command either.  This is the last command we will send before
++	 * re-initializing everything, so it doesn't matter and won't leak.
++	 */
++	return 0;
++}
++
+ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
+ 	void *buff, size_t size, u8 page_code, unsigned char *scsi3addr,
+ 	int cmd_type)
+@@ -2792,7 +2812,8 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
+ 			c->Request.Type.Attribute = ATTR_SIMPLE;
+ 			c->Request.Type.Direction = XFER_NONE;
+ 			c->Request.Timeout = 0; /* Don't time out */
+-			c->Request.CDB[0] =  0x01; /* RESET_MSG is 0x01 */
++			memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
++			c->Request.CDB[0] =  cmd;
+ 			c->Request.CDB[1] = 0x03;  /* Reset target above */
+ 			/* If bytes 4-7 are zero, it means reset the */
+ 			/* LunID device */
+@@ -2958,6 +2979,63 @@ static inline u32 process_nonindexed_cmd(struct ctlr_info *h,
+ 	return next_command(h);
+ }
+ 
++/* Some controllers, like p400, will give us one interrupt
++ * after a soft reset, even if we turned interrupts off.
++ * Only need to check for this in the hpsa_xxx_discard_completions
++ * functions.
++ */
++static int ignore_bogus_interrupt(struct ctlr_info *h)
++{
++	if (likely(!reset_devices))
++		return 0;
++
++	if (likely(h->interrupts_enabled))
++		return 0;
++
++	dev_info(&h->pdev->dev, "Received interrupt while interrupts disabled "
++		"(known firmware bug.)  Ignoring.\n");
++
++	return 1;
++}
++
++static irqreturn_t hpsa_intx_discard_completions(int irq, void *dev_id)
++{
++	struct ctlr_info *h = dev_id;
++	unsigned long flags;
++	u32 raw_tag;
++
++	if (ignore_bogus_interrupt(h))
++		return IRQ_NONE;
++
++	if (interrupt_not_for_us(h))
++		return IRQ_NONE;
++	spin_lock_irqsave(&h->lock, flags);
++	while (interrupt_pending(h)) {
++		raw_tag = get_next_completion(h);
++		while (raw_tag != FIFO_EMPTY)
++			raw_tag = next_command(h);
++	}
++	spin_unlock_irqrestore(&h->lock, flags);
++	return IRQ_HANDLED;
++}
++
++static irqreturn_t hpsa_msix_discard_completions(int irq, void *dev_id)
++{
++	struct ctlr_info *h = dev_id;
++	unsigned long flags;
++	u32 raw_tag;
++
++	if (ignore_bogus_interrupt(h))
++		return IRQ_NONE;
++
++	spin_lock_irqsave(&h->lock, flags);
++	raw_tag = get_next_completion(h);
++	while (raw_tag != FIFO_EMPTY)
++		raw_tag = next_command(h);
++	spin_unlock_irqrestore(&h->lock, flags);
++	return IRQ_HANDLED;
++}
++
+ static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id)
+ {
+ 	struct ctlr_info *h = dev_id;
+@@ -3096,7 +3174,6 @@ static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
+ 	return 0;
+ }
+ 
+-#define hpsa_soft_reset_controller(p) hpsa_message(p, 1, 0)
+ #define hpsa_noop(p) hpsa_message(p, 3, 0)
+ 
+ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
+@@ -3292,7 +3369,7 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 				"'Bit 2 doorbell reset' is "
+ 				"supported, but not 'bit 5 doorbell reset'.  "
+ 				"Firmware update is recommended.\n");
+-			rc = -ENODEV;
++			rc = -ENOTSUPP; /* try soft reset */
+ 			goto unmap_cfgtable;
+ 		}
+ 	}
+@@ -3316,13 +3393,18 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	/* Wait for board to become not ready, then ready. */
+ 	dev_info(&pdev->dev, "Waiting for board to reset.\n");
+ 	rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY);
+-	if (rc)
++	if (rc) {
+ 		dev_warn(&pdev->dev,
+-			"failed waiting for board to reset\n");
++			"failed waiting for board to reset."
++			" Will try soft reset.\n");
++		rc = -ENOTSUPP; /* Not expected, but try soft reset later */
++		goto unmap_cfgtable;
++	}
+ 	rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_READY);
+ 	if (rc) {
+ 		dev_warn(&pdev->dev,
+-			"failed waiting for board to become ready\n");
++			"failed waiting for board to become ready "
++			"after hard reset\n");
+ 		goto unmap_cfgtable;
+ 	}
+ 
+@@ -3330,11 +3412,11 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	if (rc < 0)
+ 		goto unmap_cfgtable;
+ 	if (rc) {
+-		dev_warn(&pdev->dev, "Unable to successfully reset controller,"
+-			" Ignoring controller.\n");
+-		rc = -ENODEV;
++		dev_warn(&pdev->dev, "Unable to successfully reset "
++			"controller. Will try soft reset.\n");
++		rc = -ENOTSUPP;
+ 	} else {
+-		dev_info(&pdev->dev, "board ready.\n");
++		dev_info(&pdev->dev, "board ready after hard reset.\n");
+ 	}
+ 
+ unmap_cfgtable:
+@@ -3812,7 +3894,7 @@ static __devinit int hpsa_init_reset_devices(struct pci_dev *pdev)
+ 	 * due to concerns about shared bbwc between 6402/6404 pair.
+ 	 */
+ 	if (rc == -ENOTSUPP)
+-		return 0; /* just try to do the kdump anyhow. */
++		return rc; /* just try to do the kdump anyhow. */
+ 	if (rc)
+ 		return -ENODEV;
+ 
+@@ -3882,18 +3964,79 @@ static int hpsa_request_irq(struct ctlr_info *h,
+ 	return 0;
+ }
+ 
++static int __devinit hpsa_kdump_soft_reset(struct ctlr_info *h)
++{
++	if (hpsa_send_host_reset(h, RAID_CTLR_LUNID,
++		HPSA_RESET_TYPE_CONTROLLER)) {
++		dev_warn(&h->pdev->dev, "Resetting array controller failed.\n");
++		return -EIO;
++	}
++
++	dev_info(&h->pdev->dev, "Waiting for board to soft reset.\n");
++	if (hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_NOT_READY)) {
++		dev_warn(&h->pdev->dev, "Soft reset had no effect.\n");
++		return -1;
++	}
++
++	dev_info(&h->pdev->dev, "Board reset, awaiting READY status.\n");
++	if (hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY)) {
++		dev_warn(&h->pdev->dev, "Board failed to become ready "
++			"after soft reset.\n");
++		return -1;
++	}
++
++	return 0;
++}
++
++static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
++{
++	free_irq(h->intr[h->intr_mode], h);
++#ifdef CONFIG_PCI_MSI
++	if (h->msix_vector)
++		pci_disable_msix(h->pdev);
++	else if (h->msi_vector)
++		pci_disable_msi(h->pdev);
++#endif /* CONFIG_PCI_MSI */
++	hpsa_free_sg_chain_blocks(h);
++	hpsa_free_cmd_pool(h);
++	kfree(h->blockFetchTable);
++	pci_free_consistent(h->pdev, h->reply_pool_size,
++		h->reply_pool, h->reply_pool_dhandle);
++	if (h->vaddr)
++		iounmap(h->vaddr);
++	if (h->transtable)
++		iounmap(h->transtable);
++	if (h->cfgtable)
++		iounmap(h->cfgtable);
++	pci_release_regions(h->pdev);
++	kfree(h);
++}
++
+ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 				    const struct pci_device_id *ent)
+ {
+ 	int dac, rc;
+ 	struct ctlr_info *h;
++	int try_soft_reset = 0;
++	unsigned long flags;
+ 
+ 	if (number_of_controllers == 0)
+ 		printk(KERN_INFO DRIVER_NAME "\n");
+ 
+ 	rc = hpsa_init_reset_devices(pdev);
+-	if (rc)
+-		return rc;
++	if (rc) {
++		if (rc != -ENOTSUPP)
++			return rc;
++		/* If the reset fails in a particular way (it has no way to do
++		 * a proper hard reset, so returns -ENOTSUPP) we can try to do
++		 * a soft reset once we get the controller configured up to the
++		 * point that it can accept a command.
++		 */
++		try_soft_reset = 1;
++		rc = 0;
++	}
++
++reinit_after_soft_reset:
+ 
+ 	/* Command structures must be aligned on a 32-byte boundary because
+ 	 * the 5 lower bits of the address are used by the hardware. and by
+@@ -3953,11 +4096,66 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 	h->ndevices = 0;
+ 	h->scsi_host = NULL;
+ 	spin_lock_init(&h->devlock);
++	hpsa_put_ctlr_into_performant_mode(h);
++
++	/* At this point, the controller is ready to take commands.
++	 * Now, if reset_devices and the hard reset didn't work, try
++	 * the soft reset and see if that works.
++	 */
++	if (try_soft_reset) {
++
++		/* This is kind of gross.  We may or may not get a completion
++		 * from the soft reset command, and if we do, then the value
++		 * from the fifo may or may not be valid.  So, we wait 10 secs
++		 * after the reset throwing away any completions we get during
++		 * that time.  Unregister the interrupt handler and register
++		 * fake ones to scoop up any residual completions.
++		 */
++		spin_lock_irqsave(&h->lock, flags);
++		h->access.set_intr_mask(h, HPSA_INTR_OFF);
++		spin_unlock_irqrestore(&h->lock, flags);
++		free_irq(h->intr[h->intr_mode], h);
++		rc = hpsa_request_irq(h, hpsa_msix_discard_completions,
++					hpsa_intx_discard_completions);
++		if (rc) {
++			dev_warn(&h->pdev->dev, "Failed to request_irq after "
++				"soft reset.\n");
++			goto clean4;
++		}
++
++		rc = hpsa_kdump_soft_reset(h);
++		if (rc)
++			/* Neither hard nor soft reset worked, we're hosed. */
++			goto clean4;
++
++		dev_info(&h->pdev->dev, "Board READY.\n");
++		dev_info(&h->pdev->dev,
++			"Waiting for stale completions to drain.\n");
++		h->access.set_intr_mask(h, HPSA_INTR_ON);
++		msleep(10000);
++		h->access.set_intr_mask(h, HPSA_INTR_OFF);
++
++		rc = controller_reset_failed(h->cfgtable);
++		if (rc)
++			dev_info(&h->pdev->dev,
++				"Soft reset appears to have failed.\n");
++
++		/* since the controller's reset, we have to go back and re-init
++		 * everything.  Easiest to just forget what we've done and do it
++		 * all over again.
++		 */
++		hpsa_undo_allocations_after_kdump_soft_reset(h);
++		try_soft_reset = 0;
++		if (rc)
++			/* don't go to clean4, we already unallocated */
++			return -ENODEV;
++
++		goto reinit_after_soft_reset;
++	}
+ 
+ 	/* Turn the interrupts on so we can service requests */
+ 	h->access.set_intr_mask(h, HPSA_INTR_ON);
+ 
+-	hpsa_put_ctlr_into_performant_mode(h);
+ 	hpsa_hba_inquiry(h);
+ 	hpsa_register_scsi(h);	/* hook ourselves into SCSI subsystem */
+ 	h->busy_initializing = 0;
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index b1412a7..6d8dcd4 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -127,8 +127,10 @@ struct ctlr_info {
+ };
+ #define HPSA_ABORT_MSG 0
+ #define HPSA_DEVICE_RESET_MSG 1
+-#define HPSA_BUS_RESET_MSG 2
+-#define HPSA_HOST_RESET_MSG 3
++#define HPSA_RESET_TYPE_CONTROLLER 0x00
++#define HPSA_RESET_TYPE_BUS 0x01
++#define HPSA_RESET_TYPE_TARGET 0x03
++#define HPSA_RESET_TYPE_LUN 0x04
+ #define HPSA_MSG_SEND_RETRY_LIMIT 10
+ #define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS (10000)
+ 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0115-hpsa-remove-superfluous-sleeps-around-reset-code.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0115-hpsa-remove-superfluous-sleeps-around-reset-code.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,35 @@
+From 74ea21428ef9fbf84f6c4ee2cf3f8eb576cb31a6 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 14:59:56 -0500
+Subject: [PATCH 115/136] hpsa: remove superfluous sleeps around reset code
+
+commit dfc2224828c5fc4ec7e11587b9d6b97283aa2d01 upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 71389ed..518dd07 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3189,7 +3189,6 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
+ 		 */
+ 		dev_info(&pdev->dev, "using doorbell to reset controller\n");
+ 		writel(use_doorbell, vaddr + SA5_DOORBELL);
+-		msleep(1000);
+ 	} else { /* Try to do it the PCI power state way */
+ 
+ 		/* Quoting from the Open CISS Specification: "The Power
+@@ -3220,8 +3219,6 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
+ 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+ 		pmcsr |= PCI_D0;
+ 		pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
+-
+-		msleep(500);
+ 	}
+ 	return 0;
+ }

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0116-hpsa-do-not-attempt-PCI-power-management-reset-metho.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0116-hpsa-do-not-attempt-PCI-power-management-reset-metho.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,113 @@
+From 048a06e370eb474566f59cafea6af8df80456673 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 15:00:01 -0500
+Subject: [PATCH 116/136] hpsa: do not attempt PCI power management reset
+ method if we know it won't work.
+
+commit 4638078697574be43816779845e26bf05ae70d9d upstream.
+
+Just go straight to the soft-reset method instead.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |   52 +++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 38 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 518dd07..70a35a0 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -265,7 +265,7 @@ static ssize_t host_show_transport_mode(struct device *dev,
+ 			"performant" : "simple");
+ }
+ 
+-/* List of controllers which cannot be reset on kexec with reset_devices */
++/* List of controllers which cannot be hard reset on kexec with reset_devices */
+ static u32 unresettable_controller[] = {
+ 	0x324a103C, /* Smart Array P712m */
+ 	0x324b103C, /* SmartArray P711m */
+@@ -283,16 +283,45 @@ static u32 unresettable_controller[] = {
+ 	0x409D0E11, /* Smart Array 6400 EM */
+ };
+ 
+-static int ctlr_is_resettable(struct ctlr_info *h)
++/* List of controllers which cannot even be soft reset */
++static u32 soft_unresettable_controller[] = {
++	/* Exclude 640x boards.  These are two pci devices in one slot
++	 * which share a battery backed cache module.  One controls the
++	 * cache, the other accesses the cache through the one that controls
++	 * it.  If we reset the one controlling the cache, the other will
++	 * likely not be happy.  Just forbid resetting this conjoined mess.
++	 * The 640x isn't really supported by hpsa anyway.
++	 */
++	0x409C0E11, /* Smart Array 6400 */
++	0x409D0E11, /* Smart Array 6400 EM */
++};
++
++static int ctlr_is_hard_resettable(u32 board_id)
+ {
+ 	int i;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++)
+-		if (unresettable_controller[i] == h->board_id)
++		if (unresettable_controller[i] == board_id)
++			return 0;
++	return 1;
++}
++
++static int ctlr_is_soft_resettable(u32 board_id)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(soft_unresettable_controller); i++)
++		if (soft_unresettable_controller[i] == board_id)
+ 			return 0;
+ 	return 1;
+ }
+ 
++static int ctlr_is_resettable(u32 board_id)
++{
++	return ctlr_is_hard_resettable(board_id) ||
++		ctlr_is_soft_resettable(board_id);
++}
++
+ static ssize_t host_show_resettable(struct device *dev,
+ 	struct device_attribute *attr, char *buf)
+ {
+@@ -300,7 +329,7 @@ static ssize_t host_show_resettable(struct device *dev,
+ 	struct Scsi_Host *shost = class_to_shost(dev);
+ 
+ 	h = shost_to_hba(shost);
+-	return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h));
++	return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h->board_id));
+ }
+ 
+ static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[])
+@@ -3306,20 +3335,15 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	 * using the doorbell register.
+ 	 */
+ 
+-	/* Exclude 640x boards.  These are two pci devices in one slot
+-	 * which share a battery backed cache module.  One controls the
+-	 * cache, the other accesses the cache through the one that controls
+-	 * it.  If we reset the one controlling the cache, the other will
+-	 * likely not be happy.  Just forbid resetting this conjoined mess.
+-	 * The 640x isn't really supported by hpsa anyway.
+-	 */
+ 	rc = hpsa_lookup_board_id(pdev, &board_id);
+-	if (rc < 0) {
++	if (rc < 0 || !ctlr_is_resettable(board_id)) {
+ 		dev_warn(&pdev->dev, "Not resetting device.\n");
+ 		return -ENODEV;
+ 	}
+-	if (board_id == 0x409C0E11 || board_id == 0x409D0E11)
+-		return -ENOTSUPP;
++
++	/* if controller is soft- but not hard resettable... */
++	if (!ctlr_is_hard_resettable(board_id))
++		return -ENOTSUPP; /* try soft reset later. */
+ 
+ 	/* Save the PCI command register */
+ 	pci_read_config_word(pdev, 4, &command_register);

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0117-hpsa-add-P2000-to-list-of-shared-SAS-devices.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0117-hpsa-add-P2000-to-list-of-shared-SAS-devices.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,26 @@
+From 6d7872997a66af084ac19cf49878564bba217e23 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 3 May 2011 15:00:07 -0500
+Subject: [PATCH 117/136] hpsa: add P2000 to list of shared SAS devices
+
+commit fda38518f236cbd965110938e324f6c6fcc91f38 upstream.
+
+Signed-off-by: Scott Teel <scott.stacy.teel at hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 70a35a0..d5bd28a 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1582,6 +1582,7 @@ static unsigned char *msa2xxx_model[] = {
+ 	"MSA2024",
+ 	"MSA2312",
+ 	"MSA2324",
++	"P2000 G3 SAS",
+ 	NULL,
+ };
+ 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0118-hpsa-Change-memset-using-sizeof-ptr-to-sizeof-ptr.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0118-hpsa-Change-memset-using-sizeof-ptr-to-sizeof-ptr.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,42 @@
+From e6a95e129df6f74d862606175853f9dafb57f603 Mon Sep 17 00:00:00 2001
+From: Joe Perches <joe at perches.com>
+Date: Sun, 8 May 2011 23:32:40 -0700
+Subject: [PATCH 118/136] hpsa: Change memset using sizeof(ptr) to
+ sizeof(*ptr)
+
+commit 7630abd0c690e90cea9412846f596fe1565aaa0e upstream.
+
+Not at all sure this is correct or appropriate to change,
+but this seems odd.
+
+Found via coccinelle script
+
+@@
+type T;
+T* ptr;
+expression E1;
+@@
+
+* memset(E1, 0, sizeof(ptr));
+
+Signed-off-by: Joe Perches <joe at perches.com>
+Acked-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <jbottomley at parallels.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/hpsa.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index d5bd28a..7592975 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1320,7 +1320,7 @@ static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h,
+ 	int retry_count = 0;
+ 
+ 	do {
+-		memset(c->err_info, 0, sizeof(c->err_info));
++		memset(c->err_info, 0, sizeof(*c->err_info));
+ 		hpsa_scsi_do_simple_cmd_core(h, c);
+ 		retry_count++;
+ 	} while (check_for_unit_attention(h, c) && retry_count <= 3);

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0119-hpsa-fix-dma-unmap-error-in-hpsa_passthru_ioctl.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0119-hpsa-fix-dma-unmap-error-in-hpsa_passthru_ioctl.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,27 @@
+From 5ac805964e5192d41f39fa7695a19a34a9633991 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Fri, 3 Jun 2011 09:57:29 -0500
+Subject: [PATCH 119/136] hpsa: fix dma unmap error in hpsa_passthru_ioctl
+
+commit c2dd32e02648d77466f320d6edd157b5080e7c99 upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 7592975..ffb555c3 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -2552,7 +2552,8 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+ 		c->SG[0].Ext = 0; /* we are not chaining*/
+ 	}
+ 	hpsa_scsi_do_simple_cmd_core(h, c);
+-	hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL);
++	if (iocommand.buf_size > 0)
++		hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL);
+ 	check_ioctl_unit_attention(h, c);
+ 
+ 	/* Copy the error information out */

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0120-hpsa-fix-potential-overrun-while-memcpy-ing-sense-da.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0120-hpsa-fix-potential-overrun-while-memcpy-ing-sense-da.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,62 @@
+From 1cf4a81224ce81d9da2d745ed755f1ad5e5cda27 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Fri, 3 Jun 2011 09:57:34 -0500
+Subject: [PATCH 120/136] hpsa: fix potential overrun while memcpy'ing sense
+ data
+
+commit db111e18ec19bbadbf44a60f73bf2ff5991dc915 upstream.
+
+This memcpy:
+
+   memcpy(cmd->sense_buffer, ei->SenseInfo,
+	   ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
+		   SCSI_SENSE_BUFFERSIZE :
+		   ei->SenseLen);
+
+The ei->SenseLen field is filled in by the Smart Array.  For requests to
+logical drives, it will not exceed 32 bytes, so should be ok, but for physical
+requests it depends on the target device, not the Smart Array.  It's conceivable
+that this could exceed the 32 byte size of ei->SenseInfo.  In that case, the memcpy
+would read past the end of ei->SenseInfo, copying data from the next command,
+as if it were sense data, or, if it happened to be the very last command in the
+block of allocated commands, could fall off the end of the allocated area and
+crash.  I'm not aware of anyone ever encountering this behavior, but it could
+conceivably happen.  This bug was found by Coverity.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index ffb555c3..2eff302 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1028,6 +1028,7 @@ static void complete_scsi_command(struct CommandList *cp)
+ 	unsigned char sense_key;
+ 	unsigned char asc;      /* additional sense code */
+ 	unsigned char ascq;     /* additional sense code qualifier */
++	unsigned long sense_data_size;
+ 
+ 	ei = cp->err_info;
+ 	cmd = (struct scsi_cmnd *) cp->scsi_cmd;
+@@ -1042,10 +1043,14 @@ static void complete_scsi_command(struct CommandList *cp)
+ 	cmd->result |= ei->ScsiStatus;
+ 
+ 	/* copy the sense data whether we need to or not. */
+-	memcpy(cmd->sense_buffer, ei->SenseInfo,
+-		ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
+-			SCSI_SENSE_BUFFERSIZE :
+-			ei->SenseLen);
++	if (SCSI_SENSE_BUFFERSIZE < sizeof(ei->SenseInfo))
++		sense_data_size = SCSI_SENSE_BUFFERSIZE;
++	else
++		sense_data_size = sizeof(ei->SenseInfo);
++	if (ei->SenseLen < sense_data_size)
++		sense_data_size = ei->SenseLen;
++
++	memcpy(cmd->sense_buffer, ei->SenseInfo, sense_data_size);
+ 	scsi_set_resid(cmd, ei->ResidualCnt);
+ 
+ 	if (ei->CommandStatus == 0) {

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0121-hpsa-do-not-attempt-to-read-from-a-write-only-regist.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0121-hpsa-do-not-attempt-to-read-from-a-write-only-regist.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,31 @@
+From ce9532c00d55dec1fb71bca497e6bb0fccabc31e Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Thu, 21 Jul 2011 13:16:05 -0500
+Subject: [PATCH 121/136] hpsa: do not attempt to read from a write-only
+ register
+
+commit fec62c368b9c8b05d5124ca6c3b8336b537f26f3 upstream.
+
+Most smartarrays tolerate it, but a few new ones don't.
+Without this change some newer Smart Arrays will lock up
+and i/o will grind to a halt.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 6d8dcd4..7f53ceaa 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -214,7 +214,7 @@ static void SA5_submit_command(struct ctlr_info *h,
+ 	dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr,
+ 		c->Header.Tag.lower);
+ 	writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
+-	(void) readl(h->vaddr + SA5_REQUEST_PORT_OFFSET);
++	(void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
+ 	h->commands_outstanding++;
+ 	if (h->commands_outstanding > h->max_outstanding)
+ 		h->max_outstanding = h->commands_outstanding;

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0122-hpsa-retry-commands-completing-with-status-of-UNSOLI.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0122-hpsa-retry-commands-completing-with-status-of-UNSOLI.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,35 @@
+From 401be4064af671b528803b7867ffeeb078130780 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 26 Jul 2011 11:08:52 -0500
+Subject: [PATCH 122/136] hpsa: retry commands completing with status of
+ UNSOLICITED_ABORT
+
+commit f6e76055ba778c56716ba79e106db28297775e87 upstream.
+
+In a shared SAS setup, target devices may be reset by one of
+several hosts, and outstanding commands on that device will be
+completed to corresponding hosts with status of UNSOLICITED_ABORT.
+Such commands should be retried instead of being treated as i/o
+errors.  Also fixed a nearby spelling error.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 2eff302..8b3a238 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1210,8 +1210,8 @@ static void complete_scsi_command(struct CommandList *cp)
+ 		dev_warn(&h->pdev->dev, "cp %p reports abort failed\n", cp);
+ 		break;
+ 	case CMD_UNSOLICITED_ABORT:
+-		cmd->result = DID_RESET << 16;
+-		dev_warn(&h->pdev->dev, "cp %p aborted do to an unsolicited "
++		cmd->result = DID_SOFT_ERROR << 16; /* retry the command */
++		dev_warn(&h->pdev->dev, "cp %p aborted due to an unsolicited "
+ 			"abort\n", cp);
+ 		break;
+ 	case CMD_TIMEOUT:

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0123-hpsa-fix-problem-that-OBDR-devices-are-not-detected.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0123-hpsa-fix-problem-that-OBDR-devices-are-not-detected.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,145 @@
+From 294be65bc3311f1b733693d55155e06ce94c7bff Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 9 Aug 2011 08:17:30 -0500
+Subject: [PATCH 123/136] hpsa: fix problem that OBDR devices are not detected
+
+commit 0b0e1d6cbcc8627970e0399df8f06edd690ec7d9 upstream.
+
+The test to detect OBDR ("One Button Disaster Recovery")
+cd-rom devices was comparing against uninitialized data.
+
+Fixed by moving the test for the device to where the
+inquiry data is collected, and uninitialized variable
+altogether as it wasn't really being used.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |   47 +++++++++++++++++++++++++++--------------------
+ 1 file changed, 27 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 8b3a238..91f4d9c 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1539,10 +1539,17 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device,
+ }
+ 
+ static int hpsa_update_device_info(struct ctlr_info *h,
+-	unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device)
++	unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
++	unsigned char *is_OBDR_device)
+ {
+-#define OBDR_TAPE_INQ_SIZE 49
++
++#define OBDR_SIG_OFFSET 43
++#define OBDR_TAPE_SIG "$DR-10"
++#define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1)
++#define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN)
++
+ 	unsigned char *inq_buff;
++	unsigned char *obdr_sig;
+ 
+ 	inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
+ 	if (!inq_buff)
+@@ -1574,6 +1581,16 @@ static int hpsa_update_device_info(struct ctlr_info *h,
+ 	else
+ 		this_device->raid_level = RAID_UNKNOWN;
+ 
++	if (is_OBDR_device) {
++		/* See if this is a One-Button-Disaster-Recovery device
++		 * by looking for "$DR-10" at offset 43 in inquiry data.
++		 */
++		obdr_sig = &inq_buff[OBDR_SIG_OFFSET];
++		*is_OBDR_device = (this_device->devtype == TYPE_ROM &&
++					strncmp(obdr_sig, OBDR_TAPE_SIG,
++						OBDR_SIG_LEN) == 0);
++	}
++
+ 	kfree(inq_buff);
+ 	return 0;
+ 
+@@ -1707,7 +1724,7 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
+ 		return 0;
+ 	}
+ 
+-	if (hpsa_update_device_info(h, scsi3addr, this_device))
++	if (hpsa_update_device_info(h, scsi3addr, this_device, NULL))
+ 		return 0;
+ 	(*nmsa2xxx_enclosures)++;
+ 	hpsa_set_bus_target_lun(this_device, bus, target, 0);
+@@ -1799,7 +1816,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+ 	 */
+ 	struct ReportLUNdata *physdev_list = NULL;
+ 	struct ReportLUNdata *logdev_list = NULL;
+-	unsigned char *inq_buff = NULL;
+ 	u32 nphysicals = 0;
+ 	u32 nlogicals = 0;
+ 	u32 ndev_allocated = 0;
+@@ -1815,11 +1831,9 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+ 		GFP_KERNEL);
+ 	physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
+ 	logdev_list = kzalloc(reportlunsize, GFP_KERNEL);
+-	inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
+ 	tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);
+ 
+-	if (!currentsd || !physdev_list || !logdev_list ||
+-		!inq_buff || !tmpdevice) {
++	if (!currentsd || !physdev_list || !logdev_list || !tmpdevice) {
+ 		dev_err(&h->pdev->dev, "out of memory\n");
+ 		goto out;
+ 	}
+@@ -1854,7 +1868,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+ 	/* adjust our table of devices */
+ 	nmsa2xxx_enclosures = 0;
+ 	for (i = 0; i < nphysicals + nlogicals + 1; i++) {
+-		u8 *lunaddrbytes;
++		u8 *lunaddrbytes, is_OBDR = 0;
+ 
+ 		/* Figure out where the LUN ID info is coming from */
+ 		lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
+@@ -1865,7 +1879,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+ 			continue;
+ 
+ 		/* Get device type, vendor, model, device id */
+-		if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice))
++		if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
++							&is_OBDR))
+ 			continue; /* skip it if we can't talk to it. */
+ 		figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun,
+ 			tmpdevice);
+@@ -1889,7 +1904,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+ 		hpsa_set_bus_target_lun(this_device, bus, target, lun);
+ 
+ 		switch (this_device->devtype) {
+-		case TYPE_ROM: {
++		case TYPE_ROM:
+ 			/* We don't *really* support actual CD-ROM devices,
+ 			 * just "One Button Disaster Recovery" tape drive
+ 			 * which temporarily pretends to be a CD-ROM drive.
+@@ -1897,15 +1912,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+ 			 * device by checking for "$DR-10" in bytes 43-48 of
+ 			 * the inquiry data.
+ 			 */
+-				char obdr_sig[7];
+-#define OBDR_TAPE_SIG "$DR-10"
+-				strncpy(obdr_sig, &inq_buff[43], 6);
+-				obdr_sig[6] = '\0';
+-				if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
+-					/* Not OBDR device, ignore it. */
+-					break;
+-			}
+-			ncurrent++;
++			if (is_OBDR)
++				ncurrent++;
+ 			break;
+ 		case TYPE_DISK:
+ 			if (i < nphysicals)
+@@ -1938,7 +1946,6 @@ out:
+ 	for (i = 0; i < ndev_allocated; i++)
+ 		kfree(currentsd[i]);
+ 	kfree(currentsd);
+-	kfree(inq_buff);
+ 	kfree(physdev_list);
+ 	kfree(logdev_list);
+ }

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0124-hpsa-fix-physical-device-lun-and-target-numbering-pr.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0124-hpsa-fix-physical-device-lun-and-target-numbering-pr.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,45 @@
+From 2fc73aeb60fbbbb7b3f709174a46b1fa0b5f4816 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Tue, 9 Aug 2011 08:18:01 -0500
+Subject: [PATCH 124/136] hpsa: fix physical device lun and target numbering
+ problem
+
+commit 01350d05539d1c95ef3568d062d864ab76ae7670 upstream.
+
+If a physical device exposed to the OS by hpsa
+is replaced (e.g. one hot plug tape drive is replaced
+by another, or a tape drive is placed into "OBDR" mode
+in which it acts like a CD-ROM device) and a rescan is
+initiated, the replaced device will be added to the
+SCSI midlayer with target and lun numbers set to -1.
+After that, a panic is likely to ensue.  When a physical
+device is replaced, the lun and target number should be
+preserved.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 91f4d9c..f0f2f2c 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -667,6 +667,16 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
+ 	BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
+ 	removed[*nremoved] = h->dev[entry];
+ 	(*nremoved)++;
++
++	/*
++	 * New physical devices won't have target/lun assigned yet
++	 * so we need to preserve the values in the slot we are replacing.
++	 */
++	if (new_entry->target == -1) {
++		new_entry->target = h->dev[entry]->target;
++		new_entry->lun = h->dev[entry]->lun;
++	}
++
+ 	h->dev[entry] = new_entry;
+ 	added[*nadded] = new_entry;
+ 	(*nadded)++;

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0125-hpsa-change-confusing-message-to-be-more-clear.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0125-hpsa-change-confusing-message-to-be-more-clear.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,40 @@
+From dfab1ab22543a45ff50b22fdd4bf000cabf1d7d4 Mon Sep 17 00:00:00 2001
+From: Mike Miller <mike.miller at hp.com>
+Date: Thu, 13 Oct 2011 11:44:06 -0500
+Subject: [PATCH 125/136] hpsa: change confusing message to be more clear
+
+commit fba63097b8614a4a158226c02eec0318f41cd24f upstream.
+
+The following warning message may be confusing to some users:
+
+dev_warn(&pdev->dev, "Controller claims that "
+		"'Bit 2 doorbell reset' is "
+		"supported, but not 'bit 5 doorbell reset'.  "
+		"Firmware update is recommended.\n");
+
+Most users don't know or care what bit we may be hitting. Also change
+"recommended" to "required."
+
+Signed-off-by: Mike Miller <mike.miller at hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index f0f2f2c..efddc2e 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3410,10 +3410,8 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+ 	} else {
+ 		use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
+ 		if (use_doorbell) {
+-			dev_warn(&pdev->dev, "Controller claims that "
+-				"'Bit 2 doorbell reset' is "
+-				"supported, but not 'bit 5 doorbell reset'.  "
+-				"Firmware update is recommended.\n");
++			dev_warn(&pdev->dev, "Soft reset not supported. "
++				"Firmware update is required.\n");
+ 			rc = -ENOTSUPP; /* try soft reset */
+ 			goto unmap_cfgtable;
+ 		}

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0126-hpsa-add-small-delay-when-using-PCI-Power-Management.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0126-hpsa-add-small-delay-when-using-PCI-Power-Management.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,36 @@
+From 51f0555d32145fee9bf450a9dcb6ce88c54f3196 Mon Sep 17 00:00:00 2001
+From: Mike Miller <mike.miller at hp.com>
+Date: Fri, 21 Oct 2011 08:19:43 +0200
+Subject: [PATCH 126/136] hpsa: add small delay when using PCI Power
+ Management to reset for kump
+
+commit c4853efec665134b2e6fc9c13447323240980351 upstream.
+
+The P600 requires a small delay when changing states. Otherwise we may think
+the board did not reset and we bail. This for kdump only and is particular
+to the P600.
+
+Signed-off-by: Mike Miller <mike.miller at hp.com>
+Signed-off-by: Jens Axboe <axboe at kernel.dk>
+---
+ drivers/scsi/hpsa.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index efddc2e..ac63093 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -3272,6 +3272,13 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
+ 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+ 		pmcsr |= PCI_D0;
+ 		pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
++
++		/*
++		 * The P600 requires a small delay when changing states.
++		 * Otherwise we may think the board did not reset and we bail.
++		 * This for kdump only and is particular to the P600.
++		 */
++		msleep(500);
+ 	}
+ 	return 0;
+ }

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0127-hpsa-set-max-sectors-instead-of-taking-the-default.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0127-hpsa-set-max-sectors-instead-of-taking-the-default.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,29 @@
+From 2635d44221632c7855e6e1c33bccaf8fb4441127 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Wed, 26 Oct 2011 16:20:53 -0500
+Subject: [PATCH 127/136] hpsa: set max sectors instead of taking the default
+
+commit c0d6a4d17b3848750b0285861b7a807811a0cfa6 upstream.
+
+Set the max hardware sectors in the SCSI host template to 8192
+to allow for larger i/o's (8192 is the same limit the cciss
+driver currently has.)
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index ac63093..b98d507 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -475,6 +475,7 @@ static struct scsi_host_template hpsa_driver_template = {
+ #endif
+ 	.sdev_attrs = hpsa_sdev_attrs,
+ 	.shost_attrs = hpsa_shost_attrs,
++	.max_sectors = 8192,
+ };
+ 
+ 

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0128-hpsa-remove-unused-busy_initializing-and-busy_scanni.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0128-hpsa-remove-unused-busy_initializing-and-busy_scanni.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,56 @@
+From 0159e4f4ed46880a00975a566db680527ccf80cc Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Wed, 26 Oct 2011 16:20:58 -0500
+Subject: [PATCH 128/136] hpsa: remove unused busy_initializing and
+ busy_scanning
+
+commit 03ab31f4c14f259bfa160543c83dbfd93d6fb3e2 upstream.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |    3 ---
+ drivers/scsi/hpsa.h |    2 --
+ 2 files changed, 5 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index b98d507..64a8ec4 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -4100,7 +4100,6 @@ reinit_after_soft_reset:
+ 		return -ENOMEM;
+ 
+ 	h->pdev = pdev;
+-	h->busy_initializing = 1;
+ 	h->intr_mode = hpsa_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
+ 	INIT_LIST_HEAD(&h->cmpQ);
+ 	INIT_LIST_HEAD(&h->reqQ);
+@@ -4209,7 +4208,6 @@ reinit_after_soft_reset:
+ 
+ 	hpsa_hba_inquiry(h);
+ 	hpsa_register_scsi(h);	/* hook ourselves into SCSI subsystem */
+-	h->busy_initializing = 0;
+ 	return 1;
+ 
+ clean4:
+@@ -4218,7 +4216,6 @@ clean4:
+ 	free_irq(h->intr[h->intr_mode], h);
+ clean2:
+ clean1:
+-	h->busy_initializing = 0;
+ 	kfree(h);
+ 	return rc;
+ }
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 7f53ceaa..111b79e 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -95,8 +95,6 @@ struct ctlr_info {
+ 	unsigned long  		*cmd_pool_bits;
+ 	int			nr_allocs;
+ 	int			nr_frees;
+-	int			busy_initializing;
+-	int			busy_scanning;
+ 	int			scan_finished;
+ 	spinlock_t		scan_lock;
+ 	wait_queue_head_t	scan_wait_queue;

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0129-hpsa-rename-HPSA_MAX_SCSI_DEVS_PER_HBA.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0129-hpsa-rename-HPSA_MAX_SCSI_DEVS_PER_HBA.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,115 @@
+From 307b9ca1a1e7a9830131379487b593060e93fecb Mon Sep 17 00:00:00 2001
+From: Scott Teel <scott.teel at hp.com>
+Date: Wed, 26 Oct 2011 16:21:07 -0500
+Subject: [PATCH 129/136] hpsa: rename HPSA_MAX_SCSI_DEVS_PER_HBA
+
+commit cfe5badcab2e993e71ebebbc07c21c270e5580c0 upstream.
+
+Rename HPSA_MAX_SCSI_DEVS_PER_HBA to HPSA_MAX_DEVICES
+
+Signed-off-by: Scott Teel <scott.teel at hp.com>
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |   23 ++++++++++-------------
+ drivers/scsi/hpsa.h |    4 ++--
+ 2 files changed, 12 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 64a8ec4..62e87fa 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -558,16 +558,16 @@ static int hpsa_find_target_lun(struct ctlr_info *h,
+ 	 * assumes h->devlock is held
+ 	 */
+ 	int i, found = 0;
+-	DECLARE_BITMAP(lun_taken, HPSA_MAX_SCSI_DEVS_PER_HBA);
++	DECLARE_BITMAP(lun_taken, HPSA_MAX_DEVICES);
+ 
+-	memset(&lun_taken[0], 0, HPSA_MAX_SCSI_DEVS_PER_HBA >> 3);
++	memset(&lun_taken[0], 0, HPSA_MAX_DEVICES >> 3);
+ 
+ 	for (i = 0; i < h->ndevices; i++) {
+ 		if (h->dev[i]->bus == bus && h->dev[i]->target != -1)
+ 			set_bit(h->dev[i]->target, lun_taken);
+ 	}
+ 
+-	for (i = 0; i < HPSA_MAX_SCSI_DEVS_PER_HBA; i++) {
++	for (i = 0; i < HPSA_MAX_DEVICES; i++) {
+ 		if (!test_bit(i, lun_taken)) {
+ 			/* *bus = 1; */
+ 			*target = i;
+@@ -590,7 +590,7 @@ static int hpsa_scsi_add_entry(struct ctlr_info *h, int hostno,
+ 	unsigned char addr1[8], addr2[8];
+ 	struct hpsa_scsi_dev_t *sd;
+ 
+-	if (n >= HPSA_MAX_SCSI_DEVS_PER_HBA) {
++	if (n >= HPSA_MAX_DEVICES) {
+ 		dev_err(&h->pdev->dev, "too many devices, some will be "
+ 			"inaccessible.\n");
+ 		return -1;
+@@ -665,7 +665,7 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
+ 	struct hpsa_scsi_dev_t *removed[], int *nremoved)
+ {
+ 	/* assumes h->devlock is held */
+-	BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
++	BUG_ON(entry < 0 || entry >= HPSA_MAX_DEVICES);
+ 	removed[*nremoved] = h->dev[entry];
+ 	(*nremoved)++;
+ 
+@@ -694,7 +694,7 @@ static void hpsa_scsi_remove_entry(struct ctlr_info *h, int hostno, int entry,
+ 	int i;
+ 	struct hpsa_scsi_dev_t *sd;
+ 
+-	BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
++	BUG_ON(entry < 0 || entry >= HPSA_MAX_DEVICES);
+ 
+ 	sd = h->dev[entry];
+ 	removed[*nremoved] = h->dev[entry];
+@@ -806,10 +806,8 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
+ 	int nadded, nremoved;
+ 	struct Scsi_Host *sh = NULL;
+ 
+-	added = kzalloc(sizeof(*added) * HPSA_MAX_SCSI_DEVS_PER_HBA,
+-		GFP_KERNEL);
+-	removed = kzalloc(sizeof(*removed) * HPSA_MAX_SCSI_DEVS_PER_HBA,
+-		GFP_KERNEL);
++	added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
++	removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES, GFP_KERNEL);
+ 
+ 	if (!added || !removed) {
+ 		dev_warn(&h->pdev->dev, "out of memory in "
+@@ -1838,8 +1836,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+ 	int raid_ctlr_position;
+ 	DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR);
+ 
+-	currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_SCSI_DEVS_PER_HBA,
+-		GFP_KERNEL);
++	currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL);
+ 	physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
+ 	logdev_list = kzalloc(reportlunsize, GFP_KERNEL);
+ 	tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);
+@@ -1948,7 +1945,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+ 		default:
+ 			break;
+ 		}
+-		if (ncurrent >= HPSA_MAX_SCSI_DEVS_PER_HBA)
++		if (ncurrent >= HPSA_MAX_DEVICES)
+ 			break;
+ 	}
+ 	adjust_hpsa_scsi_table(h, hostno, currentsd, ncurrent);
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 111b79e..4de9f71 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -102,8 +102,8 @@ struct ctlr_info {
+ 	struct Scsi_Host *scsi_host;
+ 	spinlock_t devlock; /* to protect hba[ctlr]->dev[];  */
+ 	int ndevices; /* number of used elements in .dev[] array. */
+-#define HPSA_MAX_SCSI_DEVS_PER_HBA 256
+-	struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA];
++#define HPSA_MAX_DEVICES 256
++	struct hpsa_scsi_dev_t *dev[HPSA_MAX_DEVICES];
+ 	/*
+ 	 * Performant mode tables.
+ 	 */

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0130-hpsa-fix-potential-array-overflow-in-hpsa_update_scs.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0130-hpsa-fix-potential-array-overflow-in-hpsa_update_scs.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,83 @@
+From 634686b1e377f822b7be5a45888eeabef7585498 Mon Sep 17 00:00:00 2001
+From: Scott Teel <scott.teel at hp.com>
+Date: Wed, 26 Oct 2011 16:21:12 -0500
+Subject: [PATCH 130/136] hpsa: fix potential array overflow in
+ hpsa_update_scsi_devices
+
+commit b7ec021fe6fe979dbd4e62604a4942f964b12864 upstream.
+
+The currentsd[] array in hpsa_update_scsi_devices had room for
+256 devices.  The code was iterating over however many physical
+and logical devices plus an additional number of possible external
+MSA2XXX controllers, which together could potentially exceed 256.
+
+We increased the size of the currentsd array to 1024 + 1024 + 32 + 1
+elements to reflect a reasonable maximum possible number of devices
+which might be encountered.  We also don't just walk off the end
+of the array if the array controller reports more devices than we
+are prepared to handle, we just ignore the excessive devices.
+
+Signed-off-by: Scott Teel <scott.teel at hp.com>
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c     |    8 +++++++-
+ drivers/scsi/hpsa.h     |    1 -
+ drivers/scsi/hpsa_cmd.h |    5 ++++-
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 62e87fa..f19b4a4 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1725,7 +1725,6 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
+ 	if (is_scsi_rev_5(h))
+ 		return 0; /* p1210m doesn't need to do this. */
+ 
+-#define MAX_MSA2XXX_ENCLOSURES 32
+ 	if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) {
+ 		dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX "
+ 			"enclosures exceeded.  Check your hardware "
+@@ -1859,6 +1858,13 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
+ 
+ 	/* Allocate the per device structures */
+ 	for (i = 0; i < ndevs_to_allocate; i++) {
++		if (i >= HPSA_MAX_DEVICES) {
++			dev_warn(&h->pdev->dev, "maximum devices (%d) exceeded."
++				"  %d devices ignored.\n", HPSA_MAX_DEVICES,
++				ndevs_to_allocate - HPSA_MAX_DEVICES);
++			break;
++		}
++
+ 		currentsd[i] = kzalloc(sizeof(*currentsd[i]), GFP_KERNEL);
+ 		if (!currentsd[i]) {
+ 			dev_warn(&h->pdev->dev, "out of memory at %s:%d\n",
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 4de9f71..73858bc 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -102,7 +102,6 @@ struct ctlr_info {
+ 	struct Scsi_Host *scsi_host;
+ 	spinlock_t devlock; /* to protect hba[ctlr]->dev[];  */
+ 	int ndevices; /* number of used elements in .dev[] array. */
+-#define HPSA_MAX_DEVICES 256
+ 	struct hpsa_scsi_dev_t *dev[HPSA_MAX_DEVICES];
+ 	/*
+ 	 * Performant mode tables.
+diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
+index 55d741b..3fd4715 100644
+--- a/drivers/scsi/hpsa_cmd.h
++++ b/drivers/scsi/hpsa_cmd.h
+@@ -123,8 +123,11 @@ union u64bit {
+ 
+ /* FIXME this is a per controller value (barf!) */
+ #define HPSA_MAX_TARGETS_PER_CTLR 16
+-#define HPSA_MAX_LUN 256
++#define HPSA_MAX_LUN 1024
+ #define HPSA_MAX_PHYS_LUN 1024
++#define MAX_MSA2XXX_ENCLOSURES 32
++#define HPSA_MAX_DEVICES (HPSA_MAX_PHYS_LUN + HPSA_MAX_LUN + \
++	MAX_MSA2XXX_ENCLOSURES + 1) /* + 1 is for the controller itself */
+ 
+ /* SCSI-3 Commands */
+ #pragma pack(1)

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0131-hpsa-fix-flush-cache-transfer-length.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0131-hpsa-fix-flush-cache-transfer-length.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,31 @@
+From 95a1e574f28db303656af6b72873ec9a3324c34c Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Wed, 26 Oct 2011 16:21:17 -0500
+Subject: [PATCH 131/136] hpsa: fix flush cache transfer length
+
+commit bb158eabda984851d7964d968b9859383f98a701 upstream.
+
+We weren't filling in the transfer length of the
+flush cache command (it transfers 4 bytes of zeroes).
+Firmware didn't seem to be bothered by this, but it
+should be fixed.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index f19b4a4..086a639 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -2848,6 +2848,8 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
+ 			c->Request.Timeout = 0;
+ 			c->Request.CDB[0] = BMIC_WRITE;
+ 			c->Request.CDB[6] = BMIC_CACHE_FLUSH;
++			c->Request.CDB[7] = (size >> 8) & 0xFF;
++			c->Request.CDB[8] = size & 0xFF;
+ 			break;
+ 		case TEST_UNIT_READY:
+ 			c->Request.CDBLen = 6;

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0132-hpsa-detect-controller-lockup.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0132-hpsa-detect-controller-lockup.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,318 @@
+From 6bfb4ac0fba2b1c66cc13987ed62ce8066a6512f Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Wed, 26 Oct 2011 16:22:04 -0500
+Subject: [PATCH 132/136] hpsa: detect controller lockup
+
+commit a0c124137a40fc22730ae87caf17e821f2dce1ed upstream.
+
+When controller lockup condition is detected,
+we should fail all outstanding commands and disable
+the controller.  This will enable multipath solutions
+to recover gracefully.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |  184 +++++++++++++++++++++++++++++++++++++++++++++++++--
+ drivers/scsi/hpsa.h |    5 ++
+ 2 files changed, 185 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 086a639..d4a1d44 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -48,6 +48,7 @@
+ #include <linux/bitmap.h>
+ #include <asm/atomic.h>
+ #include <linux/kthread.h>
++#include <linux/jiffies.h>
+ #include "hpsa_cmd.h"
+ #include "hpsa.h"
+ 
+@@ -120,6 +121,10 @@ static struct board_type products[] = {
+ 
+ static int number_of_controllers;
+ 
++static struct list_head hpsa_ctlr_list = LIST_HEAD_INIT(hpsa_ctlr_list);
++static spinlock_t lockup_detector_lock;
++static struct task_struct *hpsa_lockup_detector;
++
+ static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id);
+ static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id);
+ static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg);
+@@ -1328,6 +1333,22 @@ static inline void hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h,
+ 	wait_for_completion(&wait);
+ }
+ 
++static void hpsa_scsi_do_simple_cmd_core_if_no_lockup(struct ctlr_info *h,
++	struct CommandList *c)
++{
++	unsigned long flags;
++
++	/* If controller lockup detected, fake a hardware error. */
++	spin_lock_irqsave(&h->lock, flags);
++	if (unlikely(h->lockup_detected)) {
++		spin_unlock_irqrestore(&h->lock, flags);
++		c->err_info->CommandStatus = CMD_HARDWARE_ERR;
++	} else {
++		spin_unlock_irqrestore(&h->lock, flags);
++		hpsa_scsi_do_simple_cmd_core(h, c);
++	}
++}
++
+ static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h,
+ 	struct CommandList *c, int data_direction)
+ {
+@@ -2043,8 +2064,14 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
+ 	}
+ 	memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr));
+ 
+-	/* Need a lock as this is being allocated from the pool */
+ 	spin_lock_irqsave(&h->lock, flags);
++	if (unlikely(h->lockup_detected)) {
++		spin_unlock_irqrestore(&h->lock, flags);
++		cmd->result = DID_ERROR << 16;
++		done(cmd);
++		return 0;
++	}
++	/* Need a lock as this is being allocated from the pool */
+ 	c = cmd_alloc(h);
+ 	spin_unlock_irqrestore(&h->lock, flags);
+ 	if (c == NULL) {			/* trouble... */
+@@ -2577,7 +2604,7 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+ 		c->SG[0].Len = iocommand.buf_size;
+ 		c->SG[0].Ext = 0; /* we are not chaining*/
+ 	}
+-	hpsa_scsi_do_simple_cmd_core(h, c);
++	hpsa_scsi_do_simple_cmd_core_if_no_lockup(h, c);
+ 	if (iocommand.buf_size > 0)
+ 		hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL);
+ 	check_ioctl_unit_attention(h, c);
+@@ -2700,7 +2727,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
+ 			c->SG[i].Ext = 0;
+ 		}
+ 	}
+-	hpsa_scsi_do_simple_cmd_core(h, c);
++	hpsa_scsi_do_simple_cmd_core_if_no_lockup(h, c);
+ 	if (sg_used)
+ 		hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL);
+ 	check_ioctl_unit_attention(h, c);
+@@ -3069,6 +3096,7 @@ static irqreturn_t hpsa_intx_discard_completions(int irq, void *dev_id)
+ 	if (interrupt_not_for_us(h))
+ 		return IRQ_NONE;
+ 	spin_lock_irqsave(&h->lock, flags);
++	h->last_intr_timestamp = get_jiffies_64();
+ 	while (interrupt_pending(h)) {
+ 		raw_tag = get_next_completion(h);
+ 		while (raw_tag != FIFO_EMPTY)
+@@ -3088,6 +3116,7 @@ static irqreturn_t hpsa_msix_discard_completions(int irq, void *dev_id)
+ 		return IRQ_NONE;
+ 
+ 	spin_lock_irqsave(&h->lock, flags);
++	h->last_intr_timestamp = get_jiffies_64();
+ 	raw_tag = get_next_completion(h);
+ 	while (raw_tag != FIFO_EMPTY)
+ 		raw_tag = next_command(h);
+@@ -3104,6 +3133,7 @@ static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id)
+ 	if (interrupt_not_for_us(h))
+ 		return IRQ_NONE;
+ 	spin_lock_irqsave(&h->lock, flags);
++	h->last_intr_timestamp = get_jiffies_64();
+ 	while (interrupt_pending(h)) {
+ 		raw_tag = get_next_completion(h);
+ 		while (raw_tag != FIFO_EMPTY) {
+@@ -3124,6 +3154,7 @@ static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id)
+ 	u32 raw_tag;
+ 
+ 	spin_lock_irqsave(&h->lock, flags);
++	h->last_intr_timestamp = get_jiffies_64();
+ 	raw_tag = get_next_completion(h);
+ 	while (raw_tag != FIFO_EMPTY) {
+ 		if (hpsa_tag_contains_index(raw_tag))
+@@ -4068,6 +4099,149 @@ static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
+ 	kfree(h);
+ }
+ 
++static void remove_ctlr_from_lockup_detector_list(struct ctlr_info *h)
++{
++	assert_spin_locked(&lockup_detector_lock);
++	if (!hpsa_lockup_detector)
++		return;
++	if (h->lockup_detected)
++		return; /* already stopped the lockup detector */
++	list_del(&h->lockup_list);
++}
++
++/* Called when controller lockup detected. */
++static void fail_all_cmds_on_list(struct ctlr_info *h, struct list_head *list)
++{
++	struct CommandList *c = NULL;
++
++	assert_spin_locked(&h->lock);
++	/* Mark all outstanding commands as failed and complete them. */
++	while (!list_empty(list)) {
++		c = list_entry(list->next, struct CommandList, list);
++		c->err_info->CommandStatus = CMD_HARDWARE_ERR;
++		finish_cmd(c, c->Header.Tag.lower);
++	}
++}
++
++static void controller_lockup_detected(struct ctlr_info *h)
++{
++	unsigned long flags;
++
++	assert_spin_locked(&lockup_detector_lock);
++	remove_ctlr_from_lockup_detector_list(h);
++	h->access.set_intr_mask(h, HPSA_INTR_OFF);
++	spin_lock_irqsave(&h->lock, flags);
++	h->lockup_detected = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
++	spin_unlock_irqrestore(&h->lock, flags);
++	dev_warn(&h->pdev->dev, "Controller lockup detected: 0x%08x\n",
++			h->lockup_detected);
++	pci_disable_device(h->pdev);
++	spin_lock_irqsave(&h->lock, flags);
++	fail_all_cmds_on_list(h, &h->cmpQ);
++	fail_all_cmds_on_list(h, &h->reqQ);
++	spin_unlock_irqrestore(&h->lock, flags);
++}
++
++#define HEARTBEAT_SAMPLE_INTERVAL (10 * HZ)
++#define HEARTBEAT_CHECK_MINIMUM_INTERVAL (HEARTBEAT_SAMPLE_INTERVAL / 2)
++
++static void detect_controller_lockup(struct ctlr_info *h)
++{
++	u64 now;
++	u32 heartbeat;
++	unsigned long flags;
++
++	assert_spin_locked(&lockup_detector_lock);
++	now = get_jiffies_64();
++	/* If we've received an interrupt recently, we're ok. */
++	if (time_after64(h->last_intr_timestamp +
++				(HEARTBEAT_CHECK_MINIMUM_INTERVAL), now))
++		return;
++
++	/*
++	 * If we've already checked the heartbeat recently, we're ok.
++	 * This could happen if someone sends us a signal. We
++	 * otherwise don't care about signals in this thread.
++	 */
++	if (time_after64(h->last_heartbeat_timestamp +
++				(HEARTBEAT_CHECK_MINIMUM_INTERVAL), now))
++		return;
++
++	/* If heartbeat has not changed since we last looked, we're not ok. */
++	spin_lock_irqsave(&h->lock, flags);
++	heartbeat = readl(&h->cfgtable->HeartBeat);
++	spin_unlock_irqrestore(&h->lock, flags);
++	if (h->last_heartbeat == heartbeat) {
++		controller_lockup_detected(h);
++		return;
++	}
++
++	/* We're ok. */
++	h->last_heartbeat = heartbeat;
++	h->last_heartbeat_timestamp = now;
++}
++
++static int detect_controller_lockup_thread(void *notused)
++{
++	struct ctlr_info *h;
++	unsigned long flags;
++
++	while (1) {
++		struct list_head *this, *tmp;
++
++		schedule_timeout_interruptible(HEARTBEAT_SAMPLE_INTERVAL);
++		if (kthread_should_stop())
++			break;
++		spin_lock_irqsave(&lockup_detector_lock, flags);
++		list_for_each_safe(this, tmp, &hpsa_ctlr_list) {
++			h = list_entry(this, struct ctlr_info, lockup_list);
++			detect_controller_lockup(h);
++		}
++		spin_unlock_irqrestore(&lockup_detector_lock, flags);
++	}
++	return 0;
++}
++
++static void add_ctlr_to_lockup_detector_list(struct ctlr_info *h)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&lockup_detector_lock, flags);
++	list_add_tail(&h->lockup_list, &hpsa_ctlr_list);
++	spin_unlock_irqrestore(&lockup_detector_lock, flags);
++}
++
++static void start_controller_lockup_detector(struct ctlr_info *h)
++{
++	/* Start the lockup detector thread if not already started */
++	if (!hpsa_lockup_detector) {
++		spin_lock_init(&lockup_detector_lock);
++		hpsa_lockup_detector =
++			kthread_run(detect_controller_lockup_thread,
++						NULL, "hpsa");
++	}
++	if (!hpsa_lockup_detector) {
++		dev_warn(&h->pdev->dev,
++			"Could not start lockup detector thread\n");
++		return;
++	}
++	add_ctlr_to_lockup_detector_list(h);
++}
++
++static void stop_controller_lockup_detector(struct ctlr_info *h)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&lockup_detector_lock, flags);
++	remove_ctlr_from_lockup_detector_list(h);
++	/* If the list of ctlr's to monitor is empty, stop the thread */
++	if (list_empty(&hpsa_ctlr_list)) {
++		kthread_stop(hpsa_lockup_detector);
++		hpsa_lockup_detector = NULL;
++	}
++	spin_unlock_irqrestore(&lockup_detector_lock, flags);
++}
++
+ static int __devinit hpsa_init_one(struct pci_dev *pdev,
+ 				    const struct pci_device_id *ent)
+ {
+@@ -4213,6 +4387,7 @@ reinit_after_soft_reset:
+ 
+ 	hpsa_hba_inquiry(h);
+ 	hpsa_register_scsi(h);	/* hook ourselves into SCSI subsystem */
++	start_controller_lockup_detector(h);
+ 	return 1;
+ 
+ clean4:
+@@ -4275,10 +4450,11 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
+ 	struct ctlr_info *h;
+ 
+ 	if (pci_get_drvdata(pdev) == NULL) {
+-		dev_err(&pdev->dev, "unable to remove device \n");
++		dev_err(&pdev->dev, "unable to remove device\n");
+ 		return;
+ 	}
+ 	h = pci_get_drvdata(pdev);
++	stop_controller_lockup_detector(h);
+ 	hpsa_unregister_scsi(h);	/* unhook from SCSI subsystem */
+ 	hpsa_shutdown(pdev);
+ 	iounmap(h->vaddr);
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index 73858bc..91edafb 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -121,6 +121,11 @@ struct ctlr_info {
+ 	unsigned char reply_pool_wraparound;
+ 	u32 *blockFetchTable;
+ 	unsigned char *hba_inquiry_data;
++	u64 last_intr_timestamp;
++	u32 last_heartbeat;
++	u64 last_heartbeat_timestamp;
++	u32 lockup_detected;
++	struct list_head lockup_list;
+ };
+ #define HPSA_ABORT_MSG 0
+ #define HPSA_DEVICE_RESET_MSG 1

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0133-hpsa-Disable-ASPM.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0133-hpsa-Disable-ASPM.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,40 @@
+From 7e7d4c0815f86b5d2f60e00d3fb10a7cbc985b74 Mon Sep 17 00:00:00 2001
+From: Matthew Garrett <mjg at redhat.com>
+Date: Fri, 11 Nov 2011 11:14:23 -0500
+Subject: [PATCH 133/136] hpsa: Disable ASPM
+
+commit e5a44df85e8d78e5c2d3d2e4f59b460905691e2f upstream.
+
+The Windows driver .inf disables ASPM on hpsa devices. Do the same because the
+selection of a non default ASPM policy can cause the device to hang.
+
+Signed-off-by: Matthew Garrett <mjg at redhat.com>
+Acked-by: Mike Miller <mike.miller at hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+---
+ drivers/scsi/hpsa.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index d4a1d44..4b3ea9d 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -23,6 +23,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
++#include <linux/pci-aspm.h>
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+@@ -3894,6 +3895,10 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h)
+ 		dev_warn(&h->pdev->dev, "controller appears to be disabled\n");
+ 		return -ENODEV;
+ 	}
++
++	pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S |
++			       PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
++
+ 	err = pci_enable_device(h->pdev);
+ 	if (err) {
+ 		dev_warn(&h->pdev->dev, "unable to enable PCI device\n");

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0134-hpsa-Fix-problem-with-MSA2xxx-devices.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0134-hpsa-Fix-problem-with-MSA2xxx-devices.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,74 @@
+From af4c8bf2cceec44a21069553d8b1fd44a28d2b4e Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Thu, 19 Jan 2012 14:01:04 -0600
+Subject: [PATCH 134/136] hpsa: Fix problem with MSA2xxx devices
+
+commit 9bc3711cbb67ac620bf09b4a147cbab45b2c36c0 upstream.
+
+Upgraded firmware on Smart Array P7xx (and some others) made them show up as
+SCSI revision 5 devices and this caused the driver to fail to map MSA2xxx
+logical drives to the correct bus/target/lun.  A symptom of this would be that
+the target ID of the logical drives as presented by the external storage array
+is ignored, and all such logical drives are assigned to target zero,
+differentiated only by LUN.  Some multipath software reportedly does not deal
+well with this behavior, failing to recognize different paths to the same
+device as such.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: Scott Teel <scott.teel at hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ drivers/scsi/hpsa.c |   34 +++++++++++++++-------------------
+ 1 file changed, 15 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 4b3ea9d..59dda57 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1665,30 +1665,26 @@ static void figure_bus_target_lun(struct ctlr_info *h,
+ 
+ 	if (is_logical_dev_addr_mode(lunaddrbytes)) {
+ 		/* logical device */
+-		if (unlikely(is_scsi_rev_5(h))) {
+-			/* p1210m, logical drives lun assignments
+-			 * match SCSI REPORT LUNS data.
++		lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
++		if (is_msa2xxx(h, device)) {
++			/* msa2xxx way, put logicals on bus 1
++			 * and match target/lun numbers box
++			 * reports.
+ 			 */
+-			lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
+-			*bus = 0;
+-			*target = 0;
+-			*lun = (lunid & 0x3fff) + 1;
++			*bus = 1;
++			*target = (lunid >> 16) & 0x3fff;
++			*lun = lunid & 0x00ff;
+ 		} else {
+-			/* not p1210m... */
+-			lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
+-			if (is_msa2xxx(h, device)) {
+-				/* msa2xxx way, put logicals on bus 1
+-				 * and match target/lun numbers box
+-				 * reports.
+-				 */
+-				*bus = 1;
+-				*target = (lunid >> 16) & 0x3fff;
+-				*lun = lunid & 0x00ff;
++			if (likely(is_scsi_rev_5(h))) {
++				/* All current smart arrays (circa 2011) */
++				*bus = 0;
++				*target = 0;
++				*lun = (lunid & 0x3fff) + 1;
+ 			} else {
+-				/* Traditional smart array way. */
++				/* Traditional old smart array way. */
+ 				*bus = 0;
+-				*lun = 0;
+ 				*target = lunid & 0x3fff;
++				*lun = 0;
+ 			}
+ 		}
+ 	} else {

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0135-hpsa-Add-IRQF_SHARED-back-in-for-the-non-MSI-X-inter.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0135-hpsa-Add-IRQF_SHARED-back-in-for-the-non-MSI-X-inter.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,39 @@
+From e1ce5fac21628998a31d295320b93f00f3aa6bbd Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Mon, 28 Nov 2011 10:15:20 -0600
+Subject: [PATCH 135/136] hpsa: Add IRQF_SHARED back in for the non-MSI(X)
+ interrupt handler
+
+commit 45bcf018d1a4779d592764ef57517c92589d55d7 upstream.
+
+IRQF_SHARED is required for older controllers that don't support MSI(X)
+and which may end up sharing an interrupt.  All the controllers hpsa
+normally supports have MSI(X) capability, but older controllers may be
+encountered via the hpsa_allow_any=1 module parameter.
+
+Also remove deprecated IRQF_DISABLED.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ drivers/scsi/hpsa.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 59dda57..5b9cc14 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -4040,10 +4040,10 @@ static int hpsa_request_irq(struct ctlr_info *h,
+ 
+ 	if (h->msix_vector || h->msi_vector)
+ 		rc = request_irq(h->intr[h->intr_mode], msixhandler,
+-				IRQF_DISABLED, h->devname, h);
++				0, h->devname, h);
+ 	else
+ 		rc = request_irq(h->intr[h->intr_mode], intxhandler,
+-				IRQF_DISABLED, h->devname, h);
++				IRQF_SHARED, h->devname, h);
+ 	if (rc) {
+ 		dev_err(&h->pdev->dev, "unable to get irq %d for %s\n",
+ 		       h->intr[h->intr_mode], h->devname);

Added: dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0136-hpsa-fix-handling-of-protocol-error.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/features/all/hpsa/0136-hpsa-fix-handling-of-protocol-error.patch	Sun Dec 16 22:30:47 2012	(r19613)
@@ -0,0 +1,44 @@
+From 2f626bc37b11406310eb6600e98d5c0ffce9de76 Mon Sep 17 00:00:00 2001
+From: "Stephen M. Cameron" <scameron at beardog.cce.hp.com>
+Date: Fri, 14 Sep 2012 16:34:25 -0500
+Subject: [PATCH 136/136] hpsa: fix handling of protocol error
+
+commit 256d0eaac87da1e993190846064f339f4c7a63f5 upstream.
+
+If a command status of CMD_PROTOCOL_ERR is received, this
+information should be conveyed to the SCSI mid layer, not
+dropped on the floor.  CMD_PROTOCOL_ERR may be received
+from the Smart Array for any commands destined for an external
+RAID controller such as a P2000, or commands destined for tape
+drives or CD/DVD-ROM drives, if for instance a cable is
+disconnected.  This mostly affects multipath configurations, as
+disconnecting a cable on a non-multipath configuration is not
+going to do anything good regardless of whether CMD_PROTOCOL_ERR
+is handled correctly or not.  Not handling CMD_PROTOCOL_ERR
+correctly in a multipath configaration involving external RAID
+controllers may cause data corruption, so this is quite a serious
+bug.  This bug should not normally cause a problem for direct
+attached disk storage.
+
+Signed-off-by: Stephen M. Cameron <scameron at beardog.cce.hp.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ drivers/scsi/hpsa.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 5b9cc14..8eb56ff 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -1204,8 +1204,9 @@ static void complete_scsi_command(struct CommandList *cp)
+ 	}
+ 		break;
+ 	case CMD_PROTOCOL_ERR:
++		cmd->result = DID_ERROR << 16;
+ 		dev_warn(&h->pdev->dev, "cp %p has "
+-			"protocol error \n", cp);
++			"protocol error\n", cp);
+ 		break;
+ 	case CMD_HARDWARE_ERR:
+ 		cmd->result = DID_ERROR << 16;

Modified: dists/squeeze/linux-2.6/debian/patches/series/47
==============================================================================
--- dists/squeeze/linux-2.6/debian/patches/series/47	Sun Dec 16 19:30:35 2012	(r19612)
+++ dists/squeeze/linux-2.6/debian/patches/series/47	Sun Dec 16 22:30:47 2012	(r19613)
@@ -5,3 +5,64 @@
 + features/x86/ALSA-HD-Audio-patch-for-Intel-Panther-Point.patch
 + bugfix/all/header-fix-broken-headers-for-user-space.patch
 + bugfix/all/kernel-panic-when-mount-NFSv4.patch
+
+# Update hpsa to 3.2.35
++ features/all/hpsa/0080-hpsa-defend-against-zero-sized-buffers-in-passthru-i.patch
++ features/all/hpsa/0081-hpsa-fixup-DMA-address-before-freeing.patch
++ features/all/hpsa/0082-hpsa-Remove-duplicate-defines-of-DIRECT_LOOKUP_-cons.patch
++ features/all/hpsa/0083-hpsa-fix-board-status-waiting-code.patch
++ features/all/hpsa/0084-hpsa-Use-kernel-provided-PCI-state-save-and-restore-.patch
++ features/all/hpsa/0085-hpsa-limit-commands-allocated-on-reset_devices.patch
++ features/all/hpsa/0086-hpsa-do-not-reset-unknown-boards-on-reset_devices.patch
++ features/all/hpsa/0087-hpsa-take-the-adapter-lock-in-hpsa_wait_for_mode_cha.patch
++ features/all/hpsa/0088-hpsa-allow-driver-to-put-controller-in-either-simple.patch
++ features/all/hpsa/0089-hpsa-Add-a-per-controller-commands_outstanding-entry.patch
++ features/all/hpsa/0090-hpsa-fix-use-of-uninitialized-variable-in-hpsa_add_m.patch
++ features/all/hpsa/0091-hpsa-Fix-problem-that-CMD_UNABORTABLE-command-status.patch
++ features/all/hpsa/0092-hpsa-avoid-leaking-stack-contents-to-userland.patch
++ features/all/hpsa/0093-hpsa-do-not-re-order-commands-in-internal-queues.patch
++ features/all/hpsa/0094-hpsa-make-hpsa.hpsa_simple_mode-1-module-parameter-a.patch
++ features/all/hpsa/0095-hpsa-Add-transport_mode-host-attribute-in-sys.patch
++ features/all/hpsa/0096-hpsa-Inform-controller-we-are-using-32-bit-tags.patch
++ features/all/hpsa/0097-hpsa-Do-not-attempt-kdump-if-we-detect-resetting-con.patch
++ features/all/hpsa/0098-hpsa-fix-bad-comparison.patch
++ features/all/hpsa/0099-hpsa-fix-incorrect-PCI-IDs-and-add-two-new-ones-2nd-.patch
++ features/all/hpsa/0100-hpsa-move-device-attributes-to-avoid-forward-declara.patch
++ features/all/hpsa/0101-hpsa-export-resettable-host-attribute.patch
++ features/all/hpsa/0102-hpsa-do-readl-after-writel-in-main-i-o-path-to-ensur.patch
++ features/all/hpsa/0103-hpsa-add-readl-after-writel-in-interrupt-mask-settin.patch
++ features/all/hpsa/0104-hpsa-remove-unused-parameter-from-hpsa_complete_scsi.patch
++ features/all/hpsa/0105-hpsa-delete-old-unused-padding-garbage.patch
++ features/all/hpsa/0106-hpsa-do-a-better-job-of-detecting-controller-reset-f.patch
++ features/all/hpsa/0107-hpsa-wait-longer-for-no-op-to-complete-after-resetti.patch
++ features/all/hpsa/0108-hpsa-factor-out-cmd-pool-allocation-functions.patch
++ features/all/hpsa/0109-hpsa-factor-out-irq-request-code.patch
++ features/all/hpsa/0110-hpsa-increase-time-to-wait-for-board-reset.patch
++ features/all/hpsa/0111-hpsa-clarify-messages-around-reset-behavior.patch
++ features/all/hpsa/0112-hpsa-remove-atrophied-hpsa_scsi_setup-function.patch
++ features/all/hpsa/0113-hpsa-use-new-doorbell-bit-5-reset-method.patch
++ features/all/hpsa/0114-hpsa-do-soft-reset-if-hard-reset-is-broken.patch
++ features/all/hpsa/0115-hpsa-remove-superfluous-sleeps-around-reset-code.patch
++ features/all/hpsa/0116-hpsa-do-not-attempt-PCI-power-management-reset-metho.patch
++ features/all/hpsa/0117-hpsa-add-P2000-to-list-of-shared-SAS-devices.patch
++ features/all/hpsa/0118-hpsa-Change-memset-using-sizeof-ptr-to-sizeof-ptr.patch
++ features/all/hpsa/0119-hpsa-fix-dma-unmap-error-in-hpsa_passthru_ioctl.patch
++ features/all/hpsa/0120-hpsa-fix-potential-overrun-while-memcpy-ing-sense-da.patch
++ features/all/hpsa/0121-hpsa-do-not-attempt-to-read-from-a-write-only-regist.patch
++ features/all/hpsa/0122-hpsa-retry-commands-completing-with-status-of-UNSOLI.patch
++ features/all/hpsa/0123-hpsa-fix-problem-that-OBDR-devices-are-not-detected.patch
++ features/all/hpsa/0124-hpsa-fix-physical-device-lun-and-target-numbering-pr.patch
++ features/all/hpsa/0125-hpsa-change-confusing-message-to-be-more-clear.patch
++ features/all/hpsa/0126-hpsa-add-small-delay-when-using-PCI-Power-Management.patch
++ features/all/hpsa/0127-hpsa-set-max-sectors-instead-of-taking-the-default.patch
++ features/all/hpsa/0128-hpsa-remove-unused-busy_initializing-and-busy_scanni.patch
++ features/all/hpsa/0129-hpsa-rename-HPSA_MAX_SCSI_DEVS_PER_HBA.patch
++ features/all/hpsa/0130-hpsa-fix-potential-array-overflow-in-hpsa_update_scs.patch
++ features/all/hpsa/0131-hpsa-fix-flush-cache-transfer-length.patch
++ features/all/hpsa/0132-hpsa-detect-controller-lockup.patch
++ features/all/hpsa/0133-hpsa-Disable-ASPM.patch
++ features/all/hpsa/0134-hpsa-Fix-problem-with-MSA2xxx-devices.patch
++ features/all/hpsa/0135-hpsa-Add-IRQF_SHARED-back-in-for-the-non-MSI-X-inter.patch
++ features/all/hpsa/0136-hpsa-fix-handling-of-protocol-error.patch
++ features/all/hpsa/0137-hpsa-Use-LUN-reset-instead-of-target-reset.patch
++ features/all/hpsa/0138-hpsa-dial-down-lockup-detection-during-firmware-flas.patch



More information about the Kernel-svn-changes mailing list