summary refs log tree commit diff
path: root/drivers/scsi/stex.c
diff options
context:
space:
mode:
authorCharles <charles.chiou@tw.promise.com>2017-02-17 10:52:38 +0800
committerMartin K. Petersen <martin.petersen@oracle.com>2017-03-15 19:22:10 -0400
commit61b745fa63dbac366104c3585c0866562a8292be (patch)
tree214b6125c2626f1f6725227343044c36600b387a /drivers/scsi/stex.c
parentd65702272c8d35afc8d7e85fa8100a914f0b787f (diff)
downloadlinux-61b745fa63dbac366104c3585c0866562a8292be.tar.gz
scsi: stex: Add S6 support
1. Add reboot notifier and register it in stex_probe for all supported
   device.

2. For all supported device in restart flow, we get a callback from
   notifier and set S6flag for stex_shutdown & stex_hba_stop to send
   restart command to FW.

Signed-off-by: Charles.Chiou <charles.chiou@tw.promise.com>
Signed-off-by: Paul.Lyu <paul.lyu@tw.promise.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/stex.c')
-rw-r--r--drivers/scsi/stex.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index e177dfe08939..0751561b59da 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/ktime.h>
+#include <linux/reboot.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/byteorder.h>
@@ -362,6 +363,12 @@ struct st_card_info {
 	u16 sts_count;
 };
 
+int S6flag;
+static int stex_halt(struct notifier_block *nb, ulong event, void *buf);
+static struct notifier_block stex_notifier = {
+	stex_halt, NULL, 0
+};
+
 static int msi;
 module_param(msi, int, 0);
 MODULE_PARM_DESC(msi, "Enable Message Signaled Interrupts(0=off, 1=on)");
@@ -1673,6 +1680,9 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	pci_set_master(pdev);
 
+	S6flag = 0;
+	register_reboot_notifier(&stex_notifier);
+
 	host = scsi_host_alloc(&driver_template, sizeof(struct st_hba));
 
 	if (!host) {
@@ -1947,15 +1957,20 @@ static void stex_remove(struct pci_dev *pdev)
 	scsi_host_put(hba->host);
 
 	pci_disable_device(pdev);
+
+	unregister_reboot_notifier(&stex_notifier);
 }
 
 static void stex_shutdown(struct pci_dev *pdev)
 {
 	struct st_hba *hba = pci_get_drvdata(pdev);
 
-	if (hba->supports_pm == 0)
+	if (hba->supports_pm == 0) {
 		stex_hba_stop(hba, ST_IGNORED);
-	else
+	} else if (hba->supports_pm == 1 && S6flag) {
+		unregister_reboot_notifier(&stex_notifier);
+		stex_hba_stop(hba, ST_S6);
+	} else
 		stex_hba_stop(hba, ST_S5);
 }
 
@@ -1992,6 +2007,12 @@ static int stex_resume(struct pci_dev *pdev)
 	stex_handshake(hba);
 	return 0;
 }
+
+static int stex_halt(struct notifier_block *nb, unsigned long event, void *buf)
+{
+	S6flag = 1;
+	return NOTIFY_OK;
+}
 MODULE_DEVICE_TABLE(pci, stex_pci_tbl);
 
 static struct pci_driver stex_pci_driver = {