@@ -814,8 +814,8 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
814
814
return ret ;
815
815
}
816
816
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 )
819
819
{
820
820
struct aac_hba_tm_req * tmf ;
821
821
u64 address ;
@@ -824,7 +824,7 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
824
824
tmf = (struct aac_hba_tm_req * )fib -> hw_fib_va ;
825
825
memset (tmf , 0 , sizeof (* tmf ));
826
826
tmf -> tmf = HBA_TMF_LUN_RESET ;
827
- tmf -> it_nexus = aac -> hba_map [ bus ][ cid ]. rmw_nexus ;
827
+ tmf -> it_nexus = info -> rmw_nexus ;
828
828
int_to_scsilun (tmf_lun , (struct scsi_lun * )tmf -> lun );
829
829
830
830
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,
838
838
return HBA_IU_TYPE_SCSI_TM_REQ ;
839
839
}
840
840
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 )
843
843
{
844
844
struct aac_hba_reset_req * rst ;
845
845
u64 address ;
846
846
847
847
/* already tried, start a hard reset now */
848
848
rst = (struct aac_hba_reset_req * )fib -> hw_fib_va ;
849
849
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 ;
852
851
853
852
address = (u64 )fib -> hw_error_pa ;
854
853
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,
860
859
return HBA_IU_TYPE_SATA_REQ ;
861
860
}
862
861
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
+
863
889
/*
864
890
* aac_eh_dev_reset - Device reset command handling
865
891
* @scsi_cmd: SCSI command block causing the reset
@@ -870,6 +896,7 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
870
896
struct scsi_device * dev = cmd -> device ;
871
897
struct Scsi_Host * host = dev -> host ;
872
898
struct aac_dev * aac = (struct aac_dev * )host -> hostdata ;
899
+ struct aac_hba_map_info * info ;
873
900
int count ;
874
901
u32 bus , cid ;
875
902
struct fib * fib ;
@@ -879,8 +906,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
879
906
880
907
bus = aac_logical_to_phys (scmd_channel (cmd ));
881
908
cid = scmd_id (cmd );
909
+ info = & aac -> hba_map [bus ][cid ];
882
910
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 )
884
915
return FAILED ;
885
916
886
917
pr_err ("%s: Host adapter reset request. SCSI hang ?\n" ,
@@ -890,21 +921,19 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
890
921
if (!fib )
891
922
return ret ;
892
923
893
-
894
924
/* 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 );
897
926
898
- cmd -> SCp . sent_command = 0 ;
927
+ info -> reset_state = 1 ;
899
928
900
929
status = aac_hba_send (command , fib ,
901
- (fib_callback ) aac_hba_callback ,
902
- (void * ) cmd );
930
+ (fib_callback ) aac_tmf_callback ,
931
+ (void * ) info );
903
932
904
933
/* Wait up to 15 seconds for completion */
905
934
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 ;
908
937
break ;
909
938
}
910
939
msleep (1000 );
@@ -923,6 +952,7 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
923
952
struct scsi_device * dev = cmd -> device ;
924
953
struct Scsi_Host * host = dev -> host ;
925
954
struct aac_dev * aac = (struct aac_dev * )host -> hostdata ;
955
+ struct aac_hba_map_info * info ;
926
956
int count ;
927
957
u32 bus , cid ;
928
958
int ret = FAILED ;
@@ -932,8 +962,12 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
932
962
933
963
bus = aac_logical_to_phys (scmd_channel (cmd ));
934
964
cid = scmd_id (cmd );
965
+ info = & aac -> hba_map [bus ][cid ];
935
966
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 )
937
971
return FAILED ;
938
972
939
973
pr_err ("%s: Host adapter reset request. SCSI hang ?\n" ,
@@ -945,18 +979,18 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
945
979
946
980
947
981
/* 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 );
949
983
950
- cmd -> SCp . sent_command = 0 ;
984
+ info -> reset_state = 2 ;
951
985
952
986
status = aac_hba_send (command , fib ,
953
- (fib_callback ) aac_hba_callback ,
954
- (void * ) cmd );
987
+ (fib_callback ) aac_tmf_callback ,
988
+ (void * ) info );
955
989
956
990
/* Wait up to 15 seconds for completion */
957
991
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 ;
960
994
break ;
961
995
}
962
996
msleep (1000 );
@@ -1044,8 +1078,23 @@ int aac_eh_host_reset(struct scsi_cmnd *cmd)
1044
1078
&& aac_check_reset
1045
1079
&& (aac_check_reset != -1 || !is_ignore_reset )) {
1046
1080
/* 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
+ }
1049
1098
}
1050
1099
return ret ;
1051
1100
}
0 commit comments