* [PATCH 1/7] aacraid: split off functions to generate reset FIB
2017-06-30 17:18 [PATCH 0/7] aacraid: split off EH functions Hannes Reinecke
@ 2017-06-30 17:18 ` Hannes Reinecke
2017-06-30 17:18 ` [PATCH 2/7] aacraid: split off host reset Hannes Reinecke
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2017-06-30 17:18 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi,
Raghava Aditya Renukunta, Hannes Reinecke, Hannes Reinecke
Split off reset FIB generation into separate functions.
Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
---
drivers/scsi/aacraid/linit.c | 83 ++++++++++++++++++++++++++------------------
1 file changed, 50 insertions(+), 33 deletions(-)
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 0f277df..9a8a27f 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -814,6 +814,52 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
return ret;
}
+static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
+ int bus, int cid, u64 tmf_lun)
+{
+ struct aac_hba_tm_req *tmf;
+ u64 address;
+
+ /* start a HBA_TMF_LUN_RESET TMF request */
+ tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
+ memset(tmf, 0, sizeof(*tmf));
+ tmf->tmf = HBA_TMF_LUN_RESET;
+ tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+ int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
+
+ address = (u64)fib->hw_error_pa;
+ tmf->error_ptr_hi = cpu_to_le32
+ ((u32)(address >> 32));
+ tmf->error_ptr_lo = cpu_to_le32
+ ((u32)(address & 0xffffffff));
+ tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
+ fib->hbacmd_size = sizeof(*tmf);
+
+ return HBA_IU_TYPE_SCSI_TM_REQ;
+}
+
+static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
+ int bus, int cid)
+{
+ struct aac_hba_reset_req *rst;
+ u64 address;
+
+ /* already tried, start a hard reset now */
+ rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
+ memset(rst, 0, sizeof(*rst));
+ /* reset_type is already zero... */
+ rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+
+ address = (u64)fib->hw_error_pa;
+ rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
+ rst->error_ptr_lo = cpu_to_le32
+ ((u32)(address & 0xffffffff));
+ rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
+ fib->hbacmd_size = sizeof(*rst);
+
+ return HBA_IU_TYPE_SATA_REQ;
+}
+
/*
* aac_eh_reset - Reset command handling
* @scsi_cmd: SCSI command block causing the reset
@@ -840,7 +886,6 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
struct fib *fib;
int status;
- u64 address;
u8 command;
pr_err("%s: Host adapter reset request. SCSI hang ?\n",
@@ -852,42 +897,14 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
if (aac->hba_map[bus][cid].reset_state == 0) {
- struct aac_hba_tm_req *tmf;
-
/* start a HBA_TMF_LUN_RESET TMF request */
- tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
- memset(tmf, 0, sizeof(*tmf));
- tmf->tmf = HBA_TMF_LUN_RESET;
- tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
- tmf->lun[1] = cmd->device->lun;
-
- address = (u64)fib->hw_error_pa;
- tmf->error_ptr_hi = cpu_to_le32
- ((u32)(address >> 32));
- tmf->error_ptr_lo = cpu_to_le32
- ((u32)(address & 0xffffffff));
- tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
- fib->hbacmd_size = sizeof(*tmf);
-
- command = HBA_IU_TYPE_SCSI_TM_REQ;
+ command = aac_eh_tmf_lun_reset_fib(aac, fib,
+ bus, cid,
+ cmd->device->lun);
aac->hba_map[bus][cid].reset_state++;
} else if (aac->hba_map[bus][cid].reset_state >= 1) {
- struct aac_hba_reset_req *rst;
-
/* already tried, start a hard reset now */
- rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
- memset(rst, 0, sizeof(*rst));
- /* reset_type is already zero... */
- rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
-
- address = (u64)fib->hw_error_pa;
- rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
- rst->error_ptr_lo = cpu_to_le32
- ((u32)(address & 0xffffffff));
- rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
- fib->hbacmd_size = sizeof(*rst);
-
- command = HBA_IU_TYPE_SATA_REQ;
+ command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
aac->hba_map[bus][cid].reset_state = 0;
}
cmd->SCp.sent_command = 0;
--
1.8.5.6
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/7] aacraid: split off host reset
2017-06-30 17:18 [PATCH 0/7] aacraid: split off EH functions Hannes Reinecke
2017-06-30 17:18 ` [PATCH 1/7] aacraid: split off functions to generate reset FIB Hannes Reinecke
@ 2017-06-30 17:18 ` Hannes Reinecke
2017-06-30 17:18 ` [PATCH 3/7] aacraid: split off device, target, and bus reset Hannes Reinecke
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2017-06-30 17:18 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi,
Raghava Aditya Renukunta, Hannes Reinecke, Hannes Reinecke
Split off the host reset parts of aac_eh_reset() into a separate
host reset function.
Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
---
drivers/scsi/aacraid/linit.c | 33 ++++++++++++++++++++++-----------
1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 9a8a27f..bf21006 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -874,10 +874,6 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
u32 bus, cid;
int ret = FAILED;
int status = 0;
- __le32 supported_options2 = 0;
- bool is_mu_reset;
- bool is_ignore_reset;
- bool is_doorbell_reset;
bus = aac_logical_to_phys(scmd_channel(cmd));
@@ -923,7 +919,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
}
if (ret == SUCCESS)
- goto out;
+ return ret;
} else {
@@ -952,8 +948,24 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
dev_err(&aac->pdev->dev, "Adapter health - %d\n", status);
count = get_num_of_incomplete_fibs(aac);
- if (count == 0)
- return SUCCESS;
+ return (count == 0) ? SUCCESS : FAILED;
+}
+
+/*
+ * aac_eh_host_reset - Host reset command handling
+ * @scsi_cmd: SCSI command block causing the reset
+ *
+ */
+int aac_eh_host_reset(struct scsi_cmnd *cmd)
+{
+ struct scsi_device * dev = cmd->device;
+ struct Scsi_Host * host = dev->host;
+ struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+ int ret = FAILED;
+ __le32 supported_options2 = 0;
+ bool is_mu_reset;
+ bool is_ignore_reset;
+ bool is_doorbell_reset;
/*
* Check if reset is supported by the firmware
@@ -972,10 +984,8 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
&& (aac_check_reset != -1 || !is_ignore_reset)) {
/* Bypass wait for command quiesce */
aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET);
+ ret = SUCCESS;
}
- ret = SUCCESS;
-
-out:
return ret;
}
@@ -1399,7 +1409,8 @@ ssize_t aac_get_serial_number(struct device *device, char *buf)
.change_queue_depth = aac_change_queue_depth,
.sdev_attrs = aac_dev_attrs,
.eh_abort_handler = aac_eh_abort,
- .eh_host_reset_handler = aac_eh_reset,
+ .eh_bus_reset_handler = aac_eh_reset,
+ .eh_host_reset_handler = aac_eh_host_reset,
.can_queue = AAC_NUM_IO_FIB,
.this_id = MAXIMUM_NUM_CONTAINERS,
.sg_tablesize = 16,
--
1.8.5.6
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 3/7] aacraid: split off device, target, and bus reset
2017-06-30 17:18 [PATCH 0/7] aacraid: split off EH functions Hannes Reinecke
2017-06-30 17:18 ` [PATCH 1/7] aacraid: split off functions to generate reset FIB Hannes Reinecke
2017-06-30 17:18 ` [PATCH 2/7] aacraid: split off host reset Hannes Reinecke
@ 2017-06-30 17:18 ` Hannes Reinecke
2017-06-30 17:18 ` [PATCH 4/7] aacraid: use aac_tmf_callback for reset fib Hannes Reinecke
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2017-06-30 17:18 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi,
Raghava Aditya Renukunta, Hannes Reinecke, Hannes Reinecke
Split off device, target, and bus reset functionality into
individual functions.
Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
---
drivers/scsi/aacraid/linit.c | 141 +++++++++++++++++++++++++++++++------------
1 file changed, 102 insertions(+), 39 deletions(-)
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index bf21006..57b2077 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -861,68 +861,129 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
}
/*
- * aac_eh_reset - Reset command handling
+ * aac_eh_dev_reset - Device reset command handling
* @scsi_cmd: SCSI command block causing the reset
*
*/
-static int aac_eh_reset(struct scsi_cmnd* cmd)
+static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
{
struct scsi_device * dev = cmd->device;
struct Scsi_Host * host = dev->host;
struct aac_dev * aac = (struct aac_dev *)host->hostdata;
int count;
u32 bus, cid;
+ struct fib *fib;
int ret = FAILED;
- int status = 0;
-
+ int status;
+ u8 command;
bus = aac_logical_to_phys(scmd_channel(cmd));
cid = scmd_id(cmd);
- if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS &&
- aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
- struct fib *fib;
- int status;
- u8 command;
+ if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
+ aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
+ return FAILED;
- pr_err("%s: Host adapter reset request. SCSI hang ?\n",
- AAC_DRIVERNAME);
+ pr_err("%s: Host adapter reset request. SCSI hang ?\n",
+ AAC_DRIVERNAME);
- fib = aac_fib_alloc(aac);
- if (!fib)
- return ret;
+ fib = aac_fib_alloc(aac);
+ if (!fib)
+ return ret;
- if (aac->hba_map[bus][cid].reset_state == 0) {
- /* start a HBA_TMF_LUN_RESET TMF request */
- command = aac_eh_tmf_lun_reset_fib(aac, fib,
- bus, cid,
- cmd->device->lun);
- aac->hba_map[bus][cid].reset_state++;
- } else if (aac->hba_map[bus][cid].reset_state >= 1) {
- /* already tried, start a hard reset now */
- command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
- aac->hba_map[bus][cid].reset_state = 0;
+ /* start a HBA_TMF_LUN_RESET TMF request */
+ command = aac_eh_tmf_lun_reset_fib(aac, fib, bus, cid,
+ cmd->device->lun);
+
+ cmd->SCp.sent_command = 0;
+
+ status = aac_hba_send(command, fib,
+ (fib_callback) aac_hba_callback,
+ (void *) cmd);
+
+ /* Wait up to 15 seconds for completion */
+ for (count = 0; count < 15; ++count) {
+ if (cmd->SCp.sent_command) {
+ ret = SUCCESS;
+ break;
}
- cmd->SCp.sent_command = 0;
+ msleep(1000);
+ }
- status = aac_hba_send(command, fib,
- (fib_callback) aac_hba_callback,
- (void *) cmd);
+ return ret;
+}
- /* Wait up to 15 seconds for completion */
- for (count = 0; count < 15; ++count) {
- if (cmd->SCp.sent_command) {
- ret = SUCCESS;
- break;
- }
- msleep(1000);
+/*
+ * aac_eh_target_reset - Target reset command handling
+ * @scsi_cmd: SCSI command block causing the reset
+ *
+ */
+static int aac_eh_target_reset(struct scsi_cmnd *cmd)
+{
+ struct scsi_device * dev = cmd->device;
+ struct Scsi_Host * host = dev->host;
+ struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+ int count;
+ u32 bus, cid;
+ int ret = FAILED;
+ struct fib *fib;
+ int status;
+ u8 command;
+
+ bus = aac_logical_to_phys(scmd_channel(cmd));
+ cid = scmd_id(cmd);
+ if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
+ aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
+ return FAILED;
+
+ pr_err("%s: Host adapter reset request. SCSI hang ?\n",
+ AAC_DRIVERNAME);
+
+ fib = aac_fib_alloc(aac);
+ if (!fib)
+ return ret;
+
+
+ /* already tried, start a hard reset now */
+ command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
+
+ cmd->SCp.sent_command = 0;
+
+ status = aac_hba_send(command, fib,
+ (fib_callback) aac_hba_callback,
+ (void *) cmd);
+
+ /* Wait up to 15 seconds for completion */
+ for (count = 0; count < 15; ++count) {
+ if (cmd->SCp.sent_command) {
+ ret = SUCCESS;
+ break;
}
+ msleep(1000);
+ }
- if (ret == SUCCESS)
- return ret;
+ return ret;
+}
+
+/*
+ * aac_eh_bus_reset - Bus reset command handling
+ * @scsi_cmd: SCSI command block causing the reset
+ *
+ */
+static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
+{
+ struct scsi_device * dev = cmd->device;
+ struct Scsi_Host * host = dev->host;
+ struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+ int count;
+ u32 bus, cid;
+ int status = 0;
- } else {
+ bus = aac_logical_to_phys(scmd_channel(cmd));
+ cid = scmd_id(cmd);
+ if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
+ aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW) {
/* Mark the assoc. FIB to not complete, eh handler does this */
for (count = 0;
count < (host->can_queue + AAC_NUM_MGT_FIB);
@@ -1409,7 +1470,9 @@ ssize_t aac_get_serial_number(struct device *device, char *buf)
.change_queue_depth = aac_change_queue_depth,
.sdev_attrs = aac_dev_attrs,
.eh_abort_handler = aac_eh_abort,
- .eh_bus_reset_handler = aac_eh_reset,
+ .eh_device_reset_handler = aac_eh_dev_reset,
+ .eh_target_reset_handler = aac_eh_target_reset,
+ .eh_bus_reset_handler = aac_eh_bus_reset,
.eh_host_reset_handler = aac_eh_host_reset,
.can_queue = AAC_NUM_IO_FIB,
.this_id = MAXIMUM_NUM_CONTAINERS,
--
1.8.5.6
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 4/7] aacraid: use aac_tmf_callback for reset fib
2017-06-30 17:18 [PATCH 0/7] aacraid: split off EH functions Hannes Reinecke
` (2 preceding siblings ...)
2017-06-30 17:18 ` [PATCH 3/7] aacraid: split off device, target, and bus reset Hannes Reinecke
@ 2017-06-30 17:18 ` Hannes Reinecke
2017-07-05 18:09 ` Raghava Aditya Renukunta
2017-06-30 17:18 ` [PATCH 5/7] aacraid: enable sending of TMFs from aac_hba_send() Hannes Reinecke
` (3 subsequent siblings)
7 siblings, 1 reply; 10+ messages in thread
From: Hannes Reinecke @ 2017-06-30 17:18 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi,
Raghava Aditya Renukunta, Hannes Reinecke, Hannes Reinecke
When sending a reset fib we shouldn't rely on the scsi command,
but rather set the TMF status in the map_info->reset_state variable.
That allows us to send a TMF independent on a scsi command.
Signed-off-by: Hannes Reinecke <hare@suse.com>
---
drivers/scsi/aacraid/linit.c | 99 +++++++++++++++++++++++++++++++++-----------
1 file changed, 74 insertions(+), 25 deletions(-)
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 57b2077..e5d2d91 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -814,8 +814,8 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
return ret;
}
-static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
- int bus, int cid, u64 tmf_lun)
+static u8 aac_eh_tmf_lun_reset_fib(struct aac_hba_map_info *info,
+ struct fib *fib, u64 tmf_lun)
{
struct aac_hba_tm_req *tmf;
u64 address;
@@ -824,7 +824,7 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
memset(tmf, 0, sizeof(*tmf));
tmf->tmf = HBA_TMF_LUN_RESET;
- tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+ tmf->it_nexus = info->rmw_nexus;
int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
address = (u64)fib->hw_error_pa;
@@ -838,8 +838,8 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
return HBA_IU_TYPE_SCSI_TM_REQ;
}
-static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
- int bus, int cid)
+static u8 aac_eh_tmf_hard_reset_fib(struct aac_hba_map_info *info,
+ struct fib *fib)
{
struct aac_hba_reset_req *rst;
u64 address;
@@ -847,8 +847,7 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
/* already tried, start a hard reset now */
rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
memset(rst, 0, sizeof(*rst));
- /* reset_type is already zero... */
- rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+ rst->it_nexus = info->rmw_nexus;
address = (u64)fib->hw_error_pa;
rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
@@ -860,6 +859,33 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
return HBA_IU_TYPE_SATA_REQ;
}
+void aac_tmf_callback(void *context, struct fib *fibptr)
+{
+ struct aac_hba_resp *err =
+ &((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
+ struct aac_hba_map_info *info = context;
+ int res;
+
+ switch (err->service_response) {
+ case HBA_RESP_SVCRES_TMF_REJECTED:
+ res = -1;
+ break;
+ case HBA_RESP_SVCRES_TMF_LUN_INVALID:
+ res = 0;
+ break;
+ case HBA_RESP_SVCRES_TMF_COMPLETE:
+ case HBA_RESP_SVCRES_TMF_SUCCEEDED:
+ res = 0;
+ break;
+ default:
+ res = -2;
+ break;
+ }
+ aac_fib_complete(fibptr);
+
+ info->reset_state = res;
+}
+
/*
* aac_eh_dev_reset - Device reset command handling
* @scsi_cmd: SCSI command block causing the reset
@@ -870,6 +896,7 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
struct scsi_device * dev = cmd->device;
struct Scsi_Host * host = dev->host;
struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+ struct aac_hba_map_info *info;
int count;
u32 bus, cid;
struct fib *fib;
@@ -879,8 +906,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
bus = aac_logical_to_phys(scmd_channel(cmd));
cid = scmd_id(cmd);
+ info = &aac->hba_map[bus][cid];
if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
- aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
+ info->devtype != AAC_DEVTYPE_NATIVE_RAW)
+ return FAILED;
+
+ if (info->reset_state > 0)
return FAILED;
pr_err("%s: Host adapter reset request. SCSI hang ?\n",
@@ -890,21 +921,19 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
if (!fib)
return ret;
-
/* start a HBA_TMF_LUN_RESET TMF request */
- command = aac_eh_tmf_lun_reset_fib(aac, fib, bus, cid,
- cmd->device->lun);
+ command = aac_eh_tmf_lun_reset_fib(info, fib, dev->lun);
- cmd->SCp.sent_command = 0;
+ info->reset_state = 1;
status = aac_hba_send(command, fib,
- (fib_callback) aac_hba_callback,
- (void *) cmd);
+ (fib_callback) aac_tmf_callback,
+ (void *) info);
/* Wait up to 15 seconds for completion */
for (count = 0; count < 15; ++count) {
- if (cmd->SCp.sent_command) {
- ret = SUCCESS;
+ if (info->reset_state == 0) {
+ ret = info->reset_state == 0 ? SUCCESS : FAILED;
break;
}
msleep(1000);
@@ -923,6 +952,7 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
struct scsi_device * dev = cmd->device;
struct Scsi_Host * host = dev->host;
struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+ struct aac_hba_map_info *info;
int count;
u32 bus, cid;
int ret = FAILED;
@@ -932,8 +962,12 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
bus = aac_logical_to_phys(scmd_channel(cmd));
cid = scmd_id(cmd);
+ info = &aac->hba_map[bus][cid];
if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
- aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
+ info->devtype != AAC_DEVTYPE_NATIVE_RAW)
+ return FAILED;
+
+ if (info->reset_state > 0)
return FAILED;
pr_err("%s: Host adapter reset request. SCSI hang ?\n",
@@ -945,18 +979,18 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
/* already tried, start a hard reset now */
- command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
+ command = aac_eh_tmf_hard_reset_fib(info, fib);
- cmd->SCp.sent_command = 0;
+ info->reset_state = 2;
status = aac_hba_send(command, fib,
- (fib_callback) aac_hba_callback,
- (void *) cmd);
+ (fib_callback) aac_tmf_callback,
+ (void *) info);
/* Wait up to 15 seconds for completion */
for (count = 0; count < 15; ++count) {
- if (cmd->SCp.sent_command) {
- ret = SUCCESS;
+ if (info->reset_state <= 0) {
+ ret = info->reset_state == 0 ? SUCCESS : FAILED;
break;
}
msleep(1000);
@@ -1044,8 +1078,23 @@ int aac_eh_host_reset(struct scsi_cmnd *cmd)
&& aac_check_reset
&& (aac_check_reset != -1 || !is_ignore_reset)) {
/* Bypass wait for command quiesce */
- aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET);
- ret = SUCCESS;
+ if (aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET) == 0)
+ ret = SUCCESS;
+ }
+ /*
+ * Reset EH state
+ */
+ if (ret == SUCCESS) {
+ int bus, cid;
+ struct aac_hba_map_info *info;
+
+ for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
+ for (cid = 0; cid < AAC_MAX_TARGETS; cid++) {
+ info = &aac->hba_map[bus][cid];
+ if (info->devtype == AAC_DEVTYPE_NATIVE_RAW)
+ info->reset_state = 0;
+ }
+ }
}
return ret;
}
--
1.8.5.6
^ permalink raw reply related [flat|nested] 10+ messages in thread* RE: [PATCH 4/7] aacraid: use aac_tmf_callback for reset fib
2017-06-30 17:18 ` [PATCH 4/7] aacraid: use aac_tmf_callback for reset fib Hannes Reinecke
@ 2017-07-05 18:09 ` Raghava Aditya Renukunta
0 siblings, 0 replies; 10+ messages in thread
From: Raghava Aditya Renukunta @ 2017-07-05 18:09 UTC (permalink / raw)
To: Hannes Reinecke, Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi@vger.kernel.org,
Hannes Reinecke
> -----Original Message-----
> From: Hannes Reinecke [mailto:hare@suse.de]
> Sent: Friday, June 30, 2017 10:18 AM
> To: Martin K. Petersen <martin.petersen@oracle.com>
> Cc: Christoph Hellwig <hch@lst.de>; James Bottomley
> <james.bottomley@hansenpartnership.com>; linux-scsi@vger.kernel.org;
> Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>;
> Hannes Reinecke <hare@suse.de>; Hannes Reinecke <hare@suse.com>
> Subject: [PATCH 4/7] aacraid: use aac_tmf_callback for reset fib
>
> EXTERNAL EMAIL
>
>
> When sending a reset fib we shouldn't rely on the scsi command,
> but rather set the TMF status in the map_info->reset_state variable.
> That allows us to send a TMF independent on a scsi command.
>
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
> drivers/scsi/aacraid/linit.c | 99 +++++++++++++++++++++++++++++++++---
> --------
> 1 file changed, 74 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
> index 57b2077..e5d2d91 100644
> --- a/drivers/scsi/aacraid/linit.c
> +++ b/drivers/scsi/aacraid/linit.c
> @@ -814,8 +814,8 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
> return ret;
> }
>
> -static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
> - int bus, int cid, u64 tmf_lun)
> +static u8 aac_eh_tmf_lun_reset_fib(struct aac_hba_map_info *info,
> + struct fib *fib, u64 tmf_lun)
> {
> struct aac_hba_tm_req *tmf;
> u64 address;
> @@ -824,7 +824,7 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev
> *aac, struct fib *fib,
> tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
> memset(tmf, 0, sizeof(*tmf));
> tmf->tmf = HBA_TMF_LUN_RESET;
> - tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
> + tmf->it_nexus = info->rmw_nexus;
> int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
>
> address = (u64)fib->hw_error_pa;
> @@ -838,8 +838,8 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev
> *aac, struct fib *fib,
> return HBA_IU_TYPE_SCSI_TM_REQ;
> }
>
> -static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
> - int bus, int cid)
> +static u8 aac_eh_tmf_hard_reset_fib(struct aac_hba_map_info *info,
> + struct fib *fib)
> {
> struct aac_hba_reset_req *rst;
> u64 address;
> @@ -847,8 +847,7 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev
> *aac, struct fib *fib,
> /* already tried, start a hard reset now */
> rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
> memset(rst, 0, sizeof(*rst));
> - /* reset_type is already zero... */
> - rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
> + rst->it_nexus = info->rmw_nexus;
>
> address = (u64)fib->hw_error_pa;
> rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
> @@ -860,6 +859,33 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev
> *aac, struct fib *fib,
> return HBA_IU_TYPE_SATA_REQ;
> }
>
> +void aac_tmf_callback(void *context, struct fib *fibptr)
> +{
> + struct aac_hba_resp *err =
> + &((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
> + struct aac_hba_map_info *info = context;
> + int res;
> +
> + switch (err->service_response) {
> + case HBA_RESP_SVCRES_TMF_REJECTED:
> + res = -1;
> + break;
> + case HBA_RESP_SVCRES_TMF_LUN_INVALID:
> + res = 0;
> + break;
> + case HBA_RESP_SVCRES_TMF_COMPLETE:
> + case HBA_RESP_SVCRES_TMF_SUCCEEDED:
> + res = 0;
> + break;
> + default:
> + res = -2;
> + break;
> + }
> + aac_fib_complete(fibptr);
> +
> + info->reset_state = res;
> +}
> +
> /*
> * aac_eh_dev_reset - Device reset command handling
> * @scsi_cmd: SCSI command block causing the reset
> @@ -870,6 +896,7 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
> struct scsi_device * dev = cmd->device;
> struct Scsi_Host * host = dev->host;
> struct aac_dev * aac = (struct aac_dev *)host->hostdata;
> + struct aac_hba_map_info *info;
> int count;
> u32 bus, cid;
> struct fib *fib;
> @@ -879,8 +906,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
>
> bus = aac_logical_to_phys(scmd_channel(cmd));
> cid = scmd_id(cmd);
> + info = &aac->hba_map[bus][cid];
> if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
> - aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
> + info->devtype != AAC_DEVTYPE_NATIVE_RAW)
> + return FAILED;
> +
> + if (info->reset_state > 0)
> return FAILED;
>
> pr_err("%s: Host adapter reset request. SCSI hang ?\n",
> @@ -890,21 +921,19 @@ static int aac_eh_dev_reset(struct scsi_cmnd
> *cmd)
> if (!fib)
> return ret;
>
> -
> /* start a HBA_TMF_LUN_RESET TMF request */
> - command = aac_eh_tmf_lun_reset_fib(aac, fib, bus, cid,
> - cmd->device->lun);
> + command = aac_eh_tmf_lun_reset_fib(info, fib, dev->lun);
>
> - cmd->SCp.sent_command = 0;
> + info->reset_state = 1;
>
> status = aac_hba_send(command, fib,
> - (fib_callback) aac_hba_callback,
> - (void *) cmd);
> + (fib_callback) aac_tmf_callback,
> + (void *) info);
>
> /* Wait up to 15 seconds for completion */
> for (count = 0; count < 15; ++count) {
> - if (cmd->SCp.sent_command) {
> - ret = SUCCESS;
> + if (info->reset_state == 0) {
> + ret = info->reset_state == 0 ? SUCCESS : FAILED;
> break;
> }
> msleep(1000);
> @@ -923,6 +952,7 @@ static int aac_eh_target_reset(struct scsi_cmnd
> *cmd)
> struct scsi_device * dev = cmd->device;
> struct Scsi_Host * host = dev->host;
> struct aac_dev * aac = (struct aac_dev *)host->hostdata;
> + struct aac_hba_map_info *info;
> int count;
> u32 bus, cid;
> int ret = FAILED;
> @@ -932,8 +962,12 @@ static int aac_eh_target_reset(struct scsi_cmnd
> *cmd)
>
> bus = aac_logical_to_phys(scmd_channel(cmd));
> cid = scmd_id(cmd);
> + info = &aac->hba_map[bus][cid];
> if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
> - aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
> + info->devtype != AAC_DEVTYPE_NATIVE_RAW)
> + return FAILED;
> +
> + if (info->reset_state > 0)
> return FAILED;
>
> pr_err("%s: Host adapter reset request. SCSI hang ?\n",
> @@ -945,18 +979,18 @@ static int aac_eh_target_reset(struct scsi_cmnd
> *cmd)
>
>
> /* already tried, start a hard reset now */
> - command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
> + command = aac_eh_tmf_hard_reset_fib(info, fib);
>
> - cmd->SCp.sent_command = 0;
> + info->reset_state = 2;
>
> status = aac_hba_send(command, fib,
> - (fib_callback) aac_hba_callback,
> - (void *) cmd);
> + (fib_callback) aac_tmf_callback,
> + (void *) info);
>
> /* Wait up to 15 seconds for completion */
> for (count = 0; count < 15; ++count) {
> - if (cmd->SCp.sent_command) {
> - ret = SUCCESS;
> + if (info->reset_state <= 0) {
> + ret = info->reset_state == 0 ? SUCCESS : FAILED;
> break;
> }
> msleep(1000);
> @@ -1044,8 +1078,23 @@ int aac_eh_host_reset(struct scsi_cmnd *cmd)
> && aac_check_reset
> && (aac_check_reset != -1 || !is_ignore_reset)) {
> /* Bypass wait for command quiesce */
> - aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET);
> - ret = SUCCESS;
> + if (aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET) == 0)
> + ret = SUCCESS;
> + }
> + /*
> + * Reset EH state
> + */
> + if (ret == SUCCESS) {
> + int bus, cid;
> + struct aac_hba_map_info *info;
> +
> + for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
> + for (cid = 0; cid < AAC_MAX_TARGETS; cid++) {
> + info = &aac->hba_map[bus][cid];
> + if (info->devtype == AAC_DEVTYPE_NATIVE_RAW)
> + info->reset_state = 0;
> + }
> + }
> }
> return ret;
> }
> --
> 1.8.5.6
Reviewed-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 5/7] aacraid: enable sending of TMFs from aac_hba_send()
2017-06-30 17:18 [PATCH 0/7] aacraid: split off EH functions Hannes Reinecke
` (3 preceding siblings ...)
2017-06-30 17:18 ` [PATCH 4/7] aacraid: use aac_tmf_callback for reset fib Hannes Reinecke
@ 2017-06-30 17:18 ` Hannes Reinecke
2017-06-30 17:18 ` [PATCH 6/7] aacraid: add fib flag to mark scsi command callback Hannes Reinecke
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2017-06-30 17:18 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi,
Raghava Aditya Renukunta, Hannes Reinecke, Hannes Reinecke
aac_hba_send() will return FAILED for any non-SCSI command requests,
failing any TMFs. This patch updates the check to allow TMFs.
Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
---
drivers/scsi/aacraid/commsup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 1c617cc..348f0ea 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -770,7 +770,7 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
/* bit1 of request_id must be 0 */
hbacmd->request_id =
cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1);
- } else
+ } else if (command != HBA_IU_TYPE_SCSI_TM_REQ)
return -EINVAL;
--
1.8.5.6
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 6/7] aacraid: add fib flag to mark scsi command callback
2017-06-30 17:18 [PATCH 0/7] aacraid: split off EH functions Hannes Reinecke
` (4 preceding siblings ...)
2017-06-30 17:18 ` [PATCH 5/7] aacraid: enable sending of TMFs from aac_hba_send() Hannes Reinecke
@ 2017-06-30 17:18 ` Hannes Reinecke
2017-06-30 17:18 ` [PATCH 7/7] aacraid: complete all commands during bus reset Hannes Reinecke
2017-07-12 21:39 ` [PATCH 0/7] aacraid: split off EH functions Martin K. Petersen
7 siblings, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2017-06-30 17:18 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi,
Raghava Aditya Renukunta, Hannes Reinecke, Hannes Reinecke
To correctly identify which fib has a scsi command callback this
patch implements a flag FIB_CONTEXT_FLAG_SCSI_CMD.
Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
---
drivers/scsi/aacraid/aacraid.h | 1 +
drivers/scsi/aacraid/commsup.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index d31a9bc..6981299 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1723,6 +1723,7 @@ struct aac_dev
#define FIB_CONTEXT_FLAG_FASTRESP (0x00000008)
#define FIB_CONTEXT_FLAG_NATIVE_HBA (0x00000010)
#define FIB_CONTEXT_FLAG_NATIVE_HBA_TMF (0x00000020)
+#define FIB_CONTEXT_FLAG_SCSI_CMD (0x00000040)
/*
* Define the command values
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 348f0ea..dfe8e70 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -770,6 +770,7 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
/* bit1 of request_id must be 0 */
hbacmd->request_id =
cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1);
+ fibptr->flags |= FIB_CONTEXT_FLAG_SCSI_CMD;
} else if (command != HBA_IU_TYPE_SCSI_TM_REQ)
return -EINVAL;
--
1.8.5.6
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 7/7] aacraid: complete all commands during bus reset
2017-06-30 17:18 [PATCH 0/7] aacraid: split off EH functions Hannes Reinecke
` (5 preceding siblings ...)
2017-06-30 17:18 ` [PATCH 6/7] aacraid: add fib flag to mark scsi command callback Hannes Reinecke
@ 2017-06-30 17:18 ` Hannes Reinecke
2017-07-12 21:39 ` [PATCH 0/7] aacraid: split off EH functions Martin K. Petersen
7 siblings, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2017-06-30 17:18 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi,
Raghava Aditya Renukunta, Hannes Reinecke, Hannes Reinecke
When issuing a bus reset we should complete all commands, not
just the command triggering the reset.
Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
---
drivers/scsi/aacraid/linit.c | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index e5d2d91..a8dedc3 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1010,23 +1010,29 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
struct Scsi_Host * host = dev->host;
struct aac_dev * aac = (struct aac_dev *)host->hostdata;
int count;
- u32 bus, cid;
+ u32 cmd_bus;
int status = 0;
- bus = aac_logical_to_phys(scmd_channel(cmd));
- cid = scmd_id(cmd);
- if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
- aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW) {
- /* Mark the assoc. FIB to not complete, eh handler does this */
- for (count = 0;
- count < (host->can_queue + AAC_NUM_MGT_FIB);
- ++count) {
- struct fib *fib = &aac->fibs[count];
-
- if (fib->hw_fib_va->header.XferState &&
- (fib->flags & FIB_CONTEXT_FLAG) &&
- (fib->callback_data == cmd)) {
+ cmd_bus = aac_logical_to_phys(scmd_channel(cmd));
+ /* Mark the assoc. FIB to not complete, eh handler does this */
+ for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
+ struct fib *fib = &aac->fibs[count];
+
+ if (fib->hw_fib_va->header.XferState &&
+ (fib->flags & FIB_CONTEXT_FLAG) &&
+ (fib->flags & FIB_CONTEXT_FLAG_SCSI_CMD)) {
+ struct aac_hba_map_info *info;
+ u32 bus, cid;
+
+ cmd = (struct scsi_cmnd *)fib->callback_data;
+ bus = aac_logical_to_phys(scmd_channel(cmd));
+ if (bus != cmd_bus)
+ continue;
+ cid = scmd_id(cmd);
+ info = &aac->hba_map[bus][cid];
+ if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
+ info->devtype != AAC_DEVTYPE_NATIVE_RAW) {
fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT;
cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
}
--
1.8.5.6
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 0/7] aacraid: split off EH functions
2017-06-30 17:18 [PATCH 0/7] aacraid: split off EH functions Hannes Reinecke
` (6 preceding siblings ...)
2017-06-30 17:18 ` [PATCH 7/7] aacraid: complete all commands during bus reset Hannes Reinecke
@ 2017-07-12 21:39 ` Martin K. Petersen
7 siblings, 0 replies; 10+ messages in thread
From: Martin K. Petersen @ 2017-07-12 21:39 UTC (permalink / raw)
To: Hannes Reinecke
Cc: Martin K. Petersen, Christoph Hellwig, James Bottomley,
linux-scsi, Raghava Aditya Renukunta
Hannes,
> this patchset is a split off from the original patchset to rework SCSI
> EH function parameters. As it's pretty much independent and an
> improvement to the existing EH callback function, so I'm posting it
> separately.
Applied to 4.14/scsi-queue. Thank you!
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 10+ messages in thread