aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames.Smart@Emulex.Com <James.Smart@Emulex.Com>2005-11-28 11:42:05 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2005-12-13 20:26:47 -0500
commit6175c02a0b12f92c03b56c756c4f1e131ae1456c (patch)
treecee1a84d2c98d52456ceffc3d5d64eadc024266b /drivers
parent63c59c3b8ff444b771a245f59935c0202ece963b (diff)
[SCSI] lpfc 8.1.1 : Fixes to error handlers
- Release task management command before counting outstanding commands. TMF was being erroneously counted as an active outstanding command. - Serialize EH calls and block requests when EH function is running. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/lpfc/lpfc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c104
3 files changed, 70 insertions, 37 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 3062b39fbdb9..dc73a2f8f12c 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -167,6 +167,7 @@ struct lpfc_hba {
167 dma_addr_t slim2p_mapping; 167 dma_addr_t slim2p_mapping;
168 uint16_t pci_cfg_value; 168 uint16_t pci_cfg_value;
169 169
170 struct semaphore hba_can_block;
170 uint32_t hba_state; 171 uint32_t hba_state;
171 172
172#define LPFC_INIT_START 1 /* Initial state after board reset */ 173#define LPFC_INIT_START 1 /* Initial state after board reset */
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 4d4e217edd84..dfd59d21ec49 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1345,7 +1345,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
1345 goto out_put_host; 1345 goto out_put_host;
1346 1346
1347 host->unique_id = phba->brd_no; 1347 host->unique_id = phba->brd_no;
1348 1348 init_MUTEX(&phba->hba_can_block);
1349 INIT_LIST_HEAD(&phba->ctrspbuflist); 1349 INIT_LIST_HEAD(&phba->ctrspbuflist);
1350 INIT_LIST_HEAD(&phba->rnidrspbuflist); 1350 INIT_LIST_HEAD(&phba->rnidrspbuflist);
1351 INIT_LIST_HEAD(&phba->freebufList); 1351 INIT_LIST_HEAD(&phba->freebufList);
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index a4d8455de446..7dc7810b7482 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -41,6 +41,20 @@
41#define LPFC_ABORT_WAIT 2 41#define LPFC_ABORT_WAIT 2
42 42
43 43
44static inline void
45lpfc_block_requests(struct lpfc_hba * phba)
46{
47 down(&phba->hba_can_block);
48 scsi_block_requests(phba->host);
49}
50
51static inline void
52lpfc_unblock_requests(struct lpfc_hba * phba)
53{
54 scsi_unblock_requests(phba->host);
55 up(&phba->hba_can_block);
56}
57
44/* 58/*
45 * This routine allocates a scsi buffer, which contains all the necessary 59 * This routine allocates a scsi buffer, which contains all the necessary
46 * information needed to initiate a SCSI I/O. The non-DMAable buffer region 60 * information needed to initiate a SCSI I/O. The non-DMAable buffer region
@@ -774,6 +788,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
774 unsigned int loop_count = 0; 788 unsigned int loop_count = 0;
775 int ret = SUCCESS; 789 int ret = SUCCESS;
776 790
791 lpfc_block_requests(phba);
777 spin_lock_irq(shost->host_lock); 792 spin_lock_irq(shost->host_lock);
778 793
779 lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; 794 lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
@@ -853,6 +868,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
853 cmnd->device->lun, cmnd->serial_number); 868 cmnd->device->lun, cmnd->serial_number);
854 869
855 spin_unlock_irq(shost->host_lock); 870 spin_unlock_irq(shost->host_lock);
871 lpfc_unblock_requests(phba);
856 872
857 return ret; 873 return ret;
858} 874}
@@ -866,9 +882,11 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
866 struct lpfc_iocbq *iocbq, *iocbqrsp; 882 struct lpfc_iocbq *iocbq, *iocbqrsp;
867 struct lpfc_rport_data *rdata = cmnd->device->hostdata; 883 struct lpfc_rport_data *rdata = cmnd->device->hostdata;
868 struct lpfc_nodelist *pnode = rdata->pnode; 884 struct lpfc_nodelist *pnode = rdata->pnode;
885 uint32_t cmd_result = 0, cmd_status = 0;
869 int ret = FAILED; 886 int ret = FAILED;
870 int cnt, loopcnt; 887 int cnt, loopcnt;
871 888
889 lpfc_block_requests(phba);
872 spin_lock_irq(shost->host_lock); 890 spin_lock_irq(shost->host_lock);
873 /* 891 /*
874 * If target is not in a MAPPED state, delay the reset until 892 * If target is not in a MAPPED state, delay the reset until
@@ -912,26 +930,28 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
912 if (ret == IOCB_SUCCESS) 930 if (ret == IOCB_SUCCESS)
913 ret = SUCCESS; 931 ret = SUCCESS;
914 932
915 lpfc_cmd->result = iocbqrsp->iocb.un.ulpWord[4]; 933
916 lpfc_cmd->status = iocbqrsp->iocb.ulpStatus; 934 cmd_result = iocbqrsp->iocb.un.ulpWord[4];
917 if (lpfc_cmd->status == IOSTAT_LOCAL_REJECT) 935 cmd_status = iocbqrsp->iocb.ulpStatus;
918 if (lpfc_cmd->result & IOERR_DRVR_MASK) 936
919 lpfc_cmd->status = IOSTAT_DRIVER_REJECT; 937 lpfc_sli_release_iocbq(phba, iocbqrsp);
938 lpfc_release_scsi_buf(phba, lpfc_cmd);
920 939
921 /* 940 /*
922 * All outstanding txcmplq I/Os should have been aborted by the target. 941 * All outstanding txcmplq I/Os should have been aborted by the device.
923 * Unfortunately, some targets do not abide by this forcing the driver 942 * Unfortunately, some targets do not abide by this forcing the driver
924 * to double check. 943 * to double check.
925 */ 944 */
926 lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], 945 cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
927 cmnd->device->id, cmnd->device->lun, 0, 946 cmnd->device->id, cmnd->device->lun,
928 LPFC_CTX_LUN); 947 LPFC_CTX_LUN);
929 948 if (cnt)
949 lpfc_sli_abort_iocb(phba,
950 &phba->sli.ring[phba->sli.fcp_ring],
951 cmnd->device->id, cmnd->device->lun,
952 0, LPFC_CTX_LUN);
930 loopcnt = 0; 953 loopcnt = 0;
931 while((cnt = lpfc_sli_sum_iocb(phba, 954 while(cnt) {
932 &phba->sli.ring[phba->sli.fcp_ring],
933 cmnd->device->id, cmnd->device->lun,
934 LPFC_CTX_LUN))) {
935 spin_unlock_irq(phba->host->host_lock); 955 spin_unlock_irq(phba->host->host_lock);
936 schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); 956 schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
937 spin_lock_irq(phba->host->host_lock); 957 spin_lock_irq(phba->host->host_lock);
@@ -939,6 +959,11 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
939 if (++loopcnt 959 if (++loopcnt
940 > (2 * phba->cfg_nodev_tmo)/LPFC_RESET_WAIT) 960 > (2 * phba->cfg_nodev_tmo)/LPFC_RESET_WAIT)
941 break; 961 break;
962
963 cnt = lpfc_sli_sum_iocb(phba,
964 &phba->sli.ring[phba->sli.fcp_ring],
965 cmnd->device->id, cmnd->device->lun,
966 LPFC_CTX_LUN);
942 } 967 }
943 968
944 if (cnt) { 969 if (cnt) {
@@ -948,18 +973,16 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
948 ret = FAILED; 973 ret = FAILED;
949 } 974 }
950 975
951 lpfc_sli_release_iocbq(phba, iocbqrsp);
952
953out_free_scsi_buf: 976out_free_scsi_buf:
954 lpfc_printf_log(phba, KERN_ERR, LOG_FCP, 977 lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
955 "%d:0713 SCSI layer issued LUN reset (%d, %d) " 978 "%d:0713 SCSI layer issued LUN reset (%d, %d) "
956 "Data: x%x x%x x%x\n", 979 "Data: x%x x%x x%x\n",
957 phba->brd_no, lpfc_cmd->pCmd->device->id, 980 phba->brd_no, cmnd->device->id,cmnd->device->lun,
958 lpfc_cmd->pCmd->device->lun, ret, lpfc_cmd->status, 981 ret, cmd_status, cmd_result);
959 lpfc_cmd->result); 982
960 lpfc_release_scsi_buf(phba, lpfc_cmd);
961out: 983out:
962 spin_unlock_irq(shost->host_lock); 984 spin_unlock_irq(shost->host_lock);
985 lpfc_unblock_requests(phba);
963 return ret; 986 return ret;
964} 987}
965 988
@@ -975,6 +998,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
975 unsigned int midlayer_id = 0; 998 unsigned int midlayer_id = 0;
976 struct lpfc_scsi_buf * lpfc_cmd; 999 struct lpfc_scsi_buf * lpfc_cmd;
977 1000
1001 lpfc_block_requests(phba);
978 spin_lock_irq(shost->host_lock); 1002 spin_lock_irq(shost->host_lock);
979 1003
980 lpfc_cmd = lpfc_sli_get_scsi_buf (phba); 1004 lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
@@ -1008,18 +1032,31 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
1008 lpfc_cmd->pCmd->device->hostdata = ndlp->rport->dd_data; 1032 lpfc_cmd->pCmd->device->hostdata = ndlp->rport->dd_data;
1009 ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba); 1033 ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba);
1010 if (ret != SUCCESS) { 1034 if (ret != SUCCESS) {
1011 lpfc_printf_log(phba, KERN_INFO, LOG_FCP, 1035 lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
1012 "%d:0713 Bus Reset on target %d failed\n", 1036 "%d:0713 Bus Reset on target %d failed\n",
1013 phba->brd_no, i); 1037 phba->brd_no, i);
1014 err_count++; 1038 err_count++;
1015 } 1039 }
1016 } 1040 }
1017 1041
1042 if (err_count == 0)
1043 ret = SUCCESS;
1044
1045 lpfc_release_scsi_buf(phba, lpfc_cmd);
1046
1047 /*
1048 * All outstanding txcmplq I/Os should have been aborted by
1049 * the targets. Unfortunately, some targets do not abide by
1050 * this forcing the driver to double check.
1051 */
1018 cmnd->device->id = midlayer_id; 1052 cmnd->device->id = midlayer_id;
1053 cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
1054 0, 0, LPFC_CTX_HOST);
1055 if (cnt)
1056 lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
1057 0, 0, 0, LPFC_CTX_HOST);
1019 loopcnt = 0; 1058 loopcnt = 0;
1020 while((cnt = lpfc_sli_sum_iocb(phba, 1059 while(cnt) {
1021 &phba->sli.ring[phba->sli.fcp_ring],
1022 0, 0, LPFC_CTX_HOST))) {
1023 spin_unlock_irq(phba->host->host_lock); 1060 spin_unlock_irq(phba->host->host_lock);
1024 schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ); 1061 schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
1025 spin_lock_irq(phba->host->host_lock); 1062 spin_lock_irq(phba->host->host_lock);
@@ -1027,25 +1064,19 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
1027 if (++loopcnt 1064 if (++loopcnt
1028 > (2 * phba->cfg_nodev_tmo)/LPFC_RESET_WAIT) 1065 > (2 * phba->cfg_nodev_tmo)/LPFC_RESET_WAIT)
1029 break; 1066 break;
1067
1068 cnt = lpfc_sli_sum_iocb(phba,
1069 &phba->sli.ring[phba->sli.fcp_ring],
1070 0, 0, LPFC_CTX_HOST);
1030 } 1071 }
1031 1072
1032 if (cnt) { 1073 if (cnt) {
1033 /* flush all outstanding commands on the host */ 1074 lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
1034 i = lpfc_sli_abort_iocb(phba,
1035 &phba->sli.ring[phba->sli.fcp_ring], 0, 0, 0,
1036 LPFC_CTX_HOST);
1037
1038 lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
1039 "%d:0715 Bus Reset I/O flush failure: cnt x%x left x%x\n", 1075 "%d:0715 Bus Reset I/O flush failure: cnt x%x left x%x\n",
1040 phba->brd_no, cnt, i); 1076 phba->brd_no, cnt, i);
1041 }
1042
1043 if (cnt == 0)
1044 ret = SUCCESS;
1045 else
1046 ret = FAILED; 1077 ret = FAILED;
1078 }
1047 1079
1048 lpfc_release_scsi_buf(phba, lpfc_cmd);
1049 lpfc_printf_log(phba, 1080 lpfc_printf_log(phba,
1050 KERN_ERR, 1081 KERN_ERR,
1051 LOG_FCP, 1082 LOG_FCP,
@@ -1053,6 +1084,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
1053 phba->brd_no, ret); 1084 phba->brd_no, ret);
1054out: 1085out:
1055 spin_unlock_irq(shost->host_lock); 1086 spin_unlock_irq(shost->host_lock);
1087 lpfc_unblock_requests(phba);
1056 return ret; 1088 return ret;
1057} 1089}
1058 1090