public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] hpsa: Feb 15, 2011 updates
@ 2011-02-15 21:32 Stephen M. Cameron
  2011-02-15 21:32 ` [PATCH 1/6] hpsa: do not re-order commands in internal queues Stephen M. Cameron
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2011-02-15 21:32 UTC (permalink / raw)
  To: james.bottomley
  Cc: linux-scsi, linux-kernel, mike.mikem, thenzl, akpm, smcameron

The following series fixes a problem that commands were unintentionally
re-ordered within the driver, and another problem that the hpsa_simple_mode
module paramter didn't actually work.  It adds a host attribute in /sys to
know which mode (simple or performant) the controller is in.  It informs the
controller that we're only using 32-bit tags (needed for a couple of new
controllers to work properly).  Finally, we shouldn't proceed with kdumping
if a controller cannot be reset, as there may be outstanding commands which
interfere with kdump's i/o.

---

Dan Carpenter (1):
      hpsa: fix bad comparison

Stephen M. Cameron (5):
      hpsa: do not re-order commands in internal queues
      hpsa: make hpsa.hpsa_simple_mode=1 module parameter actually work
      hpsa: Add transport_mode host attribute in /sys
      hpsa: Inform controller we are using 32-bit tags.
      hpsa: Do not attempt kdump if we detect resetting controller failed.


 Documentation/scsi/hpsa.txt |    5 ++
 drivers/scsi/hpsa.c         |  104 +++++++++++++++++++++++++++----------------
 drivers/scsi/hpsa.h         |    5 +-
 drivers/scsi/hpsa_cmd.h     |    3 +
 4 files changed, 75 insertions(+), 42 deletions(-)

-- 
-- steve

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/6] hpsa: do not re-order commands in internal queues
  2011-02-15 21:32 [PATCH 0/6] hpsa: Feb 15, 2011 updates Stephen M. Cameron
@ 2011-02-15 21:32 ` Stephen M. Cameron
  2011-02-15 21:32 ` [PATCH 2/6] hpsa: make hpsa.hpsa_simple_mode=1 module parameter actually work Stephen M. Cameron
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2011-02-15 21:32 UTC (permalink / raw)
  To: james.bottomley
  Cc: linux-scsi, linux-kernel, mike.mikem, thenzl, akpm, smcameron

From: Stephen M. Cameron <scameron@beardog.cce.hp.com>

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@beardog.cce.hp.com>
---
 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 959eeb2..0f40de2 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -314,9 +314,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)
@@ -366,9 +366,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[])
@@ -2228,7 +2228,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;
@@ -2266,7 +2266,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;
@@ -2837,8 +2837,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");
@@ -2929,10 +2929,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);
@@ -3761,8 +3760,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;

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/6] hpsa: make hpsa.hpsa_simple_mode=1 module parameter actually work
  2011-02-15 21:32 [PATCH 0/6] hpsa: Feb 15, 2011 updates Stephen M. Cameron
  2011-02-15 21:32 ` [PATCH 1/6] hpsa: do not re-order commands in internal queues Stephen M. Cameron
@ 2011-02-15 21:32 ` Stephen M. Cameron
  2011-02-15 21:32 ` [PATCH 3/6] hpsa: Add transport_mode host attribute in /sys Stephen M. Cameron
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2011-02-15 21:32 UTC (permalink / raw)
  To: james.bottomley
  Cc: linux-scsi, linux-kernel, mike.mikem, thenzl, akpm, smcameron

From: Stephen M. Cameron <scameron@beardog.cce.hp.com>

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@beardog.cce.hp.com>
---
 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 0f40de2..66ccacf 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1186,7 +1186,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)
@@ -2902,10 +2902,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 */
@@ -2930,7 +2934,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);
@@ -2981,7 +2985,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)
 {
@@ -3047,7 +3054,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);
 	}
@@ -3379,7 +3386,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)
@@ -3760,6 +3767,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);
@@ -3790,20 +3799,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 -
@@ -3854,7 +3863,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;
@@ -3898,7 +3907,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 */

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/6] hpsa: Add transport_mode host attribute in /sys
  2011-02-15 21:32 [PATCH 0/6] hpsa: Feb 15, 2011 updates Stephen M. Cameron
  2011-02-15 21:32 ` [PATCH 1/6] hpsa: do not re-order commands in internal queues Stephen M. Cameron
  2011-02-15 21:32 ` [PATCH 2/6] hpsa: make hpsa.hpsa_simple_mode=1 module parameter actually work Stephen M. Cameron
@ 2011-02-15 21:32 ` Stephen M. Cameron
  2011-02-15 21:33 ` [PATCH 4/6] hpsa: Inform controller we are using 32-bit tags Stephen M. Cameron
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2011-02-15 21:32 UTC (permalink / raw)
  To: james.bottomley
  Cc: linux-scsi, linux-kernel, mike.mikem, thenzl, akpm, smcameron

From: Stephen M. Cameron <scameron@beardog.cce.hp.com>

Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
---
 Documentation/scsi/hpsa.txt |    5 +++++
 drivers/scsi/hpsa.c         |   18 +++++++++++++++++-
 2 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/Documentation/scsi/hpsa.txt b/Documentation/scsi/hpsa.txt
index dca6583..ed524f1 100644
--- a/Documentation/scsi/hpsa.txt
+++ b/Documentation/scsi/hpsa.txt
@@ -39,6 +39,7 @@ HPSA specific entries in /sys
 
   /sys/class/scsi_host/host*/rescan
   /sys/class/scsi_host/host*/firmware_revision
+  /sys/class/scsi_host/host*/transport_mode
 
   the host "rescan" attribute is a write only attribute.  Writing to this
   attribute will cause the driver to scan for new, changed, or removed devices
@@ -55,6 +56,10 @@ HPSA specific entries in /sys
 	root@host:/sys/class/scsi_host/host4# cat firmware_revision
 	7.14
 
+  The transport_mode indicates whether the controller is in "performant"
+  or "simple" mode.  This is controlled by the "hpsa_simple_mode" module
+  parameter.
+
   HPSA specific disk attributes:
   ------------------------------
 
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 66ccacf..563d439 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -161,6 +161,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);
@@ -192,6 +194,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,
@@ -204,6 +208,7 @@ static struct device_attribute *hpsa_shost_attrs[] = {
 	&dev_attr_rescan,
 	&dev_attr_firmware_revision,
 	&dev_attr_commands_outstanding,
+	&dev_attr_transport_mode,
 	NULL,
 };
 
@@ -313,6 +318,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)
 {
@@ -3768,7 +3785,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);


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/6] hpsa: Inform controller we are using 32-bit tags.
  2011-02-15 21:32 [PATCH 0/6] hpsa: Feb 15, 2011 updates Stephen M. Cameron
                   ` (2 preceding siblings ...)
  2011-02-15 21:32 ` [PATCH 3/6] hpsa: Add transport_mode host attribute in /sys Stephen M. Cameron
@ 2011-02-15 21:33 ` Stephen M. Cameron
  2011-02-15 21:33 ` [PATCH 5/6] hpsa: Do not attempt kdump if we detect resetting controller failed Stephen M. Cameron
  2011-02-15 21:33 ` [PATCH 6/6] hpsa: fix bad comparison Stephen M. Cameron
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2011-02-15 21:33 UTC (permalink / raw)
  To: james.bottomley
  Cc: linux-scsi, linux-kernel, mike.mikem, thenzl, akpm, smcameron

From: Stephen M. Cameron <scameron@beardog.cce.hp.com>

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@beardog.cce.hp.com>
---
 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 563d439..a778cb1 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -326,7 +326,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");
 }
 
@@ -340,7 +340,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)) {
@@ -364,7 +364,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);
 }
 
@@ -2924,7 +2924,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;
 }
@@ -3640,6 +3640,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;
 }
 
@@ -4025,7 +4026,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;
@@ -4073,7 +4075,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);
@@ -4083,6 +4085,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)
@@ -4111,11 +4116,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

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/6] hpsa: Do not attempt kdump if we detect resetting controller failed.
  2011-02-15 21:32 [PATCH 0/6] hpsa: Feb 15, 2011 updates Stephen M. Cameron
                   ` (3 preceding siblings ...)
  2011-02-15 21:33 ` [PATCH 4/6] hpsa: Inform controller we are using 32-bit tags Stephen M. Cameron
@ 2011-02-15 21:33 ` Stephen M. Cameron
  2011-02-15 21:33 ` [PATCH 6/6] hpsa: fix bad comparison Stephen M. Cameron
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2011-02-15 21:33 UTC (permalink / raw)
  To: james.bottomley
  Cc: linux-scsi, linux-kernel, mike.mikem, thenzl, akpm, smcameron

From: Stephen M. Cameron <scameron@beardog.cce.hp.com>

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@beardog.cce.hp.com>
---
 drivers/scsi/hpsa.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a778cb1..eb6938f 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3264,13 +3264,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:


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 6/6] hpsa: fix bad comparison
  2011-02-15 21:32 [PATCH 0/6] hpsa: Feb 15, 2011 updates Stephen M. Cameron
                   ` (4 preceding siblings ...)
  2011-02-15 21:33 ` [PATCH 5/6] hpsa: Do not attempt kdump if we detect resetting controller failed Stephen M. Cameron
@ 2011-02-15 21:33 ` Stephen M. Cameron
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2011-02-15 21:33 UTC (permalink / raw)
  To: james.bottomley
  Cc: linux-scsi, linux-kernel, mike.mikem, thenzl, akpm, smcameron

From: Dan Carpenter <error27@gmail.com>

'!' has higher precedence than '&'.  CFGTBL_ChangeReq is 0x1 so the
original code is equivelent to if (!doorbell_value) {...

Signed-off-by: Dan Carpenter <error27@gmail.com>
Acked-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
---
 drivers/scsi/hpsa.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index eb6938f..c30591f 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3614,7 +3614,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 */
 		usleep_range(10000, 20000);

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-02-15 21:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-15 21:32 [PATCH 0/6] hpsa: Feb 15, 2011 updates Stephen M. Cameron
2011-02-15 21:32 ` [PATCH 1/6] hpsa: do not re-order commands in internal queues Stephen M. Cameron
2011-02-15 21:32 ` [PATCH 2/6] hpsa: make hpsa.hpsa_simple_mode=1 module parameter actually work Stephen M. Cameron
2011-02-15 21:32 ` [PATCH 3/6] hpsa: Add transport_mode host attribute in /sys Stephen M. Cameron
2011-02-15 21:33 ` [PATCH 4/6] hpsa: Inform controller we are using 32-bit tags Stephen M. Cameron
2011-02-15 21:33 ` [PATCH 5/6] hpsa: Do not attempt kdump if we detect resetting controller failed Stephen M. Cameron
2011-02-15 21:33 ` [PATCH 6/6] hpsa: fix bad comparison Stephen M. Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox