Skip to content

Commit 0d643ff

Browse files
hreineckemartinkpetersen
authored andcommitted
scsi: aacraid: use aac_tmf_callback for reset fib
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> Reviewed-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent f799319 commit 0d643ff

File tree

1 file changed

+74
-25
lines changed

1 file changed

+74
-25
lines changed

drivers/scsi/aacraid/linit.c

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -814,8 +814,8 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
814814
return ret;
815815
}
816816

817-
static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
818-
int bus, int cid, u64 tmf_lun)
817+
static u8 aac_eh_tmf_lun_reset_fib(struct aac_hba_map_info *info,
818+
struct fib *fib, u64 tmf_lun)
819819
{
820820
struct aac_hba_tm_req *tmf;
821821
u64 address;
@@ -824,7 +824,7 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
824824
tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
825825
memset(tmf, 0, sizeof(*tmf));
826826
tmf->tmf = HBA_TMF_LUN_RESET;
827-
tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
827+
tmf->it_nexus = info->rmw_nexus;
828828
int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
829829

830830
address = (u64)fib->hw_error_pa;
@@ -838,17 +838,16 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
838838
return HBA_IU_TYPE_SCSI_TM_REQ;
839839
}
840840

841-
static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
842-
int bus, int cid)
841+
static u8 aac_eh_tmf_hard_reset_fib(struct aac_hba_map_info *info,
842+
struct fib *fib)
843843
{
844844
struct aac_hba_reset_req *rst;
845845
u64 address;
846846

847847
/* already tried, start a hard reset now */
848848
rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
849849
memset(rst, 0, sizeof(*rst));
850-
/* reset_type is already zero... */
851-
rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
850+
rst->it_nexus = info->rmw_nexus;
852851

853852
address = (u64)fib->hw_error_pa;
854853
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,
860859
return HBA_IU_TYPE_SATA_REQ;
861860
}
862861

862+
void aac_tmf_callback(void *context, struct fib *fibptr)
863+
{
864+
struct aac_hba_resp *err =
865+
&((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
866+
struct aac_hba_map_info *info = context;
867+
int res;
868+
869+
switch (err->service_response) {
870+
case HBA_RESP_SVCRES_TMF_REJECTED:
871+
res = -1;
872+
break;
873+
case HBA_RESP_SVCRES_TMF_LUN_INVALID:
874+
res = 0;
875+
break;
876+
case HBA_RESP_SVCRES_TMF_COMPLETE:
877+
case HBA_RESP_SVCRES_TMF_SUCCEEDED:
878+
res = 0;
879+
break;
880+
default:
881+
res = -2;
882+
break;
883+
}
884+
aac_fib_complete(fibptr);
885+
886+
info->reset_state = res;
887+
}
888+
863889
/*
864890
* aac_eh_dev_reset - Device reset command handling
865891
* @scsi_cmd: SCSI command block causing the reset
@@ -870,6 +896,7 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
870896
struct scsi_device * dev = cmd->device;
871897
struct Scsi_Host * host = dev->host;
872898
struct aac_dev * aac = (struct aac_dev *)host->hostdata;
899+
struct aac_hba_map_info *info;
873900
int count;
874901
u32 bus, cid;
875902
struct fib *fib;
@@ -879,8 +906,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
879906

880907
bus = aac_logical_to_phys(scmd_channel(cmd));
881908
cid = scmd_id(cmd);
909+
info = &aac->hba_map[bus][cid];
882910
if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
883-
aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
911+
info->devtype != AAC_DEVTYPE_NATIVE_RAW)
912+
return FAILED;
913+
914+
if (info->reset_state > 0)
884915
return FAILED;
885916

886917
pr_err("%s: Host adapter reset request. SCSI hang ?\n",
@@ -890,21 +921,19 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
890921
if (!fib)
891922
return ret;
892923

893-
894924
/* start a HBA_TMF_LUN_RESET TMF request */
895-
command = aac_eh_tmf_lun_reset_fib(aac, fib, bus, cid,
896-
cmd->device->lun);
925+
command = aac_eh_tmf_lun_reset_fib(info, fib, dev->lun);
897926

898-
cmd->SCp.sent_command = 0;
927+
info->reset_state = 1;
899928

900929
status = aac_hba_send(command, fib,
901-
(fib_callback) aac_hba_callback,
902-
(void *) cmd);
930+
(fib_callback) aac_tmf_callback,
931+
(void *) info);
903932

904933
/* Wait up to 15 seconds for completion */
905934
for (count = 0; count < 15; ++count) {
906-
if (cmd->SCp.sent_command) {
907-
ret = SUCCESS;
935+
if (info->reset_state == 0) {
936+
ret = info->reset_state == 0 ? SUCCESS : FAILED;
908937
break;
909938
}
910939
msleep(1000);
@@ -923,6 +952,7 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
923952
struct scsi_device * dev = cmd->device;
924953
struct Scsi_Host * host = dev->host;
925954
struct aac_dev * aac = (struct aac_dev *)host->hostdata;
955+
struct aac_hba_map_info *info;
926956
int count;
927957
u32 bus, cid;
928958
int ret = FAILED;
@@ -932,8 +962,12 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
932962

933963
bus = aac_logical_to_phys(scmd_channel(cmd));
934964
cid = scmd_id(cmd);
965+
info = &aac->hba_map[bus][cid];
935966
if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
936-
aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
967+
info->devtype != AAC_DEVTYPE_NATIVE_RAW)
968+
return FAILED;
969+
970+
if (info->reset_state > 0)
937971
return FAILED;
938972

939973
pr_err("%s: Host adapter reset request. SCSI hang ?\n",
@@ -945,18 +979,18 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
945979

946980

947981
/* already tried, start a hard reset now */
948-
command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
982+
command = aac_eh_tmf_hard_reset_fib(info, fib);
949983

950-
cmd->SCp.sent_command = 0;
984+
info->reset_state = 2;
951985

952986
status = aac_hba_send(command, fib,
953-
(fib_callback) aac_hba_callback,
954-
(void *) cmd);
987+
(fib_callback) aac_tmf_callback,
988+
(void *) info);
955989

956990
/* Wait up to 15 seconds for completion */
957991
for (count = 0; count < 15; ++count) {
958-
if (cmd->SCp.sent_command) {
959-
ret = SUCCESS;
992+
if (info->reset_state <= 0) {
993+
ret = info->reset_state == 0 ? SUCCESS : FAILED;
960994
break;
961995
}
962996
msleep(1000);
@@ -1044,8 +1078,23 @@ int aac_eh_host_reset(struct scsi_cmnd *cmd)
10441078
&& aac_check_reset
10451079
&& (aac_check_reset != -1 || !is_ignore_reset)) {
10461080
/* Bypass wait for command quiesce */
1047-
aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET);
1048-
ret = SUCCESS;
1081+
if (aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET) == 0)
1082+
ret = SUCCESS;
1083+
}
1084+
/*
1085+
* Reset EH state
1086+
*/
1087+
if (ret == SUCCESS) {
1088+
int bus, cid;
1089+
struct aac_hba_map_info *info;
1090+
1091+
for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
1092+
for (cid = 0; cid < AAC_MAX_TARGETS; cid++) {
1093+
info = &aac->hba_map[bus][cid];
1094+
if (info->devtype == AAC_DEVTYPE_NATIVE_RAW)
1095+
info->reset_state = 0;
1096+
}
1097+
}
10491098
}
10501099
return ret;
10511100
}

0 commit comments

Comments
 (0)