All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/37] smartpqi updates
@ 2017-04-25 19:45 Don Brace
  2017-04-25 19:45 ` [PATCH 01/37] smartpqi: correct remove scsi devices Don Brace
                   ` (36 more replies)
  0 siblings, 37 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:45 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

These patches are based on Linus's tree

The changes are:

 - correct remove SCSI devices
   - Remove spin-lock
 - cleanup interrupt management
   - minor cleanup to align with in-house driver
 - set PCI completion timeout 
 - add in controller checkpoint for controller lockups.
   - helps debug rare lockup conditions
 - ensure controller is in SIS mode at driver init
   - needed for kdump/kexec
 - add supporting events
   - manage event changes from controller
 - enhance resets
   - wait for all outstanding I/Os to complete
 - add suspend and resume support
   - Support S3/S4 system power states
 - add heartbeat check
   - add check for controller lockups
 - correct bdma hw bug
   - workaround for BDMA hardware bug 
 - add pqi_wait_for_completion_io
   - add check for controller lockup
 - change functions to inline
   - align code with in-house driver
 - make pdev pointer names consistent
   - align code with in-house driver
 - eliminate redundant error messages
 - correct BMIC identify physical drive
 - minor driver cleanup
   - align code with in-house driver
 - add new PCI device IDs
 - cleanup messages
 - update copyright
 - add ptraid support
   - RBOD support
 - change return value for LUN reset operations
 - enhance kdump
 - remove qdepth calculations for logical volumes
 - add lockup action
 - correct AIO error path
   - send commands down RAID path when they fail
     on AIO path
 - update device offline
   - improve off-lined device detection.
 - update rescan worker
 - cleanup controller branding
   - make more generic
 - map more raid errors to SCSI errors
   - map RAID path errors to Linux SCSI errors
 - update timeout on admin commands
 - enhance device add and remove messages
 - make AIO references consistent
 - add raid level show sysfs entry
 - cleanup list initialization
 - add module parameters
   - heat-beat and controller management
 - remove writeq/readq function definitions
   - from Corentin Labbe <clabbe.montjoie@gmail.com>
 - bump driver version

---

Corentin Labbe (1):
      smartpqi: remove writeq/readq function definitions

Kevin Barnett (36):
      smartpqi: correct remove scsi devices
      smartpqi: cleanup interrupt management
      smartpqi: set pci completion timeout
      smartpqi: add in controller checkpoint for controller lockups.
      smartpqi: ensure controller is in SIS mode at init
      smartpqi: add supporting events
      smartpqi: enhance resets
      smartpqi: add suspend and resume support
      smartpqi: add heartbeat check
      smartpqi: correct bdma hw bug
      smartpqi: add pqi_wait_for_completion_io
      smartpqi: change functions to inline
      smartpqi: make pdev pointer names consistent
      smartpqi: eliminate redundant error messages
      smartpqi: correct BMIC identify physical drive
      smartpqi: minor driver cleanup
      smartpqi: add new PCI device IDs
      smartpqi: cleanup messages
      smartpqi: update copyright
      smartpqi: add ptraid support
      smartpqi: change return value for LUN reset operations
      smartpqi: enhance kdump
      smartpqi: remove qdepth calculations for logical volumes
      smartpqi: add lockup action
      smartpqi: correct aio error path
      smartpqi: update device offline
      smartpqi: controller offline improvements
      smartpqi: cleanup controller branding
      smartpqi: map more raid errors to SCSI errors
      smartpqi: update timeout on admin commands
      smartpqi: enhance device add and remove messages
      smartpqi: make raid bypass references consistent
      smartpqi: add raid level show
      smartpqi: cleanup list initialization
      smartpqi: add module parameters
      smartpqi: bump driver version


 drivers/scsi/smartpqi/smartpqi.h               |  192 +-
 drivers/scsi/smartpqi/smartpqi_init.c          | 2430 ++++++++++++++++++------
 drivers/scsi/smartpqi/smartpqi_sas_transport.c |    2 
 drivers/scsi/smartpqi/smartpqi_sis.c           |  109 +
 drivers/scsi/smartpqi/smartpqi_sis.h           |    7 
 5 files changed, 2051 insertions(+), 689 deletions(-)

--
Signature

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

* [PATCH 01/37] smartpqi: correct remove scsi devices
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
@ 2017-04-25 19:45 ` Don Brace
  2017-04-25 19:46 ` [PATCH 02/37] smartpqi: cleanup interrupt management Don Brace
                   ` (35 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:45 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@microsemi.com>

correct a problem caused by holding a spinlock during device deletion.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 657ad15..dd00c69 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -1823,19 +1823,25 @@ static void pqi_remove_all_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 {
 	unsigned long flags;
 	struct pqi_scsi_dev *device;
-	struct pqi_scsi_dev *next;
 
-	spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
+	while (1) {
+		spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
+
+		device = list_first_entry_or_null(&ctrl_info->scsi_device_list,
+			struct pqi_scsi_dev, scsi_device_list_entry);
+		if (device)
+			list_del(&device->scsi_device_list_entry);
+
+		spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock,
+			flags);
+
+		if (!device)
+			break;
 
-	list_for_each_entry_safe(device, next, &ctrl_info->scsi_device_list,
-		scsi_device_list_entry) {
 		if (device->sdev)
 			pqi_remove_device(ctrl_info, device);
-		list_del(&device->scsi_device_list_entry);
 		pqi_free_device(device);
 	}
-
-	spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
 }
 
 static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info)

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

* [PATCH 02/37] smartpqi: cleanup interrupt management
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
  2017-04-25 19:45 ` [PATCH 01/37] smartpqi: correct remove scsi devices Don Brace
@ 2017-04-25 19:46 ` Don Brace
  2017-04-25 19:54   ` Bart Van Assche
  2017-04-25 19:46 ` [PATCH 03/37] smartpqi: set pci completion timeout Don Brace
                   ` (34 subsequent siblings)
  36 siblings, 1 reply; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:46 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@microsemi.com>

minor cleanup of interrupt initialization and tear-down.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   45 ++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index dd00c69..39695a4 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -2892,9 +2892,9 @@ static irqreturn_t pqi_irq_handler(int irq, void *data)
 
 static int pqi_request_irqs(struct pqi_ctrl_info *ctrl_info)
 {
-	struct pci_dev *pdev = ctrl_info->pci_dev;
 	int i;
 	int rc;
+	struct pci_dev *pdev = ctrl_info->pci_dev;
 
 	ctrl_info->event_irq = pci_irq_vector(pdev, 0);
 
@@ -2913,23 +2913,44 @@ static int pqi_request_irqs(struct pqi_ctrl_info *ctrl_info)
 	return 0;
 }
 
+static void pqi_free_irqs(struct pqi_ctrl_info *ctrl_info)
+{
+	int i;
+
+	for (i = 0; i < ctrl_info->num_msix_vectors_initialized; i++)
+		free_irq(pci_irq_vector(ctrl_info->pci_dev, i),
+			&ctrl_info->queue_groups[i]);
+
+	ctrl_info->num_msix_vectors_initialized = 0;
+}
+
 static int pqi_enable_msix_interrupts(struct pqi_ctrl_info *ctrl_info)
 {
-	int ret;
+	int num_vectors_enabled;
 
-	ret = pci_alloc_irq_vectors(ctrl_info->pci_dev,
+	num_vectors_enabled = pci_alloc_irq_vectors(ctrl_info->pci_dev,
 			PQI_MIN_MSIX_VECTORS, ctrl_info->num_queue_groups,
 			PCI_IRQ_MSIX | PCI_IRQ_AFFINITY);
-	if (ret < 0) {
+	if (num_vectors_enabled < 0) {
 		dev_err(&ctrl_info->pci_dev->dev,
-			"MSI-X init failed with error %d\n", ret);
-		return ret;
+			"MSI-X init failed with error %d\n",
+			num_vectors_enabled);
+		return num_vectors_enabled;
 	}
 
-	ctrl_info->num_msix_vectors_enabled = ret;
+	ctrl_info->num_msix_vectors_enabled = num_vectors_enabled;
+
 	return 0;
 }
 
+static void pqi_disable_msix_interrupts(struct pqi_ctrl_info *ctrl_info)
+{
+	if (ctrl_info->num_msix_vectors_enabled) {
+		pci_free_irq_vectors(ctrl_info->pci_dev);
+		ctrl_info->num_msix_vectors_enabled = 0;
+	}
+}
+
 static int pqi_alloc_operational_queues(struct pqi_ctrl_info *ctrl_info)
 {
 	unsigned int i;
@@ -5519,14 +5540,8 @@ static inline void pqi_free_ctrl_info(struct pqi_ctrl_info *ctrl_info)
 
 static void pqi_free_interrupts(struct pqi_ctrl_info *ctrl_info)
 {
-	int i;
-
-	for (i = 0; i < ctrl_info->num_msix_vectors_initialized; i++) {
-		free_irq(pci_irq_vector(ctrl_info->pci_dev, i),
-				&ctrl_info->queue_groups[i]);
-	}
-
-	pci_free_irq_vectors(ctrl_info->pci_dev);
+	pqi_free_irqs(ctrl_info);
+	pqi_disable_msix_interrupts(ctrl_info);
 }
 
 static void pqi_free_ctrl_resources(struct pqi_ctrl_info *ctrl_info)

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

* [PATCH 03/37] smartpqi: set pci completion timeout
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
  2017-04-25 19:45 ` [PATCH 01/37] smartpqi: correct remove scsi devices Don Brace
  2017-04-25 19:46 ` [PATCH 02/37] smartpqi: cleanup interrupt management Don Brace
@ 2017-04-25 19:46 ` Don Brace
  2017-04-25 19:46 ` [PATCH 04/37] smartpqi: add in controller checkpoint for controller lockups Don Brace
                   ` (33 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:46 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@microsemi.com>

add support for setting PCIe completion timeout.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 39695a4..7a09fdb 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -5437,6 +5437,13 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 	return 0;
 }
 
+static inline int pqi_set_pcie_completion_timeout(struct pci_dev *pci_dev,
+	u16 timeout)
+{
+	return pcie_capability_clear_and_set_word(pci_dev, PCI_EXP_DEVCTL2,
+		PCI_EXP_DEVCTL2_COMP_TIMEOUT, timeout);
+}
+
 static int pqi_pci_init(struct pqi_ctrl_info *ctrl_info)
 {
 	int rc;
@@ -5480,6 +5487,17 @@ static int pqi_pci_init(struct pqi_ctrl_info *ctrl_info)
 	ctrl_info->registers = ctrl_info->iomem_base;
 	ctrl_info->pqi_registers = &ctrl_info->registers->pqi_registers;
 
+#define PCI_EXP_COMP_TIMEOUT_65_TO_210_MS		0x6
+
+	/* Increase the PCIe completion timeout. */
+	rc = pqi_set_pcie_completion_timeout(ctrl_info->pci_dev,
+		PCI_EXP_COMP_TIMEOUT_65_TO_210_MS);
+	if (rc) {
+		dev_err(&ctrl_info->pci_dev->dev,
+			"failed to set PCIe completion timeout\n");
+		goto release_regions;
+	}
+
 	/* Enable bus mastering. */
 	pci_set_master(ctrl_info->pci_dev);
 

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

* [PATCH 04/37] smartpqi: add in controller checkpoint for controller lockups.
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (2 preceding siblings ...)
  2017-04-25 19:46 ` [PATCH 03/37] smartpqi: set pci completion timeout Don Brace
@ 2017-04-25 19:46 ` Don Brace
  2017-04-25 19:46 ` [PATCH 05/37] smartpqi: ensure controller is in SIS mode at init Don Brace
                   ` (32 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:46 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

tell smartpqi controller to generate a checkpoint for rare lockup
conditions.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |    2 +-
 drivers/scsi/smartpqi/smartpqi_init.c |    1 +
 drivers/scsi/smartpqi/smartpqi_sis.c  |    7 +++++++
 drivers/scsi/smartpqi/smartpqi_sis.h  |    1 +
 4 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index b673825..73754ca 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -933,10 +933,10 @@ struct pqi_ctrl_info {
 	struct Scsi_Host *scsi_host;
 
 	struct mutex	scan_mutex;
+	bool		controller_online : 1;
 	u8		inbound_spanning_supported : 1;
 	u8		outbound_spanning_supported : 1;
 	u8		pqi_mode_enabled : 1;
-	u8		controller_online : 1;
 	u8		heartbeat_timer_started : 1;
 
 	struct list_head scsi_device_list;
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 7a09fdb..8a9b48a 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -2697,6 +2697,7 @@ static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
 
 	ctrl_info->controller_online = false;
 	dev_err(&ctrl_info->pci_dev->dev, "controller offline\n");
+	sis_shutdown_ctrl(ctrl_info);
 
 	for (i = 0; i < ctrl_info->num_queue_groups; i++) {
 		queue_group = &ctrl_info->queue_groups[i];
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
index 71408f9..c7d9ea1 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.c
+++ b/drivers/scsi/smartpqi/smartpqi_sis.c
@@ -34,6 +34,7 @@
 #define SIS_REENABLE_SIS_MODE			0x1
 #define SIS_ENABLE_MSIX				0x40
 #define SIS_SOFT_RESET				0x100
+#define SIS_TRIGGER_SHUTDOWN			0x800000
 #define SIS_CMD_READY				0x200
 #define SIS_CMD_COMPLETE			0x1000
 #define SIS_CLEAR_CTRL_TO_HOST_DOORBELL		0x1000
@@ -342,6 +343,12 @@ void sis_soft_reset(struct pqi_ctrl_info *ctrl_info)
 		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
 }
 
+void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info)
+{
+	writel(SIS_TRIGGER_SHUTDOWN,
+		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
+}
+
 #define SIS_MODE_READY_TIMEOUT_SECS	30
 
 int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info)
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h
index bd6e7b0..7f7b68c 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.h
+++ b/drivers/scsi/smartpqi/smartpqi_sis.h
@@ -27,6 +27,7 @@ int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info);
 void sis_enable_msix(struct pqi_ctrl_info *ctrl_info);
 void sis_disable_msix(struct pqi_ctrl_info *ctrl_info);
 void sis_soft_reset(struct pqi_ctrl_info *ctrl_info);
+void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info);
 int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info);
 void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value);
 u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info);

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

* [PATCH 05/37] smartpqi: ensure controller is in SIS mode at init
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (3 preceding siblings ...)
  2017-04-25 19:46 ` [PATCH 04/37] smartpqi: add in controller checkpoint for controller lockups Don Brace
@ 2017-04-25 19:46 ` Don Brace
  2017-04-25 19:57   ` Bart Van Assche
  2017-04-25 19:46 ` [PATCH 06/37] smartpqi: add supporting events Don Brace
                   ` (31 subsequent siblings)
  36 siblings, 1 reply; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:46 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

put in SIS mode during initialization.
support kexec/kdump

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |    2 +
 drivers/scsi/smartpqi/smartpqi_init.c |   60 +++++++++++++++++++--------------
 drivers/scsi/smartpqi/smartpqi_sis.c  |   15 ++++++++
 drivers/scsi/smartpqi/smartpqi_sis.h  |    1 +
 4 files changed, 51 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 73754ca..62045c1 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -964,7 +964,7 @@ struct pqi_ctrl_info {
 };
 
 enum pqi_ctrl_mode {
-	UNKNOWN,
+	SIS_MODE = 0,
 	PQI_MODE
 };
 
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 8a9b48a..d28e694 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -5245,38 +5245,50 @@ static int pqi_get_ctrl_firmware_version(struct pqi_ctrl_info *ctrl_info)
 	return rc;
 }
 
-static int pqi_kdump_init(struct pqi_ctrl_info *ctrl_info)
+/* Switches the controller from PQI mode back into SIS mode. */
+
+static int pqi_revert_to_sis_mode(struct pqi_ctrl_info *ctrl_info)
+{
+	int rc;
+
+	sis_disable_msix(ctrl_info);
+	rc = pqi_reset(ctrl_info);
+	if (rc)
+		return rc;
+	sis_reenable_sis_mode(ctrl_info);
+	pqi_save_ctrl_mode(ctrl_info, SIS_MODE);
+
+	return 0;
+}
+
+/*
+ * If the controller isn't already in SIS mode, this function forces it into
+ * SIS mode.
+ */
+
+static int pqi_force_sis_mode(struct pqi_ctrl_info *ctrl_info)
 {
 	if (!sis_is_firmware_running(ctrl_info))
 		return -ENXIO;
 
-	if (pqi_get_ctrl_mode(ctrl_info) == PQI_MODE) {
-		sis_disable_msix(ctrl_info);
-		if (pqi_reset(ctrl_info) == 0)
-			sis_reenable_sis_mode(ctrl_info);
+	if (pqi_get_ctrl_mode(ctrl_info) == SIS_MODE)
+		return 0;
+
+	if (sis_is_kernel_up(ctrl_info)) {
+		pqi_save_ctrl_mode(ctrl_info, SIS_MODE);
+		return 0;
 	}
 
-	return 0;
+	return pqi_revert_to_sis_mode(ctrl_info);
 }
 
 static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 {
 	int rc;
 
-	if (reset_devices) {
-		rc = pqi_kdump_init(ctrl_info);
-		if (rc)
-			return rc;
-	}
-
-	/*
-	 * When the controller comes out of reset, it is always running
-	 * in legacy SIS mode.  This is so that it can be compatible
-	 * with legacy drivers shipped with OSes.  So we have to talk
-	 * to it using SIS commands at first.  Once we are satisified
-	 * that the controller supports PQI, we transition it into PQI
-	 * mode.
-	 */
+	rc = pqi_force_sis_mode(ctrl_info);
+	if (rc)
+		return rc;
 
 	/*
 	 * Wait until the controller is ready to start accepting SIS
@@ -5594,12 +5606,8 @@ static void pqi_remove_ctrl(struct pqi_ctrl_info *ctrl_info)
 	cancel_delayed_work_sync(&ctrl_info->update_time_work);
 	pqi_remove_all_scsi_devices(ctrl_info);
 	pqi_unregister_scsi(ctrl_info);
-
-	if (ctrl_info->pqi_mode_enabled) {
-		sis_disable_msix(ctrl_info);
-		if (pqi_reset(ctrl_info) == 0)
-			sis_reenable_sis_mode(ctrl_info);
-	}
+	if (ctrl_info->pqi_mode_enabled)
+		pqi_revert_to_sis_mode(ctrl_info);
 	pqi_free_ctrl_resources(ctrl_info);
 }
 
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
index c7d9ea1..af59998 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.c
+++ b/drivers/scsi/smartpqi/smartpqi_sis.c
@@ -127,6 +127,21 @@ bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info)
 	return running;
 }
 
+bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
+{
+	u32 status;
+	bool kernel_up;
+
+	status = readl(&ctrl_info->registers->sis_firmware_status);
+
+	if (status & SIS_CTRL_KERNEL_UP)
+		kernel_up = true;
+	else
+		kernel_up = false;
+
+	return kernel_up;
+}
+
 /* used for passing command parameters/results when issuing SIS commands */
 struct sis_sync_cmd_params {
 	u32	mailbox[6];	/* mailboxes 0-5 */
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h
index 7f7b68c..157768d 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.h
+++ b/drivers/scsi/smartpqi/smartpqi_sis.h
@@ -21,6 +21,7 @@
 
 int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info);
 bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info);
+bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info);
 int sis_get_ctrl_properties(struct pqi_ctrl_info *ctrl_info);
 int sis_get_pqi_capabilities(struct pqi_ctrl_info *ctrl_info);
 int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info);

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

* [PATCH 06/37] smartpqi: add supporting events
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (4 preceding siblings ...)
  2017-04-25 19:46 ` [PATCH 05/37] smartpqi: ensure controller is in SIS mode at init Don Brace
@ 2017-04-25 19:46 ` Don Brace
  2017-04-25 19:46 ` [PATCH 07/37] smartpqi: enhance resets Don Brace
                   ` (30 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:46 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

Only register for controller events that driver supports
cleanup event handling.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |   11 +--
 drivers/scsi/smartpqi/smartpqi_init.c |  110 ++++++++++++++++++---------------
 2 files changed, 61 insertions(+), 60 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 62045c1..02b3196 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -860,15 +860,8 @@ struct pqi_io_request {
 	struct list_head request_list_entry;
 };
 
-/* for indexing into the pending_events[] field of struct pqi_ctrl_info */
 #define PQI_EVENT_HEARTBEAT		0
-#define PQI_EVENT_HOTPLUG		1
-#define PQI_EVENT_HARDWARE		2
-#define PQI_EVENT_PHYSICAL_DEVICE	3
-#define PQI_EVENT_LOGICAL_DEVICE	4
-#define PQI_EVENT_AIO_STATE_CHANGE	5
-#define PQI_EVENT_AIO_CONFIG_CHANGE	6
-#define PQI_NUM_SUPPORTED_EVENTS	7
+#define PQI_NUM_SUPPORTED_EVENTS	6
 
 struct pqi_event {
 	bool	pending;
@@ -951,7 +944,7 @@ struct pqi_ctrl_info {
 	struct pqi_io_request *io_request_pool;
 	u16		next_io_request_slot;
 
-	struct pqi_event pending_events[PQI_NUM_SUPPORTED_EVENTS];
+	struct pqi_event events[PQI_NUM_SUPPORTED_EVENTS];
 	struct work_struct event_work;
 
 	atomic_t	num_interrupts;
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index d28e694..174867d 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -81,6 +81,15 @@ static struct scsi_transport_template *pqi_sas_transport_template;
 
 static atomic_t pqi_controller_count = ATOMIC_INIT(0);
 
+static unsigned int pqi_supported_event_types[] = {
+	PQI_EVENT_TYPE_HOTPLUG,
+	PQI_EVENT_TYPE_HARDWARE,
+	PQI_EVENT_TYPE_PHYSICAL_DEVICE,
+	PQI_EVENT_TYPE_LOGICAL_DEVICE,
+	PQI_EVENT_TYPE_AIO_STATE_CHANGE,
+	PQI_EVENT_TYPE_AIO_CONFIG_CHANGE,
+};
+
 static int pqi_disable_device_id_wildcards;
 module_param_named(disable_device_id_wildcards,
 	pqi_disable_device_id_wildcards, int, S_IRUGO | S_IWUSR);
@@ -2665,20 +2674,20 @@ static void pqi_event_worker(struct work_struct *work)
 {
 	unsigned int i;
 	struct pqi_ctrl_info *ctrl_info;
-	struct pqi_event *pending_event;
+	struct pqi_event *event;
 	bool got_non_heartbeat_event = false;
 
 	ctrl_info = container_of(work, struct pqi_ctrl_info, event_work);
 
-	pending_event = ctrl_info->pending_events;
+	event = ctrl_info->events;
 	for (i = 0; i < PQI_NUM_SUPPORTED_EVENTS; i++) {
-		if (pending_event->pending) {
-			pending_event->pending = false;
-			pqi_acknowledge_event(ctrl_info, pending_event);
-			if (i != PQI_EVENT_HEARTBEAT)
+		if (event->pending) {
+			event->pending = false;
+			pqi_acknowledge_event(ctrl_info, event);
+			if (i != PQI_EVENT_TYPE_HEARTBEAT)
 				got_non_heartbeat_event = true;
 		}
-		pending_event++;
+		event++;
 	}
 
 	if (got_non_heartbeat_event)
@@ -2742,7 +2751,7 @@ static void pqi_heartbeat_timer_handler(unsigned long data)
 			pqi_take_ctrl_offline(ctrl_info);
 			return;
 		}
-		ctrl_info->pending_events[PQI_EVENT_HEARTBEAT].pending = true;
+		ctrl_info->events[PQI_EVENT_HEARTBEAT].pending = true;
 		schedule_work(&ctrl_info->event_work);
 	} else {
 		ctrl_info->num_heartbeats_requested = 0;
@@ -2773,38 +2782,20 @@ static inline void pqi_stop_heartbeat_timer(struct pqi_ctrl_info *ctrl_info)
 		del_timer_sync(&ctrl_info->heartbeat_timer);
 }
 
-static int pqi_event_type_to_event_index(unsigned int event_type)
+static inline int pqi_event_type_to_event_index(unsigned int event_type)
 {
 	int index;
 
-	switch (event_type) {
-	case PQI_EVENT_TYPE_HEARTBEAT:
-		index = PQI_EVENT_HEARTBEAT;
-		break;
-	case PQI_EVENT_TYPE_HOTPLUG:
-		index = PQI_EVENT_HOTPLUG;
-		break;
-	case PQI_EVENT_TYPE_HARDWARE:
-		index = PQI_EVENT_HARDWARE;
-		break;
-	case PQI_EVENT_TYPE_PHYSICAL_DEVICE:
-		index = PQI_EVENT_PHYSICAL_DEVICE;
-		break;
-	case PQI_EVENT_TYPE_LOGICAL_DEVICE:
-		index = PQI_EVENT_LOGICAL_DEVICE;
-		break;
-	case PQI_EVENT_TYPE_AIO_STATE_CHANGE:
-		index = PQI_EVENT_AIO_STATE_CHANGE;
-		break;
-	case PQI_EVENT_TYPE_AIO_CONFIG_CHANGE:
-		index = PQI_EVENT_AIO_CONFIG_CHANGE;
-		break;
-	default:
-		index = -1;
-		break;
-	}
+	for (index = 0; index < ARRAY_SIZE(pqi_supported_event_types); index++)
+		if (event_type == pqi_supported_event_types[index])
+			return index;
 
-	return index;
+	return -1;
+}
+
+static inline bool pqi_is_supported_event(unsigned int event_type)
+{
+	return pqi_event_type_to_event_index(event_type) != -1;
 }
 
 static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info)
@@ -2814,7 +2805,7 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info)
 	pqi_index_t oq_ci;
 	struct pqi_event_queue *event_queue;
 	struct pqi_event_response *response;
-	struct pqi_event *pending_event;
+	struct pqi_event *event;
 	bool need_delayed_work;
 	int event_index;
 
@@ -2837,15 +2828,14 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info)
 
 		if (event_index >= 0) {
 			if (response->request_acknowlege) {
-				pending_event =
-					&ctrl_info->pending_events[event_index];
-				pending_event->event_type =
-					response->event_type;
-				pending_event->event_id = response->event_id;
-				pending_event->additional_event_id =
+				event = &ctrl_info->events[event_index];
+				event->pending = true;
+				event->event_type = response->event_type;
+				event->event_id = response->event_id;
+				event->additional_event_id =
 					response->additional_event_id;
-				if (event_index != PQI_EVENT_HEARTBEAT) {
-					pending_event->pending = true;
+				if (event_index != PQI_EVENT_TYPE_HEARTBEAT) {
+					event->pending = true;
 					need_delayed_work = true;
 				}
 			}
@@ -3899,11 +3889,13 @@ static int pqi_create_queues(struct pqi_ctrl_info *ctrl_info)
 	(offsetof(struct pqi_event_config, descriptors) + \
 	(PQI_MAX_EVENT_DESCRIPTORS * sizeof(struct pqi_event_descriptor)))
 
-static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info)
+static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info,
+	bool enable_events)
 {
 	int rc;
 	unsigned int i;
 	struct pqi_event_config *event_config;
+	struct pqi_event_descriptor *event_descriptor;
 	struct pqi_general_management_request request;
 
 	event_config = kmalloc(PQI_REPORT_EVENT_CONFIG_BUFFER_LENGTH,
@@ -3937,9 +3929,15 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info)
 	if (rc)
 		goto out;
 
-	for (i = 0; i < event_config->num_event_descriptors; i++)
-		put_unaligned_le16(ctrl_info->event_queue.oq_id,
-			&event_config->descriptors[i].oq_id);
+	for (i = 0; i < event_config->num_event_descriptors; i++) {
+		event_descriptor = &event_config->descriptors[i];
+		if (enable_events &&
+			pqi_is_supported_event(event_descriptor->event_type))
+			put_unaligned_le16(ctrl_info->event_queue.oq_id,
+					&event_descriptor->oq_id);
+		else
+			put_unaligned_le16(0, &event_descriptor->oq_id);
+	}
 
 	memset(&request, 0, sizeof(request));
 
@@ -3970,6 +3968,16 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info)
 	return rc;
 }
 
+static inline int pqi_enable_events(struct pqi_ctrl_info *ctrl_info)
+{
+	return pqi_configure_events(ctrl_info, true);
+}
+
+static inline int pqi_disable_events(struct pqi_ctrl_info *ctrl_info)
+{
+	return pqi_configure_events(ctrl_info, false);
+}
+
 static void pqi_free_all_io_requests(struct pqi_ctrl_info *ctrl_info)
 {
 	unsigned int i;
@@ -5413,10 +5421,10 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 
 	sis_enable_msix(ctrl_info);
 
-	rc = pqi_configure_events(ctrl_info);
+	rc = pqi_enable_events(ctrl_info);
 	if (rc) {
 		dev_err(&ctrl_info->pci_dev->dev,
-			"error configuring events\n");
+			"error enabling events\n");
 		return rc;
 	}
 

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

* [PATCH 07/37] smartpqi: enhance resets
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (5 preceding siblings ...)
  2017-04-25 19:46 ` [PATCH 06/37] smartpqi: add supporting events Don Brace
@ 2017-04-25 19:46 ` Don Brace
  2017-04-25 20:01   ` Bart Van Assche
  2017-04-25 19:46 ` [PATCH 08/37] smartpqi: add suspend and resume support Don Brace
                   ` (29 subsequent siblings)
  36 siblings, 1 reply; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:46 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

- Block all I/O targeted at LUN reset device.
- Wait until all I/O targeted at LUN reset device has been
  consumed by the controller.
- Issue LUN reset request.
- Wait until all outstanding I/Os and LUN reset completion
  have been received by the host.
- Return to OS results of LUN reset request.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |   13 +-
 drivers/scsi/smartpqi/smartpqi_init.c |  279 ++++++++++++++++++++++++++++++---
 2 files changed, 265 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 02b3196..5b0c6fb 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -734,6 +734,8 @@ struct pqi_scsi_dev {
 	u8	new_device : 1;
 	u8	keep_device : 1;
 	u8	volume_offline : 1;
+	bool	in_reset;
+	bool	device_offline;
 	u8	vendor[8];		/* bytes 8-15 of inquiry data */
 	u8	model[16];		/* bytes 16-31 of inquiry data */
 	u64	sas_address;
@@ -761,6 +763,8 @@ struct pqi_scsi_dev {
 	struct list_head new_device_list_entry;
 	struct list_head add_list_entry;
 	struct list_head delete_list_entry;
+
+	atomic_t scsi_cmds_outstanding;
 };
 
 /* VPD inquiry pages */
@@ -926,7 +930,9 @@ struct pqi_ctrl_info {
 	struct Scsi_Host *scsi_host;
 
 	struct mutex	scan_mutex;
-	bool		controller_online : 1;
+	struct mutex	lun_reset_mutex;
+	bool		controller_online;
+	bool		block_requests;
 	u8		inbound_spanning_supported : 1;
 	u8		outbound_spanning_supported : 1;
 	u8		pqi_mode_enabled : 1;
@@ -953,7 +959,9 @@ struct pqi_ctrl_info {
 	struct timer_list heartbeat_timer;
 
 	struct semaphore sync_request_sem;
-	struct semaphore lun_reset_sem;
+	atomic_t	num_busy_threads;
+	atomic_t	num_blocked_threads;
+	wait_queue_head_t block_requests_wait;
 };
 
 enum pqi_ctrl_mode {
@@ -1092,6 +1100,7 @@ int pqi_add_sas_device(struct pqi_sas_node *pqi_sas_node,
 void pqi_remove_sas_device(struct pqi_scsi_dev *device);
 struct pqi_scsi_dev *pqi_find_device_by_sas_rphy(
 	struct pqi_ctrl_info *ctrl_info, struct sas_rphy *rphy);
+void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd);
 
 extern struct sas_function_template pqi_sas_transport_functions;
 
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 174867d..96bf318 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -126,6 +126,7 @@ static char *pqi_raid_level_to_string(u8 raid_level)
 
 static inline void pqi_scsi_done(struct scsi_cmnd *scmd)
 {
+	pqi_prep_for_scsi_done(scmd);
 	scmd->scsi_done(scmd);
 }
 
@@ -175,7 +176,85 @@ static inline void pqi_save_ctrl_mode(struct pqi_ctrl_info *ctrl_info,
 	sis_write_driver_scratch(ctrl_info, mode);
 }
 
-#define PQI_RESCAN_WORK_INTERVAL	(10 * HZ)
+#define PQI_RESCAN_WORK_INTERVAL       (10 * HZ)
+static inline void pqi_ctrl_block_requests(struct pqi_ctrl_info *ctrl_info)
+{
+	ctrl_info->block_requests = true;
+	scsi_block_requests(ctrl_info->scsi_host);
+}
+
+static inline void pqi_ctrl_unblock_requests(struct pqi_ctrl_info *ctrl_info)
+{
+	ctrl_info->block_requests = false;
+	wake_up_all(&ctrl_info->block_requests_wait);
+	scsi_unblock_requests(ctrl_info->scsi_host);
+}
+
+static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info)
+{
+	return ctrl_info->block_requests;
+}
+
+static unsigned long pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info,
+	unsigned long timeout_msecs)
+{
+	unsigned long remaining_msecs;
+
+	if (!pqi_ctrl_blocked(ctrl_info))
+		return timeout_msecs;
+
+	atomic_inc(&ctrl_info->num_blocked_threads);
+
+	if (timeout_msecs == NO_TIMEOUT) {
+		wait_event(ctrl_info->block_requests_wait,
+			!pqi_ctrl_blocked(ctrl_info));
+		remaining_msecs = timeout_msecs;
+	} else {
+		unsigned long remaining_jiffies;
+
+		remaining_jiffies =
+			wait_event_timeout(ctrl_info->block_requests_wait,
+				!pqi_ctrl_blocked(ctrl_info),
+				msecs_to_jiffies(timeout_msecs));
+		remaining_msecs = jiffies_to_msecs(remaining_jiffies);
+	}
+
+	atomic_dec(&ctrl_info->num_blocked_threads);
+
+	return remaining_msecs;
+}
+
+static inline void pqi_ctrl_busy(struct pqi_ctrl_info *ctrl_info)
+{
+	atomic_inc(&ctrl_info->num_busy_threads);
+}
+
+static inline void pqi_ctrl_unbusy(struct pqi_ctrl_info *ctrl_info)
+{
+	atomic_dec(&ctrl_info->num_busy_threads);
+}
+
+static inline void pqi_ctrl_wait_until_quiesced(struct pqi_ctrl_info *ctrl_info)
+{
+	while (atomic_read(&ctrl_info->num_busy_threads) >
+		atomic_read(&ctrl_info->num_blocked_threads))
+		usleep_range(1000, 2000);
+}
+
+static inline void pqi_device_reset_start(struct pqi_scsi_dev *device)
+{
+	device->in_reset = true;
+}
+
+static inline void pqi_device_reset_done(struct pqi_scsi_dev *device)
+{
+	device->in_reset = false;
+}
+
+static inline bool pqi_device_in_reset(struct pqi_scsi_dev *device)
+{
+	return device->in_reset;
+}
 
 static inline void pqi_schedule_rescan_worker(struct pqi_ctrl_info *ctrl_info)
 {
@@ -2679,6 +2758,9 @@ static void pqi_event_worker(struct work_struct *work)
 
 	ctrl_info = container_of(work, struct pqi_ctrl_info, event_work);
 
+	pqi_ctrl_busy(ctrl_info);
+	pqi_wait_if_ctrl_blocked(ctrl_info, NO_TIMEOUT);
+
 	event = ctrl_info->events;
 	for (i = 0; i < PQI_NUM_SUPPORTED_EVENTS; i++) {
 		if (event->pending) {
@@ -2690,8 +2772,9 @@ static void pqi_event_worker(struct work_struct *work)
 		event++;
 	}
 
-	if (got_non_heartbeat_event)
-		pqi_schedule_rescan_worker(ctrl_info);
+	pqi_ctrl_unbusy(ctrl_info);
+
+	pqi_schedule_rescan_worker(ctrl_info);
 }
 
 static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
@@ -3436,6 +3519,13 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info,
 		}
 	}
 
+	pqi_ctrl_busy(ctrl_info);
+	timeout_msecs = pqi_wait_if_ctrl_blocked(ctrl_info, timeout_msecs);
+	if (timeout_msecs == 0) {
+		rc = -ETIMEDOUT;
+		goto out;
+	}
+
 	io_request = pqi_alloc_io_request(ctrl_info);
 
 	put_unaligned_le16(io_request->index,
@@ -3476,6 +3566,8 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info,
 
 	pqi_free_io_request(io_request);
 
+out:
+	pqi_ctrl_unbusy(ctrl_info);
 	up(&ctrl_info->sync_request_sem);
 
 	return rc;
@@ -4499,6 +4591,19 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
 	return 0;
 }
 
+/*
+ * This function gets called just before we hand the completed SCSI request
+ * back to the SML.
+ */
+
+void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd)
+{
+	struct pqi_scsi_dev *device;
+
+	device = scmd->device->hostdata;
+	atomic_dec(&device->scsi_cmds_outstanding);
+}
+
 static int pqi_scsi_queue_command(struct Scsi_Host *shost,
 	struct scsi_cmnd *scmd)
 {
@@ -4512,12 +4617,20 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
 	device = scmd->device->hostdata;
 	ctrl_info = shost_to_hba(shost);
 
+	atomic_inc(&device->scsi_cmds_outstanding);
+
 	if (pqi_ctrl_offline(ctrl_info)) {
 		set_host_byte(scmd, DID_NO_CONNECT);
 		pqi_scsi_done(scmd);
 		return 0;
 	}
 
+	pqi_ctrl_busy(ctrl_info);
+	if (pqi_ctrl_blocked(ctrl_info) || pqi_device_in_reset(device)) {
+		rc = SCSI_MLQUEUE_HOST_BUSY;
+		goto out;
+	}
+
 	/*
 	 * This is necessary because the SML doesn't zero out this field during
 	 * error recovery.
@@ -4554,9 +4667,116 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
 				queue_group);
 	}
 
+out:
+	pqi_ctrl_unbusy(ctrl_info);
+	if (rc)
+		atomic_dec(&device->scsi_cmds_outstanding);
+
 	return rc;
 }
 
+static int pqi_wait_until_queued_io_drained(struct pqi_ctrl_info *ctrl_info,
+	struct pqi_queue_group *queue_group)
+{
+	unsigned int path;
+	unsigned long flags;
+	bool list_is_empty;
+
+	for (path = 0; path < 2; path++) {
+		while (1) {
+			spin_lock_irqsave(
+				&queue_group->submit_lock[path], flags);
+			list_is_empty =
+				list_empty(&queue_group->request_list[path]);
+			spin_unlock_irqrestore(
+				&queue_group->submit_lock[path], flags);
+			if (list_is_empty)
+				break;
+			pqi_check_ctrl_health(ctrl_info);
+			if (pqi_ctrl_offline(ctrl_info))
+				return -ENXIO;
+			usleep_range(1000, 2000);
+		}
+	}
+
+	return 0;
+}
+
+static int pqi_wait_until_inbound_queues_empty(struct pqi_ctrl_info *ctrl_info)
+{
+	int rc;
+	unsigned int i;
+	unsigned int path;
+	struct pqi_queue_group *queue_group;
+	pqi_index_t iq_pi;
+	pqi_index_t iq_ci;
+
+	for (i = 0; i < ctrl_info->num_queue_groups; i++) {
+		queue_group = &ctrl_info->queue_groups[i];
+
+		rc = pqi_wait_until_queued_io_drained(ctrl_info, queue_group);
+		if (rc)
+			return rc;
+
+		for (path = 0; path < 2; path++) {
+			iq_pi = queue_group->iq_pi_copy[path];
+
+			while (1) {
+				iq_ci = *queue_group->iq_ci[path];
+				if (iq_ci == iq_pi)
+					break;
+				pqi_check_ctrl_health(ctrl_info);
+				if (pqi_ctrl_offline(ctrl_info))
+					return -ENXIO;
+				usleep_range(1000, 2000);
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info,
+	struct pqi_scsi_dev *device)
+{
+	unsigned int i;
+	unsigned int path;
+	struct pqi_queue_group *queue_group;
+	unsigned long flags;
+	struct pqi_io_request *io_request;
+	struct pqi_io_request *next;
+	struct scsi_cmnd *scmd;
+	struct pqi_scsi_dev *scsi_device;
+
+	for (i = 0; i < ctrl_info->num_queue_groups; i++) {
+		queue_group = &ctrl_info->queue_groups[i];
+
+		for (path = 0; path < 2; path++) {
+			spin_lock_irqsave(
+				&queue_group->submit_lock[path], flags);
+
+			list_for_each_entry_safe(io_request, next,
+				&queue_group->request_list[path],
+				request_list_entry) {
+				scmd = io_request->scmd;
+				if (!scmd)
+					continue;
+
+				scsi_device = scmd->device->hostdata;
+				if (scsi_device != device)
+					continue;
+
+				list_del(&io_request->request_list_entry);
+				set_host_byte(scmd, DID_RESET);
+				pqi_scsi_done(scmd);
+			}
+
+			spin_unlock_irqrestore(
+				&queue_group->submit_lock[path], flags);
+		}
+	}
+}
+
 static void pqi_lun_reset_complete(struct pqi_io_request *io_request,
 	void *context)
 {
@@ -4571,7 +4791,6 @@ static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info,
 	struct pqi_scsi_dev *device, struct completion *wait)
 {
 	int rc;
-	unsigned int wait_secs = 0;
 
 	while (1) {
 		if (wait_for_completion_io_timeout(wait,
@@ -4585,13 +4804,6 @@ static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info,
 			rc = -ETIMEDOUT;
 			break;
 		}
-
-		wait_secs += PQI_LUN_RESET_TIMEOUT_SECS;
-
-		dev_err(&ctrl_info->pci_dev->dev,
-			"resetting scsi %d:%d:%d:%d - waiting %u seconds\n",
-			ctrl_info->scsi_host->host_no, device->bus,
-			device->target, device->lun, wait_secs);
 	}
 
 	return rc;
@@ -4605,8 +4817,6 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info,
 	DECLARE_COMPLETION_ONSTACK(wait);
 	struct pqi_task_management_request *request;
 
-	down(&ctrl_info->lun_reset_sem);
-
 	io_request = pqi_alloc_io_request(ctrl_info);
 	io_request->io_complete_callback = pqi_lun_reset_complete;
 	io_request->context = &wait;
@@ -4631,7 +4841,6 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info,
 		rc = io_request->status;
 
 	pqi_free_io_request(io_request);
-	up(&ctrl_info->lun_reset_sem);
 
 	return rc;
 }
@@ -4643,10 +4852,6 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
 {
 	int rc;
 
-	pqi_check_ctrl_health(ctrl_info);
-	if (pqi_ctrl_offline(ctrl_info))
-		return FAILED;
-
 	rc = pqi_lun_reset(ctrl_info, device);
 
 	return rc == 0 ? SUCCESS : FAILED;
@@ -4655,23 +4860,46 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
 static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd)
 {
 	int rc;
+	struct Scsi_Host *shost;
 	struct pqi_ctrl_info *ctrl_info;
 	struct pqi_scsi_dev *device;
 
-	ctrl_info = shost_to_hba(scmd->device->host);
+	shost = scmd->device->host;
+	ctrl_info = shost_to_hba(shost);
 	device = scmd->device->hostdata;
 
 	dev_err(&ctrl_info->pci_dev->dev,
 		"resetting scsi %d:%d:%d:%d\n",
-		ctrl_info->scsi_host->host_no,
-		device->bus, device->target, device->lun);
+		shost->host_no, device->bus, device->target, device->lun);
 
-	rc = pqi_device_reset(ctrl_info, device);
+	pqi_check_ctrl_health(ctrl_info);
+	if (pqi_ctrl_offline(ctrl_info)) {
+		rc = FAILED;
+		goto out;
+	}
 
+	mutex_lock(&ctrl_info->lun_reset_mutex);
+
+	pqi_ctrl_block_requests(ctrl_info);
+	pqi_ctrl_wait_until_quiesced(ctrl_info);
+	pqi_fail_io_queued_for_device(ctrl_info, device);
+	rc = pqi_wait_until_inbound_queues_empty(ctrl_info);
+	pqi_device_reset_start(device);
+	pqi_ctrl_unblock_requests(ctrl_info);
+
+	if (rc)
+		rc = FAILED;
+	else
+		rc = pqi_device_reset(ctrl_info, device);
+
+	pqi_device_reset_done(device);
+
+	mutex_unlock(&ctrl_info->lun_reset_mutex);
+
+out:
 	dev_err(&ctrl_info->pci_dev->dev,
 		"reset of scsi %d:%d:%d:%d: %s\n",
-		ctrl_info->scsi_host->host_no,
-		device->bus, device->target, device->lun,
+		shost->host_no, device->bus, device->target, device->lun,
 		rc == SUCCESS ? "SUCCESS" : "FAILED");
 
 	return rc;
@@ -5552,6 +5780,7 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node)
 		return NULL;
 
 	mutex_init(&ctrl_info->scan_mutex);
+	mutex_init(&ctrl_info->lun_reset_mutex);
 
 	INIT_LIST_HEAD(&ctrl_info->scsi_device_list);
 	spin_lock_init(&ctrl_info->scsi_device_list_lock);
@@ -5564,7 +5793,7 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node)
 
 	sema_init(&ctrl_info->sync_request_sem,
 		PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS);
-	sema_init(&ctrl_info->lun_reset_sem, PQI_RESERVED_IO_SLOTS_LUN_RESET);
+	init_waitqueue_head(&ctrl_info->block_requests_wait);
 
 	ctrl_info->ctrl_id = atomic_inc_return(&pqi_controller_count) - 1;
 	ctrl_info->max_msix_vectors = PQI_MAX_MSIX_VECTORS;

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

* [PATCH 08/37] smartpqi: add suspend and resume support
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (6 preceding siblings ...)
  2017-04-25 19:46 ` [PATCH 07/37] smartpqi: enhance resets Don Brace
@ 2017-04-25 19:46 ` Don Brace
  2017-04-25 20:05   ` Bart Van Assche
  2017-04-25 19:46 ` [PATCH 09/37] smartpqi: add heartbeat check Don Brace
                   ` (28 subsequent siblings)
  36 siblings, 1 reply; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:46 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@microsemi.com>

add support for ACPI S3 (suspend) and S4 (hibernate) system power states.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |   12 +
 drivers/scsi/smartpqi/smartpqi_init.c |  424 +++++++++++++++++++++++++++++++--
 drivers/scsi/smartpqi/smartpqi_sis.c  |   75 ++++++
 drivers/scsi/smartpqi/smartpqi_sis.h  |    3 
 4 files changed, 485 insertions(+), 29 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 5b0c6fb..06e2b71 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -61,7 +61,7 @@ struct pqi_device_registers {
 /*
  * controller registers
  *
- * These are defined by the PMC implementation.
+ * These are defined by the Microsemi implementation.
  *
  * Some registers (those named sis_*) are only used when in
  * legacy SIS mode before we transition the controller into
@@ -102,6 +102,12 @@ enum pqi_io_path {
 	AIO_PATH = 1
 };
 
+enum pqi_irq_mode {
+	IRQ_MODE_NONE,
+	IRQ_MODE_INTX,
+	IRQ_MODE_MSIX
+};
+
 struct pqi_sg_descriptor {
 	__le64	address;
 	__le32	length;
@@ -908,7 +914,7 @@ struct pqi_ctrl_info {
 	dma_addr_t	error_buffer_dma_handle;
 	size_t		sg_chain_buffer_length;
 	unsigned int	num_queue_groups;
-	unsigned int	num_active_queue_groups;
+	u16		max_hw_queue_index;
 	u16		num_elements_per_iq;
 	u16		num_elements_per_oq;
 	u16		max_inbound_iu_length_per_firmware;
@@ -923,6 +929,7 @@ struct pqi_ctrl_info {
 	struct pqi_admin_queues admin_queues;
 	struct pqi_queue_group queue_groups[PQI_MAX_QUEUE_GROUPS];
 	struct pqi_event_queue event_queue;
+	enum pqi_irq_mode irq_mode;
 	int		max_msix_vectors;
 	int		num_msix_vectors_enabled;
 	int		num_msix_vectors_initialized;
@@ -937,6 +944,7 @@ struct pqi_ctrl_info {
 	u8		outbound_spanning_supported : 1;
 	u8		pqi_mode_enabled : 1;
 	u8		heartbeat_timer_started : 1;
+	u8		update_time_worker_scheduled : 1;
 
 	struct list_head scsi_device_list;
 	spinlock_t	scsi_device_list_lock;
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 96bf318..ca9d010 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -262,6 +262,11 @@ static inline void pqi_schedule_rescan_worker(struct pqi_ctrl_info *ctrl_info)
 		PQI_RESCAN_WORK_INTERVAL);
 }
 
+static inline void pqi_cancel_rescan_worker(struct pqi_ctrl_info *ctrl_info)
+{
+	cancel_delayed_work_sync(&ctrl_info->rescan_work);
+}
+
 static int pqi_map_single(struct pci_dev *pci_dev,
 	struct pqi_sg_descriptor *sg_descriptor, void *buffer,
 	size_t buffer_length, int data_direction)
@@ -588,7 +593,7 @@ static int pqi_write_driver_version_to_host_wellness(
 	buffer->driver_version_tag[1] = 'V';
 	put_unaligned_le16(sizeof(buffer->driver_version),
 		&buffer->driver_version_length);
-	strncpy(buffer->driver_version, DRIVER_VERSION,
+	strncpy(buffer->driver_version, "Linux " DRIVER_VERSION,
 		sizeof(buffer->driver_version) - 1);
 	buffer->driver_version[sizeof(buffer->driver_version) - 1] = '\0';
 	buffer->end_tag[0] = 'Z';
@@ -686,7 +691,21 @@ static void pqi_update_time_worker(struct work_struct *work)
 static inline void pqi_schedule_update_time_worker(
 	struct pqi_ctrl_info *ctrl_info)
 {
+	if (ctrl_info->update_time_worker_scheduled)
+		return;
+
 	schedule_delayed_work(&ctrl_info->update_time_work, 0);
+	ctrl_info->update_time_worker_scheduled = true;
+}
+
+static inline void pqi_cancel_update_time_worker(
+	struct pqi_ctrl_info *ctrl_info)
+{
+	if (!ctrl_info->update_time_worker_scheduled)
+		return;
+
+	cancel_delayed_work_sync(&ctrl_info->update_time_work);
+	ctrl_info->update_time_worker_scheduled = false;
 }
 
 static int pqi_report_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd,
@@ -1967,6 +1986,18 @@ static int pqi_scan_finished(struct Scsi_Host *shost,
 	return !mutex_is_locked(&ctrl_info->scan_mutex);
 }
 
+static void pqi_wait_until_scan_finished(struct pqi_ctrl_info *ctrl_info)
+{
+	mutex_lock(&ctrl_info->scan_mutex);
+	mutex_unlock(&ctrl_info->scan_mutex);
+}
+
+static void pqi_wait_until_lun_reset_finished(struct pqi_ctrl_info *ctrl_info)
+{
+	mutex_lock(&ctrl_info->lun_reset_mutex);
+	mutex_unlock(&ctrl_info->lun_reset_mutex);
+}
+
 static inline void pqi_set_encryption_info(
 	struct pqi_encryption_info *encryption_info, struct raid_map *raid_map,
 	u64 first_block)
@@ -2825,6 +2856,9 @@ static void pqi_heartbeat_timer_handler(unsigned long data)
 	int num_interrupts;
 	struct pqi_ctrl_info *ctrl_info = (struct pqi_ctrl_info *)data;
 
+	if (!ctrl_info->heartbeat_timer_started)
+		return;
+
 	num_interrupts = atomic_read(&ctrl_info->num_interrupts);
 
 	if (num_interrupts == ctrl_info->previous_num_interrupts) {
@@ -2855,14 +2889,16 @@ static void pqi_start_heartbeat_timer(struct pqi_ctrl_info *ctrl_info)
 		jiffies + PQI_HEARTBEAT_TIMER_INTERVAL;
 	ctrl_info->heartbeat_timer.data = (unsigned long)ctrl_info;
 	ctrl_info->heartbeat_timer.function = pqi_heartbeat_timer_handler;
-	add_timer(&ctrl_info->heartbeat_timer);
 	ctrl_info->heartbeat_timer_started = true;
+	add_timer(&ctrl_info->heartbeat_timer);
 }
 
 static inline void pqi_stop_heartbeat_timer(struct pqi_ctrl_info *ctrl_info)
 {
-	if (ctrl_info->heartbeat_timer_started)
+	if (ctrl_info->heartbeat_timer_started) {
+		ctrl_info->heartbeat_timer_started = false;
 		del_timer_sync(&ctrl_info->heartbeat_timer);
+	}
 }
 
 static inline int pqi_event_type_to_event_index(unsigned int event_type)
@@ -2938,6 +2974,106 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info)
 	return num_events;
 }
 
+#define PQI_LEGACY_INTX_MASK	0x1
+
+static inline void pqi_configure_legacy_intx(struct pqi_ctrl_info *ctrl_info,
+						bool enable_intx)
+{
+	u32 intx_mask;
+	struct pqi_device_registers __iomem *pqi_registers;
+	volatile void __iomem *register_addr;
+
+	pqi_registers = ctrl_info->pqi_registers;
+
+	if (enable_intx)
+		register_addr = &pqi_registers->legacy_intx_mask_clear;
+	else
+		register_addr = &pqi_registers->legacy_intx_mask_set;
+
+	intx_mask = readl(register_addr);
+	intx_mask |= PQI_LEGACY_INTX_MASK;
+	writel(intx_mask, register_addr);
+}
+
+static void pqi_change_irq_mode(struct pqi_ctrl_info *ctrl_info,
+	enum pqi_irq_mode new_mode)
+{
+	switch (ctrl_info->irq_mode) {
+	case IRQ_MODE_MSIX:
+		switch (new_mode) {
+		case IRQ_MODE_MSIX:
+			break;
+		case IRQ_MODE_INTX:
+			pqi_configure_legacy_intx(ctrl_info, true);
+			sis_disable_msix(ctrl_info);
+			sis_enable_intx(ctrl_info);
+			break;
+		case IRQ_MODE_NONE:
+			sis_disable_msix(ctrl_info);
+			break;
+		}
+		break;
+	case IRQ_MODE_INTX:
+		switch (new_mode) {
+		case IRQ_MODE_MSIX:
+			pqi_configure_legacy_intx(ctrl_info, false);
+			sis_disable_intx(ctrl_info);
+			sis_enable_msix(ctrl_info);
+			break;
+		case IRQ_MODE_INTX:
+			break;
+		case IRQ_MODE_NONE:
+			pqi_configure_legacy_intx(ctrl_info, false);
+			sis_disable_intx(ctrl_info);
+			break;
+		}
+		break;
+	case IRQ_MODE_NONE:
+		switch (new_mode) {
+		case IRQ_MODE_MSIX:
+			sis_enable_msix(ctrl_info);
+			break;
+		case IRQ_MODE_INTX:
+			pqi_configure_legacy_intx(ctrl_info, true);
+			sis_enable_intx(ctrl_info);
+			break;
+		case IRQ_MODE_NONE:
+			break;
+		}
+		break;
+	}
+
+	ctrl_info->irq_mode = new_mode;
+}
+
+#define PQI_LEGACY_INTX_PENDING		0x1
+
+static inline bool pqi_is_valid_irq(struct pqi_ctrl_info *ctrl_info)
+{
+	bool valid_irq;
+	u32 intx_status;
+
+	switch (ctrl_info->irq_mode) {
+	case IRQ_MODE_MSIX:
+		valid_irq = true;
+		break;
+	case IRQ_MODE_INTX:
+		intx_status =
+			readl(&ctrl_info->pqi_registers->legacy_intx_status);
+		if (intx_status & PQI_LEGACY_INTX_PENDING)
+			valid_irq = true;
+		else
+			valid_irq = false;
+		break;
+	case IRQ_MODE_NONE:
+	default:
+		valid_irq = false;
+		break;
+	}
+
+	return valid_irq;
+}
+
 static irqreturn_t pqi_irq_handler(int irq, void *data)
 {
 	struct pqi_ctrl_info *ctrl_info;
@@ -2947,7 +3083,7 @@ static irqreturn_t pqi_irq_handler(int irq, void *data)
 	queue_group = data;
 	ctrl_info = queue_group->ctrl_info;
 
-	if (!ctrl_info || !queue_group->oq_ci)
+	if (!pqi_is_valid_irq(ctrl_info))
 		return IRQ_NONE;
 
 	num_responses_handled = pqi_process_io_intr(ctrl_info, queue_group);
@@ -3013,6 +3149,7 @@ static int pqi_enable_msix_interrupts(struct pqi_ctrl_info *ctrl_info)
 	}
 
 	ctrl_info->num_msix_vectors_enabled = num_vectors_enabled;
+	ctrl_info->irq_mode = IRQ_MODE_MSIX;
 
 	return 0;
 }
@@ -3798,16 +3935,15 @@ static int pqi_create_event_queue(struct pqi_ctrl_info *ctrl_info)
 	return 0;
 }
 
-static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info)
+static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info,
+	unsigned int group_number)
 {
-	unsigned int i;
 	int rc;
 	struct pqi_queue_group *queue_group;
 	struct pqi_general_admin_request request;
 	struct pqi_general_admin_response response;
 
-	i = ctrl_info->num_active_queue_groups;
-	queue_group = &ctrl_info->queue_groups[i];
+	queue_group = &ctrl_info->queue_groups[group_number];
 
 	/*
 	 * Create IQ (Inbound Queue - host to device queue) for
@@ -3937,8 +4073,6 @@ static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info)
 		get_unaligned_le64(
 			&response.data.create_operational_oq.oq_ci_offset);
 
-	ctrl_info->num_active_queue_groups++;
-
 	return 0;
 
 delete_inbound_queue_aio:
@@ -3965,7 +4099,7 @@ static int pqi_create_queues(struct pqi_ctrl_info *ctrl_info)
 	}
 
 	for (i = 0; i < ctrl_info->num_queue_groups; i++) {
-		rc = pqi_create_queue_group(ctrl_info);
+		rc = pqi_create_queue_group(ctrl_info, i);
 		if (rc) {
 			dev_err(&ctrl_info->pci_dev->dev,
 				"error creating queue group number %u/%u\n",
@@ -4219,6 +4353,7 @@ static void pqi_calculate_queue_resources(struct pqi_ctrl_info *ctrl_info)
 	num_queue_groups = min(num_queue_groups, max_queue_groups);
 
 	ctrl_info->num_queue_groups = num_queue_groups;
+	ctrl_info->max_hw_queue_index = num_queue_groups - 1;
 
 	/*
 	 * Make sure that the max. inbound IU length is an even multiple
@@ -4591,6 +4726,18 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
 	return 0;
 }
 
+static inline u16 pqi_get_hw_queue(struct pqi_ctrl_info *ctrl_info,
+	struct scsi_cmnd *scmd)
+{
+	u16 hw_queue;
+
+	hw_queue = blk_mq_unique_tag_to_hwq(blk_mq_unique_tag(scmd->request));
+	if (hw_queue > ctrl_info->max_hw_queue_index)
+		hw_queue = 0;
+
+	return hw_queue;
+}
+
 /*
  * This function gets called just before we hand the completed SCSI request
  * back to the SML.
@@ -4610,7 +4757,7 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
 	int rc;
 	struct pqi_ctrl_info *ctrl_info;
 	struct pqi_scsi_dev *device;
-	u16 hwq;
+	u16 hw_queue;
 	struct pqi_queue_group *queue_group;
 	bool raid_bypassed;
 
@@ -4637,11 +4784,8 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
 	 */
 	scmd->result = 0;
 
-	hwq = blk_mq_unique_tag_to_hwq(blk_mq_unique_tag(scmd->request));
-	if (hwq >= ctrl_info->num_queue_groups)
-		hwq = 0;
-
-	queue_group = &ctrl_info->queue_groups[hwq];
+	hw_queue = pqi_get_hw_queue(ctrl_info, scmd);
+	queue_group = &ctrl_info->queue_groups[hw_queue];
 
 	if (pqi_is_logical_device(device)) {
 		raid_bypassed = false;
@@ -4777,6 +4921,52 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info,
 	}
 }
 
+static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
+	struct pqi_scsi_dev *device)
+{
+	while (atomic_read(&device->scsi_cmds_outstanding)) {
+		pqi_check_ctrl_health(ctrl_info);
+		if (pqi_ctrl_offline(ctrl_info))
+			return -ENXIO;
+		usleep_range(1000, 2000);
+	}
+
+	return 0;
+}
+
+static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info)
+{
+	bool io_pending;
+	unsigned long flags;
+	struct pqi_scsi_dev *device;
+
+	while (1) {
+		io_pending = false;
+
+		spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
+		list_for_each_entry(device, &ctrl_info->scsi_device_list,
+			scsi_device_list_entry) {
+			if (atomic_read(&device->scsi_cmds_outstanding)) {
+				io_pending = true;
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock,
+					flags);
+
+		if (!io_pending)
+			break;
+
+		pqi_check_ctrl_health(ctrl_info);
+		if (pqi_ctrl_offline(ctrl_info))
+			return -ENXIO;
+
+		usleep_range(1000, 2000);
+	}
+
+	return 0;
+}
+
 static void pqi_lun_reset_complete(struct pqi_io_request *io_request,
 	void *context)
 {
@@ -4853,6 +5043,8 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
 	int rc;
 
 	rc = pqi_lun_reset(ctrl_info, device);
+	if (rc == 0)
+		rc = pqi_device_wait_for_pending_io(ctrl_info, device);
 
 	return rc == 0 ? SUCCESS : FAILED;
 }
@@ -5487,7 +5679,7 @@ static int pqi_revert_to_sis_mode(struct pqi_ctrl_info *ctrl_info)
 {
 	int rc;
 
-	sis_disable_msix(ctrl_info);
+	pqi_change_irq_mode(ctrl_info, IRQ_MODE_NONE);
 	rc = pqi_reset(ctrl_info);
 	if (rc)
 		return rc;
@@ -5647,7 +5839,10 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 	if (rc)
 		return rc;
 
-	sis_enable_msix(ctrl_info);
+	pqi_change_irq_mode(ctrl_info, IRQ_MODE_MSIX);
+
+	ctrl_info->controller_online = true;
+	pqi_start_heartbeat_timer(ctrl_info);
 
 	rc = pqi_enable_events(ctrl_info);
 	if (rc) {
@@ -5656,10 +5851,6 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 		return rc;
 	}
 
-	pqi_start_heartbeat_timer(ctrl_info);
-
-	ctrl_info->controller_online = true;
-
 	/* Register with the SCSI subsystem. */
 	rc = pqi_register_scsi(ctrl_info);
 	if (rc)
@@ -5686,6 +5877,116 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 	return 0;
 }
 
+#if defined(CONFIG_PM)
+
+static void pqi_reinit_queues(struct pqi_ctrl_info *ctrl_info)
+{
+	unsigned int i;
+	struct pqi_admin_queues *admin_queues;
+	struct pqi_event_queue *event_queue;
+
+	admin_queues = &ctrl_info->admin_queues;
+	admin_queues->iq_pi_copy = 0;
+	admin_queues->oq_ci_copy = 0;
+	*admin_queues->oq_pi = 0;
+
+	for (i = 0; i < ctrl_info->num_queue_groups; i++) {
+		ctrl_info->queue_groups[i].iq_pi_copy[RAID_PATH] = 0;
+		ctrl_info->queue_groups[i].iq_pi_copy[AIO_PATH] = 0;
+		ctrl_info->queue_groups[i].oq_ci_copy = 0;
+
+		*ctrl_info->queue_groups[i].iq_ci[RAID_PATH] = 0;
+		*ctrl_info->queue_groups[i].iq_ci[AIO_PATH] = 0;
+		*ctrl_info->queue_groups[i].oq_pi = 0;
+	}
+
+	event_queue = &ctrl_info->event_queue;
+	*event_queue->oq_pi = 0;
+	event_queue->oq_ci_copy = 0;
+}
+
+static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info)
+{
+	int rc;
+
+	rc = pqi_force_sis_mode(ctrl_info);
+	if (rc)
+		return rc;
+
+	/*
+	 * Wait until the controller is ready to start accepting SIS
+	 * commands.
+	 */
+	rc = sis_wait_for_ctrl_ready_resume(ctrl_info);
+	if (rc)
+		return rc;
+
+	/*
+	 * If the function we are about to call succeeds, the
+	 * controller will transition from legacy SIS mode
+	 * into PQI mode.
+	 */
+	rc = sis_init_base_struct_addr(ctrl_info);
+	if (rc) {
+		dev_err(&ctrl_info->pci_dev->dev,
+			"error initializing PQI mode\n");
+		return rc;
+	}
+
+	/* Wait for the controller to complete the SIS -> PQI transition. */
+	rc = pqi_wait_for_pqi_mode_ready(ctrl_info);
+	if (rc) {
+		dev_err(&ctrl_info->pci_dev->dev,
+			"transition to PQI mode failed\n");
+		return rc;
+	}
+
+	/* From here on, we are running in PQI mode. */
+	ctrl_info->pqi_mode_enabled = true;
+	pqi_save_ctrl_mode(ctrl_info, PQI_MODE);
+
+	pqi_reinit_queues(ctrl_info);
+
+	rc = pqi_create_admin_queues(ctrl_info);
+	if (rc) {
+		dev_err(&ctrl_info->pci_dev->dev,
+			"error creating admin queues\n");
+		return rc;
+	}
+
+	rc = pqi_create_queues(ctrl_info);
+	if (rc)
+		return rc;
+
+	pqi_change_irq_mode(ctrl_info, IRQ_MODE_MSIX);
+
+	ctrl_info->controller_online = true;
+	pqi_start_heartbeat_timer(ctrl_info);
+	pqi_ctrl_unblock_requests(ctrl_info);
+
+	rc = pqi_enable_events(ctrl_info);
+	if (rc) {
+		dev_err(&ctrl_info->pci_dev->dev,
+			"error configuring events\n");
+		return rc;
+	}
+
+	rc = pqi_write_driver_version_to_host_wellness(ctrl_info);
+	if (rc) {
+		dev_err(&ctrl_info->pci_dev->dev,
+			"error updating host wellness\n");
+		return rc;
+	}
+
+	pqi_schedule_update_time_worker(ctrl_info);
+
+	pqi_scan_scsi_devices(ctrl_info);
+
+	return 0;
+}
+
+#endif /* CONFIG_PM */
+
 static inline int pqi_set_pcie_completion_timeout(struct pci_dev *pci_dev,
 	u16 timeout)
 {
@@ -5796,6 +6097,7 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node)
 	init_waitqueue_head(&ctrl_info->block_requests_wait);
 
 	ctrl_info->ctrl_id = atomic_inc_return(&pqi_controller_count) - 1;
+	ctrl_info->irq_mode = IRQ_MODE_NONE;
 	ctrl_info->max_msix_vectors = PQI_MAX_MSIX_VECTORS;
 
 	return ctrl_info;
@@ -5839,8 +6141,8 @@ static void pqi_free_ctrl_resources(struct pqi_ctrl_info *ctrl_info)
 
 static void pqi_remove_ctrl(struct pqi_ctrl_info *ctrl_info)
 {
-	cancel_delayed_work_sync(&ctrl_info->rescan_work);
-	cancel_delayed_work_sync(&ctrl_info->update_time_work);
+	pqi_cancel_rescan_worker(ctrl_info);
+	pqi_cancel_update_time_worker(ctrl_info);
 	pqi_remove_all_scsi_devices(ctrl_info);
 	pqi_unregister_scsi(ctrl_info);
 	if (ctrl_info->pqi_mode_enabled)
@@ -5952,6 +6254,71 @@ static void pqi_shutdown(struct pci_dev *pdev)
 		"unable to flush controller cache\n");
 }
 
+#if defined(CONFIG_PM)
+
+static int pqi_suspend(struct pci_dev *pci_dev, pm_message_t state)
+{
+	struct pqi_ctrl_info *ctrl_info;
+
+	ctrl_info = pci_get_drvdata(pci_dev);
+
+	pqi_disable_events(ctrl_info);
+	pqi_cancel_update_time_worker(ctrl_info);
+	pqi_cancel_rescan_worker(ctrl_info);
+	pqi_wait_until_scan_finished(ctrl_info);
+	pqi_wait_until_lun_reset_finished(ctrl_info);
+	pqi_flush_cache(ctrl_info);
+	pqi_ctrl_block_requests(ctrl_info);
+	pqi_ctrl_wait_until_quiesced(ctrl_info);
+	pqi_wait_until_inbound_queues_empty(ctrl_info);
+	pqi_ctrl_wait_for_pending_io(ctrl_info);
+	pqi_stop_heartbeat_timer(ctrl_info);
+
+	if (state.event == PM_EVENT_FREEZE)
+		return 0;
+
+	pci_save_state(pci_dev);
+	pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
+
+	ctrl_info->controller_online = false;
+	ctrl_info->pqi_mode_enabled = false;
+
+	return 0;
+}
+
+static int pqi_resume(struct pci_dev *pci_dev)
+{
+	int rc;
+	struct pqi_ctrl_info *ctrl_info;
+
+	ctrl_info = pci_get_drvdata(pci_dev);
+
+	if (pci_dev->current_state != PCI_D0) {
+		ctrl_info->max_hw_queue_index = 0;
+		pqi_free_interrupts(ctrl_info);
+		pqi_change_irq_mode(ctrl_info, IRQ_MODE_INTX);
+		rc = request_irq(pci_irq_vector(pci_dev, 0), pqi_irq_handler,
+			IRQF_SHARED, DRIVER_NAME_SHORT,
+			&ctrl_info->queue_groups[0]);
+		if (rc) {
+			dev_err(&ctrl_info->pci_dev->dev,
+				"irq %u init failed with error %d\n",
+				pci_dev->irq, rc);
+			return rc;
+		}
+		pqi_start_heartbeat_timer(ctrl_info);
+		pqi_ctrl_unblock_requests(ctrl_info);
+		return 0;
+	}
+
+	pci_set_power_state(pci_dev, PCI_D0);
+	pci_restore_state(pci_dev);
+
+	return pqi_ctrl_init_resume(ctrl_info);
+}
+
+#endif /* CONFIG_PM */
+
 /* Define the PCI IDs for the controllers that we support. */
 static const struct pci_device_id pqi_pci_id_table[] = {
 	{
@@ -6093,6 +6460,10 @@ static struct pci_driver pqi_pci_driver = {
 	.probe = pqi_pci_probe,
 	.remove = pqi_pci_remove,
 	.shutdown = pqi_shutdown,
+#if defined(CONFIG_PM)
+	.suspend = pqi_suspend,
+	.resume = pqi_resume,
+#endif
 };
 
 static int __init pqi_init(void)
@@ -6458,6 +6829,9 @@ static void __attribute__((unused)) verify_structures(void)
 	BUILD_BUG_ON(offsetof(struct pqi_event_config,
 		descriptors) != 4);
 
+	BUILD_BUG_ON(PQI_NUM_SUPPORTED_EVENTS !=
+		ARRAY_SIZE(pqi_supported_event_types));
+
 	BUILD_BUG_ON(offsetof(struct pqi_event_response,
 		header.iu_type) != 0);
 	BUILD_BUG_ON(offsetof(struct pqi_event_response,
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
index af59998..7302611 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.c
+++ b/drivers/scsi/smartpqi/smartpqi_sis.c
@@ -33,6 +33,7 @@
 /* for submission of legacy SIS commands */
 #define SIS_REENABLE_SIS_MODE			0x1
 #define SIS_ENABLE_MSIX				0x40
+#define SIS_ENABLE_INTX				0x80
 #define SIS_SOFT_RESET				0x100
 #define SIS_TRIGGER_SHUTDOWN			0x800000
 #define SIS_CMD_READY				0x200
@@ -56,6 +57,7 @@
 #define SIS_CTRL_KERNEL_UP			0x80
 #define SIS_CTRL_KERNEL_PANIC			0x100
 #define SIS_CTRL_READY_TIMEOUT_SECS		30
+#define SIS_CTRL_READY_RESUME_TIMEOUT_SECS	90
 #define SIS_CTRL_READY_POLL_INTERVAL_MSECS	10
 
 #pragma pack(1)
@@ -79,12 +81,13 @@ struct sis_base_struct {
 
 #pragma pack()
 
-int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info)
+static int sis_wait_for_ctrl_ready_with_timeout(struct pqi_ctrl_info *ctrl_info,
+	unsigned int timeout_secs)
 {
 	unsigned long timeout;
 	u32 status;
 
-	timeout = (SIS_CTRL_READY_TIMEOUT_SECS * HZ) + jiffies;
+	timeout = (timeout_secs * HZ) + jiffies;
 
 	while (1) {
 		status = readl(&ctrl_info->registers->sis_firmware_status);
@@ -107,6 +110,18 @@ int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info)
 	return 0;
 }
 
+int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info)
+{
+	return sis_wait_for_ctrl_ready_with_timeout(ctrl_info,
+		SIS_CTRL_READY_TIMEOUT_SECS);
+}
+
+int sis_wait_for_ctrl_ready_resume(struct pqi_ctrl_info *ctrl_info)
+{
+	return sis_wait_for_ctrl_ready_with_timeout(ctrl_info,
+		SIS_CTRL_READY_RESUME_TIMEOUT_SECS);
+}
+
 bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info)
 {
 	bool running;
@@ -324,6 +339,34 @@ int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info)
 	return rc;
 }
 
+#define SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS	30
+
+static void sis_wait_for_doorbell_bit_to_clear(
+	struct pqi_ctrl_info *ctrl_info, u32 bit)
+{
+	u32 doorbell_register;
+	unsigned long timeout;
+
+	timeout = (SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS * HZ) + jiffies;
+
+	while (1) {
+		doorbell_register =
+			readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell);
+		if ((doorbell_register & bit) == 0)
+			break;
+		if (readl(&ctrl_info->registers->sis_firmware_status) &
+			SIS_CTRL_KERNEL_PANIC)
+			break;
+		if (time_after(jiffies, timeout)) {
+			dev_err(&ctrl_info->pci_dev->dev,
+				"doorbell register bit 0x%x not cleared\n",
+				bit);
+			break;
+		}
+		usleep_range(1000, 2000);
+	}
+}
+
 /* Enable MSI-X interrupts on the controller. */
 
 void sis_enable_msix(struct pqi_ctrl_info *ctrl_info)
@@ -336,6 +379,8 @@ void sis_enable_msix(struct pqi_ctrl_info *ctrl_info)
 
 	writel(doorbell_register,
 		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
+
+	sis_wait_for_doorbell_bit_to_clear(ctrl_info, SIS_ENABLE_MSIX);
 }
 
 /* Disable MSI-X interrupts on the controller. */
@@ -352,6 +397,32 @@ void sis_disable_msix(struct pqi_ctrl_info *ctrl_info)
 		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
 }
 
+void sis_enable_intx(struct pqi_ctrl_info *ctrl_info)
+{
+	u32 doorbell_register;
+
+	doorbell_register =
+		readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell);
+	doorbell_register |= SIS_ENABLE_INTX;
+
+	writel(doorbell_register,
+		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
+
+	sis_wait_for_doorbell_bit_to_clear(ctrl_info, SIS_ENABLE_INTX);
+}
+
+void sis_disable_intx(struct pqi_ctrl_info *ctrl_info)
+{
+	u32 doorbell_register;
+
+	doorbell_register =
+		readl(&ctrl_info->registers->sis_host_to_ctrl_doorbell);
+	doorbell_register &= ~SIS_ENABLE_INTX;
+
+	writel(doorbell_register,
+		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
+}
+
 void sis_soft_reset(struct pqi_ctrl_info *ctrl_info)
 {
 	writel(SIS_SOFT_RESET,
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h
index 157768d..08ee0ab 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.h
+++ b/drivers/scsi/smartpqi/smartpqi_sis.h
@@ -20,6 +20,7 @@
 #define _SMARTPQI_SIS_H
 
 int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info);
+int sis_wait_for_ctrl_ready_resume(struct pqi_ctrl_info *ctrl_info);
 bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info);
 bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info);
 int sis_get_ctrl_properties(struct pqi_ctrl_info *ctrl_info);
@@ -27,6 +28,8 @@ int sis_get_pqi_capabilities(struct pqi_ctrl_info *ctrl_info);
 int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info);
 void sis_enable_msix(struct pqi_ctrl_info *ctrl_info);
 void sis_disable_msix(struct pqi_ctrl_info *ctrl_info);
+void sis_enable_intx(struct pqi_ctrl_info *ctrl_info);
+void sis_disable_intx(struct pqi_ctrl_info *ctrl_info);
 void sis_soft_reset(struct pqi_ctrl_info *ctrl_info);
 void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info);
 int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info);

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

* [PATCH 09/37] smartpqi: add heartbeat check
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (7 preceding siblings ...)
  2017-04-25 19:46 ` [PATCH 08/37] smartpqi: add suspend and resume support Don Brace
@ 2017-04-25 19:46 ` Don Brace
  2017-04-25 19:46 ` [PATCH 10/37] smartpqi: correct bdma hw bug Don Brace
                   ` (27 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:46 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@microsemi.com>

check for controller lockups

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |   60 ++++++++++++++--
 drivers/scsi/smartpqi/smartpqi_init.c |  126 ++++++++++++++++++++++-----------
 drivers/scsi/smartpqi/smartpqi_sis.c  |    4 +
 3 files changed, 143 insertions(+), 47 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 06e2b71..1ac09e7 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -490,7 +490,6 @@ struct pqi_raid_error_info {
 #define PQI_EVENT_TYPE_LOGICAL_DEVICE		0x5
 #define PQI_EVENT_TYPE_AIO_STATE_CHANGE		0xfd
 #define PQI_EVENT_TYPE_AIO_CONFIG_CHANGE	0xfe
-#define PQI_EVENT_TYPE_HEARTBEAT		0xff
 
 #pragma pack()
 
@@ -635,6 +634,58 @@ struct pqi_encryption_info {
 	u32	encrypt_tweak_upper;
 };
 
+#pragma pack(1)
+
+#define PQI_CONFIG_TABLE_SIGNATURE	"CFGTABLE"
+#define PQI_CONFIG_TABLE_MAX_LENGTH	((u16)~0)
+
+/* configuration table section IDs */
+#define PQI_CONFIG_TABLE_SECTION_GENERAL_INFO		0
+#define PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES	1
+#define PQI_CONFIG_TABLE_SECTION_FIRMWARE_ERRATA	2
+#define PQI_CONFIG_TABLE_SECTION_DEBUG			3
+#define PQI_CONFIG_TABLE_SECTION_HEARTBEAT		4
+
+struct pqi_config_table {
+	u8	signature[8];		/* "CFGTABLE" */
+	__le32	first_section_offset;	/* offset in bytes from the base */
+					/* address of this table to the */
+					/* first section */
+};
+
+struct pqi_config_table_section_header {
+	__le16	section_id;		/* as defined by the */
+					/* PQI_CONFIG_TABLE_SECTION_* */
+					/* manifest constants above */
+	__le16	next_section_offset;	/* offset in bytes from base */
+					/* address of the table of the */
+					/* next section or 0 if last entry */
+};
+
+struct pqi_config_table_general_info {
+	struct pqi_config_table_section_header header;
+	__le32	section_length;		/* size of this section in bytes */
+					/* including the section header */
+	__le32	max_outstanding_requests;	/* max. outstanding */
+						/* commands supported by */
+						/* the controller */
+	__le32	max_sg_size;		/* max. transfer size of a single */
+					/* command */
+	__le32	max_sg_per_request;	/* max. number of scatter-gather */
+					/* entries supported in a single */
+					/* command */
+};
+
+struct pqi_config_table_debug {
+	struct pqi_config_table_section_header header;
+	__le32	scratchpad;
+};
+
+struct pqi_config_table_heartbeat {
+	struct pqi_config_table_section_header header;
+	__le32	heartbeat_counter;
+};
+
 #define PQI_MAX_OUTSTANDING_REQUESTS	((u32)~0)
 #define PQI_MAX_TRANSFER_SIZE		(4 * 1024U * 1024U)
 
@@ -645,8 +696,6 @@ struct pqi_encryption_info {
 #define PQI_HBA_BUS			2
 #define PQI_MAX_BUS			PQI_HBA_BUS
 
-#pragma pack(1)
-
 struct report_lun_header {
 	__be32	list_length;
 	u8	extended_response;
@@ -870,7 +919,6 @@ struct pqi_io_request {
 	struct list_head request_list_entry;
 };
 
-#define PQI_EVENT_HEARTBEAT		0
 #define PQI_NUM_SUPPORTED_EVENTS	6
 
 struct pqi_event {
@@ -943,7 +991,6 @@ struct pqi_ctrl_info {
 	u8		inbound_spanning_supported : 1;
 	u8		outbound_spanning_supported : 1;
 	u8		pqi_mode_enabled : 1;
-	u8		heartbeat_timer_started : 1;
 	u8		update_time_worker_scheduled : 1;
 
 	struct list_head scsi_device_list;
@@ -963,7 +1010,8 @@ struct pqi_ctrl_info {
 
 	atomic_t	num_interrupts;
 	int		previous_num_interrupts;
-	unsigned int	num_heartbeats_requested;
+	u32		previous_heartbeat_count;
+	__le32 __iomem	*heartbeat_counter;
 	struct timer_list heartbeat_timer;
 
 	struct semaphore sync_request_sem;
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index ca9d010..eda5a1a 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -267,6 +267,14 @@ static inline void pqi_cancel_rescan_worker(struct pqi_ctrl_info *ctrl_info)
 	cancel_delayed_work_sync(&ctrl_info->rescan_work);
 }
 
+static inline u32 pqi_read_heartbeat_counter(struct pqi_ctrl_info *ctrl_info)
+{
+	if (!ctrl_info->heartbeat_counter)
+		return 0;
+
+	return readl(ctrl_info->heartbeat_counter);
+}
+
 static int pqi_map_single(struct pci_dev *pci_dev,
 	struct pqi_sg_descriptor *sg_descriptor, void *buffer,
 	size_t buffer_length, int data_direction)
@@ -2708,23 +2716,18 @@ static inline unsigned int pqi_num_elements_free(unsigned int pi,
 	return elements_in_queue - num_elements_used - 1;
 }
 
-#define PQI_EVENT_ACK_TIMEOUT	30
-
-static void pqi_start_event_ack(struct pqi_ctrl_info *ctrl_info,
+static void pqi_send_event_ack(struct pqi_ctrl_info *ctrl_info,
 	struct pqi_event_acknowledge_request *iu, size_t iu_length)
 {
 	pqi_index_t iq_pi;
 	pqi_index_t iq_ci;
 	unsigned long flags;
 	void *next_element;
-	unsigned long timeout;
 	struct pqi_queue_group *queue_group;
 
 	queue_group = &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP];
 	put_unaligned_le16(queue_group->oq_id, &iu->header.response_queue_id);
 
-	timeout = (PQI_EVENT_ACK_TIMEOUT * HZ) + jiffies;
-
 	while (1) {
 		spin_lock_irqsave(&queue_group->submit_lock[RAID_PATH], flags);
 
@@ -2738,11 +2741,8 @@ static void pqi_start_event_ack(struct pqi_ctrl_info *ctrl_info,
 		spin_unlock_irqrestore(
 			&queue_group->submit_lock[RAID_PATH], flags);
 
-		if (time_after(jiffies, timeout)) {
-			dev_err(&ctrl_info->pci_dev->dev,
-				"sending event acknowledge timed out\n");
+		if (pqi_ctrl_offline(ctrl_info))
 			return;
-		}
 	}
 
 	next_element = queue_group->iq_element_array[RAID_PATH] +
@@ -2751,7 +2751,6 @@ static void pqi_start_event_ack(struct pqi_ctrl_info *ctrl_info,
 	memcpy(next_element, iu, iu_length);
 
 	iq_pi = (iq_pi + 1) % ctrl_info->num_elements_per_iq;
-
 	queue_group->iq_pi_copy[RAID_PATH] = iq_pi;
 
 	/*
@@ -2777,7 +2776,7 @@ static void pqi_acknowledge_event(struct pqi_ctrl_info *ctrl_info,
 	request.event_id = event->event_id;
 	request.additional_event_id = event->additional_event_id;
 
-	pqi_start_event_ack(ctrl_info, &request, sizeof(request));
+	pqi_send_event_ack(ctrl_info, &request, sizeof(request));
 }
 
 static void pqi_event_worker(struct work_struct *work)
@@ -2785,7 +2784,6 @@ static void pqi_event_worker(struct work_struct *work)
 	unsigned int i;
 	struct pqi_ctrl_info *ctrl_info;
 	struct pqi_event *event;
-	bool got_non_heartbeat_event = false;
 
 	ctrl_info = container_of(work, struct pqi_ctrl_info, event_work);
 
@@ -2797,8 +2795,6 @@ static void pqi_event_worker(struct work_struct *work)
 		if (event->pending) {
 			event->pending = false;
 			pqi_acknowledge_event(ctrl_info, event);
-			if (i != PQI_EVENT_TYPE_HEARTBEAT)
-				got_non_heartbeat_event = true;
 		}
 		event++;
 	}
@@ -2848,57 +2844,58 @@ static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
 	}
 }
 
-#define PQI_HEARTBEAT_TIMER_INTERVAL	(5 * HZ)
-#define PQI_MAX_HEARTBEAT_REQUESTS	5
+#define PQI_HEARTBEAT_TIMER_INTERVAL	(10 * HZ)
 
 static void pqi_heartbeat_timer_handler(unsigned long data)
 {
 	int num_interrupts;
+	u32 heartbeat_count;
 	struct pqi_ctrl_info *ctrl_info = (struct pqi_ctrl_info *)data;
 
-	if (!ctrl_info->heartbeat_timer_started)
+	pqi_check_ctrl_health(ctrl_info);
+	if (pqi_ctrl_offline(ctrl_info))
 		return;
 
 	num_interrupts = atomic_read(&ctrl_info->num_interrupts);
+	heartbeat_count = pqi_read_heartbeat_counter(ctrl_info);
 
 	if (num_interrupts == ctrl_info->previous_num_interrupts) {
-		ctrl_info->num_heartbeats_requested++;
-		if (ctrl_info->num_heartbeats_requested >
-			PQI_MAX_HEARTBEAT_REQUESTS) {
+		if (heartbeat_count == ctrl_info->previous_heartbeat_count) {
+			dev_err(&ctrl_info->pci_dev->dev,
+				"no heartbeat detected - last heartbeat count: %u\n",
+				heartbeat_count);
 			pqi_take_ctrl_offline(ctrl_info);
 			return;
 		}
-		ctrl_info->events[PQI_EVENT_HEARTBEAT].pending = true;
-		schedule_work(&ctrl_info->event_work);
 	} else {
-		ctrl_info->num_heartbeats_requested = 0;
+		ctrl_info->previous_num_interrupts = num_interrupts;
 	}
 
-	ctrl_info->previous_num_interrupts = num_interrupts;
+	ctrl_info->previous_heartbeat_count = heartbeat_count;
 	mod_timer(&ctrl_info->heartbeat_timer,
 		jiffies + PQI_HEARTBEAT_TIMER_INTERVAL);
 }
 
 static void pqi_start_heartbeat_timer(struct pqi_ctrl_info *ctrl_info)
 {
+	if (!ctrl_info->heartbeat_counter)
+		return;
+
 	ctrl_info->previous_num_interrupts =
 		atomic_read(&ctrl_info->num_interrupts);
+	ctrl_info->previous_heartbeat_count =
+		pqi_read_heartbeat_counter(ctrl_info);
 
-	init_timer(&ctrl_info->heartbeat_timer);
 	ctrl_info->heartbeat_timer.expires =
 		jiffies + PQI_HEARTBEAT_TIMER_INTERVAL;
 	ctrl_info->heartbeat_timer.data = (unsigned long)ctrl_info;
 	ctrl_info->heartbeat_timer.function = pqi_heartbeat_timer_handler;
-	ctrl_info->heartbeat_timer_started = true;
 	add_timer(&ctrl_info->heartbeat_timer);
 }
 
 static inline void pqi_stop_heartbeat_timer(struct pqi_ctrl_info *ctrl_info)
 {
-	if (ctrl_info->heartbeat_timer_started) {
-		ctrl_info->heartbeat_timer_started = false;
-		del_timer_sync(&ctrl_info->heartbeat_timer);
-	}
+	del_timer_sync(&ctrl_info->heartbeat_timer);
 }
 
 static inline int pqi_event_type_to_event_index(unsigned int event_type)
@@ -2925,12 +2922,10 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info)
 	struct pqi_event_queue *event_queue;
 	struct pqi_event_response *response;
 	struct pqi_event *event;
-	bool need_delayed_work;
 	int event_index;
 
 	event_queue = &ctrl_info->event_queue;
 	num_events = 0;
-	need_delayed_work = false;
 	oq_ci = event_queue->oq_ci_copy;
 
 	while (1) {
@@ -2953,10 +2948,6 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info)
 				event->event_id = response->event_id;
 				event->additional_event_id =
 					response->additional_event_id;
-				if (event_index != PQI_EVENT_TYPE_HEARTBEAT) {
-					event->pending = true;
-					need_delayed_work = true;
-				}
 			}
 		}
 
@@ -2966,9 +2957,7 @@ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info)
 	if (num_events) {
 		event_queue->oq_ci_copy = oq_ci;
 		writel(oq_ci, event_queue->oq_ci);
-
-		if (need_delayed_work)
-			schedule_work(&ctrl_info->event_work);
+		schedule_work(&ctrl_info->event_work);
 	}
 
 	return num_events;
@@ -3221,7 +3210,7 @@ static int pqi_alloc_operational_queues(struct pqi_ctrl_info *ctrl_info)
 
 	if (!ctrl_info->queue_memory_base) {
 		dev_err(&ctrl_info->pci_dev->dev,
-			"failed to allocate memory for PQI admin queues\n");
+			"unable to allocate memory for PQI admin queues\n");
 		return -ENOMEM;
 	}
 
@@ -5673,6 +5662,55 @@ static int pqi_get_ctrl_firmware_version(struct pqi_ctrl_info *ctrl_info)
 	return rc;
 }
 
+static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info)
+{
+	u32 table_length;
+	u32 section_offset;
+	void __iomem *table_iomem_addr;
+	struct pqi_config_table *config_table;
+	struct pqi_config_table_section_header *section;
+
+	table_length = ctrl_info->config_table_length;
+
+	config_table = kmalloc(table_length, GFP_KERNEL);
+	if (!config_table) {
+		dev_err(&ctrl_info->pci_dev->dev,
+			"unable to allocate memory for PQI configuration table\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * Copy the config table contents from I/O memory space into the
+	 * temporary buffer.
+	 */
+	table_iomem_addr = ctrl_info->iomem_base +
+		ctrl_info->config_table_offset;
+	memcpy_fromio(config_table, table_iomem_addr, table_length);
+
+	section_offset =
+		get_unaligned_le32(&config_table->first_section_offset);
+
+	while (section_offset) {
+		section = (void *)config_table + section_offset;
+
+		switch (get_unaligned_le16(&section->section_id)) {
+		case PQI_CONFIG_TABLE_SECTION_HEARTBEAT:
+			ctrl_info->heartbeat_counter = table_iomem_addr +
+				section_offset +
+				offsetof(struct pqi_config_table_heartbeat,
+					heartbeat_counter);
+			break;
+		}
+
+		section_offset =
+			get_unaligned_le16(&section->next_section_offset);
+	}
+
+	kfree(config_table);
+
+	return 0;
+}
+
 /* Switches the controller from PQI mode back into SIS mode. */
 
 static int pqi_revert_to_sis_mode(struct pqi_ctrl_info *ctrl_info)
@@ -5784,6 +5822,10 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 	ctrl_info->pqi_mode_enabled = true;
 	pqi_save_ctrl_mode(ctrl_info, PQI_MODE);
 
+	rc = pqi_process_config_table(ctrl_info);
+	if (rc)
+		return rc;
+
 	rc = pqi_alloc_admin_queues(ctrl_info);
 	if (rc) {
 		dev_err(&ctrl_info->pci_dev->dev,
@@ -6092,6 +6134,8 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node)
 	INIT_DELAYED_WORK(&ctrl_info->rescan_work, pqi_rescan_worker);
 	INIT_DELAYED_WORK(&ctrl_info->update_time_work, pqi_update_time_worker);
 
+	init_timer(&ctrl_info->heartbeat_timer);
+
 	sema_init(&ctrl_info->sync_request_sem,
 		PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS);
 	init_waitqueue_head(&ctrl_info->block_requests_wait);
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
index 7302611..6ca05a6 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.c
+++ b/drivers/scsi/smartpqi/smartpqi_sis.c
@@ -431,6 +431,10 @@ void sis_soft_reset(struct pqi_ctrl_info *ctrl_info)
 
 void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info)
 {
+	if (readl(&ctrl_info->registers->sis_firmware_status) &
+		SIS_CTRL_KERNEL_PANIC)
+		return;
+
 	writel(SIS_TRIGGER_SHUTDOWN,
 		&ctrl_info->registers->sis_host_to_ctrl_doorbell);
 }

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

* [PATCH 10/37] smartpqi: correct bdma hw bug
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (8 preceding siblings ...)
  2017-04-25 19:46 ` [PATCH 09/37] smartpqi: add heartbeat check Don Brace
@ 2017-04-25 19:46 ` Don Brace
  2017-04-25 19:46 ` [PATCH 11/37] smartpqi: add pqi_wait_for_completion_io Don Brace
                   ` (26 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:46 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

add workaround for BDMA hardware bug that can cause
hw to read up to 12 SGL elements (192 bytes) beyond the
last element in the list. This fix avoids IOMMU violations

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index eda5a1a..30fc7b1 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -48,6 +48,8 @@
 #define DRIVER_NAME		"Microsemi PQI Driver (v" DRIVER_VERSION ")"
 #define DRIVER_NAME_SHORT	"smartpqi"
 
+#define PQI_EXTRA_SGL_MEMORY	(12 * sizeof(struct pqi_sg_descriptor))
+
 MODULE_AUTHOR("Microsemi");
 MODULE_DESCRIPTION("Driver for Microsemi Smart Family Controller version "
 	DRIVER_VERSION);
@@ -3203,6 +3205,8 @@ static int pqi_alloc_operational_queues(struct pqi_ctrl_info *ctrl_info)
 	alloc_length = (size_t)aligned_pointer +
 		PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT;
 
+	alloc_length += PQI_EXTRA_SGL_MEMORY;
+
 	ctrl_info->queue_memory_base =
 		dma_zalloc_coherent(&ctrl_info->pci_dev->dev,
 			alloc_length,
@@ -4320,7 +4324,8 @@ static void pqi_calculate_io_resources(struct pqi_ctrl_info *ctrl_info)
 	max_transfer_size = (max_sg_entries - 1) * PAGE_SIZE;
 
 	ctrl_info->sg_chain_buffer_length =
-		max_sg_entries * sizeof(struct pqi_sg_descriptor);
+		(max_sg_entries * sizeof(struct pqi_sg_descriptor)) +
+		PQI_EXTRA_SGL_MEMORY;
 	ctrl_info->sg_tablesize = max_sg_entries;
 	ctrl_info->max_sectors = max_transfer_size / 512;
 }

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

* [PATCH 11/37] smartpqi: add pqi_wait_for_completion_io
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (9 preceding siblings ...)
  2017-04-25 19:46 ` [PATCH 10/37] smartpqi: correct bdma hw bug Don Brace
@ 2017-04-25 19:46 ` Don Brace
  2017-04-25 19:47 ` [PATCH 12/37] smartpqi: change functions to inline Don Brace
                   ` (25 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:46 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

Add check for controller lockup during waits for synchronous
controller commands.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 30fc7b1..728db8f 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -3579,6 +3579,37 @@ static void pqi_start_io(struct pqi_ctrl_info *ctrl_info,
 	spin_unlock_irqrestore(&queue_group->submit_lock[path], flags);
 }
 
+#define PQI_WAIT_FOR_COMPLETION_IO_TIMEOUT_SECS		10
+
+static int pqi_wait_for_completion_io(struct pqi_ctrl_info *ctrl_info,
+	struct completion *wait)
+{
+	int rc;
+	unsigned int wait_secs = 0;
+
+	while (1) {
+		if (wait_for_completion_io_timeout(wait,
+			PQI_WAIT_FOR_COMPLETION_IO_TIMEOUT_SECS * HZ)) {
+			rc = 0;
+			break;
+		}
+
+		pqi_check_ctrl_health(ctrl_info);
+		if (pqi_ctrl_offline(ctrl_info)) {
+			rc = -ENXIO;
+			break;
+		}
+
+		wait_secs += PQI_WAIT_FOR_COMPLETION_IO_TIMEOUT_SECS;
+
+		dev_err(&ctrl_info->pci_dev->dev,
+			"waiting %u seconds for completion\n",
+			wait_secs);
+	}
+
+	return rc;
+}
+
 static void pqi_raid_synchronous_complete(struct pqi_io_request *io_request,
 	void *context)
 {
@@ -3602,7 +3633,7 @@ static int pqi_submit_raid_request_synchronous_with_io_request(
 		io_request);
 
 	if (timeout_msecs == NO_TIMEOUT) {
-		wait_for_completion_io(&wait);
+		pqi_wait_for_completion_io(ctrl_info, &wait);
 	} else {
 		if (!wait_for_completion_io_timeout(&wait,
 			msecs_to_jiffies(timeout_msecs))) {

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

* [PATCH 12/37] smartpqi: change functions to inline
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (10 preceding siblings ...)
  2017-04-25 19:46 ` [PATCH 11/37] smartpqi: add pqi_wait_for_completion_io Don Brace
@ 2017-04-25 19:47 ` Don Brace
  2017-04-25 20:07   ` Bart Van Assche
  2017-04-25 19:47 ` [PATCH 13/37] smartpqi: make pdev pointer names consistent Don Brace
                   ` (24 subsequent siblings)
  36 siblings, 1 reply; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:47 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 728db8f..523b730 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -432,7 +432,7 @@ static struct pqi_io_request *pqi_alloc_io_request(
 	return io_request;
 }
 
-static void pqi_free_io_request(struct pqi_io_request *io_request)
+static inline void pqi_free_io_request(struct pqi_io_request *io_request)
 {
 	atomic_dec(&io_request->refcount);
 }

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

* [PATCH 13/37] smartpqi: make pdev pointer names consistent
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (11 preceding siblings ...)
  2017-04-25 19:47 ` [PATCH 12/37] smartpqi: change functions to inline Don Brace
@ 2017-04-25 19:47 ` Don Brace
  2017-04-25 19:47 ` [PATCH 14/37] smartpqi: eliminate redundant error messages Don Brace
                   ` (23 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:47 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

make all variable names for pointers to struct pci_dev consistent
throughout the driver.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   41 +++++++++++++++++----------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 523b730..0755af2 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -3095,17 +3095,17 @@ static int pqi_request_irqs(struct pqi_ctrl_info *ctrl_info)
 {
 	int i;
 	int rc;
-	struct pci_dev *pdev = ctrl_info->pci_dev;
+	struct pci_dev *pci_dev = ctrl_info->pci_dev;
 
-	ctrl_info->event_irq = pci_irq_vector(pdev, 0);
+	ctrl_info->event_irq = pci_irq_vector(pci_dev, 0);
 
 	for (i = 0; i < ctrl_info->num_msix_vectors_enabled; i++) {
-		rc = request_irq(pci_irq_vector(pdev, i), pqi_irq_handler, 0,
+		rc = request_irq(pci_irq_vector(pci_dev, i), pqi_irq_handler, 0,
 			DRIVER_NAME_SHORT, &ctrl_info->queue_groups[i]);
 		if (rc) {
-			dev_err(&pdev->dev,
+			dev_err(&pci_dev->dev,
 				"irq %u init failed with error %d\n",
-				pci_irq_vector(pdev, i), rc);
+				pci_irq_vector(pci_dev, i), rc);
 			return rc;
 		}
 		ctrl_info->num_msix_vectors_initialized++;
@@ -6230,7 +6230,7 @@ static void pqi_remove_ctrl(struct pqi_ctrl_info *ctrl_info)
 	pqi_free_ctrl_resources(ctrl_info);
 }
 
-static void pqi_print_ctrl_info(struct pci_dev *pdev,
+static void pqi_print_ctrl_info(struct pci_dev *pci_dev,
 	const struct pci_device_id *id)
 {
 	char *ctrl_description;
@@ -6249,41 +6249,42 @@ static void pqi_print_ctrl_info(struct pci_dev *pdev,
 		}
 	}
 
-	dev_info(&pdev->dev, "%s found\n", ctrl_description);
+	dev_info(&pci_dev->dev, "%s found\n", ctrl_description);
 }
 
-static int pqi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int pqi_pci_probe(struct pci_dev *pci_dev,
+	const struct pci_device_id *id)
 {
 	int rc;
 	int node;
 	struct pqi_ctrl_info *ctrl_info;
 
-	pqi_print_ctrl_info(pdev, id);
+	pqi_print_ctrl_info(pci_dev, id);
 
 	if (pqi_disable_device_id_wildcards &&
 		id->subvendor == PCI_ANY_ID &&
 		id->subdevice == PCI_ANY_ID) {
-		dev_warn(&pdev->dev,
+		dev_warn(&pci_dev->dev,
 			"controller not probed because device ID wildcards are disabled\n");
 		return -ENODEV;
 	}
 
 	if (id->subvendor == PCI_ANY_ID || id->subdevice == PCI_ANY_ID)
-		dev_warn(&pdev->dev,
+		dev_warn(&pci_dev->dev,
 			"controller device ID matched using wildcards\n");
 
-	node = dev_to_node(&pdev->dev);
+	node = dev_to_node(&pci_dev->dev);
 	if (node == NUMA_NO_NODE)
-		set_dev_node(&pdev->dev, 0);
+		set_dev_node(&pci_dev->dev, 0);
 
 	ctrl_info = pqi_alloc_ctrl_info(node);
 	if (!ctrl_info) {
-		dev_err(&pdev->dev,
+		dev_err(&pci_dev->dev,
 			"failed to allocate controller info block\n");
 		return -ENOMEM;
 	}
 
-	ctrl_info->pci_dev = pdev;
+	ctrl_info->pci_dev = pci_dev;
 
 	rc = pqi_pci_init(ctrl_info);
 	if (rc)
@@ -6301,23 +6302,23 @@ static int pqi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	return rc;
 }
 
-static void pqi_pci_remove(struct pci_dev *pdev)
+static void pqi_pci_remove(struct pci_dev *pci_dev)
 {
 	struct pqi_ctrl_info *ctrl_info;
 
-	ctrl_info = pci_get_drvdata(pdev);
+	ctrl_info = pci_get_drvdata(pci_dev);
 	if (!ctrl_info)
 		return;
 
 	pqi_remove_ctrl(ctrl_info);
 }
 
-static void pqi_shutdown(struct pci_dev *pdev)
+static void pqi_shutdown(struct pci_dev *pci_dev)
 {
 	int rc;
 	struct pqi_ctrl_info *ctrl_info;
 
-	ctrl_info = pci_get_drvdata(pdev);
+	ctrl_info = pci_get_drvdata(pci_dev);
 	if (!ctrl_info)
 		goto error;
 
@@ -6330,7 +6331,7 @@ static void pqi_shutdown(struct pci_dev *pdev)
 		return;
 
 error:
-	dev_warn(&pdev->dev,
+	dev_warn(&pci_dev->dev,
 		"unable to flush controller cache\n");
 }
 

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

* [PATCH 14/37] smartpqi: eliminate redundant error messages
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (12 preceding siblings ...)
  2017-04-25 19:47 ` [PATCH 13/37] smartpqi: make pdev pointer names consistent Don Brace
@ 2017-04-25 19:47 ` Don Brace
  2017-04-25 19:47 ` [PATCH 15/37] smartpqi: correct BMIC identify physical drive Don Brace
                   ` (22 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:47 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

eliminate redundant error message during initialization
if the controller has crashed.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |    5 +----
 drivers/scsi/smartpqi/smartpqi_sis.c  |    5 ++++-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 0755af2..5a1fab1 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -5797,11 +5797,8 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 	 * commands.
 	 */
 	rc = sis_wait_for_ctrl_ready(ctrl_info);
-	if (rc) {
-		dev_err(&ctrl_info->pci_dev->dev,
-			"error initializing SIS interface\n");
+	if (rc)
 		return rc;
-	}
 
 	/*
 	 * Get the controller properties.  This allows us to determine
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
index 6ca05a6..7a8c0a6 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.c
+++ b/drivers/scsi/smartpqi/smartpqi_sis.c
@@ -102,8 +102,11 @@ static int sis_wait_for_ctrl_ready_with_timeout(struct pqi_ctrl_info *ctrl_info,
 			if (status & SIS_CTRL_KERNEL_UP)
 				break;
 		}
-		if (time_after(jiffies, timeout))
+		if (time_after(jiffies, timeout)) {
+			dev_err(&ctrl_info->pci_dev->dev,
+				"controller not ready\n");
 			return -ETIMEDOUT;
+		}
 		msleep(SIS_CTRL_READY_POLL_INTERVAL_MSECS);
 	}
 

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

* [PATCH 15/37] smartpqi: correct BMIC identify physical drive
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (13 preceding siblings ...)
  2017-04-25 19:47 ` [PATCH 14/37] smartpqi: eliminate redundant error messages Don Brace
@ 2017-04-25 19:47 ` Don Brace
  2017-04-25 19:47 ` [PATCH 16/37] smartpqi: minor driver cleanup Don Brace
                   ` (21 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:47 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

correct the BMIC Identify Physical Device structure
 - missing 2 fields

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |   20 ++++++++++++++++----
 drivers/scsi/smartpqi/smartpqi_init.c |   16 ++++++++++++++++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 1ac09e7..e74d3ed 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -1126,9 +1126,9 @@ struct bmic_identify_physical_device {
 	u8	multi_lun_device_lun_count;
 	u8	minimum_good_fw_revision[8];
 	u8	unique_inquiry_bytes[20];
-	u8	current_temperature_degreesC;
-	u8	temperature_threshold_degreesC;
-	u8	max_temperature_degreesC;
+	u8	current_temperature_degrees;
+	u8	temperature_threshold_degrees;
+	u8	max_temperature_degrees;
 	u8	logical_blocks_per_phys_block_exp;
 	__le16	current_queue_depth_limit;
 	u8	switch_name[10];
@@ -1141,10 +1141,22 @@ struct bmic_identify_physical_device {
 	u8	smart_carrier_authentication;
 	u8	smart_carrier_app_fw_version;
 	u8	smart_carrier_bootloader_fw_version;
+	u8	sanitize_flags;
+	u8	encryption_key_flags;
 	u8	encryption_key_name[64];
 	__le32	misc_drive_flags;
 	__le16	dek_index;
-	u8	padding[112];
+	__le16	hba_drive_encryption_flags;
+	__le16	max_overwrite_time;
+	__le16	max_block_erase_time;
+	__le16	max_crypto_erase_time;
+	u8	connector_info[5];
+	u8	connector_name[8][8];
+	u8	page_83_identifier[16];
+	u8	maximum_link_rate[256];
+	u8	negotiated_physical_link_rate[256];
+	u8	box_connector_name[8];
+	u8	padding_to_multiple_of_512[9];
 };
 
 #pragma pack()
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 5a1fab1..a32ff85 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -6983,6 +6983,22 @@ static void __attribute__((unused)) verify_structures(void)
 	BUILD_BUG_ON(offsetof(struct bmic_identify_controller,
 		controller_mode) != 292);
 
+	BUILD_BUG_ON(offsetof(struct bmic_identify_physical_device,
+		phys_bay_in_box) != 115);
+	BUILD_BUG_ON(offsetof(struct bmic_identify_physical_device,
+		device_type) != 120);
+	BUILD_BUG_ON(offsetof(struct bmic_identify_physical_device,
+		redundant_path_present_map) != 1736);
+	BUILD_BUG_ON(offsetof(struct bmic_identify_physical_device,
+		active_path_number) != 1738);
+	BUILD_BUG_ON(offsetof(struct bmic_identify_physical_device,
+		alternate_paths_phys_connector) != 1739);
+	BUILD_BUG_ON(offsetof(struct bmic_identify_physical_device,
+		alternate_paths_phys_box_on_port) != 1755);
+	BUILD_BUG_ON(offsetof(struct bmic_identify_physical_device,
+		current_queue_depth_limit) != 1796);
+	BUILD_BUG_ON(sizeof(struct bmic_identify_physical_device) != 2560);
+
 	BUILD_BUG_ON(PQI_ADMIN_IQ_NUM_ELEMENTS > 255);
 	BUILD_BUG_ON(PQI_ADMIN_OQ_NUM_ELEMENTS > 255);
 	BUILD_BUG_ON(PQI_ADMIN_IQ_ELEMENT_LENGTH %

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

* [PATCH 16/37] smartpqi: minor driver cleanup
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (14 preceding siblings ...)
  2017-04-25 19:47 ` [PATCH 15/37] smartpqi: correct BMIC identify physical drive Don Brace
@ 2017-04-25 19:47 ` Don Brace
  2017-04-25 20:09   ` Bart Van Assche
  2017-04-25 19:47 ` [PATCH 17/37] smartpqi: add new PCI device IDs Don Brace
                   ` (20 subsequent siblings)
  36 siblings, 1 reply; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:47 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

- align with in-house driver

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |    2 +-
 drivers/scsi/smartpqi/smartpqi_init.c |   38 ++++++++++++---------------------
 2 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index e74d3ed..7a95868 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -1053,7 +1053,7 @@ enum pqi_ctrl_mode {
 #define BMIC_WRITE_HOST_WELLNESS		0xa5
 #define BMIC_CACHE_FLUSH			0xc2
 
-#define SA_CACHE_FLUSH				0x01
+#define SA_CACHE_FLUSH				0x1
 
 #define MASKED_DEVICE(lunid)			((lunid)[3] & 0xc0)
 #define CISS_GET_BUS(lunid)			((lunid)[7] & 0x3f)
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index a32ff85..6da6db1 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -57,8 +57,6 @@ MODULE_SUPPORTED_DEVICE("Microsemi Smart Family Controllers");
 MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
-#define PQI_ENABLE_MULTI_QUEUE_SUPPORT	0
-
 static char *hpe_branded_controller = "HPE Smart Array Controller";
 static char *microsemi_branded_controller = "Microsemi Smart Family Controller";
 
@@ -94,7 +92,7 @@ static unsigned int pqi_supported_event_types[] = {
 
 static int pqi_disable_device_id_wildcards;
 module_param_named(disable_device_id_wildcards,
-	pqi_disable_device_id_wildcards, int, S_IRUGO | S_IWUSR);
+	pqi_disable_device_id_wildcards, int, 0644);
 MODULE_PARM_DESC(disable_device_id_wildcards,
 	"Disable device ID wildcards.");
 
@@ -383,7 +381,6 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
 	default:
 		dev_err(&ctrl_info->pci_dev->dev, "unknown command 0x%c\n",
 			cmd);
-		WARN_ON(cmd);
 		break;
 	}
 
@@ -1133,10 +1130,8 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
 	scsi_sanitize_inquiry_string(&buffer[16], 16);
 
 	device->devtype = buffer[0] & 0x1f;
-	memcpy(device->vendor, &buffer[8],
-		sizeof(device->vendor));
-	memcpy(device->model, &buffer[16],
-		sizeof(device->model));
+	memcpy(device->vendor, &buffer[8], sizeof(device->vendor));
+	memcpy(device->model, &buffer[16], sizeof(device->model));
 
 	if (pqi_is_logical_device(device) && device->devtype == TYPE_DISK) {
 		pqi_get_raid_level(ctrl_info, device);
@@ -1607,9 +1602,6 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
 			 */
 			device->new_device = true;
 			break;
-		default:
-			WARN_ON(find_result);
-			break;
 		}
 	}
 
@@ -1742,7 +1734,7 @@ static inline bool pqi_skip_device(u8 *scsi3addr,
 	return false;
 }
 
-static inline bool pqi_expose_device(struct pqi_scsi_dev *device)
+static inline bool pqi_ok_to_expose_device(struct pqi_scsi_dev *device)
 {
 	/* Expose all devices except for physical devices that are masked. */
 	if (device->is_physical_device && MASKED_DEVICE(device->scsi3addr))
@@ -1883,7 +1875,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 
 		pqi_assign_bus_target_lun(device);
 
-		device->expose_device = pqi_expose_device(device);
+		device->expose_device = pqi_ok_to_expose_device(device);
 
 		if (device->is_physical_device) {
 			device->wwid = phys_lun_ext_entry->wwid;
@@ -2682,7 +2674,6 @@ static unsigned int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info,
 			dev_err(&ctrl_info->pci_dev->dev,
 				"unexpected IU type: 0x%x\n",
 				response->header.iu_type);
-			WARN_ON(response->header.iu_type);
 			break;
 		}
 
@@ -4643,7 +4634,6 @@ static int pqi_raid_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
 		dev_err(&ctrl_info->pci_dev->dev,
 			"unknown data direction: %d\n",
 			scmd->sc_data_direction);
-		WARN_ON(scmd->sc_data_direction);
 		break;
 	}
 
@@ -4726,7 +4716,6 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
 		dev_err(&ctrl_info->pci_dev->dev,
 			"unknown data direction: %d\n",
 			scmd->sc_data_direction);
-		WARN_ON(scmd->sc_data_direction);
 		break;
 	}
 
@@ -5486,8 +5475,8 @@ static ssize_t pqi_host_rescan_store(struct device *dev,
 	return count;
 }
 
-static DEVICE_ATTR(version, S_IRUGO, pqi_version_show, NULL);
-static DEVICE_ATTR(rescan, S_IWUSR, NULL, pqi_host_rescan_store);
+static DEVICE_ATTR(version, 0444, pqi_version_show, NULL);
+static DEVICE_ATTR(rescan, 0200, NULL, pqi_host_rescan_store);
 
 static struct device_attribute *pqi_shost_attrs[] = {
 	&dev_attr_version,
@@ -5545,8 +5534,8 @@ static ssize_t pqi_ssd_smart_path_enabled_show(struct device *dev,
 	return 2;
 }
 
-static DEVICE_ATTR(sas_address, S_IRUGO, pqi_sas_address_show, NULL);
-static DEVICE_ATTR(ssd_smart_path_enabled, S_IRUGO,
+static DEVICE_ATTR(sas_address, 0444, pqi_sas_address_show, NULL);
+static DEVICE_ATTR(ssd_smart_path_enabled, 0444,
 	pqi_ssd_smart_path_enabled_show, NULL);
 
 static struct device_attribute *pqi_sdev_attrs[] = {
@@ -6109,9 +6098,6 @@ static int pqi_pci_init(struct pqi_ctrl_info *ctrl_info)
 		goto release_regions;
 	}
 
-	ctrl_info->registers = ctrl_info->iomem_base;
-	ctrl_info->pqi_registers = &ctrl_info->registers->pqi_registers;
-
 #define PCI_EXP_COMP_TIMEOUT_65_TO_210_MS		0x6
 
 	/* Increase the PCIe completion timeout. */
@@ -6126,6 +6112,9 @@ static int pqi_pci_init(struct pqi_ctrl_info *ctrl_info)
 	/* Enable bus mastering. */
 	pci_set_master(ctrl_info->pci_dev);
 
+	ctrl_info->registers = ctrl_info->iomem_base;
+	ctrl_info->pqi_registers = &ctrl_info->registers->pqi_registers;
+
 	pci_set_drvdata(ctrl_info->pci_dev, ctrl_info);
 
 	return 0;
@@ -6142,7 +6131,8 @@ static void pqi_cleanup_pci_init(struct pqi_ctrl_info *ctrl_info)
 {
 	iounmap(ctrl_info->iomem_base);
 	pci_release_regions(ctrl_info->pci_dev);
-	pci_disable_device(ctrl_info->pci_dev);
+	if (pci_is_enabled(ctrl_info->pci_dev))
+		pci_disable_device(ctrl_info->pci_dev);
 	pci_set_drvdata(ctrl_info->pci_dev, NULL);
 }
 

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

* [PATCH 17/37] smartpqi: add new PCI device IDs
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (15 preceding siblings ...)
  2017-04-25 19:47 ` [PATCH 16/37] smartpqi: minor driver cleanup Don Brace
@ 2017-04-25 19:47 ` Don Brace
  2017-04-25 19:47 ` [PATCH 18/37] smartpqi: cleanup messages Don Brace
                   ` (19 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:47 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |  134 +++++++++++++++++++++++++++------
 1 file changed, 109 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 6da6db1..10c232e 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -6391,107 +6391,191 @@ static int pqi_resume(struct pci_dev *pci_dev)
 static const struct pci_device_id pqi_pci_id_table[] = {
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x152d, 0x8a22)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x152d, 0x8a23)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x152d, 0x8a24)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x152d, 0x8a36)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       0x152d, 0x8a37)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
 			       PCI_VENDOR_ID_ADAPTEC2, 0x0110)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0600)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0605)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0601)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0800)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0602)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0801)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0603)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0802)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0650)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0803)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0651)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0804)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0652)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0805)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0653)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0806)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0654)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0900)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0655)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0901)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0700)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0902)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_HP, 0x0701)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0903)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0800)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0904)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0801)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0905)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0802)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0906)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0803)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0907)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0804)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x0908)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0805)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x1200)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0900)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x1201)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0901)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x1202)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0902)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x1280)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0903)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x1281)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0904)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x1300)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0905)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x1301)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
-			       PCI_VENDOR_ID_ADAPTEC2, 0x0906)
+			       PCI_VENDOR_ID_ADAPTEC2, 0x1380)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0600)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0601)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0602)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0603)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0604)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0606)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0650)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0651)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0652)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0653)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0654)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0655)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0656)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0657)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0700)
+	},
+	{
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+			       PCI_VENDOR_ID_HP, 0x0701)
 	},
 	{
 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,

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

* [PATCH 18/37] smartpqi: cleanup messages
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (16 preceding siblings ...)
  2017-04-25 19:47 ` [PATCH 17/37] smartpqi: add new PCI device IDs Don Brace
@ 2017-04-25 19:47 ` Don Brace
  2017-04-25 20:11   ` Bart Van Assche
  2017-04-25 19:47 ` [PATCH 19/37] smartpqi: update copyright Don Brace
                   ` (18 subsequent siblings)
  36 siblings, 1 reply; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:47 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@microsemi.com>

- improve some error messages.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   40 +++++++++++++++------------------
 drivers/scsi/smartpqi/smartpqi_sis.c  |    3 ++
 2 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 10c232e..3ffca17 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -992,7 +992,10 @@ static int pqi_validate_raid_map(struct pqi_ctrl_info *ctrl_info,
 	return 0;
 
 bad_raid_map:
-	dev_warn(&ctrl_info->pci_dev->dev, "%s\n", err_msg);
+	dev_warn(&ctrl_info->pci_dev->dev,
+		"scsi %d:%d:%d:%d %s\n",
+		ctrl_info->scsi_host->host_no,
+		device->bus, device->target, device->lun, err_msg);
 
 	return -EINVAL;
 }
@@ -1251,7 +1254,7 @@ static void pqi_show_volume_status(struct pqi_ctrl_info *ctrl_info,
 		break;
 	case CISS_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER:
 		status =
-			"Encrypted volume inaccessible - disabled on ctrl";
+		"Volume encrypted but encryption disabled on controller";
 		break;
 	case CISS_LV_PENDING_ENCRYPTION:
 		status = "Volume pending migration to encrypted state";
@@ -2429,7 +2432,7 @@ static inline void pqi_aio_path_disabled(struct pqi_io_request *io_request)
 	device->offload_enabled = false;
 }
 
-static inline void pqi_take_device_offline(struct scsi_device *sdev)
+static inline void pqi_take_device_offline(struct scsi_device *sdev, char *path)
 {
 	struct pqi_ctrl_info *ctrl_info;
 	struct pqi_scsi_dev *device;
@@ -2439,8 +2442,8 @@ static inline void pqi_take_device_offline(struct scsi_device *sdev)
 		ctrl_info = shost_to_hba(sdev->host);
 		schedule_delayed_work(&ctrl_info->rescan_work, 0);
 		device = sdev->hostdata;
-		dev_err(&ctrl_info->pci_dev->dev, "offlined scsi %d:%d:%d:%d\n",
-			ctrl_info->scsi_host->host_no, device->bus,
+		dev_err(&ctrl_info->pci_dev->dev, "offlined %s scsi %d:%d:%d:%d\n",
+			path, ctrl_info->scsi_host->host_no, device->bus,
 			device->target, device->lun);
 	}
 }
@@ -2487,7 +2490,7 @@ static void pqi_process_raid_io_error(struct pqi_io_request *io_request)
 				sshdr.sense_key == HARDWARE_ERROR &&
 				sshdr.asc == 0x3e &&
 				sshdr.ascq == 0x1) {
-			pqi_take_device_offline(scmd->device);
+			pqi_take_device_offline(scmd->device, "RAID");
 			host_byte = DID_NO_CONNECT;
 		}
 
@@ -2547,7 +2550,7 @@ static void pqi_process_aio_io_error(struct pqi_io_request *io_request)
 		case PQI_AIO_STATUS_NO_PATH_TO_DEVICE:
 		case PQI_AIO_STATUS_INVALID_DEVICE:
 			device_offline = true;
-			pqi_take_device_offline(scmd->device);
+			pqi_take_device_offline(scmd->device, "AIO");
 			host_byte = DID_NO_CONNECT;
 			scsi_status = SAM_STAT_CHECK_CONDITION;
 			break;
@@ -3203,11 +3206,8 @@ static int pqi_alloc_operational_queues(struct pqi_ctrl_info *ctrl_info)
 			alloc_length,
 			&ctrl_info->queue_memory_base_dma_handle, GFP_KERNEL);
 
-	if (!ctrl_info->queue_memory_base) {
-		dev_err(&ctrl_info->pci_dev->dev,
-			"unable to allocate memory for PQI admin queues\n");
+	if (!ctrl_info->queue_memory_base)
 		return -ENOMEM;
-	}
 
 	ctrl_info->queue_memory_length = alloc_length;
 
@@ -3576,7 +3576,6 @@ static int pqi_wait_for_completion_io(struct pqi_ctrl_info *ctrl_info,
 	struct completion *wait)
 {
 	int rc;
-	unsigned int wait_secs = 0;
 
 	while (1) {
 		if (wait_for_completion_io_timeout(wait,
@@ -3590,12 +3589,6 @@ static int pqi_wait_for_completion_io(struct pqi_ctrl_info *ctrl_info,
 			rc = -ENXIO;
 			break;
 		}
-
-		wait_secs += PQI_WAIT_FOR_COMPLETION_IO_TIMEOUT_SECS;
-
-		dev_err(&ctrl_info->pci_dev->dev,
-			"waiting %u seconds for completion\n",
-			wait_secs);
 	}
 
 	return rc;
@@ -5700,7 +5693,7 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info)
 	config_table = kmalloc(table_length, GFP_KERNEL);
 	if (!config_table) {
 		dev_err(&ctrl_info->pci_dev->dev,
-			"unable to allocate memory for PQI configuration table\n");
+			"failed to allocate memory for PQI configuration table\n");
 		return -ENOMEM;
 	}
 
@@ -5851,7 +5844,7 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 	rc = pqi_alloc_admin_queues(ctrl_info);
 	if (rc) {
 		dev_err(&ctrl_info->pci_dev->dev,
-			"error allocating admin queues\n");
+			"failed to allocate admin queues\n");
 		return rc;
 	}
 
@@ -5890,8 +5883,11 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 		return rc;
 
 	rc = pqi_alloc_operational_queues(ctrl_info);
-	if (rc)
+	if (rc) {
+		dev_err(&ctrl_info->pci_dev->dev,
+			"failed to allocate operational queues\n");
 		return rc;
+	}
 
 	pqi_init_operational_queues(ctrl_info);
 
@@ -6031,7 +6027,7 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info)
 	rc = pqi_enable_events(ctrl_info);
 	if (rc) {
 		dev_err(&ctrl_info->pci_dev->dev,
-			"error configuring events\n");
+			"error enabling events\n");
 		return rc;
 	}
 
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
index 7a8c0a6..e5a5d50 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.c
+++ b/drivers/scsi/smartpqi/smartpqi_sis.c
@@ -104,7 +104,8 @@ static int sis_wait_for_ctrl_ready_with_timeout(struct pqi_ctrl_info *ctrl_info,
 		}
 		if (time_after(jiffies, timeout)) {
 			dev_err(&ctrl_info->pci_dev->dev,
-				"controller not ready\n");
+				"controller not ready after %u seconds\n",
+				timeout_secs);
 			return -ETIMEDOUT;
 		}
 		msleep(SIS_CTRL_READY_POLL_INTERVAL_MSECS);

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

* [PATCH 19/37] smartpqi: update copyright
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (17 preceding siblings ...)
  2017-04-25 19:47 ` [PATCH 18/37] smartpqi: cleanup messages Don Brace
@ 2017-04-25 19:47 ` Don Brace
  2017-04-25 19:47 ` [PATCH 20/37] smartpqi: add ptraid support Don Brace
                   ` (17 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:47 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h               |    2 +-
 drivers/scsi/smartpqi/smartpqi_init.c          |    2 +-
 drivers/scsi/smartpqi/smartpqi_sas_transport.c |    2 +-
 drivers/scsi/smartpqi/smartpqi_sis.c           |    2 +-
 drivers/scsi/smartpqi/smartpqi_sis.h           |    2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 7a95868..d044a58c 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -1,6 +1,6 @@
 /*
  *    driver for Microsemi PQI-based storage controllers
- *    Copyright (c) 2016 Microsemi Corporation
+ *    Copyright (c) 2016-2017 Microsemi Corporation
  *    Copyright (c) 2016 PMC-Sierra, Inc.
  *
  *    This program is free software; you can redistribute it and/or modify
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 3ffca17..c5b37bc 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -1,6 +1,6 @@
 /*
  *    driver for Microsemi PQI-based storage controllers
- *    Copyright (c) 2016 Microsemi Corporation
+ *    Copyright (c) 2016-2017 Microsemi Corporation
  *    Copyright (c) 2016 PMC-Sierra, Inc.
  *
  *    This program is free software; you can redistribute it and/or modify
diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c
index 52ca4f9..0d89d37 100644
--- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c
+++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c
@@ -1,6 +1,6 @@
 /*
  *    driver for Microsemi PQI-based storage controllers
- *    Copyright (c) 2016 Microsemi Corporation
+ *    Copyright (c) 2016-2017 Microsemi Corporation
  *    Copyright (c) 2016 PMC-Sierra, Inc.
  *
  *    This program is free software; you can redistribute it and/or modify
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
index e5a5d50..e1cf280 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.c
+++ b/drivers/scsi/smartpqi/smartpqi_sis.c
@@ -1,6 +1,6 @@
 /*
  *    driver for Microsemi PQI-based storage controllers
- *    Copyright (c) 2016 Microsemi Corporation
+ *    Copyright (c) 2016-2017 Microsemi Corporation
  *    Copyright (c) 2016 PMC-Sierra, Inc.
  *
  *    This program is free software; you can redistribute it and/or modify
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h
index 08ee0ab..983184b 100644
--- a/drivers/scsi/smartpqi/smartpqi_sis.h
+++ b/drivers/scsi/smartpqi/smartpqi_sis.h
@@ -1,6 +1,6 @@
 /*
  *    driver for Microsemi PQI-based storage controllers
- *    Copyright (c) 2016 Microsemi Corporation
+ *    Copyright (c) 2016-2017 Microsemi Corporation
  *    Copyright (c) 2016 PMC-Sierra, Inc.
  *
  *    This program is free software; you can redistribute it and/or modify

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

* [PATCH 20/37] smartpqi: add ptraid support
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (18 preceding siblings ...)
  2017-04-25 19:47 ` [PATCH 19/37] smartpqi: update copyright Don Brace
@ 2017-04-25 19:47 ` Don Brace
  2017-04-25 20:13   ` Bart Van Assche
  2017-04-25 19:48 ` [PATCH 21/37] smartpqi: change return value for LUN reset operations Don Brace
                   ` (16 subsequent siblings)
  36 siblings, 1 reply; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:47 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

add support for PTRAID devices

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |    8 +++---
 drivers/scsi/smartpqi/smartpqi_init.c |   48 ++++++++++++++++++++++++++++-----
 2 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index d044a58c..be04bcb 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -694,7 +694,8 @@ struct pqi_config_table_heartbeat {
 #define PQI_PHYSICAL_DEVICE_BUS		0
 #define PQI_RAID_VOLUME_BUS		1
 #define PQI_HBA_BUS			2
-#define PQI_MAX_BUS			PQI_HBA_BUS
+#define PQI_EXTERNAL_RAID_VOLUME_BUS	3
+#define PQI_MAX_BUS			PQI_EXTERNAL_RAID_VOLUME_BUS
 
 struct report_lun_header {
 	__be32	list_length;
@@ -781,6 +782,7 @@ struct pqi_scsi_dev {
 	__be64	wwid;
 	u8	volume_id[16];
 	u8	is_physical_device : 1;
+	u8	is_external_raid_device : 1;
 	u8	target_lun_valid : 1;
 	u8	expose_device : 1;
 	u8	no_uld_attach : 1;
@@ -1056,10 +1058,10 @@ enum pqi_ctrl_mode {
 #define SA_CACHE_FLUSH				0x1
 
 #define MASKED_DEVICE(lunid)			((lunid)[3] & 0xc0)
-#define CISS_GET_BUS(lunid)			((lunid)[7] & 0x3f)
+#define CISS_GET_LEVEL_2_BUS(lunid)		((lunid)[7] & 0x3f)
 #define CISS_GET_LEVEL_2_TARGET(lunid)		((lunid)[6])
 #define CISS_GET_DRIVE_NUMBER(lunid)		\
-	(((CISS_GET_BUS((lunid)) - 1) << 8) +	\
+	(((CISS_GET_LEVEL_2_BUS((lunid)) - 1) << 8) + \
 	CISS_GET_LEVEL_2_TARGET((lunid)))
 
 #define NO_TIMEOUT		((unsigned long) -1)
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index c5b37bc..f943e58 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -147,6 +147,16 @@ static inline bool pqi_is_logical_device(struct pqi_scsi_dev *device)
 	return !device->is_physical_device;
 }
 
+static inline bool pqi_is_external_raid_device(struct pqi_scsi_dev *device)
+{
+	return device->is_external_raid_device;
+}
+
+static inline bool pqi_is_external_raid_addr(u8 *scsi3addr)
+{
+	return scsi3addr[2] != 0;
+}
+
 static inline bool pqi_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
 {
 	return !ctrl_info->controller_online;
@@ -885,6 +895,9 @@ static void pqi_assign_bus_target_lun(struct pqi_scsi_dev *device)
 {
 	u8 *scsi3addr;
 	u32 lunid;
+	int bus;
+	int target;
+	int lun;
 
 	scsi3addr = device->scsi3addr;
 	lunid = get_unaligned_le32(scsi3addr);
@@ -897,8 +910,16 @@ static void pqi_assign_bus_target_lun(struct pqi_scsi_dev *device)
 	}
 
 	if (pqi_is_logical_device(device)) {
-		pqi_set_bus_target_lun(device, PQI_RAID_VOLUME_BUS, 0,
-			lunid & 0x3fff);
+		if (pqi_is_external_raid_device(device)) {
+			bus = PQI_EXTERNAL_RAID_VOLUME_BUS;
+			target = (lunid >> 16) & 0x3fff;
+			lun = lunid & 0xff;
+		} else {
+			bus = PQI_RAID_VOLUME_BUS;
+			target = 0;
+			lun = lunid & 0x3fff;
+		}
+		pqi_set_bus_target_lun(device, bus, target, lun);
 		device->target_lun_valid = true;
 		return;
 	}
@@ -1137,9 +1158,15 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
 	memcpy(device->model, &buffer[16], sizeof(device->model));
 
 	if (pqi_is_logical_device(device) && device->devtype == TYPE_DISK) {
-		pqi_get_raid_level(ctrl_info, device);
-		pqi_get_offload_status(ctrl_info, device);
-		pqi_get_volume_status(ctrl_info, device);
+		if (pqi_is_external_raid_device(device)) {
+			device->raid_level = SA_RAID_UNKNOWN;
+			device->volume_status = CISS_LV_OK;
+			device->volume_offline = false;
+		} else {
+			pqi_get_raid_level(ctrl_info, device);
+			pqi_get_offload_status(ctrl_info, device);
+			pqi_get_volume_status(ctrl_info, device);
+		}
 	}
 
 out:
@@ -1356,6 +1383,8 @@ static void pqi_update_all_logical_drive_queue_depths(
 			continue;
 		if (!pqi_is_logical_device(device))
 			continue;
+		if (pqi_is_external_raid_device(device))
+			continue;
 		pqi_update_logical_drive_queue_depth(ctrl_info, device);
 	}
 }
@@ -1464,7 +1493,8 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info,
 		scsi_device_type(device->devtype),
 		device->vendor,
 		device->model,
-		pqi_raid_level_to_string(device->raid_level),
+		pqi_is_logical_device(device) ?
+			pqi_raid_level_to_string(device->raid_level) : "",
 		device->offload_configured ? '+' : '-',
 		device->offload_enabled_pending ? '+' : '-',
 		device->expose_device ? '+' : '-',
@@ -1488,6 +1518,8 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device,
 	/* By definition, the scsi3addr and wwid fields are already the same. */
 
 	existing_device->is_physical_device = new_device->is_physical_device;
+	existing_device->is_external_raid_device =
+		new_device->is_external_raid_device;
 	existing_device->expose_device = new_device->expose_device;
 	existing_device->no_uld_attach = new_device->no_uld_attach;
 	existing_device->aio_enabled = new_device->aio_enabled;
@@ -1856,7 +1888,9 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 
 		memcpy(device->scsi3addr, scsi3addr, sizeof(device->scsi3addr));
 		device->is_physical_device = is_physical_device;
-		device->raid_level = SA_RAID_UNKNOWN;
+		if (!is_physical_device)
+			device->is_external_raid_device =
+				pqi_is_external_raid_addr(scsi3addr);
 
 		/* Gather information about the device. */
 		rc = pqi_get_device_info(ctrl_info, device);

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

* [PATCH 21/37] smartpqi: change return value for LUN reset operations
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (19 preceding siblings ...)
  2017-04-25 19:47 ` [PATCH 20/37] smartpqi: add ptraid support Don Brace
@ 2017-04-25 19:48 ` Don Brace
  2017-04-25 19:48 ` [PATCH 22/37] smartpqi: enhance kdump Don Brace
                   ` (15 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:48 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

change return value for controller offline to be consistent
with the rest of the driver.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index f943e58..5678b6a 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -5032,7 +5032,7 @@ static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info,
 
 		pqi_check_ctrl_health(ctrl_info);
 		if (pqi_ctrl_offline(ctrl_info)) {
-			rc = -ETIMEDOUT;
+			rc = -ENXIO;
 			break;
 		}
 	}

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

* [PATCH 22/37] smartpqi: enhance kdump
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (20 preceding siblings ...)
  2017-04-25 19:48 ` [PATCH 21/37] smartpqi: change return value for LUN reset operations Don Brace
@ 2017-04-25 19:48 ` Don Brace
  2017-04-25 19:48 ` [PATCH 23/37] smartpqi: remove qdepth calculations for logical volumes Don Brace
                   ` (14 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:48 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

constrain resource usage during kdump to avoid kdump failures

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |    6 +++-
 drivers/scsi/smartpqi/smartpqi_init.c |   45 +++++++++++++++++++++++----------
 2 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index be04bcb..400d1fb 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -686,8 +686,10 @@ struct pqi_config_table_heartbeat {
 	__le32	heartbeat_counter;
 };
 
-#define PQI_MAX_OUTSTANDING_REQUESTS	((u32)~0)
-#define PQI_MAX_TRANSFER_SIZE		(4 * 1024U * 1024U)
+#define PQI_MAX_OUTSTANDING_REQUESTS		((u32)~0)
+#define PQI_MAX_OUTSTANDING_REQUESTS_KDUMP	32
+#define PQI_MAX_TRANSFER_SIZE			(4 * 1024U * 1024U)
+#define PQI_MAX_TRANSFER_SIZE_KDUMP		(512 * 1024U)
 
 #define RAID_MAP_MAX_ENTRIES		1024
 
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 5678b6a..6235b6d 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -4360,8 +4360,12 @@ static void pqi_calculate_io_resources(struct pqi_ctrl_info *ctrl_info)
 	ctrl_info->error_buffer_length =
 		ctrl_info->max_io_slots * PQI_ERROR_BUFFER_ELEMENT_LENGTH;
 
-	max_transfer_size =
-		min(ctrl_info->max_transfer_size, PQI_MAX_TRANSFER_SIZE);
+	if (reset_devices)
+		max_transfer_size = min(ctrl_info->max_transfer_size,
+			PQI_MAX_TRANSFER_SIZE_KDUMP);
+	else
+		max_transfer_size = min(ctrl_info->max_transfer_size,
+			PQI_MAX_TRANSFER_SIZE);
 
 	max_sg_entries = max_transfer_size / PAGE_SIZE;
 
@@ -4381,19 +4385,24 @@ static void pqi_calculate_io_resources(struct pqi_ctrl_info *ctrl_info)
 
 static void pqi_calculate_queue_resources(struct pqi_ctrl_info *ctrl_info)
 {
-	int num_cpus;
-	int max_queue_groups;
 	int num_queue_groups;
 	u16 num_elements_per_iq;
 	u16 num_elements_per_oq;
 
-	max_queue_groups = min(ctrl_info->max_inbound_queues / 2,
-		ctrl_info->max_outbound_queues - 1);
-	max_queue_groups = min(max_queue_groups, PQI_MAX_QUEUE_GROUPS);
+	if (reset_devices) {
+		num_queue_groups = 1;
+	} else {
+		int num_cpus;
+		int max_queue_groups;
+
+		max_queue_groups = min(ctrl_info->max_inbound_queues / 2,
+			ctrl_info->max_outbound_queues - 1);
+		max_queue_groups = min(max_queue_groups, PQI_MAX_QUEUE_GROUPS);
 
-	num_cpus = num_online_cpus();
-	num_queue_groups = min(num_cpus, ctrl_info->max_msix_vectors);
-	num_queue_groups = min(num_queue_groups, max_queue_groups);
+		num_cpus = num_online_cpus();
+		num_queue_groups = min(num_cpus, ctrl_info->max_msix_vectors);
+		num_queue_groups = min(num_queue_groups, max_queue_groups);
+	}
 
 	ctrl_info->num_queue_groups = num_queue_groups;
 	ctrl_info->max_hw_queue_index = num_queue_groups - 1;
@@ -5834,9 +5843,17 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
 		return rc;
 	}
 
-	if (ctrl_info->max_outstanding_requests > PQI_MAX_OUTSTANDING_REQUESTS)
-		ctrl_info->max_outstanding_requests =
-			PQI_MAX_OUTSTANDING_REQUESTS;
+	if (reset_devices) {
+		if (ctrl_info->max_outstanding_requests >
+			PQI_MAX_OUTSTANDING_REQUESTS_KDUMP)
+			ctrl_info->max_outstanding_requests =
+					PQI_MAX_OUTSTANDING_REQUESTS_KDUMP;
+	} else {
+		if (ctrl_info->max_outstanding_requests >
+			PQI_MAX_OUTSTANDING_REQUESTS)
+			ctrl_info->max_outstanding_requests =
+					PQI_MAX_OUTSTANDING_REQUESTS;
+	}
 
 	pqi_calculate_io_resources(ctrl_info);
 
@@ -7117,4 +7134,6 @@ static void __attribute__((unused)) verify_structures(void)
 		PQI_QUEUE_ELEMENT_LENGTH_ALIGNMENT != 0);
 
 	BUILD_BUG_ON(PQI_RESERVED_IO_SLOTS >= PQI_MAX_OUTSTANDING_REQUESTS);
+	BUILD_BUG_ON(PQI_RESERVED_IO_SLOTS >=
+		PQI_MAX_OUTSTANDING_REQUESTS_KDUMP);
 }

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

* [PATCH 23/37] smartpqi: remove qdepth calculations for logical volumes
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (21 preceding siblings ...)
  2017-04-25 19:48 ` [PATCH 22/37] smartpqi: enhance kdump Don Brace
@ 2017-04-25 19:48 ` Don Brace
  2017-04-25 19:48 ` [PATCH 24/37] smartpqi: add lockup action Don Brace
                   ` (13 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:48 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

make the queue depth for LVs the same as the maximum
I/Os supported by the controller

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |    6 -
 drivers/scsi/smartpqi/smartpqi_init.c |  140 ++-------------------------------
 2 files changed, 8 insertions(+), 138 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 400d1fb..857d1be 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -726,7 +726,6 @@ struct report_phys_lun_extended_entry {
 };
 
 /* for device_flags field of struct report_phys_lun_extended_entry */
-#define REPORT_PHYS_LUN_DEV_FLAG_NON_DISK	0x1
 #define REPORT_PHYS_LUN_DEV_FLAG_AIO_ENABLED	0x8
 
 struct report_phys_lun_extended {
@@ -786,8 +785,6 @@ struct pqi_scsi_dev {
 	u8	is_physical_device : 1;
 	u8	is_external_raid_device : 1;
 	u8	target_lun_valid : 1;
-	u8	expose_device : 1;
-	u8	no_uld_attach : 1;
 	u8	aio_enabled : 1;	/* only valid for physical disks */
 	u8	device_gone : 1;
 	u8	new_device : 1;
@@ -1034,9 +1031,6 @@ enum pqi_ctrl_mode {
  */
 #define PQI_PHYSICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH	27
 
-/* 0 = no limit */
-#define PQI_LOGICAL_DRIVE_DEFAULT_MAX_QUEUE_DEPTH	0
-
 /* CISS commands */
 #define CISS_READ		0xc0
 #define CISS_REPORT_LOG		0xc2	/* Report Logical LUNs */
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 6235b6d..2b667b5 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -1308,87 +1308,6 @@ static void pqi_show_volume_status(struct pqi_ctrl_info *ctrl_info,
 		device->bus, device->target, device->lun, status);
 }
 
-static struct pqi_scsi_dev *pqi_find_disk_by_aio_handle(
-	struct pqi_ctrl_info *ctrl_info, u32 aio_handle)
-{
-	struct pqi_scsi_dev *device;
-
-	list_for_each_entry(device, &ctrl_info->scsi_device_list,
-		scsi_device_list_entry) {
-		if (device->devtype != TYPE_DISK && device->devtype != TYPE_ZBC)
-			continue;
-		if (pqi_is_logical_device(device))
-			continue;
-		if (device->aio_handle == aio_handle)
-			return device;
-	}
-
-	return NULL;
-}
-
-static void pqi_update_logical_drive_queue_depth(
-	struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *logical_drive)
-{
-	unsigned int i;
-	struct raid_map *raid_map;
-	struct raid_map_disk_data *disk_data;
-	struct pqi_scsi_dev *phys_disk;
-	unsigned int num_phys_disks;
-	unsigned int num_raid_map_entries;
-	unsigned int queue_depth;
-
-	logical_drive->queue_depth = PQI_LOGICAL_DRIVE_DEFAULT_MAX_QUEUE_DEPTH;
-
-	raid_map = logical_drive->raid_map;
-	if (!raid_map)
-		return;
-
-	disk_data = raid_map->disk_data;
-	num_phys_disks = get_unaligned_le16(&raid_map->layout_map_count) *
-		(get_unaligned_le16(&raid_map->data_disks_per_row) +
-		get_unaligned_le16(&raid_map->metadata_disks_per_row));
-	num_raid_map_entries = num_phys_disks *
-		get_unaligned_le16(&raid_map->row_cnt);
-
-	queue_depth = 0;
-	for (i = 0; i < num_raid_map_entries; i++) {
-		phys_disk = pqi_find_disk_by_aio_handle(ctrl_info,
-			disk_data[i].aio_handle);
-
-		if (!phys_disk) {
-			dev_warn(&ctrl_info->pci_dev->dev,
-				"failed to find physical disk for logical drive %016llx\n",
-				get_unaligned_be64(logical_drive->scsi3addr));
-			logical_drive->offload_enabled = false;
-			logical_drive->offload_enabled_pending = false;
-			kfree(raid_map);
-			logical_drive->raid_map = NULL;
-			return;
-		}
-
-		queue_depth += phys_disk->queue_depth;
-	}
-
-	logical_drive->queue_depth = queue_depth;
-}
-
-static void pqi_update_all_logical_drive_queue_depths(
-	struct pqi_ctrl_info *ctrl_info)
-{
-	struct pqi_scsi_dev *device;
-
-	list_for_each_entry(device, &ctrl_info->scsi_device_list,
-		scsi_device_list_entry) {
-		if (device->devtype != TYPE_DISK && device->devtype != TYPE_ZBC)
-			continue;
-		if (!pqi_is_logical_device(device))
-			continue;
-		if (pqi_is_external_raid_device(device))
-			continue;
-		pqi_update_logical_drive_queue_depth(ctrl_info, device);
-	}
-}
-
 static void pqi_rescan_worker(struct work_struct *work)
 {
 	struct pqi_ctrl_info *ctrl_info;
@@ -1484,7 +1403,7 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info,
 	char *action, struct pqi_scsi_dev *device)
 {
 	dev_info(&ctrl_info->pci_dev->dev,
-		"%s scsi %d:%d:%d:%d: %s %.8s %.16s %-12s SSDSmartPathCap%c En%c Exp%c qd=%d\n",
+		"%s scsi %d:%d:%d:%d: %s %.8s %.16s %-12s SSDSmartPathCap%c En%c qd=%d\n",
 		action,
 		ctrl_info->scsi_host->host_no,
 		device->bus,
@@ -1497,7 +1416,6 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info,
 			pqi_raid_level_to_string(device->raid_level) : "",
 		device->offload_configured ? '+' : '-',
 		device->offload_enabled_pending ? '+' : '-',
-		device->expose_device ? '+' : '-',
 		device->queue_depth);
 }
 
@@ -1520,8 +1438,6 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device,
 	existing_device->is_physical_device = new_device->is_physical_device;
 	existing_device->is_external_raid_device =
 		new_device->is_external_raid_device;
-	existing_device->expose_device = new_device->expose_device;
-	existing_device->no_uld_attach = new_device->no_uld_attach;
 	existing_device->aio_enabled = new_device->aio_enabled;
 	memcpy(existing_device->vendor, new_device->vendor,
 		sizeof(existing_device->vendor));
@@ -1663,8 +1579,6 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
 		device->keep_device = true;
 	}
 
-	pqi_update_all_logical_drive_queue_depths(ctrl_info);
-
 	list_for_each_entry(device, &ctrl_info->scsi_device_list,
 		scsi_device_list_entry)
 		device->offload_enabled =
@@ -1703,7 +1617,7 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
 
 	/* Expose any new devices. */
 	list_for_each_entry_safe(device, next, &add_list, add_list_entry) {
-		if (device->expose_device && !device->sdev) {
+		if (!device->sdev) {
 			rc = pqi_add_device(ctrl_info, device);
 			if (rc) {
 				dev_warn(&ctrl_info->pci_dev->dev,
@@ -1746,38 +1660,15 @@ static bool pqi_is_supported_device(struct pqi_scsi_dev *device)
 	return is_supported;
 }
 
-static inline bool pqi_skip_device(u8 *scsi3addr,
-	struct report_phys_lun_extended_entry *phys_lun_ext_entry)
+static inline bool pqi_skip_device(u8 *scsi3addr)
 {
-	u8 device_flags;
-
-	if (!MASKED_DEVICE(scsi3addr))
-		return false;
-
-	/* The device is masked. */
-
-	device_flags = phys_lun_ext_entry->device_flags;
-
-	if (device_flags & REPORT_PHYS_LUN_DEV_FLAG_NON_DISK) {
-		/*
-		 * It's a non-disk device.  We ignore all devices of this type
-		 * when they're masked.
-		 */
+	/* Ignore all masked devices. */
+	if (MASKED_DEVICE(scsi3addr))
 		return true;
-	}
 
 	return false;
 }
 
-static inline bool pqi_ok_to_expose_device(struct pqi_scsi_dev *device)
-{
-	/* Expose all devices except for physical devices that are masked. */
-	if (device->is_physical_device && MASKED_DEVICE(device->scsi3addr))
-		return false;
-
-	return true;
-}
-
 static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 {
 	int i;
@@ -1876,8 +1767,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 			scsi3addr = log_lun_ext_entry->lunid;
 		}
 
-		if (is_physical_device &&
-			pqi_skip_device(scsi3addr, phys_lun_ext_entry))
+		if (is_physical_device && pqi_skip_device(scsi3addr))
 			continue;
 
 		if (device)
@@ -1912,8 +1802,6 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 
 		pqi_assign_bus_target_lun(device);
 
-		device->expose_device = pqi_ok_to_expose_device(device);
-
 		if (device->is_physical_device) {
 			device->wwid = phys_lun_ext_entry->wwid;
 			if ((phys_lun_ext_entry->device_flags &
@@ -4847,7 +4735,7 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
 				rc == SCSI_MLQUEUE_HOST_BUSY ||
 				rc == SAM_STAT_CHECK_CONDITION ||
 				rc == SAM_STAT_RESERVATION_CONFLICT)
-				raid_bypassed = true;
+					raid_bypassed = true;
 		}
 		if (!raid_bypassed)
 			rc = pqi_raid_submit_scsi_cmd(ctrl_info, device, scmd,
@@ -5173,7 +5061,7 @@ static int pqi_slave_alloc(struct scsi_device *sdev)
 			sdev_id(sdev), sdev->lun);
 	}
 
-	if (device && device->expose_device) {
+	if (device) {
 		sdev->hostdata = device;
 		device->sdev = sdev;
 		if (device->queue_depth) {
@@ -5188,17 +5076,6 @@ static int pqi_slave_alloc(struct scsi_device *sdev)
 	return 0;
 }
 
-static int pqi_slave_configure(struct scsi_device *sdev)
-{
-	struct pqi_scsi_dev *device;
-
-	device = sdev->hostdata;
-	if (!device->expose_device)
-		sdev->no_uld_attach = true;
-
-	return 0;
-}
-
 static int pqi_map_queues(struct Scsi_Host *shost)
 {
 	struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost);
@@ -5592,7 +5469,6 @@ static struct scsi_host_template pqi_driver_template = {
 	.eh_device_reset_handler = pqi_eh_device_reset_handler,
 	.ioctl = pqi_ioctl,
 	.slave_alloc = pqi_slave_alloc,
-	.slave_configure = pqi_slave_configure,
 	.map_queues = pqi_map_queues,
 	.sdev_attrs = pqi_sdev_attrs,
 	.shost_attrs = pqi_shost_attrs,

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

* [PATCH 24/37] smartpqi: add lockup action
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (22 preceding siblings ...)
  2017-04-25 19:48 ` [PATCH 23/37] smartpqi: remove qdepth calculations for logical volumes Don Brace
@ 2017-04-25 19:48 ` Don Brace
  2017-04-25 19:48 ` [PATCH 25/37] smartpqi: correct aio error path Don Brace
                   ` (12 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:48 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

add support for actions to take when controller goes offline.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |  121 +++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 2b667b5..132a419 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/reboot.h>
 #include <linux/cciss_ioctl.h>
 #include <linux/blk-mq-pci.h>
 #include <scsi/scsi_host.h>
@@ -60,6 +61,7 @@ MODULE_LICENSE("GPL");
 static char *hpe_branded_controller = "HPE Smart Array Controller";
 static char *microsemi_branded_controller = "Microsemi Smart Family Controller";
 
+static void pqi_perform_lockup_action(void);
 static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info);
 static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info);
 static void pqi_scan_start(struct Scsi_Host *shost);
@@ -81,6 +83,32 @@ static struct scsi_transport_template *pqi_sas_transport_template;
 
 static atomic_t pqi_controller_count = ATOMIC_INIT(0);
 
+enum pqi_lockup_action {
+	NONE,
+	REBOOT,
+	PANIC
+};
+
+static enum pqi_lockup_action pqi_lockup_action = NONE;
+
+static struct {
+	enum pqi_lockup_action	action;
+	char			*name;
+} pqi_lockup_actions[] = {
+	{
+		.action = NONE,
+		.name = "none",
+	},
+	{
+		.action = REBOOT,
+		.name = "reboot",
+	},
+	{
+		.action = PANIC,
+		.name = "panic",
+	},
+};
+
 static unsigned int pqi_supported_event_types[] = {
 	PQI_EVENT_TYPE_HOTPLUG,
 	PQI_EVENT_TYPE_HARDWARE,
@@ -96,6 +124,13 @@ module_param_named(disable_device_id_wildcards,
 MODULE_PARM_DESC(disable_device_id_wildcards,
 	"Disable device ID wildcards.");
 
+static char *pqi_lockup_action_param;
+module_param_named(lockup_action,
+	pqi_lockup_action_param, charp, 0644);
+MODULE_PARM_DESC(lockup_action, "Action to take when controller locked up.\n"
+	"\t\tSupported: none, reboot, panic\n"
+	"\t\tDefault: none");
+
 static char *raid_levels[] = {
 	"RAID-0",
 	"RAID-4",
@@ -2735,6 +2770,8 @@ static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
 	ctrl_info->controller_online = false;
 	dev_err(&ctrl_info->pci_dev->dev, "controller offline\n");
 	sis_shutdown_ctrl(ctrl_info);
+	pci_disable_device(ctrl_info->pci_dev);
+	pqi_perform_lockup_action();
 
 	for (i = 0; i < ctrl_info->num_queue_groups; i++) {
 		queue_group = &ctrl_info->queue_groups[i];
@@ -5388,12 +5425,55 @@ static ssize_t pqi_host_rescan_store(struct device *dev,
 	return count;
 }
 
+static ssize_t pqi_lockup_action_show(struct device *dev,
+	struct device_attribute *attr, char *buffer)
+{
+	int count = 0;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(pqi_lockup_actions); i++) {
+		if (pqi_lockup_actions[i].action == pqi_lockup_action)
+			count += snprintf(buffer + count, PAGE_SIZE - count,
+				"[%s] ", pqi_lockup_actions[i].name);
+		else
+			count += snprintf(buffer + count, PAGE_SIZE - count,
+				"%s ", pqi_lockup_actions[i].name);
+	}
+
+	count += snprintf(buffer + count, PAGE_SIZE - count, "\n");
+
+	return count;
+}
+
+static ssize_t pqi_lockup_action_store(struct device *dev,
+	struct device_attribute *attr, const char *buffer, size_t count)
+{
+	unsigned int i;
+	char *action_name;
+	char action_name_buffer[32];
+
+	strlcpy(action_name_buffer, buffer, sizeof(action_name_buffer));
+	action_name = strstrip(action_name_buffer);
+
+	for (i = 0; i < ARRAY_SIZE(pqi_lockup_actions); i++) {
+		if (strcmp(action_name, pqi_lockup_actions[i].name) == 0) {
+			pqi_lockup_action = pqi_lockup_actions[i].action;
+			return count;
+		}
+	}
+
+	return -EINVAL;
+}
+
 static DEVICE_ATTR(version, 0444, pqi_version_show, NULL);
 static DEVICE_ATTR(rescan, 0200, NULL, pqi_host_rescan_store);
+static DEVICE_ATTR(lockup_action, 0644,
+	pqi_lockup_action_show, pqi_lockup_action_store);
 
 static struct device_attribute *pqi_shost_attrs[] = {
 	&dev_attr_version,
 	&dev_attr_rescan,
+	&dev_attr_lockup_action,
 	NULL
 };
 
@@ -6140,6 +6220,21 @@ static void pqi_remove_ctrl(struct pqi_ctrl_info *ctrl_info)
 	pqi_free_ctrl_resources(ctrl_info);
 }
 
+static void pqi_perform_lockup_action(void)
+{
+	switch (pqi_lockup_action) {
+	case PANIC:
+		panic("FATAL: Smart Family Controller lockup detected");
+		break;
+	case REBOOT:
+		emergency_restart();
+		break;
+	case NONE:
+	default:
+		break;
+	}
+}
+
 static void pqi_print_ctrl_info(struct pci_dev *pci_dev,
 	const struct pci_device_id *id)
 {
@@ -6245,6 +6340,30 @@ static void pqi_shutdown(struct pci_dev *pci_dev)
 		"unable to flush controller cache\n");
 }
 
+static void pqi_process_lockup_action_param(void)
+{
+	unsigned int i;
+
+	if (!pqi_lockup_action_param)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(pqi_lockup_actions); i++) {
+		if (strcmp(pqi_lockup_action_param,
+			pqi_lockup_actions[i].name) == 0) {
+			pqi_lockup_action = pqi_lockup_actions[i].action;
+			return;
+		}
+	}
+
+	pr_warn("%s: invalid lockup action setting \"%s\" - supported settings: none, reboot, panic\n",
+		DRIVER_NAME_SHORT, pqi_lockup_action_param);
+}
+
+static void pqi_process_module_params(void)
+{
+	pqi_process_lockup_action_param();
+}
+
 #if defined(CONFIG_PM)
 
 static int pqi_suspend(struct pci_dev *pci_dev, pm_message_t state)
@@ -6552,6 +6671,8 @@ static int __init pqi_init(void)
 	if (!pqi_sas_transport_template)
 		return -ENODEV;
 
+	pqi_process_module_params();
+
 	rc = pci_register_driver(&pqi_pci_driver);
 	if (rc)
 		sas_release_transport(pqi_sas_transport_template);

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

* [PATCH 25/37] smartpqi: correct aio error path
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (23 preceding siblings ...)
  2017-04-25 19:48 ` [PATCH 24/37] smartpqi: add lockup action Don Brace
@ 2017-04-25 19:48 ` Don Brace
  2017-04-25 19:48 ` [PATCH 26/37] smartpqi: update device offline Don Brace
                   ` (11 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:48 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

set the internal flag that causes I/O to be sent down the
RAID path when the AIO path is disabled

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |    8 +
 drivers/scsi/smartpqi/smartpqi_init.c |  345 +++++++++++++++++++++++++++------
 2 files changed, 285 insertions(+), 68 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 857d1be..94b92ae 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -785,11 +785,11 @@ struct pqi_scsi_dev {
 	u8	is_physical_device : 1;
 	u8	is_external_raid_device : 1;
 	u8	target_lun_valid : 1;
-	u8	aio_enabled : 1;	/* only valid for physical disks */
 	u8	device_gone : 1;
 	u8	new_device : 1;
 	u8	keep_device : 1;
 	u8	volume_offline : 1;
+	bool	aio_enabled;		/* only valid for physical disks */
 	bool	in_reset;
 	bool	device_offline;
 	u8	vendor[8];		/* bytes 8-15 of inquiry data */
@@ -911,7 +911,9 @@ struct pqi_io_request {
 	void (*io_complete_callback)(struct pqi_io_request *io_request,
 		void *context);
 	void		*context;
+	u8		raid_bypass : 1;
 	int		status;
+	struct pqi_queue_group *queue_group;
 	struct scsi_cmnd *scmd;
 	void		*error_info;
 	struct pqi_sg_descriptor *sg_chain_buffer;
@@ -1019,6 +1021,10 @@ struct pqi_ctrl_info {
 	atomic_t	num_busy_threads;
 	atomic_t	num_blocked_threads;
 	wait_queue_head_t block_requests_wait;
+
+	struct list_head raid_bypass_retry_list;
+	spinlock_t	raid_bypass_retry_list_lock;
+	struct work_struct raid_bypass_retry_work;
 };
 
 enum pqi_ctrl_mode {
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 132a419..36cf8cd 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -63,6 +63,9 @@ static char *microsemi_branded_controller = "Microsemi Smart Family Controller";
 
 static void pqi_perform_lockup_action(void);
 static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info);
+static void pqi_complete_all_queued_raid_bypass_retries(
+	struct pqi_ctrl_info *ctrl_info, int result);
+static void pqi_retry_raid_bypass_requests(struct pqi_ctrl_info *ctrl_info);
 static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info);
 static void pqi_scan_start(struct Scsi_Host *shost);
 static void pqi_start_io(struct pqi_ctrl_info *ctrl_info,
@@ -74,7 +77,7 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info,
 static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
 	struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb,
 	unsigned int cdb_length, struct pqi_queue_group *queue_group,
-	struct pqi_encryption_info *encryption_info);
+	struct pqi_encryption_info *encryption_info, bool raid_bypass);
 
 /* for flags argument to pqi_submit_raid_request_synchronous() */
 #define PQI_SYNC_FLAGS_INTERRUPTABLE	0x1
@@ -232,6 +235,7 @@ static inline void pqi_ctrl_unblock_requests(struct pqi_ctrl_info *ctrl_info)
 {
 	ctrl_info->block_requests = false;
 	wake_up_all(&ctrl_info->block_requests_wait);
+	pqi_retry_raid_bypass_requests(ctrl_info);
 	scsi_unblock_requests(ctrl_info->scsi_host);
 }
 
@@ -450,6 +454,14 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
 		buffer, buffer_length, pci_dir);
 }
 
+static inline void pqi_reinit_io_request(struct pqi_io_request *io_request)
+{
+	io_request->scmd = NULL;
+	io_request->status = 0;
+	io_request->error_info = NULL;
+	io_request->raid_bypass = false;
+}
+
 static struct pqi_io_request *pqi_alloc_io_request(
 	struct pqi_ctrl_info *ctrl_info)
 {
@@ -467,9 +479,7 @@ static struct pqi_io_request *pqi_alloc_io_request(
 	/* benignly racy */
 	ctrl_info->next_io_request_slot = (i + 1) % ctrl_info->max_io_slots;
 
-	io_request->scmd = NULL;
-	io_request->status = 0;
-	io_request->error_info = NULL;
+	pqi_reinit_io_request(io_request);
 
 	return io_request;
 }
@@ -1684,8 +1694,8 @@ static bool pqi_is_supported_device(struct pqi_scsi_dev *device)
 		/*
 		 * Only support the HBA controller itself as a RAID
 		 * controller.  If it's a RAID controller other than
-		 * the HBA itself (an external RAID controller, MSA500
-		 * or similar), we don't support it.
+		 * the HBA itself (an external RAID controller, for
+		 * example), we don't support it.
 		 */
 		if (pqi_is_hba_lunid(device->scsi3addr))
 			is_supported = true;
@@ -2314,7 +2324,7 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
 	}
 
 	return pqi_aio_submit_io(ctrl_info, scmd, aio_handle,
-		cdb, cdb_length, queue_group, encryption_info_ptr);
+		cdb, cdb_length, queue_group, encryption_info_ptr, true);
 }
 
 #define PQI_STATUS_IDLE		0x0
@@ -2387,6 +2397,7 @@ static inline void pqi_aio_path_disabled(struct pqi_io_request *io_request)
 
 	device = io_request->scmd->device->hostdata;
 	device->offload_enabled = false;
+	device->aio_enabled = false;
 }
 
 static inline void pqi_take_device_offline(struct scsi_device *sdev, char *path)
@@ -2506,9 +2517,11 @@ static void pqi_process_aio_io_error(struct pqi_io_request *io_request)
 			break;
 		case PQI_AIO_STATUS_NO_PATH_TO_DEVICE:
 		case PQI_AIO_STATUS_INVALID_DEVICE:
-			device_offline = true;
-			pqi_take_device_offline(scmd->device, "AIO");
-			host_byte = DID_NO_CONNECT;
+			if (!io_request->raid_bypass) {
+				device_offline = true;
+				pqi_take_device_offline(scmd->device, "AIO");
+				host_byte = DID_NO_CONNECT;
+			}
 			scsi_status = SAM_STAT_CHECK_CONDITION;
 			break;
 		case PQI_AIO_STATUS_IO_ERROR:
@@ -2757,48 +2770,6 @@ static void pqi_event_worker(struct work_struct *work)
 	pqi_schedule_rescan_worker(ctrl_info);
 }
 
-static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
-{
-	unsigned int i;
-	unsigned int path;
-	struct pqi_queue_group *queue_group;
-	unsigned long flags;
-	struct pqi_io_request *io_request;
-	struct pqi_io_request *next;
-	struct scsi_cmnd *scmd;
-
-	ctrl_info->controller_online = false;
-	dev_err(&ctrl_info->pci_dev->dev, "controller offline\n");
-	sis_shutdown_ctrl(ctrl_info);
-	pci_disable_device(ctrl_info->pci_dev);
-	pqi_perform_lockup_action();
-
-	for (i = 0; i < ctrl_info->num_queue_groups; i++) {
-		queue_group = &ctrl_info->queue_groups[i];
-
-		for (path = 0; path < 2; path++) {
-			spin_lock_irqsave(
-				&queue_group->submit_lock[path], flags);
-
-			list_for_each_entry_safe(io_request, next,
-				&queue_group->request_list[path],
-				request_list_entry) {
-
-				scmd = io_request->scmd;
-				if (scmd) {
-					set_host_byte(scmd, DID_NO_CONNECT);
-					pqi_scsi_done(scmd);
-				}
-
-				list_del(&io_request->request_list_entry);
-			}
-
-			spin_unlock_irqrestore(
-				&queue_group->submit_lock[path], flags);
-		}
-	}
-}
-
 #define PQI_HEARTBEAT_TIMER_INTERVAL	(10 * HZ)
 
 static void pqi_heartbeat_timer_handler(unsigned long data)
@@ -3468,9 +3439,11 @@ static void pqi_start_io(struct pqi_ctrl_info *ctrl_info,
 
 	spin_lock_irqsave(&queue_group->submit_lock[path], flags);
 
-	if (io_request)
+	if (io_request) {
+		io_request->queue_group = queue_group;
 		list_add_tail(&io_request->request_list_entry,
 			&queue_group->request_list[path]);
+	}
 
 	iq_pi = queue_group->iq_pi_copy[path];
 
@@ -3630,6 +3603,11 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info,
 		goto out;
 	}
 
+	if (pqi_ctrl_offline(ctrl_info)) {
+		rc = -ENXIO;
+		goto out;
+	}
+
 	io_request = pqi_alloc_io_request(ctrl_info);
 
 	put_unaligned_le16(io_request->index,
@@ -4516,21 +4494,18 @@ static void pqi_raid_io_complete(struct pqi_io_request *io_request,
 	pqi_scsi_done(scmd);
 }
 
-static int pqi_raid_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
+static int pqi_raid_submit_scsi_cmd_with_io_request(
+	struct pqi_ctrl_info *ctrl_info, struct pqi_io_request *io_request,
 	struct pqi_scsi_dev *device, struct scsi_cmnd *scmd,
 	struct pqi_queue_group *queue_group)
 {
 	int rc;
 	size_t cdb_length;
-	struct pqi_io_request *io_request;
 	struct pqi_raid_path_request *request;
 
-	io_request = pqi_alloc_io_request(ctrl_info);
 	io_request->io_complete_callback = pqi_raid_io_complete;
 	io_request->scmd = scmd;
 
-	scmd->host_scribble = (unsigned char *)io_request;
-
 	request = io_request->iu;
 	memset(request, 0,
 		offsetof(struct pqi_raid_path_request, sg_descriptors));
@@ -4609,6 +4584,183 @@ static int pqi_raid_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
 	return 0;
 }
 
+static inline int pqi_raid_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
+	struct pqi_scsi_dev *device, struct scsi_cmnd *scmd,
+	struct pqi_queue_group *queue_group)
+{
+	struct pqi_io_request *io_request;
+
+	io_request = pqi_alloc_io_request(ctrl_info);
+
+	return pqi_raid_submit_scsi_cmd_with_io_request(ctrl_info, io_request,
+		device, scmd, queue_group);
+}
+
+static inline void pqi_schedule_bypass_retry(struct pqi_ctrl_info *ctrl_info)
+{
+	if (!pqi_ctrl_blocked(ctrl_info))
+		schedule_work(&ctrl_info->raid_bypass_retry_work);
+}
+
+static bool pqi_raid_bypass_retry_needed(struct pqi_io_request *io_request)
+{
+	struct scsi_cmnd *scmd;
+	struct pqi_ctrl_info *ctrl_info;
+
+	if (!io_request->raid_bypass)
+		return false;
+
+	scmd = io_request->scmd;
+	if ((scmd->result & 0xff) == SAM_STAT_GOOD)
+		return false;
+	if (host_byte(scmd->result) == DID_NO_CONNECT)
+		return false;
+
+	ctrl_info = shost_to_hba(scmd->device->host);
+	if (pqi_ctrl_offline(ctrl_info))
+		return false;
+
+	return true;
+}
+
+static inline void pqi_add_to_raid_bypass_retry_list(
+	struct pqi_ctrl_info *ctrl_info,
+	struct pqi_io_request *io_request, bool at_head)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ctrl_info->raid_bypass_retry_list_lock, flags);
+	if (at_head)
+		list_add(&io_request->request_list_entry,
+			&ctrl_info->raid_bypass_retry_list);
+	else
+		list_add_tail(&io_request->request_list_entry,
+			&ctrl_info->raid_bypass_retry_list);
+	spin_unlock_irqrestore(&ctrl_info->raid_bypass_retry_list_lock, flags);
+}
+
+static void pqi_queued_raid_bypass_complete(struct pqi_io_request *io_request,
+	void *context)
+{
+	struct scsi_cmnd *scmd;
+
+	scmd = io_request->scmd;
+	pqi_free_io_request(io_request);
+	pqi_scsi_done(scmd);
+}
+
+static void pqi_queue_raid_bypass_retry(struct pqi_io_request *io_request)
+{
+	struct scsi_cmnd *scmd;
+	struct pqi_ctrl_info *ctrl_info;
+
+	io_request->io_complete_callback = pqi_queued_raid_bypass_complete;
+	scmd = io_request->scmd;
+	scmd->result = 0;
+	ctrl_info = shost_to_hba(scmd->device->host);
+
+	pqi_add_to_raid_bypass_retry_list(ctrl_info, io_request, false);
+	pqi_schedule_bypass_retry(ctrl_info);
+}
+
+static int pqi_retry_raid_bypass(struct pqi_io_request *io_request)
+{
+	struct scsi_cmnd *scmd;
+	struct pqi_scsi_dev *device;
+	struct pqi_ctrl_info *ctrl_info;
+	struct pqi_queue_group *queue_group;
+
+	scmd = io_request->scmd;
+	device = scmd->device->hostdata;
+	if (pqi_device_in_reset(device)) {
+		pqi_free_io_request(io_request);
+		set_host_byte(scmd, DID_RESET);
+		pqi_scsi_done(scmd);
+		return 0;
+	}
+
+	ctrl_info = shost_to_hba(scmd->device->host);
+	queue_group = io_request->queue_group;
+
+	pqi_reinit_io_request(io_request);
+
+	return pqi_raid_submit_scsi_cmd_with_io_request(ctrl_info, io_request,
+		device, scmd, queue_group);
+}
+
+static inline struct pqi_io_request *pqi_next_queued_raid_bypass_request(
+	struct pqi_ctrl_info *ctrl_info)
+{
+	unsigned long flags;
+	struct pqi_io_request *io_request;
+
+	spin_lock_irqsave(&ctrl_info->raid_bypass_retry_list_lock, flags);
+	io_request = list_first_entry_or_null(
+		&ctrl_info->raid_bypass_retry_list,
+		struct pqi_io_request, request_list_entry);
+	if (io_request)
+		list_del(&io_request->request_list_entry);
+	spin_unlock_irqrestore(&ctrl_info->raid_bypass_retry_list_lock, flags);
+
+	return io_request;
+}
+
+static void pqi_retry_raid_bypass_requests(struct pqi_ctrl_info *ctrl_info)
+{
+	int rc;
+	struct pqi_io_request *io_request;
+
+	pqi_ctrl_busy(ctrl_info);
+
+	while (1) {
+		if (pqi_ctrl_blocked(ctrl_info))
+			break;
+		io_request = pqi_next_queued_raid_bypass_request(ctrl_info);
+		if (!io_request)
+			break;
+		rc = pqi_retry_raid_bypass(io_request);
+		if (rc) {
+			pqi_add_to_raid_bypass_retry_list(ctrl_info, io_request,
+				true);
+			pqi_schedule_bypass_retry(ctrl_info);
+			break;
+		}
+	}
+
+	pqi_ctrl_unbusy(ctrl_info);
+}
+
+static void pqi_raid_bypass_retry_worker(struct work_struct *work)
+{
+	struct pqi_ctrl_info *ctrl_info;
+
+	ctrl_info = container_of(work, struct pqi_ctrl_info,
+		raid_bypass_retry_work);
+	pqi_retry_raid_bypass_requests(ctrl_info);
+}
+
+static void pqi_complete_all_queued_raid_bypass_retries(
+	struct pqi_ctrl_info *ctrl_info, int result)
+{
+	unsigned long flags;
+	struct pqi_io_request *io_request;
+	struct pqi_io_request *next;
+	struct scsi_cmnd *scmd;
+
+	spin_lock_irqsave(&ctrl_info->raid_bypass_retry_list_lock, flags);
+
+	list_for_each_entry_safe(io_request, next,
+		&ctrl_info->raid_bypass_retry_list, request_list_entry) {
+		list_del(&io_request->request_list_entry);
+		scmd = io_request->scmd;
+		pqi_free_io_request(io_request);
+		scmd->result = result;
+		pqi_scsi_done(scmd);
+	}
+
+	spin_unlock_irqrestore(&ctrl_info->raid_bypass_retry_list_lock, flags);
+}
+
 static void pqi_aio_io_complete(struct pqi_io_request *io_request,
 	void *context)
 {
@@ -4618,6 +4770,10 @@ static void pqi_aio_io_complete(struct pqi_io_request *io_request,
 	scsi_dma_unmap(scmd);
 	if (io_request->status == -EAGAIN)
 		set_host_byte(scmd, DID_IMM_RETRY);
+	else if (pqi_raid_bypass_retry_needed(io_request)) {
+		pqi_queue_raid_bypass_retry(io_request);
+		return;
+	}
 	pqi_free_io_request(io_request);
 	pqi_scsi_done(scmd);
 }
@@ -4627,13 +4783,13 @@ static inline int pqi_aio_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
 	struct pqi_queue_group *queue_group)
 {
 	return pqi_aio_submit_io(ctrl_info, scmd, device->aio_handle,
-		scmd->cmnd, scmd->cmd_len, queue_group, NULL);
+		scmd->cmnd, scmd->cmd_len, queue_group, NULL, false);
 }
 
 static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
 	struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb,
 	unsigned int cdb_length, struct pqi_queue_group *queue_group,
-	struct pqi_encryption_info *encryption_info)
+	struct pqi_encryption_info *encryption_info, bool raid_bypass)
 {
 	int rc;
 	struct pqi_io_request *io_request;
@@ -4642,8 +4798,7 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
 	io_request = pqi_alloc_io_request(ctrl_info);
 	io_request->io_complete_callback = pqi_aio_io_complete;
 	io_request->scmd = scmd;
-
-	scmd->host_scribble = (unsigned char *)io_request;
+	io_request->raid_bypass = raid_bypass;
 
 	request = io_request->iu;
 	memset(request, 0,
@@ -4768,11 +4923,8 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
 				!blk_rq_is_passthrough(scmd->request)) {
 			rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device,
 				scmd, queue_group);
-			if (rc == 0 ||
-				rc == SCSI_MLQUEUE_HOST_BUSY ||
-				rc == SAM_STAT_CHECK_CONDITION ||
-				rc == SAM_STAT_RESERVATION_CONFLICT)
-					raid_bypassed = true;
+			if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY)
+				raid_bypassed = true;
 		}
 		if (!raid_bypassed)
 			rc = pqi_raid_submit_scsi_cmd(ctrl_info, device, scmd,
@@ -6166,6 +6318,11 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node)
 		PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS);
 	init_waitqueue_head(&ctrl_info->block_requests_wait);
 
+	INIT_LIST_HEAD(&ctrl_info->raid_bypass_retry_list);
+	spin_lock_init(&ctrl_info->raid_bypass_retry_list_lock);
+	INIT_WORK(&ctrl_info->raid_bypass_retry_work,
+		pqi_raid_bypass_retry_worker);
+
 	ctrl_info->ctrl_id = atomic_inc_return(&pqi_controller_count) - 1;
 	ctrl_info->irq_mode = IRQ_MODE_NONE;
 	ctrl_info->max_msix_vectors = PQI_MAX_MSIX_VECTORS;
@@ -6235,6 +6392,60 @@ static void pqi_perform_lockup_action(void)
 	}
 }
 
+static void pqi_complete_all_queued_requests(struct pqi_ctrl_info *ctrl_info,
+	int result)
+{
+	unsigned int i;
+	unsigned int path;
+	struct pqi_queue_group *queue_group;
+	unsigned long flags;
+	struct pqi_io_request *io_request;
+	struct pqi_io_request *next;
+	struct scsi_cmnd *scmd;
+
+	for (i = 0; i < ctrl_info->num_queue_groups; i++) {
+		queue_group = &ctrl_info->queue_groups[i];
+
+		for (path = 0; path < 2; path++) {
+			spin_lock_irqsave(
+				&queue_group->submit_lock[path], flags);
+
+			list_for_each_entry_safe(io_request, next,
+				&queue_group->request_list[path],
+				request_list_entry) {
+
+				scmd = io_request->scmd;
+				if (scmd) {
+					scmd->result = result;
+					pqi_scsi_done(scmd);
+				}
+
+				list_del(&io_request->request_list_entry);
+			}
+
+			spin_unlock_irqrestore(
+				&queue_group->submit_lock[path], flags);
+		}
+	}
+}
+
+static void pqi_fail_all_queued_requests(struct pqi_ctrl_info *ctrl_info)
+{
+	pqi_complete_all_queued_requests(ctrl_info, DID_NO_CONNECT << 16);
+	pqi_complete_all_queued_raid_bypass_retries(ctrl_info,
+		DID_NO_CONNECT << 16);
+}
+
+static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
+{
+	ctrl_info->controller_online = false;
+	sis_shutdown_ctrl(ctrl_info);
+	pci_disable_device(ctrl_info->pci_dev);
+	dev_err(&ctrl_info->pci_dev->dev, "controller offline\n");
+	pqi_perform_lockup_action();
+	pqi_fail_all_queued_requests(ctrl_info);
+}
+
 static void pqi_print_ctrl_info(struct pci_dev *pci_dev,
 	const struct pci_device_id *id)
 {

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

* [PATCH 26/37] smartpqi: update device offline
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (24 preceding siblings ...)
  2017-04-25 19:48 ` [PATCH 25/37] smartpqi: correct aio error path Don Brace
@ 2017-04-25 19:48 ` Don Brace
  2017-04-25 19:48 ` [PATCH 27/37] smartpqi: controller offline improvements Don Brace
                   ` (10 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:48 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@microsemi.com>

- Improve handling of offline devices.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 36cf8cd..8a0a486 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -290,6 +290,11 @@ static inline void pqi_ctrl_wait_until_quiesced(struct pqi_ctrl_info *ctrl_info)
 		usleep_range(1000, 2000);
 }
 
+static inline bool pqi_device_offline(struct pqi_scsi_dev *device)
+{
+	return device->device_offline;
+}
+
 static inline void pqi_device_reset_start(struct pqi_scsi_dev *device)
 {
 	device->in_reset = true;
@@ -2405,15 +2410,17 @@ static inline void pqi_take_device_offline(struct scsi_device *sdev, char *path)
 	struct pqi_ctrl_info *ctrl_info;
 	struct pqi_scsi_dev *device;
 
-	if (scsi_device_online(sdev)) {
-		scsi_device_set_state(sdev, SDEV_OFFLINE);
-		ctrl_info = shost_to_hba(sdev->host);
-		schedule_delayed_work(&ctrl_info->rescan_work, 0);
-		device = sdev->hostdata;
-		dev_err(&ctrl_info->pci_dev->dev, "offlined %s scsi %d:%d:%d:%d\n",
-			path, ctrl_info->scsi_host->host_no, device->bus,
-			device->target, device->lun);
-	}
+	device = sdev->hostdata;
+	if (device->device_offline)
+		return;
+
+	device->device_offline = true;
+	scsi_device_set_state(sdev, SDEV_OFFLINE);
+	ctrl_info = shost_to_hba(sdev->host);
+	pqi_schedule_rescan_worker(ctrl_info);
+	dev_err(&ctrl_info->pci_dev->dev, "offlined %s scsi %d:%d:%d:%d\n",
+		path, ctrl_info->scsi_host->host_no, device->bus,
+		device->target, device->lun);
 }
 
 static void pqi_process_raid_io_error(struct pqi_io_request *io_request)
@@ -4605,6 +4612,7 @@ static inline void pqi_schedule_bypass_retry(struct pqi_ctrl_info *ctrl_info)
 static bool pqi_raid_bypass_retry_needed(struct pqi_io_request *io_request)
 {
 	struct scsi_cmnd *scmd;
+	struct pqi_scsi_dev *device;
 	struct pqi_ctrl_info *ctrl_info;
 
 	if (!io_request->raid_bypass)
@@ -4616,6 +4624,10 @@ static bool pqi_raid_bypass_retry_needed(struct pqi_io_request *io_request)
 	if (host_byte(scmd->result) == DID_NO_CONNECT)
 		return false;
 
+	device = scmd->device->hostdata;
+	if (pqi_device_offline(device))
+		return false;
+
 	ctrl_info = shost_to_hba(scmd->device->host);
 	if (pqi_ctrl_offline(ctrl_info))
 		return false;

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

* [PATCH 27/37] smartpqi: controller offline improvements
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (25 preceding siblings ...)
  2017-04-25 19:48 ` [PATCH 26/37] smartpqi: update device offline Don Brace
@ 2017-04-25 19:48 ` Don Brace
  2017-04-25 19:48 ` [PATCH 28/37] smartpqi: cleanup controller branding Don Brace
                   ` (9 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:48 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@microsemi.com>

improve support for taking controller offline.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |    2 
 drivers/scsi/smartpqi/smartpqi_init.c |  141 ++++++++++++++++++---------------
 2 files changed, 77 insertions(+), 66 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 94b92ae..2ed15cf 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -994,7 +994,6 @@ struct pqi_ctrl_info {
 	u8		inbound_spanning_supported : 1;
 	u8		outbound_spanning_supported : 1;
 	u8		pqi_mode_enabled : 1;
-	u8		update_time_worker_scheduled : 1;
 
 	struct list_head scsi_device_list;
 	spinlock_t	scsi_device_list_lock;
@@ -1016,6 +1015,7 @@ struct pqi_ctrl_info {
 	u32		previous_heartbeat_count;
 	__le32 __iomem	*heartbeat_counter;
 	struct timer_list heartbeat_timer;
+	struct work_struct ctrl_offline_work;
 
 	struct semaphore sync_request_sem;
 	atomic_t	num_busy_threads;
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 8a0a486..66f02f4 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -61,10 +61,8 @@ MODULE_LICENSE("GPL");
 static char *hpe_branded_controller = "HPE Smart Array Controller";
 static char *microsemi_branded_controller = "Microsemi Smart Family Controller";
 
-static void pqi_perform_lockup_action(void);
 static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info);
-static void pqi_complete_all_queued_raid_bypass_retries(
-	struct pqi_ctrl_info *ctrl_info, int result);
+static void pqi_ctrl_offline_worker(struct work_struct *work);
 static void pqi_retry_raid_bypass_requests(struct pqi_ctrl_info *ctrl_info);
 static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info);
 static void pqi_scan_start(struct Scsi_Host *shost);
@@ -224,7 +222,6 @@ static inline void pqi_save_ctrl_mode(struct pqi_ctrl_info *ctrl_info,
 	sis_write_driver_scratch(ctrl_info, mode);
 }
 
-#define PQI_RESCAN_WORK_INTERVAL       (10 * HZ)
 static inline void pqi_ctrl_block_requests(struct pqi_ctrl_info *ctrl_info)
 {
 	ctrl_info->block_requests = true;
@@ -310,10 +307,26 @@ static inline bool pqi_device_in_reset(struct pqi_scsi_dev *device)
 	return device->in_reset;
 }
 
+static inline void pqi_schedule_rescan_worker_with_delay(
+	struct pqi_ctrl_info *ctrl_info, unsigned long delay)
+{
+	if (pqi_ctrl_offline(ctrl_info))
+		return;
+
+	schedule_delayed_work(&ctrl_info->rescan_work, delay);
+}
+
 static inline void pqi_schedule_rescan_worker(struct pqi_ctrl_info *ctrl_info)
 {
-	schedule_delayed_work(&ctrl_info->rescan_work,
-		PQI_RESCAN_WORK_INTERVAL);
+	pqi_schedule_rescan_worker_with_delay(ctrl_info, 0);
+}
+
+#define PQI_RESCAN_WORK_DELAY  (10 * HZ)
+
+static inline void pqi_schedule_rescan_worker_delayed(
+	struct pqi_ctrl_info *ctrl_info)
+{
+	pqi_schedule_rescan_worker_with_delay(ctrl_info, PQI_RESCAN_WORK_DELAY);
 }
 
 static inline void pqi_cancel_rescan_worker(struct pqi_ctrl_info *ctrl_info)
@@ -746,6 +759,9 @@ static void pqi_update_time_worker(struct work_struct *work)
 	ctrl_info = container_of(to_delayed_work(work), struct pqi_ctrl_info,
 		update_time_work);
 
+	if (pqi_ctrl_offline(ctrl_info))
+		return;
+
 	rc = pqi_write_current_time_to_host_wellness(ctrl_info);
 	if (rc)
 		dev_warn(&ctrl_info->pci_dev->dev,
@@ -758,21 +774,13 @@ static void pqi_update_time_worker(struct work_struct *work)
 static inline void pqi_schedule_update_time_worker(
 	struct pqi_ctrl_info *ctrl_info)
 {
-	if (ctrl_info->update_time_worker_scheduled)
-		return;
-
 	schedule_delayed_work(&ctrl_info->update_time_work, 0);
-	ctrl_info->update_time_worker_scheduled = true;
 }
 
 static inline void pqi_cancel_update_time_worker(
 	struct pqi_ctrl_info *ctrl_info)
 {
-	if (!ctrl_info->update_time_worker_scheduled)
-		return;
-
 	cancel_delayed_work_sync(&ctrl_info->update_time_work);
-	ctrl_info->update_time_worker_scheduled = false;
 }
 
 static int pqi_report_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd,
@@ -1939,7 +1947,7 @@ static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 
 	rc = pqi_update_scsi_devices(ctrl_info);
 	if (rc)
-		pqi_schedule_rescan_worker(ctrl_info);
+		pqi_schedule_rescan_worker_delayed(ctrl_info);
 
 	mutex_unlock(&ctrl_info->scan_mutex);
 
@@ -2762,6 +2770,10 @@ static void pqi_event_worker(struct work_struct *work)
 
 	pqi_ctrl_busy(ctrl_info);
 	pqi_wait_if_ctrl_blocked(ctrl_info, NO_TIMEOUT);
+	if (pqi_ctrl_offline(ctrl_info))
+		goto out;
+
+	pqi_schedule_rescan_worker_delayed(ctrl_info);
 
 	event = ctrl_info->events;
 	for (i = 0; i < PQI_NUM_SUPPORTED_EVENTS; i++) {
@@ -2772,9 +2784,8 @@ static void pqi_event_worker(struct work_struct *work)
 		event++;
 	}
 
+out:
 	pqi_ctrl_unbusy(ctrl_info);
-
-	pqi_schedule_rescan_worker(ctrl_info);
 }
 
 #define PQI_HEARTBEAT_TIMER_INTERVAL	(10 * HZ)
@@ -4751,25 +4762,13 @@ static void pqi_raid_bypass_retry_worker(struct work_struct *work)
 	pqi_retry_raid_bypass_requests(ctrl_info);
 }
 
-static void pqi_complete_all_queued_raid_bypass_retries(
-	struct pqi_ctrl_info *ctrl_info, int result)
+static void pqi_clear_all_queued_raid_bypass_retries(
+	struct pqi_ctrl_info *ctrl_info)
 {
 	unsigned long flags;
-	struct pqi_io_request *io_request;
-	struct pqi_io_request *next;
-	struct scsi_cmnd *scmd;
 
 	spin_lock_irqsave(&ctrl_info->raid_bypass_retry_list_lock, flags);
-
-	list_for_each_entry_safe(io_request, next,
-		&ctrl_info->raid_bypass_retry_list, request_list_entry) {
-		list_del(&io_request->request_list_entry);
-		scmd = io_request->scmd;
-		pqi_free_io_request(io_request);
-		scmd->result = result;
-		pqi_scsi_done(scmd);
-	}
-
+	INIT_LIST_HEAD(&ctrl_info->raid_bypass_retry_list);
 	spin_unlock_irqrestore(&ctrl_info->raid_bypass_retry_list_lock, flags);
 }
 
@@ -6325,6 +6324,7 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node)
 	INIT_DELAYED_WORK(&ctrl_info->update_time_work, pqi_update_time_worker);
 
 	init_timer(&ctrl_info->heartbeat_timer);
+	INIT_WORK(&ctrl_info->ctrl_offline_work, pqi_ctrl_offline_worker);
 
 	sema_init(&ctrl_info->sync_request_sem,
 		PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS);
@@ -6404,58 +6404,69 @@ static void pqi_perform_lockup_action(void)
 	}
 }
 
-static void pqi_complete_all_queued_requests(struct pqi_ctrl_info *ctrl_info,
-	int result)
+static struct pqi_raid_error_info pqi_ctrl_offline_raid_error_info = {
+	.data_out_result = PQI_DATA_IN_OUT_HARDWARE_ERROR,
+	.status = SAM_STAT_CHECK_CONDITION,
+};
+
+static void pqi_fail_all_outstanding_requests(struct pqi_ctrl_info *ctrl_info)
 {
 	unsigned int i;
-	unsigned int path;
-	struct pqi_queue_group *queue_group;
-	unsigned long flags;
 	struct pqi_io_request *io_request;
-	struct pqi_io_request *next;
 	struct scsi_cmnd *scmd;
 
-	for (i = 0; i < ctrl_info->num_queue_groups; i++) {
-		queue_group = &ctrl_info->queue_groups[i];
-
-		for (path = 0; path < 2; path++) {
-			spin_lock_irqsave(
-				&queue_group->submit_lock[path], flags);
-
-			list_for_each_entry_safe(io_request, next,
-				&queue_group->request_list[path],
-				request_list_entry) {
-
-				scmd = io_request->scmd;
-				if (scmd) {
-					scmd->result = result;
-					pqi_scsi_done(scmd);
-				}
-
-				list_del(&io_request->request_list_entry);
-			}
+	for (i = 0; i < ctrl_info->max_io_slots; i++) {
+		io_request = &ctrl_info->io_request_pool[i];
+		if (atomic_read(&io_request->refcount) == 0)
+			continue;
 
-			spin_unlock_irqrestore(
-				&queue_group->submit_lock[path], flags);
+		scmd = io_request->scmd;
+		if (scmd) {
+			set_host_byte(scmd, DID_NO_CONNECT);
+		} else {
+			io_request->status = -ENXIO;
+			io_request->error_info =
+				&pqi_ctrl_offline_raid_error_info;
 		}
+
+		io_request->io_complete_callback(io_request,
+			io_request->context);
 	}
 }
 
-static void pqi_fail_all_queued_requests(struct pqi_ctrl_info *ctrl_info)
+static void pqi_take_ctrl_offline_deferred(struct pqi_ctrl_info *ctrl_info)
 {
-	pqi_complete_all_queued_requests(ctrl_info, DID_NO_CONNECT << 16);
-	pqi_complete_all_queued_raid_bypass_retries(ctrl_info,
-		DID_NO_CONNECT << 16);
+	pqi_perform_lockup_action();
+	pqi_stop_heartbeat_timer(ctrl_info);
+	pqi_free_interrupts(ctrl_info);
+	pqi_cancel_rescan_worker(ctrl_info);
+	pqi_cancel_update_time_worker(ctrl_info);
+	pqi_ctrl_wait_until_quiesced(ctrl_info);
+	pqi_fail_all_outstanding_requests(ctrl_info);
+	pqi_clear_all_queued_raid_bypass_retries(ctrl_info);
+	pqi_ctrl_unblock_requests(ctrl_info);
+}
+
+static void pqi_ctrl_offline_worker(struct work_struct *work)
+{
+	struct pqi_ctrl_info *ctrl_info;
+
+	ctrl_info = container_of(work, struct pqi_ctrl_info, ctrl_offline_work);
+	pqi_take_ctrl_offline_deferred(ctrl_info);
 }
 
 static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
 {
+	if (!ctrl_info->controller_online)
+		return;
+
 	ctrl_info->controller_online = false;
+	ctrl_info->pqi_mode_enabled = false;
+	pqi_ctrl_block_requests(ctrl_info);
 	sis_shutdown_ctrl(ctrl_info);
 	pci_disable_device(ctrl_info->pci_dev);
 	dev_err(&ctrl_info->pci_dev->dev, "controller offline\n");
-	pqi_perform_lockup_action();
-	pqi_fail_all_queued_requests(ctrl_info);
+	schedule_work(&ctrl_info->ctrl_offline_work);
 }
 
 static void pqi_print_ctrl_info(struct pci_dev *pci_dev,

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

* [PATCH 28/37] smartpqi: cleanup controller branding
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (26 preceding siblings ...)
  2017-04-25 19:48 ` [PATCH 27/37] smartpqi: controller offline improvements Don Brace
@ 2017-04-25 19:48 ` Don Brace
  2017-04-25 19:48 ` [PATCH 29/37] smartpqi: map more raid errors to SCSI errors Don Brace
                   ` (8 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:48 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

- Improve controller branding support.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 66f02f4..790dfc4 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -58,9 +58,6 @@ MODULE_SUPPORTED_DEVICE("Microsemi Smart Family Controllers");
 MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
-static char *hpe_branded_controller = "HPE Smart Array Controller";
-static char *microsemi_branded_controller = "Microsemi Smart Family Controller";
-
 static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info);
 static void pqi_ctrl_offline_worker(struct work_struct *work);
 static void pqi_retry_raid_bypass_requests(struct pqi_ctrl_info *ctrl_info);
@@ -6474,19 +6471,10 @@ static void pqi_print_ctrl_info(struct pci_dev *pci_dev,
 {
 	char *ctrl_description;
 
-	if (id->driver_data) {
+	if (id->driver_data)
 		ctrl_description = (char *)id->driver_data;
-	} else {
-		switch (id->subvendor) {
-		case PCI_VENDOR_ID_HP:
-			ctrl_description = hpe_branded_controller;
-			break;
-		case PCI_VENDOR_ID_ADAPTEC2:
-		default:
-			ctrl_description = microsemi_branded_controller;
-			break;
-		}
-	}
+	else
+		ctrl_description = "Microsemi Smart Family Controller";
 
 	dev_info(&pci_dev->dev, "%s found\n", ctrl_description);
 }

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

* [PATCH 29/37] smartpqi: map more raid errors to SCSI errors
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (27 preceding siblings ...)
  2017-04-25 19:48 ` [PATCH 28/37] smartpqi: cleanup controller branding Don Brace
@ 2017-04-25 19:48 ` Don Brace
  2017-04-25 19:48 ` [PATCH 30/37] smartpqi: update timeout on admin commands Don Brace
                   ` (7 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:48 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

enhance mapping of RAID path errors to Linux SCSI host
error codes.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 790dfc4..e841c1b 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -2447,13 +2447,43 @@ static void pqi_process_raid_io_error(struct pqi_io_request *io_request)
 	scsi_status = error_info->status;
 	host_byte = DID_OK;
 
-	if (error_info->data_out_result == PQI_DATA_IN_OUT_UNDERFLOW) {
+	switch (error_info->data_out_result) {
+	case PQI_DATA_IN_OUT_GOOD:
+		break;
+	case PQI_DATA_IN_OUT_UNDERFLOW:
 		xfer_count =
 			get_unaligned_le32(&error_info->data_out_transferred);
 		residual_count = scsi_bufflen(scmd) - xfer_count;
 		scsi_set_resid(scmd, residual_count);
 		if (xfer_count < scmd->underflow)
 			host_byte = DID_SOFT_ERROR;
+		break;
+	case PQI_DATA_IN_OUT_UNSOLICITED_ABORT:
+	case PQI_DATA_IN_OUT_ABORTED:
+		host_byte = DID_ABORT;
+		break;
+	case PQI_DATA_IN_OUT_TIMEOUT:
+		host_byte = DID_TIME_OUT;
+		break;
+	case PQI_DATA_IN_OUT_BUFFER_OVERFLOW:
+	case PQI_DATA_IN_OUT_PROTOCOL_ERROR:
+	case PQI_DATA_IN_OUT_BUFFER_ERROR:
+	case PQI_DATA_IN_OUT_BUFFER_OVERFLOW_DESCRIPTOR_AREA:
+	case PQI_DATA_IN_OUT_BUFFER_OVERFLOW_BRIDGE:
+	case PQI_DATA_IN_OUT_ERROR:
+	case PQI_DATA_IN_OUT_HARDWARE_ERROR:
+	case PQI_DATA_IN_OUT_PCIE_FABRIC_ERROR:
+	case PQI_DATA_IN_OUT_PCIE_COMPLETION_TIMEOUT:
+	case PQI_DATA_IN_OUT_PCIE_COMPLETER_ABORT_RECEIVED:
+	case PQI_DATA_IN_OUT_PCIE_UNSUPPORTED_REQUEST_RECEIVED:
+	case PQI_DATA_IN_OUT_PCIE_ECRC_CHECK_FAILED:
+	case PQI_DATA_IN_OUT_PCIE_UNSUPPORTED_REQUEST:
+	case PQI_DATA_IN_OUT_PCIE_ACS_VIOLATION:
+	case PQI_DATA_IN_OUT_PCIE_TLP_PREFIX_BLOCKED:
+	case PQI_DATA_IN_OUT_PCIE_POISONED_MEMORY_READ:
+	default:
+		host_byte = DID_ERROR;
+		break;
 	}
 
 	sense_data_length = get_unaligned_le16(&error_info->sense_data_length);

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

* [PATCH 30/37] smartpqi: update timeout on admin commands
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (28 preceding siblings ...)
  2017-04-25 19:48 ` [PATCH 29/37] smartpqi: map more raid errors to SCSI errors Don Brace
@ 2017-04-25 19:48 ` Don Brace
  2017-04-25 19:49 ` [PATCH 31/37] smartpqi: enhance device add and remove messages Don Brace
                   ` (6 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:48 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

Increase the timeout on admin commands from 3 seconds to 60
seconds and added a check for controller crash in the loop
where the driver polls for admin command completion.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index e841c1b..52ad6e7 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -3432,6 +3432,8 @@ static void pqi_submit_admin_request(struct pqi_ctrl_info *ctrl_info,
 	writel(iq_pi, admin_queues->iq_pi);
 }
 
+#define PQI_ADMIN_REQUEST_TIMEOUT_SECS	60
+
 static int pqi_poll_for_admin_response(struct pqi_ctrl_info *ctrl_info,
 	struct pqi_general_admin_response *response)
 {
@@ -3443,7 +3445,7 @@ static int pqi_poll_for_admin_response(struct pqi_ctrl_info *ctrl_info,
 	admin_queues = &ctrl_info->admin_queues;
 	oq_ci = admin_queues->oq_ci_copy;
 
-	timeout = (3 * HZ) + jiffies;
+	timeout = (PQI_ADMIN_REQUEST_TIMEOUT_SECS * HZ) + jiffies;
 
 	while (1) {
 		oq_pi = *admin_queues->oq_pi;
@@ -3454,6 +3456,8 @@ static int pqi_poll_for_admin_response(struct pqi_ctrl_info *ctrl_info,
 				"timed out waiting for admin response\n");
 			return -ETIMEDOUT;
 		}
+		if (!sis_is_firmware_running(ctrl_info))
+			return -ENXIO;
 		usleep_range(1000, 2000);
 	}
 

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

* [PATCH 31/37] smartpqi: enhance device add and remove messages
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (29 preceding siblings ...)
  2017-04-25 19:48 ` [PATCH 30/37] smartpqi: update timeout on admin commands Don Brace
@ 2017-04-25 19:49 ` Don Brace
  2017-04-25 19:49 ` [PATCH 32/37] smartpqi: make raid bypass references consistent Don Brace
                   ` (5 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:49 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

Improved formatting of information displayed when devices
are added/removed from the system.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   90 +++++++++++++++++++++++++--------
 1 file changed, 69 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 52ad6e7..c20d731 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -1454,24 +1454,66 @@ static enum pqi_find_result pqi_scsi_find_entry(struct pqi_ctrl_info *ctrl_info,
 	return DEVICE_NOT_FOUND;
 }
 
+#define PQI_DEV_INFO_BUFFER_LENGTH	128
+
 static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info,
 	char *action, struct pqi_scsi_dev *device)
 {
-	dev_info(&ctrl_info->pci_dev->dev,
-		"%s scsi %d:%d:%d:%d: %s %.8s %.16s %-12s SSDSmartPathCap%c En%c qd=%d\n",
-		action,
-		ctrl_info->scsi_host->host_no,
-		device->bus,
-		device->target,
-		device->lun,
+	ssize_t count;
+	char buffer[PQI_DEV_INFO_BUFFER_LENGTH];
+
+	count = snprintf(buffer, PQI_DEV_INFO_BUFFER_LENGTH,
+		"%d:%d:", ctrl_info->scsi_host->host_no, device->bus);
+
+	if (device->target_lun_valid)
+		count += snprintf(buffer + count,
+			PQI_DEV_INFO_BUFFER_LENGTH - count,
+			"%d:%d",
+			device->target,
+			device->lun);
+	else
+		count += snprintf(buffer + count,
+			PQI_DEV_INFO_BUFFER_LENGTH - count,
+			"-:-");
+
+	if (pqi_is_logical_device(device))
+		count += snprintf(buffer + count,
+			PQI_DEV_INFO_BUFFER_LENGTH - count,
+			" %08x%08x",
+			*((u32 *)&device->scsi3addr),
+			*((u32 *)&device->scsi3addr[4]));
+	else
+		count += snprintf(buffer + count,
+			PQI_DEV_INFO_BUFFER_LENGTH - count,
+			" %016llx", device->sas_address);
+
+	count += snprintf(buffer + count, PQI_DEV_INFO_BUFFER_LENGTH - count,
+		" %s %.8s %.16s ",
 		scsi_device_type(device->devtype),
 		device->vendor,
-		device->model,
-		pqi_is_logical_device(device) ?
-			pqi_raid_level_to_string(device->raid_level) : "",
-		device->offload_configured ? '+' : '-',
-		device->offload_enabled_pending ? '+' : '-',
-		device->queue_depth);
+		device->model);
+
+	if (pqi_is_logical_device(device)) {
+		if (device->devtype == TYPE_DISK)
+			count += snprintf(buffer + count,
+				PQI_DEV_INFO_BUFFER_LENGTH - count,
+				"SSDSmartPathCap%c En%c %-12s",
+				device->offload_configured ? '+' : '-',
+				(device->offload_enabled ||
+				device->offload_enabled_pending) ? '+' : '-',
+				pqi_raid_level_to_string(device->raid_level));
+	} else {
+		count += snprintf(buffer + count,
+			PQI_DEV_INFO_BUFFER_LENGTH - count,
+			"AIO%c", device->aio_enabled ? '+' : '-');
+		if (device->devtype == TYPE_DISK ||
+			device->devtype == TYPE_ZBC)
+			count += snprintf(buffer + count,
+				PQI_DEV_INFO_BUFFER_LENGTH - count,
+				" qd=%-6d", device->queue_depth);
+	}
+
+	dev_info(&ctrl_info->pci_dev->dev, "%s %s\n", action, buffer);
 }
 
 /* Assumes the SCSI device list lock is held. */
@@ -1644,14 +1686,14 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
 	/* Remove all devices that have gone away. */
 	list_for_each_entry_safe(device, next, &delete_list,
 		delete_list_entry) {
-		if (device->sdev)
-			pqi_remove_device(ctrl_info, device);
 		if (device->volume_offline) {
 			pqi_dev_info(ctrl_info, "offline", device);
 			pqi_show_volume_status(ctrl_info, device);
 		} else {
 			pqi_dev_info(ctrl_info, "removed", device);
 		}
+		if (device->sdev)
+			pqi_remove_device(ctrl_info, device);
 		list_del(&device->delete_list_entry);
 		pqi_free_device(device);
 	}
@@ -1673,6 +1715,7 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
 	/* Expose any new devices. */
 	list_for_each_entry_safe(device, next, &add_list, add_list_entry) {
 		if (!device->sdev) {
+			pqi_dev_info(ctrl_info, "added", device);
 			rc = pqi_add_device(ctrl_info, device);
 			if (rc) {
 				dev_warn(&ctrl_info->pci_dev->dev,
@@ -1681,10 +1724,8 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
 					device->bus, device->target,
 					device->lun);
 				pqi_fixup_botched_add(ctrl_info, device);
-				continue;
 			}
 		}
-		pqi_dev_info(ctrl_info, "added", device);
 	}
 }
 
@@ -1744,7 +1785,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 	bool is_physical_device;
 	u8 *scsi3addr;
 	static char *out_of_memory_msg =
-		"out of memory, device discovery stopped";
+		"failed to allocate memory, device discovery stopped";
 
 	INIT_LIST_HEAD(&new_device_list_head);
 
@@ -1845,9 +1886,16 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 			goto out;
 		}
 		if (rc) {
-			dev_warn(&ctrl_info->pci_dev->dev,
-				"obtaining device info failed, skipping device %016llx\n",
-				get_unaligned_be64(device->scsi3addr));
+			if (device->is_physical_device)
+				dev_warn(&ctrl_info->pci_dev->dev,
+					"obtaining device info failed, skipping physical device %016llx\n",
+					get_unaligned_be64(
+						&phys_lun_ext_entry->wwid));
+			else
+				dev_warn(&ctrl_info->pci_dev->dev,
+					"obtaining device info failed, skipping logical device %08x%08x\n",
+					*((u32 *)&device->scsi3addr),
+					*((u32 *)&device->scsi3addr[4]));
 			rc = 0;
 			continue;
 		}

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

* [PATCH 32/37] smartpqi: make raid bypass references consistent
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (30 preceding siblings ...)
  2017-04-25 19:49 ` [PATCH 31/37] smartpqi: enhance device add and remove messages Don Brace
@ 2017-04-25 19:49 ` Don Brace
  2017-04-25 19:49 ` [PATCH 33/37] smartpqi: add raid level show Don Brace
                   ` (4 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:49 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

- make all references to RAID bypass consistent throughout driver.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |   13 ++++----
 drivers/scsi/smartpqi/smartpqi_init.c |   56 ++++++++++++++-------------------
 2 files changed, 30 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 2ed15cf..e9f113a 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -805,12 +805,11 @@ struct pqi_scsi_dev {
 	u8	bay;
 	u8	box[8];
 	u16	phys_connector[8];
-	int	offload_configured;	/* I/O accel RAID offload configured */
-	int	offload_enabled;	/* I/O accel RAID offload enabled */
-	int	offload_enabled_pending;
-	int	offload_to_mirror;	/* Send next I/O accelerator RAID */
-					/* offload request to mirror drive. */
-	struct raid_map *raid_map;	/* I/O accelerator RAID map */
+	bool	raid_bypass_configured;	/* RAID bypass configured */
+	bool	raid_bypass_enabled;	/* RAID bypass enabled */
+	int	offload_to_mirror;	/* Send next RAID bypass request */
+					/* to mirror drive. */
+	struct raid_map *raid_map;	/* RAID bypass map */
 
 	struct pqi_sas_port *sas_port;
 	struct scsi_device *sdev;
@@ -827,7 +826,7 @@ struct pqi_scsi_dev {
 #define SCSI_VPD_SUPPORTED_PAGES	0x0	/* standard page */
 #define SCSI_VPD_DEVICE_ID		0x83	/* standard page */
 #define CISS_VPD_LV_DEVICE_GEOMETRY	0xc1	/* vendor-specific page */
-#define CISS_VPD_LV_OFFLOAD_STATUS	0xc2	/* vendor-specific page */
+#define CISS_VPD_LV_BYPASS_STATUS	0xc2	/* vendor-specific page */
 #define CISS_VPD_LV_STATUS		0xc3	/* vendor-specific page */
 
 #define VPD_PAGE	(1 << 8)
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index c20d731..23d4686 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -1117,35 +1117,33 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info,
 	return rc;
 }
 
-static void pqi_get_offload_status(struct pqi_ctrl_info *ctrl_info,
+static void pqi_get_raid_bypass_status(struct pqi_ctrl_info *ctrl_info,
 	struct pqi_scsi_dev *device)
 {
 	int rc;
 	u8 *buffer;
-	u8 offload_status;
+	u8 bypass_status;
 
 	buffer = kmalloc(64, GFP_KERNEL);
 	if (!buffer)
 		return;
 
 	rc = pqi_scsi_inquiry(ctrl_info, device->scsi3addr,
-		VPD_PAGE | CISS_VPD_LV_OFFLOAD_STATUS, buffer, 64);
+		VPD_PAGE | CISS_VPD_LV_BYPASS_STATUS, buffer, 64);
 	if (rc)
 		goto out;
 
-#define OFFLOAD_STATUS_BYTE	4
-#define OFFLOAD_CONFIGURED_BIT	0x1
-#define OFFLOAD_ENABLED_BIT	0x2
+#define RAID_BYPASS_STATUS	4
+#define RAID_BYPASS_CONFIGURED	0x1
+#define RAID_BYPASS_ENABLED	0x2
 
-	offload_status = buffer[OFFLOAD_STATUS_BYTE];
-	device->offload_configured =
-		!!(offload_status & OFFLOAD_CONFIGURED_BIT);
-	if (device->offload_configured) {
-		device->offload_enabled_pending =
-			!!(offload_status & OFFLOAD_ENABLED_BIT);
-		if (pqi_get_raid_map(ctrl_info, device))
-			device->offload_enabled_pending = false;
-	}
+	bypass_status = buffer[RAID_BYPASS_STATUS];
+	device->raid_bypass_configured =
+		(bypass_status & RAID_BYPASS_CONFIGURED) != 0;
+	if (device->raid_bypass_configured &&
+		(bypass_status & RAID_BYPASS_ENABLED) &&
+		pqi_get_raid_map(ctrl_info, device) == 0)
+		device->raid_bypass_enabled = true;
 
 out:
 	kfree(buffer);
@@ -1219,7 +1217,7 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
 			device->volume_offline = false;
 		} else {
 			pqi_get_raid_level(ctrl_info, device);
-			pqi_get_offload_status(ctrl_info, device);
+			pqi_get_raid_bypass_status(ctrl_info, device);
 			pqi_get_volume_status(ctrl_info, device);
 		}
 	}
@@ -1498,9 +1496,8 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info,
 			count += snprintf(buffer + count,
 				PQI_DEV_INFO_BUFFER_LENGTH - count,
 				"SSDSmartPathCap%c En%c %-12s",
-				device->offload_configured ? '+' : '-',
-				(device->offload_enabled ||
-				device->offload_enabled_pending) ? '+' : '-',
+				device->raid_bypass_configured ? '+' : '-',
+				device->raid_bypass_enabled ? '+' : '-',
 				pqi_raid_level_to_string(device->raid_level));
 	} else {
 		count += snprintf(buffer + count,
@@ -1552,13 +1549,13 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device,
 		sizeof(existing_device->box));
 	memcpy(existing_device->phys_connector, new_device->phys_connector,
 		sizeof(existing_device->phys_connector));
-	existing_device->offload_configured = new_device->offload_configured;
-	existing_device->offload_enabled = false;
-	existing_device->offload_enabled_pending =
-		new_device->offload_enabled_pending;
 	existing_device->offload_to_mirror = 0;
 	kfree(existing_device->raid_map);
 	existing_device->raid_map = new_device->raid_map;
+	existing_device->raid_bypass_configured =
+		new_device->raid_bypass_configured;
+	existing_device->raid_bypass_enabled =
+		new_device->raid_bypass_enabled;
 
 	/* To prevent this from being freed later. */
 	new_device->raid_map = NULL;
@@ -1676,11 +1673,6 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
 		device->keep_device = true;
 	}
 
-	list_for_each_entry(device, &ctrl_info->scsi_device_list,
-		scsi_device_list_entry)
-		device->offload_enabled =
-			device->offload_enabled_pending;
-
 	spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
 
 	/* Remove all devices that have gone away. */
@@ -2050,7 +2042,7 @@ static inline void pqi_set_encryption_info(
 }
 
 /*
- * Attempt to perform offload RAID mapping for a logical volume I/O.
+ * Attempt to perform RAID bypass mapping for a logical volume I/O.
  */
 
 #define PQI_RAID_BYPASS_INELIGIBLE	1
@@ -2454,7 +2446,7 @@ static inline void pqi_aio_path_disabled(struct pqi_io_request *io_request)
 	struct pqi_scsi_dev *device;
 
 	device = io_request->scmd->device->hostdata;
-	device->offload_enabled = false;
+	device->raid_bypass_enabled = false;
 	device->aio_enabled = false;
 }
 
@@ -5009,7 +5001,7 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
 
 	if (pqi_is_logical_device(device)) {
 		raid_bypassed = false;
-		if (device->offload_enabled &&
+		if (device->raid_bypass_enabled &&
 				!blk_rq_is_passthrough(scmd->request)) {
 			rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device,
 				scmd, queue_group);
@@ -5760,7 +5752,7 @@ static ssize_t pqi_ssd_smart_path_enabled_show(struct device *dev,
 	spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
 
 	device = sdev->hostdata;
-	buffer[0] = device->offload_enabled ? '1' : '0';
+	buffer[0] = device->raid_bypass_enabled ? '1' : '0';
 	buffer[1] = '\n';
 	buffer[2] = '\0';
 

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

* [PATCH 33/37] smartpqi: add raid level show
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (31 preceding siblings ...)
  2017-04-25 19:49 ` [PATCH 32/37] smartpqi: make raid bypass references consistent Don Brace
@ 2017-04-25 19:49 ` Don Brace
  2017-04-25 19:49 ` [PATCH 34/37] smartpqi: cleanup list initialization Don Brace
                   ` (3 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:49 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

Display the RAID level via sysfs

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 23d4686..8b285ad 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -144,7 +144,7 @@ static char *pqi_raid_level_to_string(u8 raid_level)
 	if (raid_level < ARRAY_SIZE(raid_levels))
 		return raid_levels[raid_level];
 
-	return "";
+	return "RAID UNKNOWN";
 }
 
 #define SA_RAID_0		0
@@ -5761,13 +5761,41 @@ static ssize_t pqi_ssd_smart_path_enabled_show(struct device *dev,
 	return 2;
 }
 
+static ssize_t pqi_raid_level_show(struct device *dev,
+	struct device_attribute *attr, char *buffer)
+{
+	struct pqi_ctrl_info *ctrl_info;
+	struct scsi_device *sdev;
+	struct pqi_scsi_dev *device;
+	unsigned long flags;
+	char *raid_level;
+
+	sdev = to_scsi_device(dev);
+	ctrl_info = shost_to_hba(sdev->host);
+
+	spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
+
+	device = sdev->hostdata;
+
+	if (pqi_is_logical_device(device))
+		raid_level = pqi_raid_level_to_string(device->raid_level);
+	else
+		raid_level = "N/A";
+
+	spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+
+	return snprintf(buffer, PAGE_SIZE, "%s\n", raid_level);
+}
+
 static DEVICE_ATTR(sas_address, 0444, pqi_sas_address_show, NULL);
 static DEVICE_ATTR(ssd_smart_path_enabled, 0444,
 	pqi_ssd_smart_path_enabled_show, NULL);
+static DEVICE_ATTR(raid_level, 0444, pqi_raid_level_show, NULL);
 
 static struct device_attribute *pqi_sdev_attrs[] = {
 	&dev_attr_sas_address,
 	&dev_attr_ssd_smart_path_enabled,
+	&dev_attr_raid_level,
 	NULL
 };
 

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

* [PATCH 34/37] smartpqi: cleanup list initialization
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (32 preceding siblings ...)
  2017-04-25 19:49 ` [PATCH 33/37] smartpqi: add raid level show Don Brace
@ 2017-04-25 19:49 ` Don Brace
  2017-04-25 19:49 ` [PATCH 35/37] smartpqi: add module parameters Don Brace
                   ` (2 subsequent siblings)
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:49 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@microsemi.com>

Better initialization of linked list heads.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 8b285ad..13d3ed5 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -1597,11 +1597,8 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
 	struct pqi_scsi_dev *device;
 	struct pqi_scsi_dev *next;
 	struct pqi_scsi_dev *matching_device;
-	struct list_head add_list;
-	struct list_head delete_list;
-
-	INIT_LIST_HEAD(&add_list);
-	INIT_LIST_HEAD(&delete_list);
+	LIST_HEAD(add_list);
+	LIST_HEAD(delete_list);
 
 	/*
 	 * The idea here is to do as little work as possible while holding the
@@ -1761,7 +1758,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 {
 	int i;
 	int rc;
-	struct list_head new_device_list_head;
+	LIST_HEAD(new_device_list_head);
 	struct report_phys_lun_extended *physdev_list = NULL;
 	struct report_log_lun_extended *logdev_list = NULL;
 	struct report_phys_lun_extended_entry *phys_lun_ext_entry;
@@ -1779,8 +1776,6 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
 	static char *out_of_memory_msg =
 		"failed to allocate memory, device discovery stopped";
 
-	INIT_LIST_HEAD(&new_device_list_head);
-
 	rc = pqi_get_device_lists(ctrl_info, &physdev_list, &logdev_list);
 	if (rc)
 		goto out;

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

* [PATCH 35/37] smartpqi: add module parameters
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (33 preceding siblings ...)
  2017-04-25 19:49 ` [PATCH 34/37] smartpqi: cleanup list initialization Don Brace
@ 2017-04-25 19:49 ` Don Brace
  2017-04-25 19:49 ` [PATCH 36/37] smartpqi: remove writeq/readq function definitions Don Brace
  2017-04-25 19:49 ` [PATCH 37/37] smartpqi: bump driver version Don Brace
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:49 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@microsemi.com>

Add module parameters to disable heartbeat support and to disable
shutting down the controller when a controller is taken offline.

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 13d3ed5..cf13f3e 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -122,6 +122,18 @@ module_param_named(disable_device_id_wildcards,
 MODULE_PARM_DESC(disable_device_id_wildcards,
 	"Disable device ID wildcards.");
 
+static int pqi_disable_heartbeat;
+module_param_named(disable_heartbeat,
+	pqi_disable_heartbeat, int, 0644);
+MODULE_PARM_DESC(disable_heartbeat,
+	"Disable heartbeat.");
+
+static int pqi_disable_ctrl_shutdown;
+module_param_named(disable_ctrl_shutdown,
+	pqi_disable_ctrl_shutdown, int, 0644);
+MODULE_PARM_DESC(disable_ctrl_shutdown,
+	"Disable controller shutdown when controller locked up.");
+
 static char *pqi_lockup_action_param;
 module_param_named(lockup_action,
 	pqi_lockup_action_param, charp, 0644);
@@ -5969,10 +5981,16 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info)
 
 		switch (get_unaligned_le16(&section->section_id)) {
 		case PQI_CONFIG_TABLE_SECTION_HEARTBEAT:
-			ctrl_info->heartbeat_counter = table_iomem_addr +
-				section_offset +
-				offsetof(struct pqi_config_table_heartbeat,
-					heartbeat_counter);
+			if (pqi_disable_heartbeat)
+				dev_warn(&ctrl_info->pci_dev->dev,
+				"heartbeat disabled by module parameter\n");
+			else
+				ctrl_info->heartbeat_counter =
+					table_iomem_addr +
+					section_offset +
+					offsetof(
+					struct pqi_config_table_heartbeat,
+						heartbeat_counter);
 			break;
 		}
 
@@ -6557,7 +6575,8 @@ static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
 	ctrl_info->controller_online = false;
 	ctrl_info->pqi_mode_enabled = false;
 	pqi_ctrl_block_requests(ctrl_info);
-	sis_shutdown_ctrl(ctrl_info);
+	if (!pqi_disable_ctrl_shutdown)
+		sis_shutdown_ctrl(ctrl_info);
 	pci_disable_device(ctrl_info->pci_dev);
 	dev_err(&ctrl_info->pci_dev->dev, "controller offline\n");
 	schedule_work(&ctrl_info->ctrl_offline_work);

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

* [PATCH 36/37] smartpqi: remove writeq/readq function definitions
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (34 preceding siblings ...)
  2017-04-25 19:49 ` [PATCH 35/37] smartpqi: add module parameters Don Brace
@ 2017-04-25 19:49 ` Don Brace
  2017-04-26  9:35   ` kbuild test robot
  2017-04-25 19:49 ` [PATCH 37/37] smartpqi: bump driver version Don Brace
  36 siblings, 1 reply; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:49 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Corentin Labbe <clabbe.montjoie@gmail.com>

Instead of rewriting write/readq, use existing functions

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi.h |   29 -----------------------------
 1 file changed, 29 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index e9f113a..446e17b 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -1175,33 +1175,4 @@ void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd);
 
 extern struct sas_function_template pqi_sas_transport_functions;
 
-#if !defined(readq)
-#define readq readq
-static inline u64 readq(const volatile void __iomem *addr)
-{
-	u32 lower32;
-	u32 upper32;
-
-	lower32 = readl(addr);
-	upper32 = readl(addr + 4);
-
-	return ((u64)upper32 << 32) | lower32;
-}
-#endif
-
-#if !defined(writeq)
-#define writeq writeq
-static inline void writeq(u64 value, volatile void __iomem *addr)
-{
-	u32 lower32;
-	u32 upper32;
-
-	lower32 = lower_32_bits(value);
-	upper32 = upper_32_bits(value);
-
-	writel(lower32, addr);
-	writel(upper32, addr + 4);
-}
-#endif
-
 #endif /* _SMARTPQI_H */

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

* [PATCH 37/37] smartpqi: bump driver version
  2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
                   ` (35 preceding siblings ...)
  2017-04-25 19:49 ` [PATCH 36/37] smartpqi: remove writeq/readq function definitions Don Brace
@ 2017-04-25 19:49 ` Don Brace
  36 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-04-25 19:49 UTC (permalink / raw)
  To: joseph.szczypek, gerry.morong, john.hall, jejb, Kevin.Barnett,
	Mahesh.Rajashekhara, bader.alisaleh, hch, scott.teel, Viswas.G,
	Justin.Lindley, scott.benesh, POSWALD
  Cc: linux-scsi

From: Kevin Barnett <kevin.barnett@hpe.com>

Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Gerry Morong <gerry.morong@microsemi.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index cf13f3e..ef5ccb2 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -40,13 +40,14 @@
 #define BUILD_TIMESTAMP
 #endif
 
-#define DRIVER_VERSION		"0.9.13-370"
-#define DRIVER_MAJOR		0
-#define DRIVER_MINOR		9
-#define DRIVER_RELEASE		13
-#define DRIVER_REVISION		370
-
-#define DRIVER_NAME		"Microsemi PQI Driver (v" DRIVER_VERSION ")"
+#define DRIVER_VERSION		"1.0.4-100"
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		0
+#define DRIVER_RELEASE		4
+#define DRIVER_REVISION		100
+
+#define DRIVER_NAME		"Microsemi PQI Driver (v" \
+				DRIVER_VERSION BUILD_TIMESTAMP ")"
 #define DRIVER_NAME_SHORT	"smartpqi"
 
 #define PQI_EXTRA_SGL_MEMORY	(12 * sizeof(struct pqi_sg_descriptor))

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

* Re: [PATCH 02/37] smartpqi: cleanup interrupt management
  2017-04-25 19:46 ` [PATCH 02/37] smartpqi: cleanup interrupt management Don Brace
@ 2017-04-25 19:54   ` Bart Van Assche
  2017-05-03 15:23     ` Don Brace
  0 siblings, 1 reply; 55+ messages in thread
From: Bart Van Assche @ 2017-04-25 19:54 UTC (permalink / raw)
  To: hch, Viswas.G, gerry.morong, Mahesh.Rajashekhara, POSWALD,
	scott.benesh, don.brace, bader.alisaleh, Kevin.Barnett,
	joseph.szczypek, scott.teel, jejb, Justin.Lindley, john.hall
  Cc: linux-scsi

On Tue, 2017-04-25 at 14:46 -0500, Don Brace wrote:
>  static int pqi_request_irqs(struct pqi_ctrl_info *ctrl_info)
>  {
> -	struct pci_dev *pdev = ctrl_info->pci_dev;
>  	int i;
>  	int rc;
> +	struct pci_dev *pdev = ctrl_info->pci_dev;

Was this change necessary? If not, please leave it out.

Thanks,

Bart.

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

* Re: [PATCH 05/37] smartpqi: ensure controller is in SIS mode at init
  2017-04-25 19:46 ` [PATCH 05/37] smartpqi: ensure controller is in SIS mode at init Don Brace
@ 2017-04-25 19:57   ` Bart Van Assche
  2017-05-03 15:46     ` Don Brace
  0 siblings, 1 reply; 55+ messages in thread
From: Bart Van Assche @ 2017-04-25 19:57 UTC (permalink / raw)
  To: hch, Viswas.G, gerry.morong, Mahesh.Rajashekhara, POSWALD,
	scott.benesh, don.brace, bader.alisaleh, Kevin.Barnett,
	joseph.szczypek, scott.teel, jejb, Justin.Lindley, john.hall
  Cc: linux-scsi

On Tue, 2017-04-25 at 14:46 -0500, Don Brace wrote:
> +bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
> +{
> +	u32 status;
> +	bool kernel_up;
> +
> +	status = readl(&ctrl_info->registers->sis_firmware_status);
> +
> +	if (status & SIS_CTRL_KERNEL_UP)
> +		kernel_up = true;
> +	else
> +		kernel_up = false;
> +
> +	return kernel_up;
> +}

Since bool is a synonym for the C11 type _Bool, it is not necessary to
convert explicitly to a truth value. The above code can be simplified into:

bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
{
	return readl(&ctrl_info->registers->sis_firmware_status) &
		SIS_CTRL_KERNEL_UP;
}

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

* Re: [PATCH 07/37] smartpqi: enhance resets
  2017-04-25 19:46 ` [PATCH 07/37] smartpqi: enhance resets Don Brace
@ 2017-04-25 20:01   ` Bart Van Assche
  2017-05-03 19:19     ` Don Brace
  0 siblings, 1 reply; 55+ messages in thread
From: Bart Van Assche @ 2017-04-25 20:01 UTC (permalink / raw)
  To: hch, Viswas.G, gerry.morong, Mahesh.Rajashekhara, POSWALD,
	scott.benesh, don.brace, bader.alisaleh, Kevin.Barnett,
	joseph.szczypek, scott.teel, jejb, Justin.Lindley, john.hall
  Cc: linux-scsi

On Tue, 2017-04-25 at 14:46 -0500, Don Brace wrote:
> @@ -4655,23 +4860,46 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
>  static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd)
>  {
>  	int rc;
> +	struct Scsi_Host *shost;
>  	struct pqi_ctrl_info *ctrl_info;
>  	struct pqi_scsi_dev *device;
>  
> -	ctrl_info = shost_to_hba(scmd->device->host);
> +	shost = scmd->device->host;
> +	ctrl_info = shost_to_hba(shost);
>  	device = scmd->device->hostdata;
>  
>  	dev_err(&ctrl_info->pci_dev->dev,
>  		"resetting scsi %d:%d:%d:%d\n",
> -		ctrl_info->scsi_host->host_no,
> -		device->bus, device->target, device->lun);
> +		shost->host_no, device->bus, device->target, device->lun);
>  
> -	rc = pqi_device_reset(ctrl_info, device);
> +	pqi_check_ctrl_health(ctrl_info);
> +	if (pqi_ctrl_offline(ctrl_info)) {
> +		rc = FAILED;
> +		goto out;
> +	}
>  
> +	mutex_lock(&ctrl_info->lun_reset_mutex);
> +
> +	pqi_ctrl_block_requests(ctrl_info);
> +	pqi_ctrl_wait_until_quiesced(ctrl_info);
> +	pqi_fail_io_queued_for_device(ctrl_info, device);
> +	rc = pqi_wait_until_inbound_queues_empty(ctrl_info);
> +	pqi_device_reset_start(device);
> +	pqi_ctrl_unblock_requests(ctrl_info);
> +
> +	if (rc)
> +		rc = FAILED;
> +	else
> +		rc = pqi_device_reset(ctrl_info, device);
> +
> +	pqi_device_reset_done(device);
> +
> +	mutex_unlock(&ctrl_info->lun_reset_mutex);
> +
> +out:
>  	dev_err(&ctrl_info->pci_dev->dev,
>  		"reset of scsi %d:%d:%d:%d: %s\n",
> -		ctrl_info->scsi_host->host_no,
> -		device->bus, device->target, device->lun,
> +		shost->host_no, device->bus, device->target, device->lun,
>  		rc == SUCCESS ? "SUCCESS" : "FAILED");
>  
>  	return rc;

Please use scsi_target_block() / scsi_target_unblock() instead of reimplementing
these functions.

Thanks,

Bart.

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

* Re: [PATCH 08/37] smartpqi: add suspend and resume support
  2017-04-25 19:46 ` [PATCH 08/37] smartpqi: add suspend and resume support Don Brace
@ 2017-04-25 20:05   ` Bart Van Assche
  2017-05-03 19:21     ` Don Brace
  0 siblings, 1 reply; 55+ messages in thread
From: Bart Van Assche @ 2017-04-25 20:05 UTC (permalink / raw)
  To: hch, Viswas.G, gerry.morong, Mahesh.Rajashekhara, POSWALD,
	scott.benesh, don.brace, bader.alisaleh, Kevin.Barnett,
	joseph.szczypek, scott.teel, jejb, Justin.Lindley, john.hall
  Cc: linux-scsi

On Tue, 2017-04-25 at 14:46 -0500, Don Brace wrote:
> +static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
> +       struct pqi_scsi_dev *device)
> +{
> +       while (atomic_read(&device->scsi_cmds_outstanding)) {
> +               pqi_check_ctrl_health(ctrl_info);
> +               if (pqi_ctrl_offline(ctrl_info))
> +                       return -ENXIO;
> +               usleep_range(1000, 2000);
> +       }
> +
> +       return 0;
> +}
> +
> +static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info)
> +{
> +       bool io_pending;
> +       unsigned long flags;
> +       struct pqi_scsi_dev *device;
> +
> +       while (1) {
> +               io_pending = false;
> +
> +               spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
> +               list_for_each_entry(device, &ctrl_info->scsi_device_list,
> +                       scsi_device_list_entry) {
> +                       if (atomic_read(&device->scsi_cmds_outstanding)) {
> +                               io_pending = true;
> +                               break;
> +                       }
> +               }
> +               spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock,
> +                                       flags);
> +
> +               if (!io_pending)
> +                       break;
> +
> +               pqi_check_ctrl_health(ctrl_info);
> +               if (pqi_ctrl_offline(ctrl_info))
> +                       return -ENXIO;
> +
> +               usleep_range(1000, 2000);
> +       }
> +
> +       return 0;
> +}

The same comment applies here that applies to the previous patch: please use
scsi_target_block() / scsi_target_unblock() instead of reimplementing these
functions.

Thanks,

Bart.

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

* Re: [PATCH 12/37] smartpqi: change functions to inline
  2017-04-25 19:47 ` [PATCH 12/37] smartpqi: change functions to inline Don Brace
@ 2017-04-25 20:07   ` Bart Van Assche
  2017-05-03 19:32     ` Don Brace
  0 siblings, 1 reply; 55+ messages in thread
From: Bart Van Assche @ 2017-04-25 20:07 UTC (permalink / raw)
  To: hch, Viswas.G, gerry.morong, Mahesh.Rajashekhara, POSWALD,
	scott.benesh, don.brace, bader.alisaleh, Kevin.Barnett,
	joseph.szczypek, scott.teel, jejb, Justin.Lindley, john.hall
  Cc: linux-scsi

On Tue, 2017-04-25 at 14:47 -0500, Don Brace wrote:
> From: Kevin Barnett <kevin.barnett@hpe.com>
> 
> Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
> Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
> Signed-off-by: Don Brace <don.brace@microsemi.com>
> ---
>  drivers/scsi/smartpqi/smartpqi_init.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
> index 728db8f..523b730 100644
> --- a/drivers/scsi/smartpqi/smartpqi_init.c
> +++ b/drivers/scsi/smartpqi/smartpqi_init.c
> @@ -432,7 +432,7 @@ static struct pqi_io_request *pqi_alloc_io_request(
>  	return io_request;
>  }
>  
> -static void pqi_free_io_request(struct pqi_io_request *io_request)
> +static inline void pqi_free_io_request(struct pqi_io_request *io_request)
>  {
>  	atomic_dec(&io_request->refcount);
>  }

A patch description should not only explain what has been changed but also
why a change has been made. What is the reason that this function has been
declared inline? Why do you think that the compiler is not smart enough to
decide on its own to inline this function?

Thanks,

Bart.

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

* Re: [PATCH 16/37] smartpqi: minor driver cleanup
  2017-04-25 19:47 ` [PATCH 16/37] smartpqi: minor driver cleanup Don Brace
@ 2017-04-25 20:09   ` Bart Van Assche
  2017-05-03 19:43     ` Don Brace
  0 siblings, 1 reply; 55+ messages in thread
From: Bart Van Assche @ 2017-04-25 20:09 UTC (permalink / raw)
  To: hch, Viswas.G, gerry.morong, Mahesh.Rajashekhara, POSWALD,
	scott.benesh, don.brace, bader.alisaleh, Kevin.Barnett,
	joseph.szczypek, scott.teel, jejb, Justin.Lindley, john.hall
  Cc: linux-scsi

On Tue, 2017-04-25 at 14:47 -0500, Don Brace wrote:
> From: Kevin Barnett <kevin.barnett@hpe.com>
> 
> - align with in-house driver

This is not an appropriate patch description. A patch description should
explain what has been changed and also what the purpose is of these changes.

Thanks,

Bart.

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

* Re: [PATCH 18/37] smartpqi: cleanup messages
  2017-04-25 19:47 ` [PATCH 18/37] smartpqi: cleanup messages Don Brace
@ 2017-04-25 20:11   ` Bart Van Assche
  2017-05-03 19:47     ` Don Brace
  0 siblings, 1 reply; 55+ messages in thread
From: Bart Van Assche @ 2017-04-25 20:11 UTC (permalink / raw)
  To: hch, Viswas.G, gerry.morong, Mahesh.Rajashekhara, POSWALD,
	scott.benesh, don.brace, bader.alisaleh, Kevin.Barnett,
	joseph.szczypek, scott.teel, jejb, Justin.Lindley, john.hall
  Cc: linux-scsi

On Tue, 2017-04-25 at 14:47 -0500, Don Brace wrote:
>  	case CISS_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER:
>  		status =
> -			"Encrypted volume inaccessible - disabled on ctrl";
> +		"Volume encrypted but encryption disabled on controller";
>  		break;

This indentation style is confusing. Please don't do this.

Thanks,

Bart.

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

* Re: [PATCH 20/37] smartpqi: add ptraid support
  2017-04-25 19:47 ` [PATCH 20/37] smartpqi: add ptraid support Don Brace
@ 2017-04-25 20:13   ` Bart Van Assche
  2017-05-03 20:06     ` Don Brace
  0 siblings, 1 reply; 55+ messages in thread
From: Bart Van Assche @ 2017-04-25 20:13 UTC (permalink / raw)
  To: hch, Viswas.G, gerry.morong, Mahesh.Rajashekhara, POSWALD,
	scott.benesh, don.brace, bader.alisaleh, Kevin.Barnett,
	joseph.szczypek, scott.teel, jejb, Justin.Lindley, john.hall
  Cc: linux-scsi

On Tue, 2017-04-25 at 14:47 -0500, Don Brace wrote:
> +static inline bool pqi_is_external_raid_device(struct pqi_scsi_dev *device)
> +{
> +	return device->is_external_raid_device;
> +}

The name of this function is almost as long as its implementation. Please drop
this function definition and inline the function into its callers.

Thanks,

Bart.

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

* Re: [PATCH 36/37] smartpqi: remove writeq/readq function definitions
  2017-04-25 19:49 ` [PATCH 36/37] smartpqi: remove writeq/readq function definitions Don Brace
@ 2017-04-26  9:35   ` kbuild test robot
  0 siblings, 0 replies; 55+ messages in thread
From: kbuild test robot @ 2017-04-26  9:35 UTC (permalink / raw)
  To: Don Brace
  Cc: kbuild-all, joseph.szczypek, gerry.morong, john.hall, jejb,
	Kevin.Barnett, Mahesh.Rajashekhara, bader.alisaleh, hch,
	scott.teel, Viswas.G, Justin.Lindley, scott.benesh, POSWALD,
	linux-scsi

[-- Attachment #1: Type: text/plain, Size: 3583 bytes --]

Hi Corentin,

[auto build test ERROR on scsi/for-next]
[also build test ERROR on v4.11-rc8 next-20170424]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Don-Brace/smartpqi-updates/20170426-164057
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 4.9.0
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=xtensa 

All errors (new ones prefixed by >>):

   drivers/scsi//smartpqi/smartpqi_init.c: In function 'pqi_wait_for_pqi_mode_ready':
>> drivers/scsi//smartpqi/smartpqi_init.c:2412:3: error: implicit declaration of function 'readq' [-Werror=implicit-function-declaration]
      signature = readq(&pqi_registers->signature);
      ^
   drivers/scsi//smartpqi/smartpqi_init.c: In function 'pqi_create_admin_queues':
>> drivers/scsi//smartpqi/smartpqi_init.c:3416:2: error: implicit declaration of function 'writeq' [-Werror=implicit-function-declaration]
     writeq((u64)admin_queues->iq_element_array_bus_addr,
     ^
   cc1: some warnings being treated as errors

vim +/readq +2412 drivers/scsi//smartpqi/smartpqi_init.c

6c223761 Kevin Barnett 2016-06-27  2396  #define PQI_DEVICE_STATE_ERROR				0x4
6c223761 Kevin Barnett 2016-06-27  2397  
6c223761 Kevin Barnett 2016-06-27  2398  #define PQI_MODE_READY_TIMEOUT_SECS		30
6c223761 Kevin Barnett 2016-06-27  2399  #define PQI_MODE_READY_POLL_INTERVAL_MSECS	1
6c223761 Kevin Barnett 2016-06-27  2400  
6c223761 Kevin Barnett 2016-06-27  2401  static int pqi_wait_for_pqi_mode_ready(struct pqi_ctrl_info *ctrl_info)
6c223761 Kevin Barnett 2016-06-27  2402  {
6c223761 Kevin Barnett 2016-06-27  2403  	struct pqi_device_registers __iomem *pqi_registers;
6c223761 Kevin Barnett 2016-06-27  2404  	unsigned long timeout;
6c223761 Kevin Barnett 2016-06-27  2405  	u64 signature;
6c223761 Kevin Barnett 2016-06-27  2406  	u8 status;
6c223761 Kevin Barnett 2016-06-27  2407  
6c223761 Kevin Barnett 2016-06-27  2408  	pqi_registers = ctrl_info->pqi_registers;
6c223761 Kevin Barnett 2016-06-27  2409  	timeout = (PQI_MODE_READY_TIMEOUT_SECS * HZ) + jiffies;
6c223761 Kevin Barnett 2016-06-27  2410  
6c223761 Kevin Barnett 2016-06-27  2411  	while (1) {
6c223761 Kevin Barnett 2016-06-27 @2412  		signature = readq(&pqi_registers->signature);
6c223761 Kevin Barnett 2016-06-27  2413  		if (memcmp(&signature, PQI_DEVICE_SIGNATURE,
6c223761 Kevin Barnett 2016-06-27  2414  			sizeof(signature)) == 0)
6c223761 Kevin Barnett 2016-06-27  2415  			break;
6c223761 Kevin Barnett 2016-06-27  2416  		if (time_after(jiffies, timeout)) {
6c223761 Kevin Barnett 2016-06-27  2417  			dev_err(&ctrl_info->pci_dev->dev,
6c223761 Kevin Barnett 2016-06-27  2418  				"timed out waiting for PQI signature\n");
6c223761 Kevin Barnett 2016-06-27  2419  			return -ETIMEDOUT;
6c223761 Kevin Barnett 2016-06-27  2420  		}

:::::: The code at line 2412 was first introduced by commit
:::::: 6c223761eb5482dca2bd981d0a800c4aba3c9009 smartpqi: initial commit of Microsemi smartpqi driver

:::::: TO: Kevin Barnett <kevin.barnett@microsemi.com>
:::::: CC: Martin K. Petersen <martin.petersen@oracle.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 49082 bytes --]

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

* RE: [PATCH 02/37] smartpqi: cleanup interrupt management
  2017-04-25 19:54   ` Bart Van Assche
@ 2017-05-03 15:23     ` Don Brace
  0 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-05-03 15:23 UTC (permalink / raw)
  To: Bart Van Assche, hch, Viswas G, Gerry Morong,
	Mahesh Rajashekhara, POSWALD, Scott Benesh, Bader Ali - Saleh,
	Kevin Barnett, joseph.szczypek, Scott Teel, jejb, Justin Lindley,
	John Hall
  Cc: linux-scsi

> -----Original Message-----
> From: Bart Van Assche [mailto:Bart.VanAssche@sandisk.com]
> Sent: Tuesday, April 25, 2017 2:55 PM
> To: hch@infradead.org; Viswas G <viswas.g@microsemi.com>; Gerry
> Morong <gerry.morong@microsemi.com>; Mahesh Rajashekhara
> <mahesh.rajashekhara@microsemi.com>; POSWALD@suse.com; Scott
> Benesh <scott.benesh@microsemi.com>; Don Brace
> <don.brace@microsemi.com>; Bader Ali - Saleh
> <bader.alisaleh@microsemi.com>; Kevin Barnett
> <kevin.barnett@microsemi.com>; joseph.szczypek@hpe.com; Scott Teel
> <scott.teel@microsemi.com>; jejb@linux.vnet.ibm.com; Justin Lindley
> <justin.lindley@microsemi.com>; John Hall <John.Hall@microsemi.com>
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH 02/37] smartpqi: cleanup interrupt management
> 
> EXTERNAL EMAIL
> 
> 
> On Tue, 2017-04-25 at 14:46 -0500, Don Brace wrote:
> >  static int pqi_request_irqs(struct pqi_ctrl_info *ctrl_info)
> >  {
> > -     struct pci_dev *pdev = ctrl_info->pci_dev;
> >       int i;
> >       int rc;
> > +     struct pci_dev *pdev = ctrl_info->pci_dev;
> 
> Was this change necessary? If not, please leave it out.
> 
> Thanks,
> 
> Bart.
Done

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

* RE: [PATCH 05/37] smartpqi: ensure controller is in SIS mode at init
  2017-04-25 19:57   ` Bart Van Assche
@ 2017-05-03 15:46     ` Don Brace
  0 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-05-03 15:46 UTC (permalink / raw)
  To: Bart Van Assche, hch, Viswas G, Gerry Morong,
	Mahesh Rajashekhara, POSWALD, Scott Benesh, Bader Ali - Saleh,
	Kevin Barnett, joseph.szczypek, Scott Teel, jejb, Justin Lindley,
	John Hall
  Cc: linux-scsi

> -----Original Message-----
> From: Bart Van Assche [mailto:Bart.VanAssche@sandisk.com]
> Sent: Tuesday, April 25, 2017 2:58 PM
> To: hch@infradead.org; Viswas G <viswas.g@microsemi.com>; Gerry
> Morong <gerry.morong@microsemi.com>; Mahesh Rajashekhara
> <mahesh.rajashekhara@microsemi.com>; POSWALD@suse.com; Scott
> Benesh <scott.benesh@microsemi.com>; Don Brace
> <don.brace@microsemi.com>; Bader Ali - Saleh
> <bader.alisaleh@microsemi.com>; Kevin Barnett
> <kevin.barnett@microsemi.com>; joseph.szczypek@hpe.com; Scott Teel
> <scott.teel@microsemi.com>; jejb@linux.vnet.ibm.com; Justin Lindley
> <justin.lindley@microsemi.com>; John Hall <John.Hall@microsemi.com>
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH 05/37] smartpqi: ensure controller is in SIS mode at init
> 
> EXTERNAL EMAIL
> 
> 
> On Tue, 2017-04-25 at 14:46 -0500, Don Brace wrote:
> > +bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
> > +{
> > +     u32 status;
> > +     bool kernel_up;
> > +
> > +     status = readl(&ctrl_info->registers->sis_firmware_status);
> > +
> > +     if (status & SIS_CTRL_KERNEL_UP)
> > +             kernel_up = true;
> > +     else
> > +             kernel_up = false;
> > +
> > +     return kernel_up;
> > +}
> 
> Since bool is a synonym for the C11 type _Bool, it is not necessary to
> convert explicitly to a truth value. The above code can be simplified into:
> 
> bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
> {
>         return readl(&ctrl_info->registers->sis_firmware_status) &
>                 SIS_CTRL_KERNEL_UP;
> }

Done
Thanks for your review

Thanks,
Don Brace
ESC - Smart Storage
Microsemi Corporation

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

* RE: [PATCH 07/37] smartpqi: enhance resets
  2017-04-25 20:01   ` Bart Van Assche
@ 2017-05-03 19:19     ` Don Brace
  0 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-05-03 19:19 UTC (permalink / raw)
  To: Bart Van Assche, hch, Viswas G, Gerry Morong,
	Mahesh Rajashekhara, POSWALD, Scott Benesh, Bader Ali - Saleh,
	Kevin Barnett, joseph.szczypek, Scott Teel, jejb, Justin Lindley,
	John Hall
  Cc: linux-scsi

> -----Original Message-----
> On Tue, 2017-04-25 at 14:46 -0500, Don Brace wrote:
> > @@ -4655,23 +4860,46 @@ static int pqi_device_reset(struct pqi_ctrl_info
> *ctrl_info,
> >  static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd)
> >  {
> >       int rc;
> > +     struct Scsi_Host *shost;
> >       struct pqi_ctrl_info *ctrl_info;
> >       struct pqi_scsi_dev *device;
> >
> > -     ctrl_info = shost_to_hba(scmd->device->host);
> > +     shost = scmd->device->host;
> > +     ctrl_info = shost_to_hba(shost);
> >       device = scmd->device->hostdata;
> >
> >       dev_err(&ctrl_info->pci_dev->dev,
> >               "resetting scsi %d:%d:%d:%d\n",
> > -             ctrl_info->scsi_host->host_no,
> > -             device->bus, device->target, device->lun);
> > +             shost->host_no, device->bus, device->target, device->lun);
> >
> > -     rc = pqi_device_reset(ctrl_info, device);
> > +     pqi_check_ctrl_health(ctrl_info);
> > +     if (pqi_ctrl_offline(ctrl_info)) {
> > +             rc = FAILED;
> > +             goto out;
> > +     }
> >
> > +     mutex_lock(&ctrl_info->lun_reset_mutex);
> > +
> > +     pqi_ctrl_block_requests(ctrl_info);
> > +     pqi_ctrl_wait_until_quiesced(ctrl_info);
> > +     pqi_fail_io_queued_for_device(ctrl_info, device);
> > +     rc = pqi_wait_until_inbound_queues_empty(ctrl_info);
> > +     pqi_device_reset_start(device);
> > +     pqi_ctrl_unblock_requests(ctrl_info);
> > +
> > +     if (rc)
> > +             rc = FAILED;
> > +     else
> > +             rc = pqi_device_reset(ctrl_info, device);
> > +
> > +     pqi_device_reset_done(device);
> > +
> > +     mutex_unlock(&ctrl_info->lun_reset_mutex);
> > +
> > +out:
> >       dev_err(&ctrl_info->pci_dev->dev,
> >               "reset of scsi %d:%d:%d:%d: %s\n",
> > -             ctrl_info->scsi_host->host_no,
> > -             device->bus, device->target, device->lun,
> > +             shost->host_no, device->bus, device->target, device->lun,
> >               rc == SUCCESS ? "SUCCESS" : "FAILED");
> >
> >       return rc;
> 
> Please use scsi_target_block() / scsi_target_unblock() instead of
> reimplementing
> these functions.
> 
> Thanks,
> 
> Bart.

Our LUN reset functions have to do several PQI-specific things in order to work correctly,
which is why we did not use scsi_target_block()/scsi_target_unblock()

Hope this is acceptable

Thanks for your review
Don Brace
ESC - Smart Storage
Microsemi Corporation

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

* RE: [PATCH 08/37] smartpqi: add suspend and resume support
  2017-04-25 20:05   ` Bart Van Assche
@ 2017-05-03 19:21     ` Don Brace
  0 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-05-03 19:21 UTC (permalink / raw)
  To: Bart Van Assche, hch, Viswas G, Gerry Morong,
	Mahesh Rajashekhara, POSWALD, Scott Benesh, Bader Ali - Saleh,
	Kevin Barnett, joseph.szczypek, Scott Teel, jejb, Justin Lindley,
	John Hall
  Cc: linux-scsi

> -----Original Message-----
> On Tue, 2017-04-25 at 14:46 -0500, Don Brace wrote:
> > +static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
> > +       struct pqi_scsi_dev *device)
> > +{
> > +       while (atomic_read(&device->scsi_cmds_outstanding)) {
> > +               pqi_check_ctrl_health(ctrl_info);
> > +               if (pqi_ctrl_offline(ctrl_info))
> > +                       return -ENXIO;
> > +               usleep_range(1000, 2000);
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info)
> > +{
> > +       bool io_pending;
> > +       unsigned long flags;
> > +       struct pqi_scsi_dev *device;
> > +
> > +       while (1) {
> > +               io_pending = false;
> > +
> > +               spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
> > +               list_for_each_entry(device, &ctrl_info->scsi_device_list,
> > +                       scsi_device_list_entry) {
> > +                       if (atomic_read(&device->scsi_cmds_outstanding)) {
> > +                               io_pending = true;
> > +                               break;
> > +                       }
> > +               }
> > +               spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock,
> > +                                       flags);
> > +
> > +               if (!io_pending)
> > +                       break;
> > +
> > +               pqi_check_ctrl_health(ctrl_info);
> > +               if (pqi_ctrl_offline(ctrl_info))
> > +                       return -ENXIO;
> > +
> > +               usleep_range(1000, 2000);
> > +       }
> > +
> > +       return 0;
> > +}
> 
> The same comment applies here that applies to the previous patch: please
> use
> scsi_target_block() / scsi_target_unblock() instead of reimplementing these
> functions.
> 
> Thanks,
> 
> Bart.

Our LUN reset functions have to do several PQI-specific things in order to work correctly,
which is why we did not use scsi_target_block()/scsi_target_unblock()

Hope this is acceptable

Thanks for your review
Don Brace
ESC - Smart Storage
Microsemi Corporation

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

* RE: [PATCH 12/37] smartpqi: change functions to inline
  2017-04-25 20:07   ` Bart Van Assche
@ 2017-05-03 19:32     ` Don Brace
  0 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-05-03 19:32 UTC (permalink / raw)
  To: Bart Van Assche, hch, Viswas G, Gerry Morong,
	Mahesh Rajashekhara, POSWALD, Scott Benesh, Bader Ali - Saleh,
	Kevin Barnett, joseph.szczypek, Scott Teel, jejb, Justin Lindley,
	John Hall
  Cc: linux-scsi

> -----Original Message-----
> From: Bart Van Assche [mailto:Bart.VanAssche@sandisk.com]
> Sent: Tuesday, April 25, 2017 3:08 PM
> To: hch@infradead.org; Viswas G <viswas.g@microsemi.com>; Gerry
> Morong <gerry.morong@microsemi.com>; Mahesh Rajashekhara
> <mahesh.rajashekhara@microsemi.com>; POSWALD@suse.com; Scott
> Benesh <scott.benesh@microsemi.com>; Don Brace
> <don.brace@microsemi.com>; Bader Ali - Saleh
> <bader.alisaleh@microsemi.com>; Kevin Barnett
> <kevin.barnett@microsemi.com>; joseph.szczypek@hpe.com; Scott Teel
> <scott.teel@microsemi.com>; jejb@linux.vnet.ibm.com; Justin Lindley
> <justin.lindley@microsemi.com>; John Hall <John.Hall@microsemi.com>
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH 12/37] smartpqi: change functions to inline
> 
> EXTERNAL EMAIL
> 
> 
> On Tue, 2017-04-25 at 14:47 -0500, Don Brace wrote:
> > From: Kevin Barnett <kevin.barnett@hpe.com>
> >
> > Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
> > Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
> > Signed-off-by: Don Brace <don.brace@microsemi.com>
> > ---
> >  drivers/scsi/smartpqi/smartpqi_init.c |    2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/scsi/smartpqi/smartpqi_init.c
> b/drivers/scsi/smartpqi/smartpqi_init.c
> > index 728db8f..523b730 100644
> > --- a/drivers/scsi/smartpqi/smartpqi_init.c
> > +++ b/drivers/scsi/smartpqi/smartpqi_init.c
> > @@ -432,7 +432,7 @@ static struct pqi_io_request *pqi_alloc_io_request(
> >       return io_request;
> >  }
> >
> > -static void pqi_free_io_request(struct pqi_io_request *io_request)
> > +static inline void pqi_free_io_request(struct pqi_io_request *io_request)
> >  {
> >       atomic_dec(&io_request->refcount);
> >  }
> 
> A patch description should not only explain what has been changed but also
> why a change has been made. What is the reason that this function has been
> declared inline? Why do you think that the compiler is not smart enough to
> decide on its own to inline this function?
> 
> Thanks,
> 
> Bart.

We could have given a patch description. I'll provide one.

Thanks,
Don Brace
ESC - Smart Storage
Microsemi Corporation

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

* RE: [PATCH 16/37] smartpqi: minor driver cleanup
  2017-04-25 20:09   ` Bart Van Assche
@ 2017-05-03 19:43     ` Don Brace
  0 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-05-03 19:43 UTC (permalink / raw)
  To: Bart Van Assche, hch, Viswas G, Gerry Morong,
	Mahesh Rajashekhara, POSWALD, Scott Benesh, Bader Ali - Saleh,
	Kevin Barnett, joseph.szczypek, Scott Teel, jejb, Justin Lindley,
	John Hall
  Cc: linux-scsi

> -----Original Message-----
> From: Bart Van Assche [mailto:Bart.VanAssche@sandisk.com]
> Sent: Tuesday, April 25, 2017 3:10 PM
> To: hch@infradead.org; Viswas G <viswas.g@microsemi.com>; Gerry
> Morong <gerry.morong@microsemi.com>; Mahesh Rajashekhara
> <mahesh.rajashekhara@microsemi.com>; POSWALD@suse.com; Scott
> Benesh <scott.benesh@microsemi.com>; Don Brace
> <don.brace@microsemi.com>; Bader Ali - Saleh
> <bader.alisaleh@microsemi.com>; Kevin Barnett
> <kevin.barnett@microsemi.com>; joseph.szczypek@hpe.com; Scott Teel
> <scott.teel@microsemi.com>; jejb@linux.vnet.ibm.com; Justin Lindley
> <justin.lindley@microsemi.com>; John Hall <John.Hall@microsemi.com>
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH 16/37] smartpqi: minor driver cleanup
> 
> EXTERNAL EMAIL
> 
> 
> On Tue, 2017-04-25 at 14:47 -0500, Don Brace wrote:
> > From: Kevin Barnett <kevin.barnett@hpe.com>
> >
> > - align with in-house driver
> 
> This is not an appropriate patch description. A patch description should
> explain what has been changed and also what the purpose is of these
> changes.
> 
> Thanks,
> 
> Bart.

Agreed, added patch description

Thanks,
Don Brace
ESC - Smart Storage
Microsemi Corporation

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

* RE: [PATCH 18/37] smartpqi: cleanup messages
  2017-04-25 20:11   ` Bart Van Assche
@ 2017-05-03 19:47     ` Don Brace
  0 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-05-03 19:47 UTC (permalink / raw)
  To: Bart Van Assche, hch, Viswas G, Gerry Morong,
	Mahesh Rajashekhara, POSWALD, Scott Benesh, Bader Ali - Saleh,
	Kevin Barnett, joseph.szczypek, Scott Teel, jejb, Justin Lindley,
	John Hall
  Cc: linux-scsi

> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Bart Van Assche
> Sent: Tuesday, April 25, 2017 3:11 PM
> To: hch@infradead.org; Viswas G <viswas.g@microsemi.com>; Gerry
> Morong <gerry.morong@microsemi.com>; Mahesh Rajashekhara
> <mahesh.rajashekhara@microsemi.com>; POSWALD@suse.com; Scott
> Benesh <scott.benesh@microsemi.com>; Don Brace
> <don.brace@microsemi.com>; Bader Ali - Saleh
> <bader.alisaleh@microsemi.com>; Kevin Barnett
> <kevin.barnett@microsemi.com>; joseph.szczypek@hpe.com; Scott Teel
> <scott.teel@microsemi.com>; jejb@linux.vnet.ibm.com; Justin Lindley
> <justin.lindley@microsemi.com>; John Hall <John.Hall@microsemi.com>
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH 18/37] smartpqi: cleanup messages
> 
> EXTERNAL EMAIL
> 
> 
> On Tue, 2017-04-25 at 14:47 -0500, Don Brace wrote:
> >       case CISS_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER:
> >               status =
> > -                     "Encrypted volume inaccessible - disabled on ctrl";
> > +             "Volume encrypted but encryption disabled on controller";
> >               break;
> 
> This indentation style is confusing. Please don't do this.
> 
> Thanks,
> 
> Bart.

Done

Thanks,
Don Brace
ESC - Smart Storage
Microsemi Corporation

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

* RE: [PATCH 20/37] smartpqi: add ptraid support
  2017-04-25 20:13   ` Bart Van Assche
@ 2017-05-03 20:06     ` Don Brace
  0 siblings, 0 replies; 55+ messages in thread
From: Don Brace @ 2017-05-03 20:06 UTC (permalink / raw)
  To: Bart Van Assche, hch, Viswas G, Gerry Morong,
	Mahesh Rajashekhara, POSWALD, Scott Benesh, Bader Ali - Saleh,
	Kevin Barnett, joseph.szczypek, Scott Teel, jejb, Justin Lindley,
	John Hall
  Cc: linux-scsi

> -----Original Message-----
> From: Bart Van Assche [mailto:Bart.VanAssche@sandisk.com]
> Sent: Tuesday, April 25, 2017 3:13 PM
> To: hch@infradead.org; Viswas G <viswas.g@microsemi.com>; Gerry
> Morong <gerry.morong@microsemi.com>; Mahesh Rajashekhara
> <mahesh.rajashekhara@microsemi.com>; POSWALD@suse.com; Scott
> Benesh <scott.benesh@microsemi.com>; Don Brace
> <don.brace@microsemi.com>; Bader Ali - Saleh
> <bader.alisaleh@microsemi.com>; Kevin Barnett
> <kevin.barnett@microsemi.com>; joseph.szczypek@hpe.com; Scott Teel
> <scott.teel@microsemi.com>; jejb@linux.vnet.ibm.com; Justin Lindley
> <justin.lindley@microsemi.com>; John Hall <John.Hall@microsemi.com>
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH 20/37] smartpqi: add ptraid support
> 
> EXTERNAL EMAIL
> 
> 
> On Tue, 2017-04-25 at 14:47 -0500, Don Brace wrote:
> > +static inline bool pqi_is_external_raid_device(struct pqi_scsi_dev
> *device)
> > +{
> > +     return device->is_external_raid_device;
> > +}
> 
> The name of this function is almost as long as its implementation. Please drop
> this function definition and inline the function into its callers.
> 
> Thanks,
> 
> Bart.
Done

Thanks,
Don Brace
ESC - Smart Storage
Microsemi Corporation

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

end of thread, other threads:[~2017-05-03 20:06 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-25 19:45 [PATCH 00/37] smartpqi updates Don Brace
2017-04-25 19:45 ` [PATCH 01/37] smartpqi: correct remove scsi devices Don Brace
2017-04-25 19:46 ` [PATCH 02/37] smartpqi: cleanup interrupt management Don Brace
2017-04-25 19:54   ` Bart Van Assche
2017-05-03 15:23     ` Don Brace
2017-04-25 19:46 ` [PATCH 03/37] smartpqi: set pci completion timeout Don Brace
2017-04-25 19:46 ` [PATCH 04/37] smartpqi: add in controller checkpoint for controller lockups Don Brace
2017-04-25 19:46 ` [PATCH 05/37] smartpqi: ensure controller is in SIS mode at init Don Brace
2017-04-25 19:57   ` Bart Van Assche
2017-05-03 15:46     ` Don Brace
2017-04-25 19:46 ` [PATCH 06/37] smartpqi: add supporting events Don Brace
2017-04-25 19:46 ` [PATCH 07/37] smartpqi: enhance resets Don Brace
2017-04-25 20:01   ` Bart Van Assche
2017-05-03 19:19     ` Don Brace
2017-04-25 19:46 ` [PATCH 08/37] smartpqi: add suspend and resume support Don Brace
2017-04-25 20:05   ` Bart Van Assche
2017-05-03 19:21     ` Don Brace
2017-04-25 19:46 ` [PATCH 09/37] smartpqi: add heartbeat check Don Brace
2017-04-25 19:46 ` [PATCH 10/37] smartpqi: correct bdma hw bug Don Brace
2017-04-25 19:46 ` [PATCH 11/37] smartpqi: add pqi_wait_for_completion_io Don Brace
2017-04-25 19:47 ` [PATCH 12/37] smartpqi: change functions to inline Don Brace
2017-04-25 20:07   ` Bart Van Assche
2017-05-03 19:32     ` Don Brace
2017-04-25 19:47 ` [PATCH 13/37] smartpqi: make pdev pointer names consistent Don Brace
2017-04-25 19:47 ` [PATCH 14/37] smartpqi: eliminate redundant error messages Don Brace
2017-04-25 19:47 ` [PATCH 15/37] smartpqi: correct BMIC identify physical drive Don Brace
2017-04-25 19:47 ` [PATCH 16/37] smartpqi: minor driver cleanup Don Brace
2017-04-25 20:09   ` Bart Van Assche
2017-05-03 19:43     ` Don Brace
2017-04-25 19:47 ` [PATCH 17/37] smartpqi: add new PCI device IDs Don Brace
2017-04-25 19:47 ` [PATCH 18/37] smartpqi: cleanup messages Don Brace
2017-04-25 20:11   ` Bart Van Assche
2017-05-03 19:47     ` Don Brace
2017-04-25 19:47 ` [PATCH 19/37] smartpqi: update copyright Don Brace
2017-04-25 19:47 ` [PATCH 20/37] smartpqi: add ptraid support Don Brace
2017-04-25 20:13   ` Bart Van Assche
2017-05-03 20:06     ` Don Brace
2017-04-25 19:48 ` [PATCH 21/37] smartpqi: change return value for LUN reset operations Don Brace
2017-04-25 19:48 ` [PATCH 22/37] smartpqi: enhance kdump Don Brace
2017-04-25 19:48 ` [PATCH 23/37] smartpqi: remove qdepth calculations for logical volumes Don Brace
2017-04-25 19:48 ` [PATCH 24/37] smartpqi: add lockup action Don Brace
2017-04-25 19:48 ` [PATCH 25/37] smartpqi: correct aio error path Don Brace
2017-04-25 19:48 ` [PATCH 26/37] smartpqi: update device offline Don Brace
2017-04-25 19:48 ` [PATCH 27/37] smartpqi: controller offline improvements Don Brace
2017-04-25 19:48 ` [PATCH 28/37] smartpqi: cleanup controller branding Don Brace
2017-04-25 19:48 ` [PATCH 29/37] smartpqi: map more raid errors to SCSI errors Don Brace
2017-04-25 19:48 ` [PATCH 30/37] smartpqi: update timeout on admin commands Don Brace
2017-04-25 19:49 ` [PATCH 31/37] smartpqi: enhance device add and remove messages Don Brace
2017-04-25 19:49 ` [PATCH 32/37] smartpqi: make raid bypass references consistent Don Brace
2017-04-25 19:49 ` [PATCH 33/37] smartpqi: add raid level show Don Brace
2017-04-25 19:49 ` [PATCH 34/37] smartpqi: cleanup list initialization Don Brace
2017-04-25 19:49 ` [PATCH 35/37] smartpqi: add module parameters Don Brace
2017-04-25 19:49 ` [PATCH 36/37] smartpqi: remove writeq/readq function definitions Don Brace
2017-04-26  9:35   ` kbuild test robot
2017-04-25 19:49 ` [PATCH 37/37] smartpqi: bump driver version Don Brace

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.