All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] hpsa: supplemental February 2014 driver updates
@ 2014-02-21 22:24 Stephen M. Cameron
  2014-02-21 22:24 ` [PATCH 1/6] hpsa: remove unused kthread.h header Stephen M. Cameron
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2014-02-21 22:24 UTC (permalink / raw)
  To: james.bottomley
  Cc: martin.petersen, linux-scsi, stephenmcameron, joseph.t.handzik,
	thenzl, michael.miller, scott.teel

The following series applies on top of the 35 patches I sent on Feb 18
(see http://thread.gmane.org/gmane.linux.scsi/88433 )

The two main changes are to bring temporarily offline devices
(e.g. logical drives undergoing "rapid parity initialization")
online automatically when they become ready, and adding support
for "hba mode" for controllers which support this feature,
to expose physical disks to the OS.

---

Stephen M. Cameron (5):
      hpsa: remove unused kthread.h header
      hpsa: bring format-in-progress drives online when ready
      hpsa: remove unused struct request from CommandList
      hpsa: Add hba mode to the hpsa driver
      hpsa: Do not zero fields of ioaccel2 command structure twice

Tomas Henzl (1):
      hpsa: increase the probability of a reported success after a device reset


 drivers/scsi/hpsa.c     |  410 +++++++++++++++++++++++++++++++++++++++++++----
 drivers/scsi/hpsa.h     |   50 ++++++
 drivers/scsi/hpsa_cmd.h |   21 ++
 3 files changed, 446 insertions(+), 35 deletions(-)

-- 
-- steve


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

* [PATCH 1/6] hpsa: remove unused kthread.h header
  2014-02-21 22:24 [PATCH 0/6] hpsa: supplemental February 2014 driver updates Stephen M. Cameron
@ 2014-02-21 22:24 ` Stephen M. Cameron
  2014-02-21 22:25 ` [PATCH 2/6] hpsa: bring format-in-progress drives online when ready Stephen M. Cameron
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2014-02-21 22:24 UTC (permalink / raw)
  To: james.bottomley
  Cc: martin.petersen, linux-scsi, stephenmcameron, joseph.t.handzik,
	thenzl, michael.miller, scott.teel

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

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9f593b9..cb984c2 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -47,7 +47,6 @@
 #include <linux/string.h>
 #include <linux/bitmap.h>
 #include <linux/atomic.h>
-#include <linux/kthread.h>
 #include <linux/jiffies.h>
 #include <asm/div64.h>
 #include "hpsa_cmd.h"


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

* [PATCH 2/6] hpsa: bring format-in-progress drives online when ready
  2014-02-21 22:24 [PATCH 0/6] hpsa: supplemental February 2014 driver updates Stephen M. Cameron
  2014-02-21 22:24 ` [PATCH 1/6] hpsa: remove unused kthread.h header Stephen M. Cameron
@ 2014-02-21 22:25 ` Stephen M. Cameron
  2014-02-21 22:25 ` [PATCH 3/6] hpsa: increase the probability of a reported success after a device reset Stephen M. Cameron
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2014-02-21 22:25 UTC (permalink / raw)
  To: james.bottomley
  Cc: martin.petersen, linux-scsi, stephenmcameron, joseph.t.handzik,
	thenzl, michael.miller, scott.teel

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

Do not expose drives that are undergoing a format immediately
to the OS, instead wait until they are ready before bringing
them online.  This is so that logical drives created with
"rapid parity initialization" do not get immediately kicked
off the system for being unresponsive.

Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
---
 drivers/scsi/hpsa.c     |  311 +++++++++++++++++++++++++++++++++++++++++++----
 drivers/scsi/hpsa.h     |    9 +
 drivers/scsi/hpsa_cmd.h |   15 ++
 3 files changed, 311 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index cb984c2..a0fcaa6 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1133,6 +1133,9 @@ static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle,
 					return DEVICE_UPDATED;
 				return DEVICE_SAME;
 			} else {
+				/* Keep offline devices offline */
+				if (needle->volume_offline)
+					return DEVICE_NOT_FOUND;
 				return DEVICE_CHANGED;
 			}
 		}
@@ -1141,6 +1144,110 @@ static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle,
 	return DEVICE_NOT_FOUND;
 }
 
+static void hpsa_monitor_offline_device(struct ctlr_info *h,
+					unsigned char scsi3addr[])
+{
+	struct offline_device_entry *device;
+	unsigned long flags;
+
+	/* Check to see if device is already on the list */
+	spin_lock_irqsave(&h->offline_device_lock, flags);
+	list_for_each_entry(device, &h->offline_device_list, offline_list) {
+		if (memcmp(device->scsi3addr, scsi3addr,
+			sizeof(device->scsi3addr)) == 0) {
+			spin_unlock_irqrestore(&h->offline_device_lock, flags);
+			return;
+		}
+	}
+	spin_unlock_irqrestore(&h->offline_device_lock, flags);
+
+	/* Device is not on the list, add it. */
+	device = kmalloc(sizeof(*device), GFP_KERNEL);
+	if (!device) {
+		dev_warn(&h->pdev->dev, "out of memory in %s\n", __func__);
+		return;
+	}
+	memcpy(device->scsi3addr, scsi3addr, sizeof(device->scsi3addr));
+	spin_lock_irqsave(&h->offline_device_lock, flags);
+	list_add_tail(&device->offline_list, &h->offline_device_list);
+	spin_unlock_irqrestore(&h->offline_device_lock, flags);
+}
+
+/* Print a message explaining various offline volume states */
+static void hpsa_show_volume_status(struct ctlr_info *h,
+	struct hpsa_scsi_dev_t *sd)
+{
+	if (sd->volume_offline == HPSA_VPD_LV_STATUS_UNSUPPORTED)
+		dev_info(&h->pdev->dev,
+			"C%d:B%d:T%d:L%d Volume status is not available through vital product data pages.\n",
+			h->scsi_host->host_no,
+			sd->bus, sd->target, sd->lun);
+	switch (sd->volume_offline) {
+	case HPSA_LV_OK:
+		break;
+	case HPSA_LV_UNDERGOING_ERASE:
+		dev_info(&h->pdev->dev,
+			"C%d:B%d:T%d:L%d Volume is undergoing background erase process.\n",
+			h->scsi_host->host_no,
+			sd->bus, sd->target, sd->lun);
+		break;
+	case HPSA_LV_UNDERGOING_RPI:
+		dev_info(&h->pdev->dev,
+			"C%d:B%d:T%d:L%d Volume is undergoing rapid parity initialization process.\n",
+			h->scsi_host->host_no,
+			sd->bus, sd->target, sd->lun);
+		break;
+	case HPSA_LV_PENDING_RPI:
+		dev_info(&h->pdev->dev,
+				"C%d:B%d:T%d:L%d Volume is queued for rapid parity initialization process.\n",
+				h->scsi_host->host_no,
+				sd->bus, sd->target, sd->lun);
+		break;
+	case HPSA_LV_ENCRYPTED_NO_KEY:
+		dev_info(&h->pdev->dev,
+			"C%d:B%d:T%d:L%d Volume is encrypted and cannot be accessed because key is not present.\n",
+			h->scsi_host->host_no,
+			sd->bus, sd->target, sd->lun);
+		break;
+	case HPSA_LV_PLAINTEXT_IN_ENCRYPT_ONLY_CONTROLLER:
+		dev_info(&h->pdev->dev,
+			"C%d:B%d:T%d:L%d Volume is not encrypted and cannot be accessed because controller is in encryption-only mode.\n",
+			h->scsi_host->host_no,
+			sd->bus, sd->target, sd->lun);
+		break;
+	case HPSA_LV_UNDERGOING_ENCRYPTION:
+		dev_info(&h->pdev->dev,
+			"C%d:B%d:T%d:L%d Volume is undergoing encryption process.\n",
+			h->scsi_host->host_no,
+			sd->bus, sd->target, sd->lun);
+		break;
+	case HPSA_LV_UNDERGOING_ENCRYPTION_REKEYING:
+		dev_info(&h->pdev->dev,
+			"C%d:B%d:T%d:L%d Volume is undergoing encryption re-keying process.\n",
+			h->scsi_host->host_no,
+			sd->bus, sd->target, sd->lun);
+		break;
+	case HPSA_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER:
+		dev_info(&h->pdev->dev,
+			"C%d:B%d:T%d:L%d Volume is encrypted and cannot be accessed because controller does not have encryption enabled.\n",
+			h->scsi_host->host_no,
+			sd->bus, sd->target, sd->lun);
+		break;
+	case HPSA_LV_PENDING_ENCRYPTION:
+		dev_info(&h->pdev->dev,
+			"C%d:B%d:T%d:L%d Volume is pending migration to encrypted state, but process has not started.\n",
+			h->scsi_host->host_no,
+			sd->bus, sd->target, sd->lun);
+		break;
+	case HPSA_LV_PENDING_ENCRYPTION_REKEYING:
+		dev_info(&h->pdev->dev,
+			"C%d:B%d:T%d:L%d Volume is encrypted and is pending encryption rekeying.\n",
+			h->scsi_host->host_no,
+			sd->bus, sd->target, sd->lun);
+		break;
+	}
+}
+
 static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
 	struct hpsa_scsi_dev_t *sd[], int nsds)
 {
@@ -1205,6 +1312,20 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
 	for (i = 0; i < nsds; i++) {
 		if (!sd[i]) /* if already added above. */
 			continue;
+
+		/* Don't add devices which are NOT READY, FORMAT IN PROGRESS
+		 * as the SCSI mid-layer does not handle such devices well.
+		 * It relentlessly loops sending TUR at 3Hz, then READ(10)
+		 * at 160Hz, and prevents the system from coming up.
+		 */
+		if (sd[i]->volume_offline) {
+			hpsa_show_volume_status(h, sd[i]);
+			dev_info(&h->pdev->dev, "c%db%dt%dl%d: temporarily offline\n",
+				h->scsi_host->host_no,
+				sd[i]->bus, sd[i]->target, sd[i]->lun);
+			continue;
+		}
+
 		device_change = hpsa_scsi_find_entry(sd[i], h->dev,
 					h->ndevices, &entry);
 		if (device_change == DEVICE_NOT_FOUND) {
@@ -1223,6 +1344,17 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
 	}
 	spin_unlock_irqrestore(&h->devlock, flags);
 
+	/* Monitor devices which are in one of several NOT READY states to be
+	 * brought online later. This must be done without holding h->devlock,
+	 * so don't touch h->dev[]
+	 */
+	for (i = 0; i < nsds; i++) {
+		if (!sd[i]) /* if already added above. */
+			continue;
+		if (sd[i]->volume_offline)
+			hpsa_monitor_offline_device(h, sd[i]->scsi3addr);
+	}
+
 	/* Don't notify scsi mid layer of any changes the first time through
 	 * (or if there are no changes) scsi_scan_host will do it later the
 	 * first time through.
@@ -2326,6 +2458,117 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device,
 	device->lun = lun;
 }
 
+/* Use VPD inquiry to get details of volume status */
+static int hpsa_get_volume_status(struct ctlr_info *h,
+					unsigned char scsi3addr[])
+{
+	int rc;
+	int status;
+	int size;
+	unsigned char *buf;
+
+	buf = kzalloc(64, GFP_KERNEL);
+	if (!buf)
+		return HPSA_VPD_LV_STATUS_UNSUPPORTED;
+
+	/* Does controller have VPD for logical volume status? */
+	if (!hpsa_vpd_page_supported(h, scsi3addr, HPSA_VPD_LV_STATUS)) {
+		dev_warn(&h->pdev->dev, "Logical volume status VPD page is unsupported.\n");
+		goto exit_failed;
+	}
+
+	/* Get the size of the VPD return buffer */
+	rc = hpsa_scsi_do_inquiry(h, scsi3addr, VPD_PAGE | HPSA_VPD_LV_STATUS,
+					buf, HPSA_VPD_HEADER_SZ);
+	if (rc != 0) {
+		dev_warn(&h->pdev->dev, "Logical volume status VPD inquiry failed.\n");
+		goto exit_failed;
+	}
+	size = buf[3];
+
+	/* Now get the whole VPD buffer */
+	rc = hpsa_scsi_do_inquiry(h, scsi3addr, VPD_PAGE | HPSA_VPD_LV_STATUS,
+					buf, size + HPSA_VPD_HEADER_SZ);
+	if (rc != 0) {
+		dev_warn(&h->pdev->dev, "Logical volume status VPD inquiry failed.\n");
+		goto exit_failed;
+	}
+	status = buf[4]; /* status byte */
+
+	kfree(buf);
+	return status;
+exit_failed:
+	kfree(buf);
+	return HPSA_VPD_LV_STATUS_UNSUPPORTED;
+}
+
+/* Determine offline status of a volume.
+ * Return either:
+ *  0 (not offline)
+ * -1 (offline for unknown reasons)
+ *  # (integer code indicating one of several NOT READY states
+ *     describing why a volume is to be kept offline)
+ */
+static unsigned char hpsa_volume_offline(struct ctlr_info *h,
+					unsigned char scsi3addr[])
+{
+	struct CommandList *c;
+	unsigned char *sense, sense_key, asc, ascq;
+	int ldstat = 0;
+	u16 cmd_status;
+	u8 scsi_status;
+#define ASC_LUN_NOT_READY 0x04
+#define ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS 0x04
+#define ASCQ_LUN_NOT_READY_INITIALIZING_CMD_REQ 0x02
+
+	c = cmd_alloc(h);
+	if (!c)
+		return 0;
+	(void) fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, scsi3addr, TYPE_CMD);
+	hpsa_scsi_do_simple_cmd_core(h, c);
+	sense = c->err_info->SenseInfo;
+	sense_key = sense[2];
+	asc = sense[12];
+	ascq = sense[13];
+	cmd_status = c->err_info->CommandStatus;
+	scsi_status = c->err_info->ScsiStatus;
+	cmd_free(h, c);
+	/* Is the volume 'not ready'? */
+	if (cmd_status != CMD_TARGET_STATUS ||
+		scsi_status != SAM_STAT_CHECK_CONDITION ||
+		sense_key != NOT_READY ||
+		asc != ASC_LUN_NOT_READY)  {
+		return 0;
+	}
+
+	/* Determine the reason for not ready state */
+	ldstat = hpsa_get_volume_status(h, scsi3addr);
+
+	/* Keep volume offline in certain cases: */
+	switch (ldstat) {
+	case HPSA_LV_UNDERGOING_ERASE:
+	case HPSA_LV_UNDERGOING_RPI:
+	case HPSA_LV_PENDING_RPI:
+	case HPSA_LV_ENCRYPTED_NO_KEY:
+	case HPSA_LV_PLAINTEXT_IN_ENCRYPT_ONLY_CONTROLLER:
+	case HPSA_LV_UNDERGOING_ENCRYPTION:
+	case HPSA_LV_UNDERGOING_ENCRYPTION_REKEYING:
+	case HPSA_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER:
+		return ldstat;
+	case HPSA_VPD_LV_STATUS_UNSUPPORTED:
+		/* If VPD status page isn't available,
+		 * use ASC/ASCQ to determine state
+		 */
+		if ((ascq == ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS) ||
+			(ascq == ASCQ_LUN_NOT_READY_INITIALIZING_CMD_REQ))
+			return ldstat;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 static int hpsa_update_device_info(struct ctlr_info *h,
 	unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
 	unsigned char *is_OBDR_device)
@@ -2368,10 +2611,13 @@ static int hpsa_update_device_info(struct ctlr_info *h,
 		hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level);
 		if (h->fw_support & MISC_FW_RAID_OFFLOAD_BASIC)
 			hpsa_get_ioaccel_status(h, scsi3addr, this_device);
+		this_device->volume_offline =
+			hpsa_volume_offline(h, scsi3addr);
 	} else {
 		this_device->raid_level = RAID_UNKNOWN;
 		this_device->offload_config = 0;
 		this_device->offload_enabled = 0;
+		this_device->volume_offline = 0;
 	}
 
 	if (is_OBDR_device) {
@@ -6442,7 +6688,7 @@ static void detect_controller_lockup(struct ctlr_info *h)
 	h->last_heartbeat_timestamp = now;
 }
 
-static int hpsa_kickoff_rescan(struct ctlr_info *h)
+static void hpsa_ack_ctlr_events(struct ctlr_info *h)
 {
 	int i;
 	char *event_type;
@@ -6485,42 +6731,49 @@ static int hpsa_kickoff_rescan(struct ctlr_info *h)
 		hpsa_wait_for_mode_change_ack(h);
 #endif
 	}
-
-	/* Something in the device list may have changed to trigger
-	 * the event, so do a rescan.
-	 */
-	hpsa_scan_start(h->scsi_host);
-	/* release reference taken on scsi host in check_controller_events */
-	scsi_host_put(h->scsi_host);
-	return 0;
+	return;
 }
 
 /* Check a register on the controller to see if there are configuration
  * changes (added/changed/removed logical drives, etc.) which mean that
  * we should rescan the controller for devices.
  * Also check flag for driver-initiated rescan.
- * If either flag or controller event indicate rescan, add the controller
- * to the list of controllers needing to be rescanned, and gets a
- * reference to the associated scsi_host.
  */
-static void hpsa_ctlr_needs_rescan(struct ctlr_info *h)
+static int hpsa_ctlr_needs_rescan(struct ctlr_info *h)
 {
+	if (h->drv_req_rescan)
+		return 1;
+
 	if (!(h->fw_support & MISC_FW_EVENT_NOTIFY))
-		return;
+		return 0;
 
 	h->events = readl(&(h->cfgtable->event_notify));
-	if (!(h->events & RESCAN_REQUIRED_EVENT_BITS) && !h->drv_req_rescan)
-		return;
+	return h->events & RESCAN_REQUIRED_EVENT_BITS;
+}
 
-	/*
-	 * Take a reference on scsi host for the duration of the scan
-	 * Release in hpsa_kickoff_rescan().  No lock needed for scan_list
-	 * as only a single thread accesses this list.
-	 */
-	scsi_host_get(h->scsi_host);
-	hpsa_kickoff_rescan(h);
+/*
+ * Check if any of the offline devices have become ready
+ */
+static int hpsa_offline_devices_ready(struct ctlr_info *h)
+{
+	unsigned long flags;
+	struct offline_device_entry *d;
+	struct list_head *this, *tmp;
+
+	spin_lock_irqsave(&h->offline_device_lock, flags);
+	list_for_each_safe(this, tmp, &h->offline_device_list) {
+		d = list_entry(this, struct offline_device_entry,
+				offline_list);
+		spin_unlock_irqrestore(&h->offline_device_lock, flags);
+		if (!hpsa_volume_offline(h, d->scsi3addr))
+			return 1;
+		spin_lock_irqsave(&h->offline_device_lock, flags);
+	}
+	spin_unlock_irqrestore(&h->offline_device_lock, flags);
+	return 0;
 }
 
+
 static void hpsa_monitor_ctlr_worker(struct work_struct *work)
 {
 	unsigned long flags;
@@ -6529,7 +6782,15 @@ static void hpsa_monitor_ctlr_worker(struct work_struct *work)
 	detect_controller_lockup(h);
 	if (h->lockup_detected)
 		return;
-	hpsa_ctlr_needs_rescan(h);
+
+	if (hpsa_ctlr_needs_rescan(h) || hpsa_offline_devices_ready(h)) {
+		scsi_host_get(h->scsi_host);
+		h->drv_req_rescan = 0;
+		hpsa_ack_ctlr_events(h);
+		hpsa_scan_start(h->scsi_host);
+		scsi_host_put(h->scsi_host);
+	}
+
 	spin_lock_irqsave(&h->lock, flags);
 	if (h->remove_in_progress) {
 		spin_unlock_irqrestore(&h->lock, flags);
@@ -6579,7 +6840,9 @@ reinit_after_soft_reset:
 	h->intr_mode = hpsa_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
 	INIT_LIST_HEAD(&h->cmpQ);
 	INIT_LIST_HEAD(&h->reqQ);
+	INIT_LIST_HEAD(&h->offline_device_list);
 	spin_lock_init(&h->lock);
+	spin_lock_init(&h->offline_device_lock);
 	spin_lock_init(&h->scan_lock);
 	spin_lock_init(&h->passthru_count_lock);
 	rc = hpsa_pci_init(h);
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index c4a81f0..ae8c592 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -46,6 +46,7 @@ struct hpsa_scsi_dev_t {
 	unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
 	unsigned char model[16];        /* bytes 16-31 of inquiry data */
 	unsigned char raid_level;	/* from inquiry page 0xC1 */
+	unsigned char volume_offline;	/* discovered via TUR or VPD */
 	u32 ioaccel_handle;
 	int offload_config;		/* I/O accel RAID offload configured */
 	int offload_enabled;		/* I/O accel RAID offload enabled */
@@ -197,10 +198,18 @@ struct ctlr_info {
 		CTLR_STATE_CHANGE_EVENT_REDUNDANT_CNTRL | \
 		CTLR_STATE_CHANGE_EVENT_AIO_ENABLED_DISABLED | \
 		CTLR_STATE_CHANGE_EVENT_AIO_CONFIG_CHANGE)
+	spinlock_t offline_device_lock;
+	struct list_head offline_device_list;
 	int	acciopath_status;
 	int	drv_req_rescan;	/* flag for driver to request rescan event */
 	int	raid_offload_debug;
 };
+
+struct offline_device_entry {
+	unsigned char scsi3addr[8];
+	struct list_head offline_list;
+};
+
 #define HPSA_ABORT_MSG 0
 #define HPSA_DEVICE_RESET_MSG 1
 #define HPSA_RESET_TYPE_CONTROLLER 0x00
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index eaa7fda..8026d2e 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -147,8 +147,23 @@
 #define HPSA_VPD_SUPPORTED_PAGES        0x00
 #define HPSA_VPD_LV_DEVICE_GEOMETRY     0xC1
 #define HPSA_VPD_LV_IOACCEL_STATUS      0xC2
+#define HPSA_VPD_LV_STATUS		0xC3
 #define HPSA_VPD_HEADER_SZ              4
 
+/* Logical volume states */
+#define HPSA_VPD_LV_STATUS_UNSUPPORTED			-1
+#define HPSA_LV_OK                                      0x0
+#define HPSA_LV_UNDERGOING_ERASE			0x0F
+#define HPSA_LV_UNDERGOING_RPI				0x12
+#define HPSA_LV_PENDING_RPI				0x13
+#define HPSA_LV_ENCRYPTED_NO_KEY			0x14
+#define HPSA_LV_PLAINTEXT_IN_ENCRYPT_ONLY_CONTROLLER	0x15
+#define HPSA_LV_UNDERGOING_ENCRYPTION			0x16
+#define HPSA_LV_UNDERGOING_ENCRYPTION_REKEYING		0x17
+#define HPSA_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER	0x18
+#define HPSA_LV_PENDING_ENCRYPTION			0x19
+#define HPSA_LV_PENDING_ENCRYPTION_REKEYING		0x1A
+
 struct vals32 {
 	u32   lower;
 	u32   upper;


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

* [PATCH 3/6] hpsa: increase the probability of a reported success after a device reset
  2014-02-21 22:24 [PATCH 0/6] hpsa: supplemental February 2014 driver updates Stephen M. Cameron
  2014-02-21 22:24 ` [PATCH 1/6] hpsa: remove unused kthread.h header Stephen M. Cameron
  2014-02-21 22:25 ` [PATCH 2/6] hpsa: bring format-in-progress drives online when ready Stephen M. Cameron
@ 2014-02-21 22:25 ` Stephen M. Cameron
  2014-02-21 22:25 ` [PATCH 4/6] hpsa: remove unused struct request from CommandList Stephen M. Cameron
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2014-02-21 22:25 UTC (permalink / raw)
  To: james.bottomley
  Cc: martin.petersen, linux-scsi, stephenmcameron, joseph.t.handzik,
	thenzl, michael.miller, scott.teel

From: Tomas Henzl <thenzl@redhat.com>

rc is set in the loop, and it isn't set back to zero anywhere
this patch fixes it

Signed-off-by: Tomas Henzl <thenzl@redhat.com>
---
 drivers/scsi/hpsa.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a0fcaa6..23110a8 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4142,7 +4142,7 @@ static int hpsa_register_scsi(struct ctlr_info *h)
 static int wait_for_device_to_become_ready(struct ctlr_info *h,
 	unsigned char lunaddr[])
 {
-	int rc = 0;
+	int rc;
 	int count = 0;
 	int waittime = 1; /* seconds */
 	struct CommandList *c;
@@ -4162,6 +4162,7 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
 		 */
 		msleep(1000 * waittime);
 		count++;
+		rc = 0; /* Device ready. */
 
 		/* Increase wait time with each try, up to a point. */
 		if (waittime < HPSA_MAX_WAIT_INTERVAL_SECS)


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

* [PATCH 4/6] hpsa: remove unused struct request from CommandList
  2014-02-21 22:24 [PATCH 0/6] hpsa: supplemental February 2014 driver updates Stephen M. Cameron
                   ` (2 preceding siblings ...)
  2014-02-21 22:25 ` [PATCH 3/6] hpsa: increase the probability of a reported success after a device reset Stephen M. Cameron
@ 2014-02-21 22:25 ` Stephen M. Cameron
  2014-02-21 22:25 ` [PATCH 5/6] hpsa: Add hba mode to the hpsa driver Stephen M. Cameron
  2014-02-21 22:25 ` [PATCH 6/6] hpsa: Do not zero fields of ioaccel2 command structure twice Stephen M. Cameron
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2014-02-21 22:25 UTC (permalink / raw)
  To: james.bottomley
  Cc: martin.petersen, linux-scsi, stephenmcameron, joseph.t.handzik,
	thenzl, michael.miller, scott.teel

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

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

diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 8026d2e..50388f1 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -386,7 +386,6 @@ struct CommandList {
 	int			   cmd_type;
 	long			   cmdindex;
 	struct list_head list;
-	struct request *rq;
 	struct completion *waiting;
 	void   *scsi_cmd;
 
@@ -399,8 +398,8 @@ struct CommandList {
  */
 #define IS_32_BIT ((8 - sizeof(long))/4)
 #define IS_64_BIT (!IS_32_BIT)
-#define PAD_32 (36)
-#define PAD_64 (4)
+#define PAD_32 (40)
+#define PAD_64 (12)
 #define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64)
 	u8 pad[COMMANDLIST_PAD];
 };


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

* [PATCH 5/6] hpsa: Add hba mode to the hpsa driver
  2014-02-21 22:24 [PATCH 0/6] hpsa: supplemental February 2014 driver updates Stephen M. Cameron
                   ` (3 preceding siblings ...)
  2014-02-21 22:25 ` [PATCH 4/6] hpsa: remove unused struct request from CommandList Stephen M. Cameron
@ 2014-02-21 22:25 ` Stephen M. Cameron
  2014-02-21 22:25 ` [PATCH 6/6] hpsa: Do not zero fields of ioaccel2 command structure twice Stephen M. Cameron
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2014-02-21 22:25 UTC (permalink / raw)
  To: james.bottomley
  Cc: martin.petersen, linux-scsi, stephenmcameron, joseph.t.handzik,
	thenzl, michael.miller, scott.teel

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

This allows exposing physical disks behind Smart
Array controllers to the OS (if the controller
has the right firmware and is in "hba" mode)

Signed-off-by: Joe Handzik <joseph.t.handzik@hp.com>
---
 drivers/scsi/hpsa.c     |   93 +++++++++++++++++++++++++++++++++++++++++++++--
 drivers/scsi/hpsa.h     |   41 +++++++++++++++++++++
 drivers/scsi/hpsa_cmd.h |    1 +
 3 files changed, 131 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 23110a8..355ebf3 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2128,6 +2128,37 @@ out:
 	return rc;
 }
 
+static int hpsa_bmic_ctrl_mode_sense(struct ctlr_info *h,
+		unsigned char *scsi3addr, unsigned char page,
+		struct bmic_controller_parameters *buf, size_t bufsize)
+{
+	int rc = IO_OK;
+	struct CommandList *c;
+	struct ErrorInfo *ei;
+
+	c = cmd_special_alloc(h);
+
+	if (c == NULL) {			/* trouble... */
+		dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n");
+		return -ENOMEM;
+	}
+
+	if (fill_cmd(c, BMIC_SENSE_CONTROLLER_PARAMETERS, h, buf, bufsize,
+			page, scsi3addr, TYPE_CMD)) {
+		rc = -1;
+		goto out;
+	}
+	hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE);
+	ei = c->err_info;
+	if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
+		hpsa_scsi_interpret_error(h, c);
+		rc = -1;
+	}
+out:
+	cmd_special_free(h, c);
+	return rc;
+	}
+
 static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
 	u8 reset_type)
 {
@@ -2929,6 +2960,24 @@ u8 *figure_lunaddrbytes(struct ctlr_info *h, int raid_ctlr_position, int i,
 	return NULL;
 }
 
+static int hpsa_hba_mode_enabled(struct ctlr_info *h)
+{
+	int rc;
+	struct bmic_controller_parameters *ctlr_params;
+	ctlr_params = kzalloc(sizeof(struct bmic_controller_parameters),
+		GFP_KERNEL);
+
+	if (!ctlr_params)
+		return 0;
+	rc = hpsa_bmic_ctrl_mode_sense(h, RAID_CTLR_LUNID, 0, ctlr_params,
+		sizeof(struct bmic_controller_parameters));
+	if (rc != 0) {
+		kfree(ctlr_params);
+		return 0;
+	}
+	return ctlr_params->nvram_flags & (1 << 3) ? 1 : 0;
+}
+
 static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 {
 	/* the idea here is we could get notified
@@ -2952,6 +3001,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 	int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 24;
 	int i, n_ext_target_devs, ndevs_to_allocate;
 	int raid_ctlr_position;
+	u8 rescan_hba_mode;
 	DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS);
 
 	currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL);
@@ -2965,6 +3015,15 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 	}
 	memset(lunzerobits, 0, sizeof(lunzerobits));
 
+	rescan_hba_mode = hpsa_hba_mode_enabled(h);
+
+	if (!h->hba_mode_enabled && rescan_hba_mode)
+		dev_warn(&h->pdev->dev, "HBA mode enabled\n");
+	else if (h->hba_mode_enabled && !rescan_hba_mode)
+		dev_warn(&h->pdev->dev, "HBA mode disabled\n");
+
+	h->hba_mode_enabled = rescan_hba_mode;
+
 	if (hpsa_gather_lun_info(h, reportlunsize,
 			(struct ReportLUNdata *) physdev_list, &nphysicals,
 			&physical_mode, logdev_list, &nlogicals))
@@ -3048,7 +3107,19 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 				ncurrent++;
 			break;
 		case TYPE_DISK:
-			if (i >= nphysicals) {
+			if (h->hba_mode_enabled) {
+				/* never use raid mapper in HBA mode */
+				this_device->offload_enabled = 0;
+				ncurrent++;
+				break;
+			} else if (h->acciopath_status) {
+				if (i >= nphysicals) {
+					ncurrent++;
+					break;
+				}
+			} else {
+				if (i < nphysicals)
+					break;
 				ncurrent++;
 				break;
 			}
@@ -4116,7 +4187,10 @@ static int hpsa_register_scsi(struct ctlr_info *h)
 	sh->max_lun = HPSA_MAX_LUN;
 	sh->max_id = HPSA_MAX_LUN;
 	sh->can_queue = h->nr_cmds;
-	sh->cmd_per_lun = h->nr_cmds;
+	if (h->hba_mode_enabled)
+		sh->cmd_per_lun = 7;
+	else
+		sh->cmd_per_lun = h->nr_cmds;
 	sh->sg_tablesize = h->maxsgentries;
 	h->scsi_host = sh;
 	sh->hostdata[0] = (unsigned long) h;
@@ -5261,6 +5335,16 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
 			c->Request.CDB[8] = (size >> 8) & 0xFF;
 			c->Request.CDB[9] = size & 0xFF;
 			break;
+		case BMIC_SENSE_CONTROLLER_PARAMETERS:
+			c->Request.CDBLen = 10;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_READ;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = BMIC_READ;
+			c->Request.CDB[6] = BMIC_SENSE_CONTROLLER_PARAMETERS;
+			c->Request.CDB[7] = (size >> 16) & 0xFF;
+			c->Request.CDB[8] = (size >> 8) & 0xFF;
+			break;
 		default:
 			dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd);
 			BUG();
@@ -6885,6 +6969,7 @@ reinit_after_soft_reset:
 
 	pci_set_drvdata(pdev, h);
 	h->ndevices = 0;
+	h->hba_mode_enabled = 0;
 	h->scsi_host = NULL;
 	spin_lock_init(&h->devlock);
 	hpsa_put_ctlr_into_performant_mode(h);
@@ -6944,8 +7029,8 @@ reinit_after_soft_reset:
 		goto reinit_after_soft_reset;
 	}
 
-	/* Enable Accelerated IO path at driver layer */
-	h->acciopath_status = 1;
+		/* Enable Accelerated IO path at driver layer */
+		h->acciopath_status = 1;
 
 	h->drv_req_rescan = 0;
 
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index ae8c592..44235a2 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -64,6 +64,46 @@ struct reply_pool {
 	u32 current_entry;
 };
 
+#pragma pack(1)
+struct bmic_controller_parameters {
+	u8   led_flags;
+	u8   enable_command_list_verification;
+	u8   backed_out_write_drives;
+	u16  stripes_for_parity;
+	u8   parity_distribution_mode_flags;
+	u16  max_driver_requests;
+	u16  elevator_trend_count;
+	u8   disable_elevator;
+	u8   force_scan_complete;
+	u8   scsi_transfer_mode;
+	u8   force_narrow;
+	u8   rebuild_priority;
+	u8   expand_priority;
+	u8   host_sdb_asic_fix;
+	u8   pdpi_burst_from_host_disabled;
+	char software_name[64];
+	char hardware_name[32];
+	u8   bridge_revision;
+	u8   snapshot_priority;
+	u32  os_specific;
+	u8   post_prompt_timeout;
+	u8   automatic_drive_slamming;
+	u8   reserved1;
+	u8   nvram_flags;
+	u8   cache_nvram_flags;
+	u8   drive_config_flags;
+	u16  reserved2;
+	u8   temp_warning_level;
+	u8   temp_shutdown_level;
+	u8   temp_condition_reset;
+	u8   max_coalesce_commands;
+	u32  max_coalesce_delay;
+	u8   orca_password[4];
+	u8   access_id[16];
+	u8   reserved[356];
+};
+#pragma pack()
+
 struct ctlr_info {
 	int	ctlr;
 	char	devname[8];
@@ -89,6 +129,7 @@ struct ctlr_info {
 	unsigned int msi_vector;
 	int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */
 	struct access_method access;
+	char hba_mode_enabled;
 
 	/* queue and queue Info */
 	struct list_head reqQ;
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 50388f1..b5cc705 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -257,6 +257,7 @@ struct SenseSubsystem_info {
 #define BMIC_CACHE_FLUSH 0xc2
 #define HPSA_CACHE_FLUSH 0x01	/* C2 was already being used by HPSA */
 #define BMIC_FLASH_FIRMWARE 0xF7
+#define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64
 
 /* Command List Structure */
 union SCSI3Addr {


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

* [PATCH 6/6] hpsa: Do not zero fields of ioaccel2 command structure twice
  2014-02-21 22:24 [PATCH 0/6] hpsa: supplemental February 2014 driver updates Stephen M. Cameron
                   ` (4 preceding siblings ...)
  2014-02-21 22:25 ` [PATCH 5/6] hpsa: Add hba mode to the hpsa driver Stephen M. Cameron
@ 2014-02-21 22:25 ` Stephen M. Cameron
  5 siblings, 0 replies; 7+ messages in thread
From: Stephen M. Cameron @ 2014-02-21 22:25 UTC (permalink / raw)
  To: james.bottomley
  Cc: martin.petersen, linux-scsi, stephenmcameron, joseph.t.handzik,
	thenzl, michael.miller, scott.teel

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

Structure was already memset to zero at the top
of hpsa_scsi_ioaccel2_queue_command

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 355ebf3..a32a510 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3570,8 +3570,6 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
 	cp->Tag = (c->cmdindex << DIRECT_LOOKUP_SHIFT) |
 				DIRECT_LOOKUP_BIT;
 	memcpy(cp->cdb, cdb, sizeof(cp->cdb));
-	memset(cp->cciss_lun, 0, sizeof(cp->cciss_lun));
-	cp->cmd_priority_task_attr = 0;
 
 	/* fill in sg elements */
 	cp->sg_count = (u8) use_sg;


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

end of thread, other threads:[~2014-02-21 22:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-21 22:24 [PATCH 0/6] hpsa: supplemental February 2014 driver updates Stephen M. Cameron
2014-02-21 22:24 ` [PATCH 1/6] hpsa: remove unused kthread.h header Stephen M. Cameron
2014-02-21 22:25 ` [PATCH 2/6] hpsa: bring format-in-progress drives online when ready Stephen M. Cameron
2014-02-21 22:25 ` [PATCH 3/6] hpsa: increase the probability of a reported success after a device reset Stephen M. Cameron
2014-02-21 22:25 ` [PATCH 4/6] hpsa: remove unused struct request from CommandList Stephen M. Cameron
2014-02-21 22:25 ` [PATCH 5/6] hpsa: Add hba mode to the hpsa driver Stephen M. Cameron
2014-02-21 22:25 ` [PATCH 6/6] hpsa: Do not zero fields of ioaccel2 command structure twice 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.