Skip to contentSkip to conversation

hpsa: fix a few more small things

PATCH In review Stephen M. Cameron 4 participants 9 messages Dec 8, 2009 – Dec 16, 2009

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover hpsa: fix a few more small things

Use msleep instead of schedlue_timeout, rename a few too-generic variable names, return SCSI_MLQUEUE_HOST_BUSY on command allocation failure, fix (again) incorrect SCSI status reporting, suppress noisy messages about unsupported SCSI REPORT LUNS.

---
These patches apply on top of the big hpsa patch already in Andrew Morton's tree.

Stephen M. Cameron (5):
Use msleep() instead of schedule_timeout
hpsa: rename too generic variable names
hpsa: Return SCSI_MLQUEUE_HOST_BUSY on command allocation failure.
hpsa: Fix incorrect SCSI status reporting
hpsa: suppress messages due to unsupport SCSI REPORT_LUNS

 drivers/scsi/hpsa.c |   93 +++++++++++++++++++++++++++------------------------
 drivers/scsi/hpsa.h |    4 +-
 2 files changed, 52 insertions(+), 45 deletions(-)

--
-- steve

#1 lore raw

PATCH 1/5 Use msleep() instead of schedule_timeout

From: Stephen M. Cameron <[email protected]>

Use msleep() instead of schedule_timeout

---
 drivers/scsi/hpsa.c |   27 ++++++++++++++-------------
 drivers/scsi/hpsa.h |    4 ++--
 2 files changed, 16 insertions(+), 15 deletions(-)
drivers/scsi/hpsa.c +14 -13
index 3c079a4..dc5e518 100644
@@ -1933,7 +1933,7 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
 {
 	int rc = 0;
 	int count = 0;
-	int waittime = HZ;
+	int waittime = 1; /* seconds */
 	struct CommandList *c;
 
 	c = cmd_special_alloc(h);
@@ -1950,11 +1950,11 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
 		 * the TUR right away, the reset will just abort it.
 		 */
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(waittime);
+		msleep(1000 * waittime);
 		count++;
 
 		/* Increase wait time with each try, up to a point. */
-		if (waittime < (HZ * HPSA_MAX_WAIT_INTERVAL_SECS))
+		if (waittime < HPSA_MAX_WAIT_INTERVAL_SECS)
 			waittime = waittime * 2;
 
 		/* Send the Test Unit Ready */
@@ -1972,7 +1972,7 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
 			break;
 
 		dev_warn(&h->pdev->dev, "waiting %d secs "
-			"for device to become ready.\n", waittime / HZ);
+			"for device to become ready.\n", waittime);
 		rc = 1; /* device not ready. */
 	}
 
@@ -2838,8 +2838,8 @@ static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
 		tag = readl(vaddr + SA5_REPLY_PORT_OFFSET);
 		if (HPSA_TAG_DISCARD_ERROR_BITS(tag) == paddr32)
 			break;
-		schedule_timeout_uninterruptible(
-			HPSA_MSG_SEND_RETRY_INTERVAL_SECS * HZ);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		msleep(HPSA_MSG_SEND_RETRY_INTERVAL_MSECS);
 	}
 
 	iounmap(vaddr);
@@ -2953,7 +2953,7 @@ static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev)
 	pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
 
 	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ >> 1);
+	msleep(500);
 
 	/* enter the D0 power management state */
 	pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
@@ -2961,7 +2961,7 @@ static __devinit int hpsa_hard_reset_controller(struct pci_dev *pdev)
 	pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
 
 	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ >> 1);
+	msleep(500);
 
 	/* Restore the PCI configuration space.  The Open CISS
 	 * Specification says, "Restore the PCI Configuration
@@ -3187,8 +3187,8 @@ static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
 		scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
 		if (scratchpad == HPSA_FIRMWARE_READY)
 			break;
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HPSA_BOARD_READY_POLL_INTERVAL);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		msleep(HPSA_BOARD_READY_POLL_INTERVAL_MSECS);
 	}
 	if (scratchpad != HPSA_FIRMWARE_READY) {
 		dev_warn(&pdev->dev, "board not ready, timed out.\n");
@@ -3262,8 +3262,8 @@ static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
 		if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
 			break;
 		/* delay and try again */
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(10);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		msleep(10);
 	}
 
 #ifdef HPSA_DEBUG
@@ -3302,7 +3302,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
 
 		/* Some devices (notably the HP Smart Array 5i Controller)
 		   need a little pause here */
-		schedule_timeout_uninterruptible(HPSA_POST_RESET_PAUSE);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		msleep(HPSA_POST_RESET_PAUSE_MSECS);
 
 		/* Now try to get the controller to respond to a no-op */
 		for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) {
drivers/scsi/hpsa.h +2 -2
index ffa8c50..6bd1949 100644
@@ -108,7 +108,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_SECS 1
+#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS 1000
 
 /* Maximum time in seconds driver will wait for command completions
  * when polling before giving up.
@@ -139,7 +139,7 @@ struct ctlr_info {
 #define HPSA_BOARD_READY_ITERATIONS \
 	((HPSA_BOARD_READY_WAIT_SECS * 1000) / \
 		HPSA_BOARD_READY_POLL_INTERVAL_MSECS)
-#define HPSA_POST_RESET_PAUSE (30 * HZ)
+#define HPSA_POST_RESET_PAUSE_MSECS (3000)
 #define HPSA_POST_RESET_NOOP_RETRIES (12)
 
 /*  Defining the diffent access_menthods */
#3 lore raw

Re: [PATCH 1/5] Use msleep() instead of schedule_timeout

In reply to Stephen M. Cameron
Quoted 1 line · On Tue, 08 Dec 2009 15:38:12 -0600 "Stephen M. Cameron"…

Use msleep() instead of schedule_timeout

msleep() does set_current_state() itself.

drivers/scsi/hpsa.c renamed from drivers/scsi/hpsa.c~hpsa-use-msleep-instead-of-schedule_timeout-fix +0 -7
@@ -1949,7 +1949,6 @@ static int wait_for_device_to_become_rea
 		/* Wait for a bit.  do this first, because if we send
 		 * the TUR right away, the reset will just abort it.
 		 */
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		msleep(1000 * waittime);
 		count++;
 
@@ -2838,7 +2837,6 @@ static __devinit int hpsa_message(struct
 		tag = readl(vaddr + SA5_REPLY_PORT_OFFSET);
 		if (HPSA_TAG_DISCARD_ERROR_BITS(tag) == paddr32)
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		msleep(HPSA_MSG_SEND_RETRY_INTERVAL_MSECS);
 	}
 
@@ -2952,7 +2950,6 @@ static __devinit int hpsa_hard_reset_con
 	pmcsr |= PCI_D3hot;
 	pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
 
-	set_current_state(TASK_UNINTERRUPTIBLE);
 	msleep(500);
 
 	/* enter the D0 power management state */
@@ -2960,7 +2957,6 @@ static __devinit int hpsa_hard_reset_con
 	pmcsr |= PCI_D0;
 	pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
 
-	set_current_state(TASK_UNINTERRUPTIBLE);
 	msleep(500);
 
 	/* Restore the PCI configuration space.  The Open CISS
@@ -3187,7 +3183,6 @@ static int hpsa_pci_init(struct ctlr_inf
 		scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
 		if (scratchpad == HPSA_FIRMWARE_READY)
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		msleep(HPSA_BOARD_READY_POLL_INTERVAL_MSECS);
 	}
 	if (scratchpad != HPSA_FIRMWARE_READY) {
@@ -3262,7 +3257,6 @@ static int hpsa_pci_init(struct ctlr_inf
 		if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
 			break;
 		/* delay and try again */
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		msleep(10);
 	}
 
@@ -3302,7 +3296,6 @@ static int __devinit hpsa_init_one(struc
 
 		/* Some devices (notably the HP Smart Array 5i Controller)
 		   need a little pause here */
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		msleep(HPSA_POST_RESET_PAUSE_MSECS);
 
 		/* Now try to get the controller to respond to a no-op */

diff -puN drivers/scsi/hpsa.h~hpsa-use-msleep-instead-of-schedule_timeout-fix drivers/scsi/hpsa.h _

#4 lore raw

PATCH 2/5 hpsa: rename too generic variable names

In reply to Stephen M. Cameron

From: Stephen M. Cameron <[email protected]>

hpsa: rename too generic variable names

---
 drivers/scsi/hpsa.c |   50 +++++++++++++++++++++++++++-----------------------
 1 files changed, 27 insertions(+), 23 deletions(-)
drivers/scsi/hpsa.c +27 -23
index dc5e518..8b8ddfc 100644
@@ -196,9 +196,9 @@ static inline struct ctlr_info *sdev_to_hba(struct scsi_device *sdev)
 }
 
 static struct task_struct *hpsa_scan_thread;
-static DEFINE_MUTEX(scan_mutex);
-static LIST_HEAD(scan_q);
-static int scan_thread(void *data);
+static DEFINE_MUTEX(hpsa_scan_mutex);
+static LIST_HEAD(hpsa_scan_q);
+static int hpsa_scan_func(void *data);
 
 /**
  * add_to_scan_list() - add controller to rescan queue
@@ -219,11 +219,15 @@ static int add_to_scan_list(struct ctlr_info *h)
 	if (h->busy_initializing)
 		return 0;
 
+	/*
+	 * If we don't get the lock, it means the driver is unloading
+	 * and there's no point in scheduling a new scan.
+	 */
 	if (!mutex_trylock(&h->busy_shutting_down))
 		return 0;
 
-	mutex_lock(&scan_mutex);
-	list_for_each_entry(test_h, &scan_q, scan_list) {
+	mutex_lock(&hpsa_scan_mutex);
+	list_for_each_entry(test_h, &hpsa_scan_q, scan_list) {
 		if (test_h == h) {
 			found = 1;
 			break;
@@ -231,10 +235,10 @@ static int add_to_scan_list(struct ctlr_info *h)
 	}
 	if (!found && !h->busy_scanning) {
 		INIT_COMPLETION(h->scan_wait);
-		list_add_tail(&h->scan_list, &scan_q);
+		list_add_tail(&h->scan_list, &hpsa_scan_q);
 		ret = 1;
 	}
-	mutex_unlock(&scan_mutex);
+	mutex_unlock(&hpsa_scan_mutex);
 	mutex_unlock(&h->busy_shutting_down);
 
 	return ret;
@@ -257,24 +261,24 @@ static void remove_from_scan_list(struct ctlr_info *h)
 {
 	struct ctlr_info *test_h, *tmp_h;
 
-	mutex_lock(&scan_mutex);
-	list_for_each_entry_safe(test_h, tmp_h, &scan_q, scan_list) {
+	mutex_lock(&hpsa_scan_mutex);
+	list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) {
 		if (test_h == h) { /* state 2. */
 			list_del(&h->scan_list);
 			complete_all(&h->scan_wait);
-			mutex_unlock(&scan_mutex);
+			mutex_unlock(&hpsa_scan_mutex);
 			return;
 		}
 	}
 	if (h->busy_scanning) { /* state 3. */
-		mutex_unlock(&scan_mutex);
+		mutex_unlock(&hpsa_scan_mutex);
 		wait_for_completion(&h->scan_wait);
 	} else { /* state 1, nothing to do. */
-		mutex_unlock(&scan_mutex);
+		mutex_unlock(&hpsa_scan_mutex);
 	}
 }
 
-/* scan_thread() - kernel thread used to rescan controllers
+/* hpsa_scan_func() - kernel thread used to rescan controllers
  * @data:	 Ignored.
  *
  * A kernel thread used scan for drive topology changes on
@@ -285,7 +289,7 @@ static void remove_from_scan_list(struct ctlr_info *h)
  *
  * returns 0.
  **/
-static int scan_thread(__attribute__((unused)) void *data)
+static int hpsa_scan_func(__attribute__((unused)) void *data)
 {
 	struct ctlr_info *h;
 	int host_no;
@@ -297,22 +301,22 @@ static int scan_thread(__attribute__((unused)) void *data)
 			break;
 
 		while (1) {
-			mutex_lock(&scan_mutex);
-			if (list_empty(&scan_q)) {
-				mutex_unlock(&scan_mutex);
+			mutex_lock(&hpsa_scan_mutex);
+			if (list_empty(&hpsa_scan_q)) {
+				mutex_unlock(&hpsa_scan_mutex);
 				break;
 			}
-			h = list_entry(scan_q.next, struct ctlr_info,
+			h = list_entry(hpsa_scan_q.next, struct ctlr_info,
 					scan_list);
 			list_del(&h->scan_list);
 			h->busy_scanning = 1;
-			mutex_unlock(&scan_mutex);
+			mutex_unlock(&hpsa_scan_mutex);
 			host_no = h->scsi_host ?  h->scsi_host->host_no : -1;
 			hpsa_update_scsi_devices(h, host_no);
 			complete_all(&h->scan_wait);
-			mutex_lock(&scan_mutex);
+			mutex_lock(&hpsa_scan_mutex);
 			h->busy_scanning = 0;
-			mutex_unlock(&scan_mutex);
+			mutex_unlock(&hpsa_scan_mutex);
 		}
 	}
 	return 0;
@@ -341,7 +345,7 @@ static int check_for_unit_attention(struct ctlr_info *h,
 	 * except that it's quite likely that we will get more than one
 	 * REPORT_LUNS_CHANGED condition in quick succession, which means
 	 * that those which occur after the first one will likely happen
-	 * *during* the scan_thread's rescan.  And the rescan code is not
+	 * *during* the hpsa_scan_thread's rescan.  And the rescan code is not
 	 * robust enough to restart in the middle, undoing what it has already
 	 * done, and it's not clear that it's even possible to do this, since
 	 * part of what it does is notify the SCSI mid layer, which starts
@@ -3511,7 +3515,7 @@ static int __init hpsa_init(void)
 {
 	int err;
 	/* Start the scan thread */
-	hpsa_scan_thread = kthread_run(scan_thread, NULL, "hpsa_scan");
+	hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan");
 	if (IS_ERR(hpsa_scan_thread)) {
 		err = PTR_ERR(hpsa_scan_thread);
 		return -ENODEV;
#5 lore raw

PATCH 3/5 hpsa: Return SCSI_MLQUEUE_HOST_BUSY on command allocation failure.

In reply to Stephen M. Cameron

From: Stephen M. Cameron <[email protected]>

hpsa: Return SCSI_MLQUEUE_HOST_BUSY on command allocation failure.

---
 drivers/scsi/hpsa.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)
drivers/scsi/hpsa.c +1 -3
index 8b8ddfc..0e696ee 100644
@@ -1842,9 +1842,7 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
 	spin_unlock_irqrestore(&h->lock, flags);
 	if (c == NULL) {			/* trouble... */
 		dev_err(&h->pdev->dev, "cmd_alloc returned NULL!\n");
-		cmd->result = DID_NO_CONNECT << 16;
-		done(cmd);
-		return 0;
+		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
 	/* Fill in the command list header */
#6 lore raw

PATCH 4/5 hpsa: Fix incorrect SCSI status reporting

In reply to Stephen M. Cameron

From: Stephen M. Cameron <[email protected]>

hpsa: Fix incorrect SCSI status reporting

---
 drivers/scsi/hpsa.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)
drivers/scsi/hpsa.c +1 -4
index 0e696ee..380236a 100644
@@ -930,7 +930,7 @@ static void complete_scsi_command(struct CommandList *cp,
 
 	cmd->result = (DID_OK << 16); 		/* host byte */
 	cmd->result |= (COMMAND_COMPLETE << 8);	/* msg byte */
-	cmd->result |= (ei->ScsiStatus);
+	cmd->result |= (ei->ScsiStatus << 1);
 
 	/* copy the sense data whether we need to or not. */
 	memcpy(cmd->sense_buffer, ei->SenseInfo,
@@ -991,7 +991,6 @@ static void complete_scsi_command(struct CommandList *cp,
 
 
 			/* Must be some other type of check condition */
-			cmd->result |= (ei->ScsiStatus << 1);
 			dev_warn(&h->pdev->dev, "cp %p has check condition: "
 					"unknown type: "
 					"Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, "
@@ -1013,8 +1012,6 @@ static void complete_scsi_command(struct CommandList *cp,
 		 * Pass it up to the upper layers...
 		 */
 		if (ei->ScsiStatus) {
-
-			cmd->result |= (ei->ScsiStatus << 1);
 			dev_warn(&h->pdev->dev, "cp %p has status 0x%x "
 				"Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, "
 				"Returning result: 0x%x\n",
#7 lore raw

Re: [PATCH 4/5] hpsa: Fix incorrect SCSI status reporting

Quoted 19 lines · Stephen M. Cameron

From: Stephen M. Cameron <[email protected]>
Subject: [PATCH 4/5] hpsa: Fix incorrect SCSI status reporting
To: [email protected], [email protected]
Cc: [email protected], [email protected], [email protected], [email protected]
Date: Tuesday, December 8, 2009, 3:38 PM
From: Stephen M. Cameron <[email protected]>

hpsa: Fix incorrect SCSI status reporting

---
 drivers/scsi/hpsa.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)
drivers/scsi/hpsa.c +0 -0
index 0e696ee..380236a 100644

drivers/scsi/hpsa.c static void · line 935

Quoted 7 lines
drivers/scsi/hpsa.c +1 -1
@@ -930,7 +930,7 @@ static void
 complete_scsi_command(struct CommandList *cp,
 
     cmd->result = (DID_OK << 16);
         /* host byte */
     cmd->result |= (COMMAND_COMPLETE << 8);    /* msg byte */
-    cmd->result |= (ei->ScsiStatus);
+    cmd->result |= (ei->ScsiStatus << 1);

I don't think this is correct.

I got fooled by some code in other drivers (3w-9xxx.c, gdth.c) which use CHECK_CONDITION, and shift it left 1, but I failed to notice that CHECK_CONDITION is defined to be 0x01, not 0x02.

Might be nice if there were some macros or helper functions for setting the status bytes in scsi.h (there are some for unpacking, but not for packing, but drivers mainly need to pack these, not unpack them.)

Will send a patch tomorrow in any case.

-- steve

Quoted 29 lines
drivers/scsi/hpsa.c +0 -0
     /* copy the sense data whether we need

to or not. */
    memcpy(cmd->sense_buffer,
ei->SenseInfo,

drivers/scsi/hpsa.c +0 -1
@@ -991,7 +991,6 @@ static void
 complete_scsi_command(struct CommandList *cp,
 
 
            
 /* Must be some other type of check condition */
-           
 cmd->result |= (ei->ScsiStatus << 1);


dev_warn(&h->pdev->dev, "cp %p has check
condition: "

        "unknown type: "

        "Sense: 0x%x, ASC:
0x%x, ASCQ: 0x%x, "

drivers/scsi/hpsa.c +0 -0
@@ -1013,8 +1012,6 @@ static void
 complete_scsi_command(struct CommandList *cp,
          * Pass it

up to the upper layers...
         */
        if
(ei->ScsiStatus) {
-

Quoted 10 lines

-
cmd->result |= (ei->ScsiStatus << 1);

dev_warn(&h->pdev->dev, "cp %p has status 0x%x "

    "Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, "

    "Returning result: 0x%x\n",

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#8 lore raw

PATCH 5/5 hpsa: suppress messages due to unsupport SCSI REPORT_LUNS

In reply to Stephen M. Cameron

From: Stephen M. Cameron <[email protected]>

hpsa: suppress messages due to unsupport SCSI REPORT_LUNS

---
 drivers/scsi/hpsa.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/scsi/hpsa.c +7 -0
index 380236a..22bca00 100644
@@ -964,6 +964,13 @@ static void complete_scsi_command(struct CommandList *cp,
 				break;
 			}
 			if (sense_key == ILLEGAL_REQUEST) {
+				/*
+				 * SCSI REPORT_LUNS is commonly unsupported on
+				 * Smart Array.  Suppress noisy complaint.
+				 */
+				if (cp->Request.CDB[0] == REPORT_LUNS)
+					break;
+
 				/* If ASC/ASCQ indicate Logical Unit
 				 * Not Supported condition,
 				 */