Skip to contentSkip to conversation

scsi:stex.c Add hotplug support

PATCH Superseded Charles Chiou 2 participants 4 messages Sep 3, 2015 – Feb 4, 2016 SCSI

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 2/3 scsi:stex.c Add hotplug support

From 60e14c245c18cbe0300cfa244334e2850a52a381 Mon Sep 17 00:00:00 2001
From: Charles <[email protected]>
Date: Wed, 2 Sep 2015 20:48:55 +0800
Subject: [PATCH 2/3] scsi:stex.c Add hotplug support

1. Add hotplug support. Pegasus support surprise removal. To this end, I use return_abnormal_state function to return DID_NO_CONNECT for all commands which sent to driver.

2. Remove stex_hba_stop in stex_remove because we cannot send command to device after hotplug.

3. Add new device status: MU_STATE_STOP, MU_STATE_NOCONNECT, MU_STATE_STOP. MU_STATE_STOP is currently not referenced. MU_STATE_NOCONNECT represent that device is plugged out from the host.

4. Use return_abnormal_function() to substitute part of code in stex_do_reset.

V2: N/A

---
 drivers/scsi/stex.c | 53 
++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 19 deletions(-)
drivers/scsi/stex.c +34 -19
index 0c93f1f..4ef0c80 100644
@@ -83,6 +83,8 @@ enum {
 	MU_STATE_STARTED			= 2,
 	MU_STATE_RESETTING			= 3,
 	MU_STATE_FAILED				= 4,
+	MU_STATE_STOP				= 5,
+	MU_STATE_NOCONNECT			= 6,
 
 	MU_MAX_DELAY				= 120,
 	MU_HANDSHAKE_SIGNATURE			= 0x55aaaa55,
@@ -544,6 +546,27 @@ stex_ss_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag)
 	readl(hba->mmio_base + YH2I_REQ); /* flush */
 }
 
+static void return_abnormal_state(struct st_hba *hba, int status)
+{
+	struct st_ccb *ccb;
+	unsigned long flags;
+	u16 tag;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	for (tag = 0; tag < hba->host->can_queue; tag++) {
+		ccb = &hba->ccb[tag];
+		if (ccb->req == NULL)
+			continue;
+		ccb->req = NULL;
+		if (ccb->cmd) {
+			scsi_dma_unmap(ccb->cmd);
+			ccb->cmd->result = status << 16;
+			ccb->cmd->scsi_done(ccb->cmd);
+			ccb->cmd = NULL;
+		}
+	}
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+}
 static int
 stex_slave_config(struct scsi_device *sdev)
 {
@@ -567,8 +590,12 @@ stex_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 	id = cmd->device->id;
 	lun = cmd->device->lun;
 	hba = (struct st_hba *) &host->hostdata[0];
-
-	if (unlikely(hba->mu_status == MU_STATE_RESETTING))
+	if (hba->mu_status == MU_STATE_NOCONNECT) {
+		cmd->result = DID_NO_CONNECT;
+		done(cmd);
+		return 0;
+	}
+	if (unlikely(hba->mu_status != MU_STATE_STARTED))
 		return SCSI_MLQUEUE_HOST_BUSY;
 
 	switch (cmd->cmnd[0]) {
@@ -1267,10 +1294,8 @@ static void stex_ss_reset(struct st_hba *hba)
 
 static int stex_do_reset(struct st_hba *hba)
 {
-	struct st_ccb *ccb;
 	unsigned long flags;
 	unsigned int mu_status = MU_STATE_RESETTING;
-	u16 tag;
 
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	if (hba->mu_status == MU_STATE_STARTING) {
@@ -1304,20 +1329,8 @@ static int stex_do_reset(struct st_hba *hba)
 	else if (hba->cardtype == st_yel)
 		stex_ss_reset(hba);
 
-	spin_lock_irqsave(hba->host->host_lock, flags);
-	for (tag = 0; tag < hba->host->can_queue; tag++) {
-		ccb = &hba->ccb[tag];
-		if (ccb->req == NULL)
-			continue;
-		ccb->req = NULL;
-		if (ccb->cmd) {
-			scsi_dma_unmap(ccb->cmd);
-			ccb->cmd->result = DID_RESET << 16;
-			ccb->cmd->scsi_done(ccb->cmd);
-			ccb->cmd = NULL;
-		}
-	}
-	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	return_abnormal_state(hba, DID_RESET);
 
 	if (stex_handshake(hba) == 0)
 		return 0;
@@ -1786,9 +1799,11 @@ static void stex_remove(struct pci_dev *pdev)
 {
 	struct st_hba *hba = pci_get_drvdata(pdev);
 
+	hba->mu_status = MU_STATE_NOCONNECT;
+	return_abnormal_state(hba, DID_NO_CONNECT);
 	scsi_remove_host(hba->host);
 
-	stex_hba_stop(hba);
+	scsi_block_requests(hba->host);
 
 	stex_hba_free(hba);
 
Signature · 1 line
1.9.1
Reviewed-by on v2 2/3
#1 lore raw
Quoted 119 lines · Charles Chiou

From 60e14c245c18cbe0300cfa244334e2850a52a381 Mon Sep 17 00:00:00 2001
From: Charles <[email protected]>
Date: Wed, 2 Sep 2015 20:48:55 +0800
Subject: [PATCH 2/3] scsi:stex.c Add hotplug support

1. Add hotplug support. Pegasus support surprise removal. To this end, I use return_abnormal_state function to return DID_NO_CONNECT for all commands which sent to driver.

2. Remove stex_hba_stop in stex_remove because we cannot send command to device after hotplug.

3. Add new device status: MU_STATE_STOP, MU_STATE_NOCONNECT, MU_STATE_STOP. MU_STATE_STOP is currently not referenced. MU_STATE_NOCONNECT represent that device is plugged out from the host.

4. Use return_abnormal_function() to substitute part of code in stex_do_reset.

V2: N/A

---
 drivers/scsi/stex.c | 53 ++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 19 deletions(-)
drivers/scsi/stex.c +23 -0
index 0c93f1f..4ef0c80 100644
@@ -83,6 +83,8 @@ enum {
 	MU_STATE_STARTED			= 2,
 	MU_STATE_RESETTING			= 3,
 	MU_STATE_FAILED				= 4,
+	MU_STATE_STOP				= 5,
+	MU_STATE_NOCONNECT			= 6,
 
 	MU_MAX_DELAY				= 120,
 	MU_HANDSHAKE_SIGNATURE			= 0x55aaaa55,
@@ -544,6 +546,27 @@ stex_ss_send_cmd(struct st_hba *hba, struct req_msg *req,
 u16 tag)
 	readl(hba->mmio_base + YH2I_REQ); /* flush */
 }
 
+static void return_abnormal_state(struct st_hba *hba, int status)
+{
+	struct st_ccb *ccb;
+	unsigned long flags;
+	u16 tag;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	for (tag = 0; tag < hba->host->can_queue; tag++) {
+		ccb = &hba->ccb[tag];
+		if (ccb->req == NULL)
+			continue;
+		ccb->req = NULL;
+		if (ccb->cmd) {
+			scsi_dma_unmap(ccb->cmd);
+			ccb->cmd->result = status << 16;
+			ccb->cmd->scsi_done(ccb->cmd);
+			ccb->cmd = NULL;
+		}
+	}
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+}
 static int
 stex_slave_config(struct scsi_device *sdev)

{

drivers/scsi/stex.c +6 -2
@@ -567,8 +590,12 @@ stex_queuecommand_lck(struct scsi_cmnd *cmd, void
 (*done)(struct scsi_cmnd *))
 	id = cmd->device->id;
 	lun = cmd->device->lun;
 	hba = (struct st_hba *) &host->hostdata[0];
-
-	if (unlikely(hba->mu_status == MU_STATE_RESETTING))
+	if (hba->mu_status == MU_STATE_NOCONNECT) {
+		cmd->result = DID_NO_CONNECT;
+		done(cmd);
+		return 0;
+	}
+	if (unlikely(hba->mu_status != MU_STATE_STARTED))
 		return SCSI_MLQUEUE_HOST_BUSY;
 
drivers/scsi/stex.c +2 -16
 	switch (cmd->cmnd[0]) {
@@ -1267,10 +1294,8 @@ static void stex_ss_reset(struct st_hba *hba)
 
 static int stex_do_reset(struct st_hba *hba)
 {
-	struct st_ccb *ccb;
 	unsigned long flags;
 	unsigned int mu_status = MU_STATE_RESETTING;
-	u16 tag;
 
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	if (hba->mu_status == MU_STATE_STARTING) {
@@ -1304,20 +1329,8 @@ static int stex_do_reset(struct st_hba *hba)
 	else if (hba->cardtype == st_yel)
 		stex_ss_reset(hba);
 
-	spin_lock_irqsave(hba->host->host_lock, flags);
-	for (tag = 0; tag < hba->host->can_queue; tag++) {
-		ccb = &hba->ccb[tag];
-		if (ccb->req == NULL)
-			continue;
-		ccb->req = NULL;
-		if (ccb->cmd) {
-			scsi_dma_unmap(ccb->cmd);
-			ccb->cmd->result = DID_RESET << 16;
-			ccb->cmd->scsi_done(ccb->cmd);
-			ccb->cmd = NULL;
-		}
-	}
-	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	return_abnormal_state(hba, DID_RESET);
 
 	if (stex_handshake(hba) == 0)
 		return 0;
@@ -1786,9 +1799,11 @@ static void stex_remove(struct pci_dev *pdev)
 {

drivers/scsi/stex.c static void stex_remove(struct pci_dev *pdev) · line 1808

Quoted 10 lines
drivers/scsi/stex.c +3 -1
 	struct st_hba *hba = pci_get_drvdata(pdev);
 
+	hba->mu_status = MU_STATE_NOCONNECT;
+	return_abnormal_state(hba, DID_NO_CONNECT);
 	scsi_remove_host(hba->host);
 
-	stex_hba_stop(hba);
+	scsi_block_requests(hba->host);
 
 	stex_hba_free(hba);

Looks OK to me, so

Signature · 6 lines
Johannes Thumshirn                                           Storage
[email protected]                                 +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600  D0D0 0393 969D 2D76 0850
#2 lore raw

Hi all, Ping?
Does this patch has others issues need to fix? Thank you. Charles

Quoted 135 lines · Johannes Thumshirn
Quoted 119 lines · Charles Chiou

From 60e14c245c18cbe0300cfa244334e2850a52a381 Mon Sep 17 00:00:00 2001
From: Charles <[email protected]>
Date: Wed, 2 Sep 2015 20:48:55 +0800
Subject: [PATCH 2/3] scsi:stex.c Add hotplug support

1. Add hotplug support. Pegasus support surprise removal. To this end, I use return_abnormal_state function to return DID_NO_CONNECT for all commands which sent to driver.

2. Remove stex_hba_stop in stex_remove because we cannot send command to device after hotplug.

3. Add new device status: MU_STATE_STOP, MU_STATE_NOCONNECT, MU_STATE_STOP. MU_STATE_STOP is currently not referenced. MU_STATE_NOCONNECT represent that device is plugged out from the host.

4. Use return_abnormal_function() to substitute part of code in stex_do_reset.

V2: N/A

---
  drivers/scsi/stex.c | 53 ++++++++++++++++++++++++++++++++++-------------------
  1 file changed, 34 insertions(+), 19 deletions(-)
drivers/scsi/stex.c +23 -0
index 0c93f1f..4ef0c80 100644
@@ -83,6 +83,8 @@ enum {
  	MU_STATE_STARTED			= 2,
  	MU_STATE_RESETTING			= 3,
  	MU_STATE_FAILED				= 4,
+	MU_STATE_STOP				= 5,
+	MU_STATE_NOCONNECT			= 6,
 
  	MU_MAX_DELAY				= 120,
  	MU_HANDSHAKE_SIGNATURE			= 0x55aaaa55,
@@ -544,6 +546,27 @@ stex_ss_send_cmd(struct st_hba *hba, struct req_msg *req,
 u16 tag)
  	readl(hba->mmio_base + YH2I_REQ); /* flush */
  }
 
+static void return_abnormal_state(struct st_hba *hba, int status)
+{
+	struct st_ccb *ccb;
+	unsigned long flags;
+	u16 tag;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	for (tag = 0; tag < hba->host->can_queue; tag++) {
+		ccb = &hba->ccb[tag];
+		if (ccb->req == NULL)
+			continue;
+		ccb->req = NULL;
+		if (ccb->cmd) {
+			scsi_dma_unmap(ccb->cmd);
+			ccb->cmd->result = status << 16;
+			ccb->cmd->scsi_done(ccb->cmd);
+			ccb->cmd = NULL;
+		}
+	}
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+}
  static int
  stex_slave_config(struct scsi_device *sdev)
  {
drivers/scsi/stex.c +6 -2
@@ -567,8 +590,12 @@ stex_queuecommand_lck(struct scsi_cmnd *cmd, void
 (*done)(struct scsi_cmnd *))
  	id = cmd->device->id;
  	lun = cmd->device->lun;
  	hba = (struct st_hba *) &host->hostdata[0];
-
-	if (unlikely(hba->mu_status == MU_STATE_RESETTING))
+	if (hba->mu_status == MU_STATE_NOCONNECT) {
+		cmd->result = DID_NO_CONNECT;
+		done(cmd);
+		return 0;
+	}
+	if (unlikely(hba->mu_status != MU_STATE_STARTED))
  		return SCSI_MLQUEUE_HOST_BUSY;
 
  	switch (cmd->cmnd[0]) {
drivers/scsi/stex.c +2 -16
@@ -1267,10 +1294,8 @@ static void stex_ss_reset(struct st_hba *hba)
 
  static int stex_do_reset(struct st_hba *hba)
  {
-	struct st_ccb *ccb;
  	unsigned long flags;
  	unsigned int mu_status = MU_STATE_RESETTING;
-	u16 tag;
 
  	spin_lock_irqsave(hba->host->host_lock, flags);
  	if (hba->mu_status == MU_STATE_STARTING) {
@@ -1304,20 +1329,8 @@ static int stex_do_reset(struct st_hba *hba)
  	else if (hba->cardtype == st_yel)
  		stex_ss_reset(hba);
 
-	spin_lock_irqsave(hba->host->host_lock, flags);
-	for (tag = 0; tag < hba->host->can_queue; tag++) {
-		ccb = &hba->ccb[tag];
-		if (ccb->req == NULL)
-			continue;
-		ccb->req = NULL;
-		if (ccb->cmd) {
-			scsi_dma_unmap(ccb->cmd);
-			ccb->cmd->result = DID_RESET << 16;
-			ccb->cmd->scsi_done(ccb->cmd);
-			ccb->cmd = NULL;
-		}
-	}
-	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	return_abnormal_state(hba, DID_RESET);
 
  	if (stex_handshake(hba) == 0)
  		return 0;
@@ -1786,9 +1799,11 @@ static void stex_remove(struct pci_dev *pdev)
  {

drivers/scsi/stex.c static void stex_remove(struct pci_dev *pdev) · line 1808

Quoted 10 lines
drivers/scsi/stex.c +3 -1
  	struct st_hba *hba = pci_get_drvdata(pdev);
 
+	hba->mu_status = MU_STATE_NOCONNECT;
+	return_abnormal_state(hba, DID_NO_CONNECT);
  	scsi_remove_host(hba->host);
 
-	stex_hba_stop(hba);
+	scsi_block_requests(hba->host);
 
  	stex_hba_free(hba);

Looks OK to me, so

#3 lore raw

PATCH RESEND 2/3 scsi:stex.c Add hotplug support

From 60e14c245c18cbe0300cfa244334e2850a52a381 Mon Sep 17 00:00:00 2001
From: Charles <[email protected]>
Date: Wed, 2 Sep 2015 20:48:55 +0800
Subject: [PATCH 2/3] scsi:stex.c Add hotplug support

1. Add hotplug support. Pegasus support surprise removal. To this end, I use return_abnormal_state function to return DID_NO_CONNECT for all commands which sent to driver.

2. Remove stex_hba_stop in stex_remove because we cannot send command to device after hotplug.

3. Add new device status: MU_STATE_STOP, MU_STATE_NOCONNECT, MU_STATE_STOP. MU_STATE_STOP is currently not referenced. MU_STATE_NOCONNECT represent that device is plugged out from the host.

4. Use return_abnormal_function() to substitute part of code in stex_do_reset.

V2: N/A

---
  drivers/scsi/stex.c | 53 
++++++++++++++++++++++++++++++++++-------------------
  1 file changed, 34 insertions(+), 19 deletions(-)
drivers/scsi/stex.c +2 -0
index 0c93f1f..4ef0c80 100644
@@ -83,6 +83,8 @@ enum {
      MU_STATE_STARTED            = 2,
      MU_STATE_RESETTING            = 3,
      MU_STATE_FAILED                = 4,
+    MU_STATE_STOP                = 5,
+    MU_STATE_NOCONNECT            = 6,
 
      MU_MAX_DELAY                = 120,
      MU_HANDSHAKE_SIGNATURE            = 0x55aaaa55,
@@ -544,6 +546,27 @@ stex_ss_send_cmd(struct st_hba *hba, struct req_msg *req,

u16 tag)

      readl(hba->mmio_base + YH2I_REQ); /* flush */

}

+static void return_abnormal_state(struct st_hba *hba, int status) +{

+    struct st_ccb *ccb;
+    unsigned long flags;
+    u16 tag;

+
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ for (tag = 0; tag < hba->host->can_queue; tag++) {
+ ccb = &hba->ccb[tag];
+ if (ccb->req == NULL)
+ continue;
+ ccb->req = NULL;
+ if (ccb->cmd) {

+            scsi_dma_unmap(ccb->cmd);
+            ccb->cmd->result = status << 16;
+            ccb->cmd->scsi_done(ccb->cmd);
+            ccb->cmd = NULL;

+ }
+ }
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+}
static int
stex_slave_config(struct scsi_device *sdev)
{
@@ -567,8 +590,12 @@ stex_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))

      id = cmd->device->id;
      lun = cmd->device->lun;
      hba = (struct st_hba *) &host->hostdata[0];
-
-    if (unlikely(hba->mu_status == MU_STATE_RESETTING))
+    if (hba->mu_status == MU_STATE_NOCONNECT) {
+        cmd->result = DID_NO_CONNECT;
+        done(cmd);
+        return 0;
+    }
+    if (unlikely(hba->mu_status != MU_STATE_STARTED))
          return SCSI_MLQUEUE_HOST_BUSY;

      switch (cmd->cmnd[0]) {

@@ -1267,10 +1294,8 @@ static void stex_ss_reset(struct st_hba *hba)

static int stex_do_reset(struct st_hba *hba)
{

-    struct st_ccb *ccb;
      unsigned long flags;
      unsigned int mu_status = MU_STATE_RESETTING;

- u16 tag;

      spin_lock_irqsave(hba->host->host_lock, flags);
      if (hba->mu_status == MU_STATE_STARTING) {
@@ -1304,20 +1329,8 @@ static int stex_do_reset(struct st_hba *hba)
      else if (hba->cardtype == st_yel)
          stex_ss_reset(hba);

- spin_lock_irqsave(hba->host->host_lock, flags);
- for (tag = 0; tag < hba->host->can_queue; tag++) {
- ccb = &hba->ccb[tag];
- if (ccb->req == NULL)
- continue;
- ccb->req = NULL;
- if (ccb->cmd) {

-            scsi_dma_unmap(ccb->cmd);
-            ccb->cmd->result = DID_RESET << 16;
-            ccb->cmd->scsi_done(ccb->cmd);
-            ccb->cmd = NULL;

- }
- }
- spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+ return_abnormal_state(hba, DID_RESET);

      if (stex_handshake(hba) == 0)
          return 0;
@@ -1786,9 +1799,11 @@ static void stex_remove(struct pci_dev *pdev)
  {
      struct st_hba *hba = pci_get_drvdata(pdev);

+ hba->mu_status = MU_STATE_NOCONNECT;

+    return_abnormal_state(hba, DID_NO_CONNECT);
      scsi_remove_host(hba->host);

- stex_hba_stop(hba);
+ scsi_block_requests(hba->host);

      stex_hba_free(hba);