All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] hpsa: driver updates
@ 2010-02-25 20:02 Stephen M. Cameron
  2010-02-25 20:02 ` [PATCH 1/9] hpsa: allow modifying device queue depth Stephen M. Cameron
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Stephen M. Cameron @ 2010-02-25 20:02 UTC (permalink / raw)
  To: linux-scsi; +Cc: james.bottomley, mikem

The two biggest things are removal of the scan thread, and
support for more scatter gather entries.

Mike Miller (1):
      hpsa: remove scan thread

Stephen M. Cameron (8):
      hpsa: allow modifying device queue depth.
      hpsa: fix firmwart typo
      hpsa: fix scsi status mis-shift
      hpsa: return -ENOMEM, not -1
      hpsa: mark hpsa_pci_init as __devinit
      hpsa: Clarify calculation of padding for commandlist structure
      hpsa: Increase the number of scatter gather elements supported.
      hpsa: remove unused members next, prev, and retry_count from command list structure.


 drivers/scsi/hpsa.c     |  330 ++++++++++++++++++++++-------------------------
 drivers/scsi/hpsa.h     |    7 +
 drivers/scsi/hpsa_cmd.h |   20 ++-
 3 files changed, 168 insertions(+), 189 deletions(-)

-- 
-- steve

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

* [PATCH 1/9] hpsa: allow modifying device queue depth.
  2010-02-25 20:02 [PATCH 0/9] hpsa: driver updates Stephen M. Cameron
@ 2010-02-25 20:02 ` Stephen M. Cameron
  2010-02-25 20:02 ` [PATCH 2/9] hpsa: fix firmwart typo Stephen M. Cameron
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stephen M. Cameron @ 2010-02-25 20:02 UTC (permalink / raw)
  To: linux-scsi; +Cc: james.bottomley, mikem

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

hpsa: allow modifying device queue depth.

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 03697ba..745c624 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -43,6 +43,7 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 #include <linux/cciss_ioctl.h>
 #include <linux/string.h>
 #include <linux/bitmap.h>
@@ -134,6 +135,8 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
 static void hpsa_scan_start(struct Scsi_Host *);
 static int hpsa_scan_finished(struct Scsi_Host *sh,
 	unsigned long elapsed_time);
+static int hpsa_change_queue_depth(struct scsi_device *sdev,
+	int qdepth, int reason);
 
 static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
 static int hpsa_slave_alloc(struct scsi_device *sdev);
@@ -182,6 +185,7 @@ static struct scsi_host_template hpsa_driver_template = {
 	.queuecommand		= hpsa_scsi_queue_command,
 	.scan_start		= hpsa_scan_start,
 	.scan_finished		= hpsa_scan_finished,
+	.change_queue_depth	= hpsa_change_queue_depth,
 	.this_id		= -1,
 	.sg_tablesize		= MAXSGENTRIES,
 	.use_clustering		= ENABLE_CLUSTERING,
@@ -2077,6 +2081,23 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
 	return finished;
 }
 
+static int hpsa_change_queue_depth(struct scsi_device *sdev,
+	int qdepth, int reason)
+{
+	struct ctlr_info *h = sdev_to_hba(sdev);
+
+	if (reason != SCSI_QDEPTH_DEFAULT)
+		return -ENOTSUPP;
+
+	if (qdepth < 1)
+		qdepth = 1;
+	else
+		if (qdepth > h->nr_cmds)
+			qdepth = h->nr_cmds;
+	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	return sdev->queue_depth;
+}
+
 static void hpsa_unregister_scsi(struct ctlr_info *h)
 {
 	/* we are being forcibly unloaded, and may not refuse. */


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

* [PATCH 2/9] hpsa: fix firmwart typo
  2010-02-25 20:02 [PATCH 0/9] hpsa: driver updates Stephen M. Cameron
  2010-02-25 20:02 ` [PATCH 1/9] hpsa: allow modifying device queue depth Stephen M. Cameron
@ 2010-02-25 20:02 ` Stephen M. Cameron
  2010-02-25 20:03 ` [PATCH 3/9] hpsa: fix scsi status mis-shift Stephen M. Cameron
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stephen M. Cameron @ 2010-02-25 20:02 UTC (permalink / raw)
  To: linux-scsi; +Cc: james.bottomley, mikem

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

hpsa: fix firmwart typo

Signed-off-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 745c624..3734f31 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2982,7 +2982,7 @@ static irqreturn_t do_hpsa_intr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-/* Send a message CDB to the firmwart. */
+/* Send a message CDB to the firmware. */
 static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
 						unsigned char type)
 {


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

* [PATCH 3/9] hpsa: fix scsi status mis-shift
  2010-02-25 20:02 [PATCH 0/9] hpsa: driver updates Stephen M. Cameron
  2010-02-25 20:02 ` [PATCH 1/9] hpsa: allow modifying device queue depth Stephen M. Cameron
  2010-02-25 20:02 ` [PATCH 2/9] hpsa: fix firmwart typo Stephen M. Cameron
@ 2010-02-25 20:03 ` Stephen M. Cameron
  2010-02-25 20:03 ` [PATCH 4/9] hpsa: return -ENOMEM, not -1 Stephen M. Cameron
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stephen M. Cameron @ 2010-02-25 20:03 UTC (permalink / raw)
  To: linux-scsi; +Cc: james.bottomley, mikem

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

hpsa: fix scsi status mis-shift.  The SCSI status does not need to be shifted.

Signed-off-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 3734f31..604b4c9 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1006,7 +1006,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 << 1);
+	cmd->result |= ei->ScsiStatus;
 
 	/* copy the sense data whether we need to or not. */
 	memcpy(cmd->sense_buffer, ei->SenseInfo,


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

* [PATCH 4/9] hpsa: return -ENOMEM, not -1
  2010-02-25 20:02 [PATCH 0/9] hpsa: driver updates Stephen M. Cameron
                   ` (2 preceding siblings ...)
  2010-02-25 20:03 ` [PATCH 3/9] hpsa: fix scsi status mis-shift Stephen M. Cameron
@ 2010-02-25 20:03 ` Stephen M. Cameron
  2010-02-25 20:03 ` [PATCH 5/9] hpsa: remove scan thread Stephen M. Cameron
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stephen M. Cameron @ 2010-02-25 20:03 UTC (permalink / raw)
  To: linux-scsi; +Cc: james.bottomley, mikem

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

hpsa: return -ENOMEM, not -1

Signed-off-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 604b4c9..a72a18e 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1386,7 +1386,7 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr)
 
 	if (c == NULL) {			/* trouble... */
 		dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
-		return -1;
+		return -ENOMEM;
 	}
 
 	fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG);


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

* [PATCH 5/9] hpsa: remove scan thread
  2010-02-25 20:02 [PATCH 0/9] hpsa: driver updates Stephen M. Cameron
                   ` (3 preceding siblings ...)
  2010-02-25 20:03 ` [PATCH 4/9] hpsa: return -ENOMEM, not -1 Stephen M. Cameron
@ 2010-02-25 20:03 ` Stephen M. Cameron
  2010-02-25 20:03 ` [PATCH 6/9] hpsa: mark hpsa_pci_init as __devinit Stephen M. Cameron
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stephen M. Cameron @ 2010-02-25 20:03 UTC (permalink / raw)
  To: linux-scsi; +Cc: james.bottomley, mikem

From: Mike Miller <mikem@beardog.cce.hp.com>

hpsa: remove scan thread
The intent of the scan thread was to allow a UNIT ATTENTION/LUN
DATA CHANGED condition encountered in the interrupt handler
to trigger a rescan of devices, which can't be done in interrupt
context.  However, we weren't able to get this to work, due to
multiple such UNIT ATTENTION conditions arriving during the rescan,
during updating of the SCSI mid layer, etc.  There's no way to tell
the devices, "stand still while I scan you!"  Since it doesn't work,
there's no point in having the thread, as the rescan triggered via
ioctl or sysfs can be done without such a thread.

Signed-off-by: Mike Miller <mikem@beardog.cce.hp.com>
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
---
 drivers/scsi/hpsa.c |  167 +--------------------------------------------------
 drivers/scsi/hpsa.h |    3 -
 2 files changed, 4 insertions(+), 166 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a72a18e..3d43bb2 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -53,7 +53,7 @@
 #include "hpsa.h"
 
 /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
-#define HPSA_DRIVER_VERSION "2.0.1-3"
+#define HPSA_DRIVER_VERSION "2.0.2-1"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 
 /* How long to wait (in milliseconds) for board to go into simple mode */
@@ -212,133 +212,6 @@ static inline struct ctlr_info *shost_to_hba(struct Scsi_Host *sh)
 	return (struct ctlr_info *) *priv;
 }
 
-static struct task_struct *hpsa_scan_thread;
-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
- * @h:		      Pointer to the controller.
- *
- * Adds the controller to the rescan queue if not already on the queue.
- *
- * returns 1 if added to the queue, 0 if skipped (could be on the
- * queue already, or the controller could be initializing or shutting
- * down).
- **/
-static int add_to_scan_list(struct ctlr_info *h)
-{
-	struct ctlr_info *test_h;
-	int found = 0;
-	int ret = 0;
-
-	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(&hpsa_scan_mutex);
-	list_for_each_entry(test_h, &hpsa_scan_q, scan_list) {
-		if (test_h == h) {
-			found = 1;
-			break;
-		}
-	}
-	if (!found && !h->busy_scanning) {
-		INIT_COMPLETION(h->scan_wait);
-		list_add_tail(&h->scan_list, &hpsa_scan_q);
-		ret = 1;
-	}
-	mutex_unlock(&hpsa_scan_mutex);
-	mutex_unlock(&h->busy_shutting_down);
-
-	return ret;
-}
-
-/**
- * remove_from_scan_list() - remove controller from rescan queue
- * @h:			   Pointer to the controller.
- *
- * Removes the controller from the rescan queue if present. Blocks if
- * the controller is currently conducting a rescan.  The controller
- * can be in one of three states:
- * 1. Doesn't need a scan
- * 2. On the scan list, but not scanning yet (we remove it)
- * 3. Busy scanning (and not on the list). In this case we want to wait for
- *    the scan to complete to make sure the scanning thread for this
- *    controller is completely idle.
- **/
-static void remove_from_scan_list(struct ctlr_info *h)
-{
-	struct ctlr_info *test_h, *tmp_h;
-
-	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(&hpsa_scan_mutex);
-			return;
-		}
-	}
-	if (h->busy_scanning) { /* state 3. */
-		mutex_unlock(&hpsa_scan_mutex);
-		wait_for_completion(&h->scan_wait);
-	} else { /* state 1, nothing to do. */
-		mutex_unlock(&hpsa_scan_mutex);
-	}
-}
-
-/* hpsa_scan_func() - kernel thread used to rescan controllers
- * @data:	 Ignored.
- *
- * A kernel thread used scan for drive topology changes on
- * controllers. The thread processes only one controller at a time
- * using a queue.  Controllers are added to the queue using
- * add_to_scan_list() and removed from the queue either after done
- * processing or using remove_from_scan_list().
- *
- * returns 0.
- **/
-static int hpsa_scan_func(__attribute__((unused)) void *data)
-{
-	struct ctlr_info *h;
-	int host_no;
-
-	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule();
-		if (kthread_should_stop())
-			break;
-
-		while (1) {
-			mutex_lock(&hpsa_scan_mutex);
-			if (list_empty(&hpsa_scan_q)) {
-				mutex_unlock(&hpsa_scan_mutex);
-				break;
-			}
-			h = list_entry(hpsa_scan_q.next, struct ctlr_info,
-					scan_list);
-			list_del(&h->scan_list);
-			h->busy_scanning = 1;
-			mutex_unlock(&hpsa_scan_mutex);
-			host_no = h->scsi_host ?  h->scsi_host->host_no : -1;
-			hpsa_scan_start(h->scsi_host);
-			complete_all(&h->scan_wait);
-			mutex_lock(&hpsa_scan_mutex);
-			h->busy_scanning = 0;
-			mutex_unlock(&hpsa_scan_mutex);
-		}
-	}
-	return 0;
-}
-
 static int check_for_unit_attention(struct ctlr_info *h,
 	struct CommandList *c)
 {
@@ -356,21 +229,8 @@ static int check_for_unit_attention(struct ctlr_info *h,
 		break;
 	case REPORT_LUNS_CHANGED:
 		dev_warn(&h->pdev->dev, "hpsa%d: report LUN data "
-			"changed\n", h->ctlr);
+			"changed, action required\n", h->ctlr);
 	/*
-	 * Here, we could call add_to_scan_list and wake up the scan thread,
-	 * 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 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
-	 * doing it's own i/o to read partition tables and so on, and the
-	 * driver doesn't have visibility to know what might need undoing.
-	 * In any event, if possible, it is horribly complicated to get right
-	 * so we just don't do it for now.
-	 *
 	 * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012.
 	 */
 		break;
@@ -397,10 +257,7 @@ static ssize_t host_store_rescan(struct device *dev,
 	struct ctlr_info *h;
 	struct Scsi_Host *shost = class_to_shost(dev);
 	h = shost_to_hba(shost);
-	if (add_to_scan_list(h)) {
-		wake_up_process(hpsa_scan_thread);
-		wait_for_completion_interruptible(&h->scan_wait);
-	}
+	hpsa_scan_start(h->scsi_host);
 	return count;
 }
 
@@ -3553,8 +3410,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
 	h->busy_initializing = 1;
 	INIT_HLIST_HEAD(&h->cmpQ);
 	INIT_HLIST_HEAD(&h->reqQ);
-	mutex_init(&h->busy_shutting_down);
-	init_completion(&h->scan_wait);
 	rc = hpsa_pci_init(h, pdev);
 	if (rc != 0)
 		goto clean1;
@@ -3702,8 +3557,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
 		return;
 	}
 	h = pci_get_drvdata(pdev);
-	mutex_lock(&h->busy_shutting_down);
-	remove_from_scan_list(h);
 	hpsa_unregister_scsi(h);	/* unhook from SCSI subsystem */
 	hpsa_shutdown(pdev);
 	iounmap(h->vaddr);
@@ -3724,7 +3577,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
 	 */
 	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
-	mutex_unlock(&h->busy_shutting_down);
 	kfree(h);
 }
 
@@ -3878,23 +3730,12 @@ clean_up:
  */
 static int __init hpsa_init(void)
 {
-	int err;
-	/* Start the scan thread */
-	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;
-	}
-	err = pci_register_driver(&hpsa_pci_driver);
-	if (err)
-		kthread_stop(hpsa_scan_thread);
-	return err;
+	return pci_register_driver(&hpsa_pci_driver);
 }
 
 static void __exit hpsa_cleanup(void)
 {
 	pci_unregister_driver(&hpsa_pci_driver);
-	kthread_stop(hpsa_scan_thread);
 }
 
 module_init(hpsa_init);
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index a0502b3..fc15215 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -97,9 +97,6 @@ struct ctlr_info {
 	int			scan_finished;
 	spinlock_t		scan_lock;
 	wait_queue_head_t	scan_wait_queue;
-	struct mutex		busy_shutting_down;
-	struct list_head	scan_list;
-	struct completion	scan_wait;
 
 	struct Scsi_Host *scsi_host;
 	spinlock_t devlock; /* to protect hba[ctlr]->dev[];  */


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

* [PATCH 6/9] hpsa: mark hpsa_pci_init as __devinit
  2010-02-25 20:02 [PATCH 0/9] hpsa: driver updates Stephen M. Cameron
                   ` (4 preceding siblings ...)
  2010-02-25 20:03 ` [PATCH 5/9] hpsa: remove scan thread Stephen M. Cameron
@ 2010-02-25 20:03 ` Stephen M. Cameron
  2010-02-25 20:03 ` [PATCH 7/9] hpsa: Clarify calculation of padding for commandlist structure Stephen M. Cameron
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Stephen M. Cameron @ 2010-02-25 20:03 UTC (permalink / raw)
  To: linux-scsi; +Cc: james.bottomley, mikem

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

hpsa: mark hpsa_pci_init as __devinit

Signed-off-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 3d43bb2..2e1edce 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3174,7 +3174,7 @@ default_int_mode:
 	h->intr[PERF_MODE_INT] = pdev->irq;
 }
 
-static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
+static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
 {
 	ushort subsystem_vendor_id, subsystem_device_id, command;
 	u32 board_id, scratchpad = 0;


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

* [PATCH 7/9] hpsa: Clarify calculation of padding for commandlist structure
  2010-02-25 20:02 [PATCH 0/9] hpsa: driver updates Stephen M. Cameron
                   ` (5 preceding siblings ...)
  2010-02-25 20:03 ` [PATCH 6/9] hpsa: mark hpsa_pci_init as __devinit Stephen M. Cameron
@ 2010-02-25 20:03 ` Stephen M. Cameron
  2010-02-25 20:03 ` [PATCH 8/9] hpsa: Increase the number of scatter gather elements supported Stephen M. Cameron
  2010-02-25 20:03 ` [PATCH 9/9] hpsa: remove unused members next, prev, and retry_count from command list structure Stephen M. Cameron
  8 siblings, 0 replies; 10+ messages in thread
From: Stephen M. Cameron @ 2010-02-25 20:03 UTC (permalink / raw)
  To: linux-scsi; +Cc: james.bottomley, mikem

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

hpsa: Clarify calculation of padding for commandlist structure

Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
---
 drivers/scsi/hpsa_cmd.h |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 3e0abdf..43b6f1c 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -313,12 +313,18 @@ struct CommandList {
 	void   *scsi_cmd;
 
 /* on 64 bit architectures, to get this to be 32-byte-aligned
- * it so happens we need no padding, on 32 bit systems,
- * we need 8 bytes of padding.   This does that.
+ * it so happens we need PAD_64 bytes of padding, on 32 bit systems,
+ * we need PAD_32 bytes of padding (see below).   This does that.
+ * If it happens that 64 bit and 32 bit systems need different
+ * padding, PAD_32 and PAD_64 can be set independently, and.
+ * the code below will do the right thing.
  */
-#define COMMANDLIST_PAD ((8 - sizeof(long))/4 * 8)
+#define IS_32_BIT ((8 - sizeof(long))/4)
+#define IS_64_BIT (!IS_32_BIT)
+#define PAD_32 (8)
+#define PAD_64 (0)
+#define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64)
 	u8 pad[COMMANDLIST_PAD];
-
 };
 
 /* Configuration Table Structure */


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

* [PATCH 8/9] hpsa: Increase the number of scatter gather elements supported.
  2010-02-25 20:02 [PATCH 0/9] hpsa: driver updates Stephen M. Cameron
                   ` (6 preceding siblings ...)
  2010-02-25 20:03 ` [PATCH 7/9] hpsa: Clarify calculation of padding for commandlist structure Stephen M. Cameron
@ 2010-02-25 20:03 ` Stephen M. Cameron
  2010-02-25 20:03 ` [PATCH 9/9] hpsa: remove unused members next, prev, and retry_count from command list structure Stephen M. Cameron
  8 siblings, 0 replies; 10+ messages in thread
From: Stephen M. Cameron @ 2010-02-25 20:03 UTC (permalink / raw)
  To: linux-scsi; +Cc: james.bottomley, mikem

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

hpsa: Increase the number of scatter gather elements supported.
This uses the scatter-gather chaining feature of Smart Array
controllers.  32 scatter-gather elements are embedded in the
"command list", and the last element in the list may be marked
as a "chain pointer", and point to an additional block of
scatter gather elements.  The precise number of scatter gather
elements supported is dependent on the particular kind of
Smart Array, and is determined at runtime by querying the
hardware.

Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
---
 drivers/scsi/hpsa.c     |  134 +++++++++++++++++++++++++++++++++++++++++++----
 drivers/scsi/hpsa.h     |    4 +
 drivers/scsi/hpsa_cmd.h |    7 +-
 3 files changed, 131 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 2e1edce..183d3a4 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -187,7 +187,6 @@ static struct scsi_host_template hpsa_driver_template = {
 	.scan_finished		= hpsa_scan_finished,
 	.change_queue_depth	= hpsa_change_queue_depth,
 	.this_id		= -1,
-	.sg_tablesize		= MAXSGENTRIES,
 	.use_clustering		= ENABLE_CLUSTERING,
 	.eh_device_reset_handler = hpsa_eh_device_reset_handler,
 	.ioctl			= hpsa_ioctl,
@@ -844,6 +843,76 @@ static void hpsa_scsi_setup(struct ctlr_info *h)
 	spin_lock_init(&h->devlock);
 }
 
+static void hpsa_free_sg_chain_blocks(struct ctlr_info *h)
+{
+	int i;
+
+	if (!h->cmd_sg_list)
+		return;
+	for (i = 0; i < h->nr_cmds; i++) {
+		kfree(h->cmd_sg_list[i]);
+		h->cmd_sg_list[i] = NULL;
+	}
+	kfree(h->cmd_sg_list);
+	h->cmd_sg_list = NULL;
+}
+
+static int hpsa_allocate_sg_chain_blocks(struct ctlr_info *h)
+{
+	int i;
+
+	if (h->chainsize <= 0)
+		return 0;
+
+	h->cmd_sg_list = kzalloc(sizeof(*h->cmd_sg_list) * h->nr_cmds,
+				GFP_KERNEL);
+	if (!h->cmd_sg_list)
+		return -ENOMEM;
+	for (i = 0; i < h->nr_cmds; i++) {
+		h->cmd_sg_list[i] = kmalloc(sizeof(*h->cmd_sg_list[i]) *
+						h->chainsize, GFP_KERNEL);
+		if (!h->cmd_sg_list[i])
+			goto clean;
+	}
+	return 0;
+
+clean:
+	hpsa_free_sg_chain_blocks(h);
+	return -ENOMEM;
+}
+
+static void hpsa_map_sg_chain_block(struct ctlr_info *h,
+	struct CommandList *c)
+{
+	struct SGDescriptor *chain_sg, *chain_block;
+	u64 temp64;
+
+	chain_sg = &c->SG[h->max_cmd_sg_entries - 1];
+	chain_block = h->cmd_sg_list[c->cmdindex];
+	chain_sg->Ext = HPSA_SG_CHAIN;
+	chain_sg->Len = sizeof(*chain_sg) *
+		(c->Header.SGTotal - h->max_cmd_sg_entries);
+	temp64 = pci_map_single(h->pdev, chain_block, chain_sg->Len,
+				PCI_DMA_TODEVICE);
+	chain_sg->Addr.lower = (u32) (temp64 & 0x0FFFFFFFFULL);
+	chain_sg->Addr.upper = (u32) ((temp64 >> 32) & 0x0FFFFFFFFULL);
+}
+
+static void hpsa_unmap_sg_chain_block(struct ctlr_info *h,
+	struct CommandList *c)
+{
+	struct SGDescriptor *chain_sg;
+	union u64bit temp64;
+
+	if (c->Header.SGTotal <= h->max_cmd_sg_entries)
+		return;
+
+	chain_sg = &c->SG[h->max_cmd_sg_entries - 1];
+	temp64.val32.lower = chain_sg->Addr.lower;
+	temp64.val32.upper = chain_sg->Addr.upper;
+	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)
 {
@@ -860,6 +929,8 @@ static void complete_scsi_command(struct CommandList *cp,
 	h = cp->h;
 
 	scsi_dma_unmap(cmd); /* undo the DMA mappings */
+	if (cp->Header.SGTotal > h->max_cmd_sg_entries)
+		hpsa_unmap_sg_chain_block(h, cp);
 
 	cmd->result = (DID_OK << 16); 		/* host byte */
 	cmd->result |= (COMMAND_COMPLETE << 8);	/* msg byte */
@@ -1064,6 +1135,7 @@ static int hpsa_scsi_detect(struct ctlr_info *h)
 	sh->max_id = HPSA_MAX_LUN;
 	sh->can_queue = h->nr_cmds;
 	sh->cmd_per_lun = h->nr_cmds;
+	sh->sg_tablesize = h->maxsgentries;
 	h->scsi_host = sh;
 	sh->hostdata[0] = (unsigned long) h;
 	sh->irq = h->intr[PERF_MODE_INT];
@@ -1765,16 +1837,17 @@ out:
  * dma mapping  and fills in the scatter gather entries of the
  * hpsa command, cp.
  */
-static int hpsa_scatter_gather(struct pci_dev *pdev,
+static int hpsa_scatter_gather(struct ctlr_info *h,
 		struct CommandList *cp,
 		struct scsi_cmnd *cmd)
 {
 	unsigned int len;
 	struct scatterlist *sg;
 	u64 addr64;
-	int use_sg, i;
+	int use_sg, i, sg_index, chained;
+	struct SGDescriptor *curr_sg;
 
-	BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
+	BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
 
 	use_sg = scsi_dma_map(cmd);
 	if (use_sg < 0)
@@ -1783,15 +1856,33 @@ static int hpsa_scatter_gather(struct pci_dev *pdev,
 	if (!use_sg)
 		goto sglist_finished;
 
+	curr_sg = cp->SG;
+	chained = 0;
+	sg_index = 0;
 	scsi_for_each_sg(cmd, sg, use_sg, i) {
+		if (i == h->max_cmd_sg_entries - 1 &&
+			use_sg > h->max_cmd_sg_entries) {
+			chained = 1;
+			curr_sg = h->cmd_sg_list[cp->cmdindex];
+			sg_index = 0;
+		}
 		addr64 = (u64) sg_dma_address(sg);
 		len  = sg_dma_len(sg);
-		cp->SG[i].Addr.lower =
-			(u32) (addr64 & (u64) 0x00000000FFFFFFFF);
-		cp->SG[i].Addr.upper =
-			(u32) ((addr64 >> 32) & (u64) 0x00000000FFFFFFFF);
-		cp->SG[i].Len = len;
-		cp->SG[i].Ext = 0;  /* we are not chaining */
+		curr_sg->Addr.lower = (u32) (addr64 & 0x0FFFFFFFFULL);
+		curr_sg->Addr.upper = (u32) ((addr64 >> 32) & 0x0FFFFFFFFULL);
+		curr_sg->Len = len;
+		curr_sg->Ext = 0;  /* we are not chaining */
+		curr_sg++;
+	}
+
+	if (use_sg + chained > h->maxSG)
+		h->maxSG = use_sg + chained;
+
+	if (chained) {
+		cp->Header.SGList = h->max_cmd_sg_entries;
+		cp->Header.SGTotal = (u16) (use_sg + 1);
+		hpsa_map_sg_chain_block(h, cp);
+		return 0;
 	}
 
 sglist_finished:
@@ -1887,7 +1978,7 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
 		break;
 	}
 
-	if (hpsa_scatter_gather(h->pdev, c, cmd) < 0) { /* Fill SG list */
+	if (hpsa_scatter_gather(h, c, cmd) < 0) { /* Fill SG list */
 		cmd_free(h, c);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
@@ -3283,6 +3374,23 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev)
 
 	h->board_id = board_id;
 	h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+	h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements));
+
+	/*
+	 * Limit in-command s/g elements to 32 save dma'able memory.
+	 * Howvever spec says if 0, use 31
+	 */
+
+	h->max_cmd_sg_entries = 31;
+	if (h->maxsgentries > 512) {
+		h->max_cmd_sg_entries = 32;
+		h->chainsize = h->maxsgentries - h->max_cmd_sg_entries + 1;
+		h->maxsgentries--; /* save one for chain pointer */
+	} else {
+		h->maxsgentries = 31; /* default to traditional values */
+		h->chainsize = 0;
+	}
+
 	h->product_name = products[prod_index].product_name;
 	h->access = *(products[prod_index].access);
 	/* Allow room for some ioctls */
@@ -3463,6 +3571,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
 		rc = -ENOMEM;
 		goto clean4;
 	}
+	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);
@@ -3485,6 +3595,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev,
 	return 1;
 
 clean4:
+	hpsa_free_sg_chain_blocks(h);
 	kfree(h->cmd_pool_bits);
 	if (h->cmd_pool)
 		pci_free_consistent(h->pdev,
@@ -3560,6 +3671,7 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
 	hpsa_unregister_scsi(h);	/* unhook from SCSI subsystem */
 	hpsa_shutdown(pdev);
 	iounmap(h->vaddr);
+	hpsa_free_sg_chain_blocks(h);
 	pci_free_consistent(h->pdev,
 		h->nr_cmds * sizeof(struct CommandList),
 		h->cmd_pool, h->cmd_pool_dhandle);
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index fc15215..1bb5233 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -83,6 +83,10 @@ struct ctlr_info {
 	unsigned int maxQsinceinit;
 	unsigned int maxSG;
 	spinlock_t lock;
+	int maxsgentries;
+	u8 max_cmd_sg_entries;
+	int chainsize;
+	struct SGDescriptor **cmd_sg_list;
 
 	/* pointers to command and error info pool */
 	struct CommandList 	*cmd_pool;
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 43b6f1c..cb0c238 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -23,7 +23,8 @@
 
 /* general boundary defintions */
 #define SENSEINFOBYTES          32 /* may vary between hbas */
-#define MAXSGENTRIES            31
+#define MAXSGENTRIES            32
+#define HPSA_SG_CHAIN		0x80000000
 #define MAXREPLYQS              256
 
 /* Command Status value */
@@ -321,8 +322,8 @@ struct CommandList {
  */
 #define IS_32_BIT ((8 - sizeof(long))/4)
 #define IS_64_BIT (!IS_32_BIT)
-#define PAD_32 (8)
-#define PAD_64 (0)
+#define PAD_32 (24)
+#define PAD_64 (16)
 #define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64)
 	u8 pad[COMMANDLIST_PAD];
 };


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

* [PATCH 9/9] hpsa: remove unused members next, prev, and retry_count from command list structure.
  2010-02-25 20:02 [PATCH 0/9] hpsa: driver updates Stephen M. Cameron
                   ` (7 preceding siblings ...)
  2010-02-25 20:03 ` [PATCH 8/9] hpsa: Increase the number of scatter gather elements supported Stephen M. Cameron
@ 2010-02-25 20:03 ` Stephen M. Cameron
  8 siblings, 0 replies; 10+ messages in thread
From: Stephen M. Cameron @ 2010-02-25 20:03 UTC (permalink / raw)
  To: linux-scsi; +Cc: james.bottomley, mikem

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

hpsa: remove unused members next, prev, and retry_count from command list structure.

Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
---
 drivers/scsi/hpsa_cmd.h |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index cb0c238..56fb982 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -306,11 +306,8 @@ struct CommandList {
 	int			   cmd_type;
 	long			   cmdindex;
 	struct hlist_node list;
-	struct CommandList *prev;
-	struct CommandList *next;
 	struct request *rq;
 	struct completion *waiting;
-	int	 retry_count;
 	void   *scsi_cmd;
 
 /* on 64 bit architectures, to get this to be 32-byte-aligned
@@ -322,8 +319,8 @@ struct CommandList {
  */
 #define IS_32_BIT ((8 - sizeof(long))/4)
 #define IS_64_BIT (!IS_32_BIT)
-#define PAD_32 (24)
-#define PAD_64 (16)
+#define PAD_32 (4)
+#define PAD_64 (4)
 #define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64)
 	u8 pad[COMMANDLIST_PAD];
 };


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

end of thread, other threads:[~2010-02-25 20:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-25 20:02 [PATCH 0/9] hpsa: driver updates Stephen M. Cameron
2010-02-25 20:02 ` [PATCH 1/9] hpsa: allow modifying device queue depth Stephen M. Cameron
2010-02-25 20:02 ` [PATCH 2/9] hpsa: fix firmwart typo Stephen M. Cameron
2010-02-25 20:03 ` [PATCH 3/9] hpsa: fix scsi status mis-shift Stephen M. Cameron
2010-02-25 20:03 ` [PATCH 4/9] hpsa: return -ENOMEM, not -1 Stephen M. Cameron
2010-02-25 20:03 ` [PATCH 5/9] hpsa: remove scan thread Stephen M. Cameron
2010-02-25 20:03 ` [PATCH 6/9] hpsa: mark hpsa_pci_init as __devinit Stephen M. Cameron
2010-02-25 20:03 ` [PATCH 7/9] hpsa: Clarify calculation of padding for commandlist structure Stephen M. Cameron
2010-02-25 20:03 ` [PATCH 8/9] hpsa: Increase the number of scatter gather elements supported Stephen M. Cameron
2010-02-25 20:03 ` [PATCH 9/9] hpsa: remove unused members next, prev, and retry_count from command list structure Stephen M. Cameron

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.