diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 85 |
1 files changed, 57 insertions, 28 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index aea1ee472f3d..a8816a8738f8 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/delay.h> | ||
24 | 25 | ||
25 | #include <scsi/scsi.h> | 26 | #include <scsi/scsi.h> |
26 | #include <scsi/scsi_device.h> | 27 | #include <scsi/scsi_device.h> |
@@ -153,22 +154,6 @@ static void | |||
153 | lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) | 154 | lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) |
154 | { | 155 | { |
155 | unsigned long iflag = 0; | 156 | unsigned long iflag = 0; |
156 | /* | ||
157 | * There are only two special cases to consider. (1) the scsi command | ||
158 | * requested scatter-gather usage or (2) the scsi command allocated | ||
159 | * a request buffer, but did not request use_sg. There is a third | ||
160 | * case, but it does not require resource deallocation. | ||
161 | */ | ||
162 | if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) { | ||
163 | dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer, | ||
164 | psb->seg_cnt, psb->pCmd->sc_data_direction); | ||
165 | } else { | ||
166 | if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) { | ||
167 | dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys, | ||
168 | psb->pCmd->request_bufflen, | ||
169 | psb->pCmd->sc_data_direction); | ||
170 | } | ||
171 | } | ||
172 | 157 | ||
173 | spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); | 158 | spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); |
174 | psb->pCmd = NULL; | 159 | psb->pCmd = NULL; |
@@ -282,6 +267,27 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd) | |||
282 | } | 267 | } |
283 | 268 | ||
284 | static void | 269 | static void |
270 | lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) | ||
271 | { | ||
272 | /* | ||
273 | * There are only two special cases to consider. (1) the scsi command | ||
274 | * requested scatter-gather usage or (2) the scsi command allocated | ||
275 | * a request buffer, but did not request use_sg. There is a third | ||
276 | * case, but it does not require resource deallocation. | ||
277 | */ | ||
278 | if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) { | ||
279 | dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer, | ||
280 | psb->seg_cnt, psb->pCmd->sc_data_direction); | ||
281 | } else { | ||
282 | if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) { | ||
283 | dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys, | ||
284 | psb->pCmd->request_bufflen, | ||
285 | psb->pCmd->sc_data_direction); | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | |||
290 | static void | ||
285 | lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) | 291 | lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) |
286 | { | 292 | { |
287 | struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; | 293 | struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; |
@@ -454,6 +460,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
454 | cmd->scsi_done(cmd); | 460 | cmd->scsi_done(cmd); |
455 | 461 | ||
456 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 462 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
463 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | ||
457 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 464 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
458 | return; | 465 | return; |
459 | } | 466 | } |
@@ -511,6 +518,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
511 | } | 518 | } |
512 | } | 519 | } |
513 | 520 | ||
521 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | ||
514 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 522 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
515 | } | 523 | } |
516 | 524 | ||
@@ -609,6 +617,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd, | |||
609 | static int | 617 | static int |
610 | lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | 618 | lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, |
611 | struct lpfc_scsi_buf *lpfc_cmd, | 619 | struct lpfc_scsi_buf *lpfc_cmd, |
620 | unsigned int lun, | ||
612 | uint8_t task_mgmt_cmd) | 621 | uint8_t task_mgmt_cmd) |
613 | { | 622 | { |
614 | struct lpfc_sli *psli; | 623 | struct lpfc_sli *psli; |
@@ -627,8 +636,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
627 | piocb = &piocbq->iocb; | 636 | piocb = &piocbq->iocb; |
628 | 637 | ||
629 | fcp_cmnd = lpfc_cmd->fcp_cmnd; | 638 | fcp_cmnd = lpfc_cmd->fcp_cmnd; |
630 | int_to_scsilun(lpfc_cmd->pCmd->device->lun, | 639 | int_to_scsilun(lun, &lpfc_cmd->fcp_cmnd->fcp_lun); |
631 | &lpfc_cmd->fcp_cmnd->fcp_lun); | ||
632 | fcp_cmnd->fcpCntl2 = task_mgmt_cmd; | 640 | fcp_cmnd->fcpCntl2 = task_mgmt_cmd; |
633 | 641 | ||
634 | piocb->ulpCommand = CMD_FCP_ICMND64_CR; | 642 | piocb->ulpCommand = CMD_FCP_ICMND64_CR; |
@@ -655,14 +663,16 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
655 | 663 | ||
656 | static int | 664 | static int |
657 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, | 665 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, |
658 | unsigned tgt_id, struct lpfc_rport_data *rdata) | 666 | unsigned tgt_id, unsigned int lun, |
667 | struct lpfc_rport_data *rdata) | ||
659 | { | 668 | { |
660 | struct lpfc_iocbq *iocbq; | 669 | struct lpfc_iocbq *iocbq; |
661 | struct lpfc_iocbq *iocbqrsp; | 670 | struct lpfc_iocbq *iocbqrsp; |
662 | int ret; | 671 | int ret; |
663 | 672 | ||
664 | lpfc_cmd->rdata = rdata; | 673 | lpfc_cmd->rdata = rdata; |
665 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); | 674 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, |
675 | FCP_TARGET_RESET); | ||
666 | if (!ret) | 676 | if (!ret) |
667 | return FAILED; | 677 | return FAILED; |
668 | 678 | ||
@@ -822,6 +832,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
822 | return 0; | 832 | return 0; |
823 | 833 | ||
824 | out_host_busy_free_buf: | 834 | out_host_busy_free_buf: |
835 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | ||
825 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 836 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
826 | out_host_busy: | 837 | out_host_busy: |
827 | return SCSI_MLQUEUE_HOST_BUSY; | 838 | return SCSI_MLQUEUE_HOST_BUSY; |
@@ -831,6 +842,21 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
831 | return 0; | 842 | return 0; |
832 | } | 843 | } |
833 | 844 | ||
845 | static void | ||
846 | lpfc_block_error_handler(struct scsi_cmnd *cmnd) | ||
847 | { | ||
848 | struct Scsi_Host *shost = cmnd->device->host; | ||
849 | struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); | ||
850 | |||
851 | spin_lock_irq(shost->host_lock); | ||
852 | while (rport->port_state == FC_PORTSTATE_BLOCKED) { | ||
853 | spin_unlock_irq(shost->host_lock); | ||
854 | msleep(1000); | ||
855 | spin_lock_irq(shost->host_lock); | ||
856 | } | ||
857 | spin_unlock_irq(shost->host_lock); | ||
858 | return; | ||
859 | } | ||
834 | 860 | ||
835 | static int | 861 | static int |
836 | lpfc_abort_handler(struct scsi_cmnd *cmnd) | 862 | lpfc_abort_handler(struct scsi_cmnd *cmnd) |
@@ -845,6 +871,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
845 | unsigned int loop_count = 0; | 871 | unsigned int loop_count = 0; |
846 | int ret = SUCCESS; | 872 | int ret = SUCCESS; |
847 | 873 | ||
874 | lpfc_block_error_handler(cmnd); | ||
848 | spin_lock_irq(shost->host_lock); | 875 | spin_lock_irq(shost->host_lock); |
849 | 876 | ||
850 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; | 877 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
@@ -947,6 +974,7 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
947 | int ret = FAILED; | 974 | int ret = FAILED; |
948 | int cnt, loopcnt; | 975 | int cnt, loopcnt; |
949 | 976 | ||
977 | lpfc_block_error_handler(cmnd); | ||
950 | spin_lock_irq(shost->host_lock); | 978 | spin_lock_irq(shost->host_lock); |
951 | /* | 979 | /* |
952 | * If target is not in a MAPPED state, delay the reset until | 980 | * If target is not in a MAPPED state, delay the reset until |
@@ -969,12 +997,12 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
969 | if (lpfc_cmd == NULL) | 997 | if (lpfc_cmd == NULL) |
970 | goto out; | 998 | goto out; |
971 | 999 | ||
972 | lpfc_cmd->pCmd = cmnd; | ||
973 | lpfc_cmd->timeout = 60; | 1000 | lpfc_cmd->timeout = 60; |
974 | lpfc_cmd->scsi_hba = phba; | 1001 | lpfc_cmd->scsi_hba = phba; |
975 | lpfc_cmd->rdata = rdata; | 1002 | lpfc_cmd->rdata = rdata; |
976 | 1003 | ||
977 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET); | 1004 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun, |
1005 | FCP_LUN_RESET); | ||
978 | if (!ret) | 1006 | if (!ret) |
979 | goto out_free_scsi_buf; | 1007 | goto out_free_scsi_buf; |
980 | 1008 | ||
@@ -1001,7 +1029,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
1001 | cmd_status = iocbqrsp->iocb.ulpStatus; | 1029 | cmd_status = iocbqrsp->iocb.ulpStatus; |
1002 | 1030 | ||
1003 | lpfc_sli_release_iocbq(phba, iocbqrsp); | 1031 | lpfc_sli_release_iocbq(phba, iocbqrsp); |
1004 | lpfc_release_scsi_buf(phba, lpfc_cmd); | ||
1005 | 1032 | ||
1006 | /* | 1033 | /* |
1007 | * All outstanding txcmplq I/Os should have been aborted by the device. | 1034 | * All outstanding txcmplq I/Os should have been aborted by the device. |
@@ -1040,6 +1067,8 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
1040 | } | 1067 | } |
1041 | 1068 | ||
1042 | out_free_scsi_buf: | 1069 | out_free_scsi_buf: |
1070 | lpfc_release_scsi_buf(phba, lpfc_cmd); | ||
1071 | |||
1043 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1072 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
1044 | "%d:0713 SCSI layer issued LUN reset (%d, %d) " | 1073 | "%d:0713 SCSI layer issued LUN reset (%d, %d) " |
1045 | "Data: x%x x%x x%x\n", | 1074 | "Data: x%x x%x x%x\n", |
@@ -1062,6 +1091,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1062 | int cnt, loopcnt; | 1091 | int cnt, loopcnt; |
1063 | struct lpfc_scsi_buf * lpfc_cmd; | 1092 | struct lpfc_scsi_buf * lpfc_cmd; |
1064 | 1093 | ||
1094 | lpfc_block_error_handler(cmnd); | ||
1065 | spin_lock_irq(shost->host_lock); | 1095 | spin_lock_irq(shost->host_lock); |
1066 | 1096 | ||
1067 | lpfc_cmd = lpfc_get_scsi_buf(phba); | 1097 | lpfc_cmd = lpfc_get_scsi_buf(phba); |
@@ -1070,7 +1100,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1070 | 1100 | ||
1071 | /* The lpfc_cmd storage is reused. Set all loop invariants. */ | 1101 | /* The lpfc_cmd storage is reused. Set all loop invariants. */ |
1072 | lpfc_cmd->timeout = 60; | 1102 | lpfc_cmd->timeout = 60; |
1073 | lpfc_cmd->pCmd = cmnd; | ||
1074 | lpfc_cmd->scsi_hba = phba; | 1103 | lpfc_cmd->scsi_hba = phba; |
1075 | 1104 | ||
1076 | /* | 1105 | /* |
@@ -1078,7 +1107,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1078 | * targets known to the driver. Should any target reset | 1107 | * targets known to the driver. Should any target reset |
1079 | * fail, this routine returns failure to the midlayer. | 1108 | * fail, this routine returns failure to the midlayer. |
1080 | */ | 1109 | */ |
1081 | for (i = 0; i < MAX_FCP_TARGET; i++) { | 1110 | for (i = 0; i < LPFC_MAX_TARGET; i++) { |
1082 | /* Search the mapped list for this target ID */ | 1111 | /* Search the mapped list for this target ID */ |
1083 | match = 0; | 1112 | match = 0; |
1084 | list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { | 1113 | list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { |
@@ -1090,11 +1119,11 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1090 | if (!match) | 1119 | if (!match) |
1091 | continue; | 1120 | continue; |
1092 | 1121 | ||
1093 | ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, | 1122 | ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, i, cmnd->device->lun, |
1094 | i, ndlp->rport->dd_data); | 1123 | ndlp->rport->dd_data); |
1095 | if (ret != SUCCESS) { | 1124 | if (ret != SUCCESS) { |
1096 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1125 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
1097 | "%d:0713 Bus Reset on target %d failed\n", | 1126 | "%d:0700 Bus Reset on target %d failed\n", |
1098 | phba->brd_no, i); | 1127 | phba->brd_no, i); |
1099 | err_count++; | 1128 | err_count++; |
1100 | } | 1129 | } |