public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: "Stephen M. Cameron" <scameron@beardog.cce.hp.com>
To: jbottomley@parallels.com
Cc: stephenmcameron@gmail.com, mikem@beardog.cce.hp.com,
	matthew.gates@hp.com, linux-scsi@vger.kernel.org,
	scott.teel@hp.com
Subject: [PATCH 15/41] hpsa: poll controller to detect device change event
Date: Wed, 15 Jan 2014 16:37:35 -0600	[thread overview]
Message-ID: <20140115223735.5061.83830.stgit@beardog.cce.hp.com> (raw)
In-Reply-To: <20140115223354.5061.50276.stgit@beardog.cce.hp.com>

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

For shared SAS configurations, hosts need to poll Smart Arrays
periodically in order to be able to detect configuration changes
such as logical drives being added or removed from remote hosts.
A register on the controller indicates when such events have
occurred, and the driver polls the register via a workqueue
and kicks off a rescan of devices if such an event is detected.
Additionally, changes to logical drive raid offload eligibility
are autodetected in this way.

Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: Scott Teel <scott.teel@hp.com>
---
 drivers/scsi/hpsa.c     |  108 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/scsi/hpsa.h     |    1 
 drivers/scsi/hpsa_cmd.h |    3 +
 3 files changed, 112 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 4c9dd2e..1383169 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -220,6 +220,8 @@ static inline void finish_cmd(struct CommandList *c);
 static void hpsa_wait_for_mode_change_ack(struct ctlr_info *h);
 #define BOARD_NOT_READY 0
 #define BOARD_READY 1
+static void hpsa_drain_commands(struct ctlr_info *h);
+static void hpsa_flush_cache(struct ctlr_info *h);
 
 static inline struct ctlr_info *sdev_to_hba(struct scsi_device *sdev)
 {
@@ -5029,6 +5031,23 @@ static inline void hpsa_p600_dma_prefetch_quirk(struct ctlr_info *h)
 	writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG);
 }
 
+static void hpsa_wait_for_clear_event_notify_ack(struct ctlr_info *h)
+{
+	int i;
+	u32 doorbell_value;
+	unsigned long flags;
+	/* wait until the clear_event_notify bit 6 is cleared by controller. */
+	for (i = 0; i < MAX_CONFIG_WAIT; i++) {
+		spin_lock_irqsave(&h->lock, flags);
+		doorbell_value = readl(h->vaddr + SA5_DOORBELL);
+		spin_unlock_irqrestore(&h->lock, flags);
+		if (!(doorbell_value & DOORBELL_CLEAR_EVENTS))
+			break;
+		/* delay and try again */
+		msleep(20);
+	}
+}
+
 static void hpsa_wait_for_mode_change_ack(struct ctlr_info *h)
 {
 	int i;
@@ -5405,6 +5424,79 @@ static void detect_controller_lockup(struct ctlr_info *h)
 	h->last_heartbeat_timestamp = now;
 }
 
+static int hpsa_kickoff_rescan(struct ctlr_info *h)
+{
+	int i;
+	char *event_type;
+
+	/* Ask the controller to clear the events we're handling. */
+	if (h->transMethod & (CFGTBL_Trans_io_accel1) &&
+		(h->events & HPSA_EVENT_NOTIFY_ACCEL_IO_PATH_STATE_CHANGE ||
+		 h->events & HPSA_EVENT_NOTIFY_ACCEL_IO_PATH_CONFIG_CHANGE)) {
+
+		if (h->events & HPSA_EVENT_NOTIFY_ACCEL_IO_PATH_STATE_CHANGE)
+			event_type = "state change";
+		if (h->events & HPSA_EVENT_NOTIFY_ACCEL_IO_PATH_CONFIG_CHANGE)
+			event_type = "configuration change";
+		/* Stop sending new RAID offload reqs via the IO accelerator */
+		scsi_block_requests(h->scsi_host);
+		for (i = 0; i < h->ndevices; i++)
+			h->dev[i]->offload_enabled = 0;
+		hpsa_drain_commands(h);
+		/* Set 'accelerator path config change' bit */
+		dev_warn(&h->pdev->dev,
+			"Acknowledging event: 0x%08x (HP SSD Smart Path %s)\n",
+			h->events, event_type);
+		writel(h->events, &(h->cfgtable->clear_event_notify));
+		/* Set the "clear event notify field update" bit 6 */
+		writel(DOORBELL_CLEAR_EVENTS, h->vaddr + SA5_DOORBELL);
+		/* Wait until ctlr clears 'clear event notify field', bit 6 */
+		hpsa_wait_for_clear_event_notify_ack(h);
+		scsi_unblock_requests(h->scsi_host);
+	} else {
+		/* Acknowledge controller notification events. */
+		writel(h->events, &(h->cfgtable->clear_event_notify));
+		writel(DOORBELL_CLEAR_EVENTS, h->vaddr + SA5_DOORBELL);
+		hpsa_wait_for_clear_event_notify_ack(h);
+#if 0
+		writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+		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;
+}
+
+/* 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.  If so, 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)
+{
+	if (!(h->fw_support & MISC_FW_EVENT_NOTIFY))
+		return;
+
+	h->events = readl(&(h->cfgtable->event_notify));
+	if (!h->events)
+		return;
+
+	/*
+	 * 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);
+}
+
 static void hpsa_monitor_ctlr_worker(struct work_struct *work)
 {
 	unsigned long flags;
@@ -5413,6 +5505,7 @@ static void hpsa_monitor_ctlr_worker(struct work_struct *work)
 	detect_controller_lockup(h);
 	if (h->lockup_detected)
 		return;
+	hpsa_ctlr_needs_rescan(h);
 	spin_lock_irqsave(&h->lock, flags);
 	if (h->remove_in_progress) {
 		spin_unlock_irqrestore(&h->lock, flags);
@@ -5954,6 +6047,21 @@ clean_up:
 	kfree(h->blockFetchTable);
 }
 
+static void hpsa_drain_commands(struct ctlr_info *h)
+{
+	int cmds_out;
+	unsigned long flags;
+
+	do { /* wait for all outstanding commands to drain out */
+		spin_lock_irqsave(&h->lock, flags);
+		cmds_out = h->commands_outstanding;
+		spin_unlock_irqrestore(&h->lock, flags);
+		if (cmds_out <= 0)
+			break;
+		msleep(100);
+	} while (1);
+}
+
 /*
  *  This is it.  Register the PCI driver information for the cards we control
  *  the OS will call our registered routines when it finds one of our cards.
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index ae08f1c..df2f88d 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -176,6 +176,7 @@ struct ctlr_info {
 #define HPSATMF_LOG_QRY_TASK    (1 << 23)
 #define HPSATMF_LOG_QRY_TSET    (1 << 24)
 #define HPSATMF_LOG_QRY_ASYNC   (1 << 25)
+	u32 events;
 };
 #define HPSA_ABORT_MSG 0
 #define HPSA_DEVICE_RESET_MSG 1
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index c1ae8d2..21f8a61 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -128,6 +128,7 @@
 #define CFGTBL_AccCmds          0x00000001l
 #define DOORBELL_CTLR_RESET	0x00000004l
 #define DOORBELL_CTLR_RESET2	0x00000020l
+#define DOORBELL_CLEAR_EVENTS	0x00000040l
 
 #define CFGTBL_Trans_Simple     0x00000002l
 #define CFGTBL_Trans_Performant 0x00000004l
@@ -495,6 +496,8 @@ struct CfgTable {
 	u32		io_accel_max_embedded_sg_count;
 	u32		io_accel_request_size_offset;
 	u32		event_notify;
+#define HPSA_EVENT_NOTIFY_ACCEL_IO_PATH_STATE_CHANGE (1 << 30)
+#define HPSA_EVENT_NOTIFY_ACCEL_IO_PATH_CONFIG_CHANGE (1 << 31)
 	u32		clear_event_notify;
 };
 


  parent reply	other threads:[~2014-01-15 21:37 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-15 22:36 [PATCH 00/41] hpsa January 2014 driver updates Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 01/41] hpsa: revert bring logical drives online when format completes Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 02/41] hpsa: revert hide logical drives with format in progress from linux Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 03/41] hpsa: use workqueue instead of kernel thread for lockup detection Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 04/41] hpsa: rename scsi prefetch field Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 05/41] hpsa: enable unit attention reporting Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 06/41] hpsa: do not require board "not ready" status after hard reset Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 07/41] hpsa: allow SCSI mid layer to handle unit attention Stephen M. Cameron
2014-01-15 22:36 ` [PATCH 08/41] hpsa: use extended report luns command for HP SSD SmartPath Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 09/41] hpsa: mark last scatter gather element as the last Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 10/41] hpsa: add support for 'fastpath' i/o Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 11/41] hpsa: only allow REQ_TYPE_FS to use fast path Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 12/41] hpsa: fix task management for mode-1 ioaccell path Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 13/41] hpsa: add ioaccell mode 1 RAID offload support Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 14/41] hpsa: update raid offload status on device rescan Stephen M. Cameron
2014-01-15 22:37 ` Stephen M. Cameron [this message]
2014-01-15 22:37 ` [PATCH 16/41] hpsa: do not rescan controllers known to be locked up Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 17/41] hpsa: add hp_ssd_smart_path_enabled sysfs attribute Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 18/41] hpsa: complain if physical or logical aborts are not supported Stephen M. Cameron
2014-01-15 22:37 ` [PATCH 19/41] hpsa: add ioaccel mode 2 structure definitions Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 20/41] hpsa: Acknowledge controller events in ioaccell mode 2 as well as mode 1 Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 21/41] hpsa: do ioaccel mode 2 resource allocations Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 22/41] hpsa: get physical device handles for io accel mode 2 as well as mode 1 Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 23/41] hpsa: initialize controller to perform io accelerator mode 2 Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 24/41] hpsa: get ioaccel mode 2 i/o working Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 25/41] hpsa: teach hpsa_device_reset to do either target or lun reset Stephen M. Cameron
2014-01-16  8:36   ` Hannes Reinecke
2014-01-16 13:33     ` Gates, Matt
2014-01-15 22:38 ` [PATCH 26/41] hpsa: add task management for ioaccel mode 2 Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 27/41] hpsa: make device update copy the raid map also Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 28/41] hpsa: complete the ioaccel raidmap code Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 29/41] hpsa: allow user to disable accelerated i/o path Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 30/41] hpsa: rescan devices on ioaccel2 error Stephen M. Cameron
2014-01-15 22:38 ` [PATCH 31/41] hpsa: allow VPD page zero to be queried Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 32/41] hpsa: do not inquire for unsupported ioaccel status vpd page Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 33/41] hpsa: retry certain ioaccel error cases on the RAID path Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 34/41] hpsa: update source file copyrights Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 35/41] hpsa: add controller base data-at-rest encryption compatibility ioaccel2 Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 36/41] hpsa: when switching out of accel mode await only accel command completions Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 37/41] hpsa: only do device rescan for certain events Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 38/41] hpsa: improve error messages for driver initiated commands Stephen M. Cameron
2014-01-16  8:42   ` Hannes Reinecke
2014-01-16 16:14     ` scameron
2014-01-15 22:39 ` [PATCH 39/41] hpsa add sysfs debug switch for raid map debugging messages Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 40/41] pci: add HP/3PAR vendor id to pci_ids.h Stephen M. Cameron
2014-01-15 22:39 ` [PATCH 41/41] hpsa: Add support for a few HP Storage controllers Stephen M. Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140115223735.5061.83830.stgit@beardog.cce.hp.com \
    --to=scameron@beardog.cce.hp.com \
    --cc=jbottomley@parallels.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=matthew.gates@hp.com \
    --cc=mikem@beardog.cce.hp.com \
    --cc=scott.teel@hp.com \
    --cc=stephenmcameron@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox