diff options
author | James Smart <James.Smart@Emulex.Com> | 2006-05-01 21:50:40 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-05-03 13:12:39 -0400 |
commit | 0b18ac42aa036c7fa217f178aa6a02c66e19e0a1 (patch) | |
tree | e0f63327348e57975d2f4e7ce623c2c1d28b71f7 /drivers/scsi/lpfc/lpfc_scsi.c | |
parent | 6e1cad02763edec83dba8559d4be8d518a6562a5 (diff) |
[SCSI] lpfc 8.1.6 : Fix Data Corruption in Bus Reset Path
This patch updates the lpfc driver to revision 8.1.6, which includes
the following changes:
- Fix data corruption in SCSI BUS reset path, due to reusing
the same request structure for each target.
- Change version number to 8.1.6
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 68 |
1 files changed, 19 insertions, 49 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index f93799873721..7dc4c2e6bed2 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -629,8 +629,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
629 | struct lpfc_iocbq *piocbq; | 629 | struct lpfc_iocbq *piocbq; |
630 | IOCB_t *piocb; | 630 | IOCB_t *piocb; |
631 | struct fcp_cmnd *fcp_cmnd; | 631 | struct fcp_cmnd *fcp_cmnd; |
632 | struct scsi_device *scsi_dev = lpfc_cmd->pCmd->device; | 632 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; |
633 | struct lpfc_rport_data *rdata = scsi_dev->hostdata; | ||
634 | struct lpfc_nodelist *ndlp = rdata->pnode; | 633 | struct lpfc_nodelist *ndlp = rdata->pnode; |
635 | 634 | ||
636 | if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { | 635 | if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { |
@@ -665,56 +664,18 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
665 | piocb->ulpTimeout = lpfc_cmd->timeout; | 664 | piocb->ulpTimeout = lpfc_cmd->timeout; |
666 | } | 665 | } |
667 | 666 | ||
668 | lpfc_cmd->rdata = rdata; | ||
669 | |||
670 | switch (task_mgmt_cmd) { | ||
671 | case FCP_LUN_RESET: | ||
672 | /* Issue LUN Reset to TGT <num> LUN <num> */ | ||
673 | lpfc_printf_log(phba, | ||
674 | KERN_INFO, | ||
675 | LOG_FCP, | ||
676 | "%d:0703 Issue LUN Reset to TGT %d LUN %d " | ||
677 | "Data: x%x x%x\n", | ||
678 | phba->brd_no, | ||
679 | scsi_dev->id, scsi_dev->lun, | ||
680 | ndlp->nlp_rpi, ndlp->nlp_flag); | ||
681 | |||
682 | break; | ||
683 | case FCP_ABORT_TASK_SET: | ||
684 | /* Issue Abort Task Set to TGT <num> LUN <num> */ | ||
685 | lpfc_printf_log(phba, | ||
686 | KERN_INFO, | ||
687 | LOG_FCP, | ||
688 | "%d:0701 Issue Abort Task Set to TGT %d LUN %d " | ||
689 | "Data: x%x x%x\n", | ||
690 | phba->brd_no, | ||
691 | scsi_dev->id, scsi_dev->lun, | ||
692 | ndlp->nlp_rpi, ndlp->nlp_flag); | ||
693 | |||
694 | break; | ||
695 | case FCP_TARGET_RESET: | ||
696 | /* Issue Target Reset to TGT <num> */ | ||
697 | lpfc_printf_log(phba, | ||
698 | KERN_INFO, | ||
699 | LOG_FCP, | ||
700 | "%d:0702 Issue Target Reset to TGT %d " | ||
701 | "Data: x%x x%x\n", | ||
702 | phba->brd_no, | ||
703 | scsi_dev->id, ndlp->nlp_rpi, | ||
704 | ndlp->nlp_flag); | ||
705 | break; | ||
706 | } | ||
707 | |||
708 | return (1); | 667 | return (1); |
709 | } | 668 | } |
710 | 669 | ||
711 | static int | 670 | static int |
712 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) | 671 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, |
672 | unsigned tgt_id, struct lpfc_rport_data *rdata) | ||
713 | { | 673 | { |
714 | struct lpfc_iocbq *iocbq; | 674 | struct lpfc_iocbq *iocbq; |
715 | struct lpfc_iocbq *iocbqrsp; | 675 | struct lpfc_iocbq *iocbqrsp; |
716 | int ret; | 676 | int ret; |
717 | 677 | ||
678 | lpfc_cmd->rdata = rdata; | ||
718 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); | 679 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); |
719 | if (!ret) | 680 | if (!ret) |
720 | return FAILED; | 681 | return FAILED; |
@@ -726,6 +687,13 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba) | |||
726 | if (!iocbqrsp) | 687 | if (!iocbqrsp) |
727 | return FAILED; | 688 | return FAILED; |
728 | 689 | ||
690 | /* Issue Target Reset to TGT <num> */ | ||
691 | lpfc_printf_log(phba, KERN_INFO, LOG_FCP, | ||
692 | "%d:0702 Issue Target Reset to TGT %d " | ||
693 | "Data: x%x x%x\n", | ||
694 | phba->brd_no, tgt_id, rdata->pnode->nlp_rpi, | ||
695 | rdata->pnode->nlp_flag); | ||
696 | |||
729 | ret = lpfc_sli_issue_iocb_wait(phba, | 697 | ret = lpfc_sli_issue_iocb_wait(phba, |
730 | &phba->sli.ring[phba->sli.fcp_ring], | 698 | &phba->sli.ring[phba->sli.fcp_ring], |
731 | iocbq, iocbqrsp, lpfc_cmd->timeout); | 699 | iocbq, iocbqrsp, lpfc_cmd->timeout); |
@@ -1021,6 +989,7 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
1021 | lpfc_cmd->pCmd = cmnd; | 989 | lpfc_cmd->pCmd = cmnd; |
1022 | lpfc_cmd->timeout = 60; | 990 | lpfc_cmd->timeout = 60; |
1023 | lpfc_cmd->scsi_hba = phba; | 991 | lpfc_cmd->scsi_hba = phba; |
992 | lpfc_cmd->rdata = rdata; | ||
1024 | 993 | ||
1025 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET); | 994 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET); |
1026 | if (!ret) | 995 | if (!ret) |
@@ -1033,6 +1002,11 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
1033 | if (iocbqrsp == NULL) | 1002 | if (iocbqrsp == NULL) |
1034 | goto out_free_scsi_buf; | 1003 | goto out_free_scsi_buf; |
1035 | 1004 | ||
1005 | lpfc_printf_log(phba, KERN_INFO, LOG_FCP, | ||
1006 | "%d:0703 Issue LUN Reset to TGT %d LUN %d " | ||
1007 | "Data: x%x x%x\n", phba->brd_no, cmnd->device->id, | ||
1008 | cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); | ||
1009 | |||
1036 | ret = lpfc_sli_issue_iocb_wait(phba, | 1010 | ret = lpfc_sli_issue_iocb_wait(phba, |
1037 | &phba->sli.ring[phba->sli.fcp_ring], | 1011 | &phba->sli.ring[phba->sli.fcp_ring], |
1038 | iocbq, iocbqrsp, lpfc_cmd->timeout); | 1012 | iocbq, iocbqrsp, lpfc_cmd->timeout); |
@@ -1104,7 +1078,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1104 | int match; | 1078 | int match; |
1105 | int ret = FAILED, i, err_count = 0; | 1079 | int ret = FAILED, i, err_count = 0; |
1106 | int cnt, loopcnt; | 1080 | int cnt, loopcnt; |
1107 | unsigned int midlayer_id = 0; | ||
1108 | struct lpfc_scsi_buf * lpfc_cmd; | 1081 | struct lpfc_scsi_buf * lpfc_cmd; |
1109 | 1082 | ||
1110 | lpfc_block_requests(phba); | 1083 | lpfc_block_requests(phba); |
@@ -1124,7 +1097,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1124 | * targets known to the driver. Should any target reset | 1097 | * targets known to the driver. Should any target reset |
1125 | * fail, this routine returns failure to the midlayer. | 1098 | * fail, this routine returns failure to the midlayer. |
1126 | */ | 1099 | */ |
1127 | midlayer_id = cmnd->device->id; | ||
1128 | for (i = 0; i < MAX_FCP_TARGET; i++) { | 1100 | for (i = 0; i < MAX_FCP_TARGET; i++) { |
1129 | /* Search the mapped list for this target ID */ | 1101 | /* Search the mapped list for this target ID */ |
1130 | match = 0; | 1102 | match = 0; |
@@ -1137,9 +1109,8 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1137 | if (!match) | 1109 | if (!match) |
1138 | continue; | 1110 | continue; |
1139 | 1111 | ||
1140 | lpfc_cmd->pCmd->device->id = i; | 1112 | ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, |
1141 | lpfc_cmd->pCmd->device->hostdata = ndlp->rport->dd_data; | 1113 | i, ndlp->rport->dd_data); |
1142 | ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba); | ||
1143 | if (ret != SUCCESS) { | 1114 | if (ret != SUCCESS) { |
1144 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1115 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
1145 | "%d:0713 Bus Reset on target %d failed\n", | 1116 | "%d:0713 Bus Reset on target %d failed\n", |
@@ -1158,7 +1129,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1158 | * the targets. Unfortunately, some targets do not abide by | 1129 | * the targets. Unfortunately, some targets do not abide by |
1159 | * this forcing the driver to double check. | 1130 | * this forcing the driver to double check. |
1160 | */ | 1131 | */ |
1161 | cmnd->device->id = midlayer_id; | ||
1162 | cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], | 1132 | cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], |
1163 | 0, 0, LPFC_CTX_HOST); | 1133 | 0, 0, LPFC_CTX_HOST); |
1164 | if (cnt) | 1134 | if (cnt) |