diff options
author | James Smart <James.Smart@Emulex.Com> | 2006-07-06 15:50:16 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-07-09 11:43:43 -0400 |
commit | 420b630d6e9ff41dc3e2a2a2808b67907951e094 (patch) | |
tree | ea841e7d646a7cfd37358321e922f63e48d70ed7 /drivers/scsi/lpfc | |
parent | bcf4dbfaf38502d3919e0601c06afac7d5e42685 (diff) |
[SCSI] lpfc 8.1.7: Fix panic in lpfc_sli_validate_fcp_iocb
Fix panic in lpfc_sli_validate_fcp_iocb due to access of scsi_cmnd after
returning it to the midlayer
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index d45616e70c67..a760a44173df 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -616,6 +616,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd, | |||
616 | static int | 616 | static int |
617 | lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | 617 | lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, |
618 | struct lpfc_scsi_buf *lpfc_cmd, | 618 | struct lpfc_scsi_buf *lpfc_cmd, |
619 | unsigned int lun, | ||
619 | uint8_t task_mgmt_cmd) | 620 | uint8_t task_mgmt_cmd) |
620 | { | 621 | { |
621 | struct lpfc_sli *psli; | 622 | struct lpfc_sli *psli; |
@@ -634,8 +635,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
634 | piocb = &piocbq->iocb; | 635 | piocb = &piocbq->iocb; |
635 | 636 | ||
636 | fcp_cmnd = lpfc_cmd->fcp_cmnd; | 637 | fcp_cmnd = lpfc_cmd->fcp_cmnd; |
637 | int_to_scsilun(lpfc_cmd->pCmd->device->lun, | 638 | int_to_scsilun(lun, &lpfc_cmd->fcp_cmnd->fcp_lun); |
638 | &lpfc_cmd->fcp_cmnd->fcp_lun); | ||
639 | fcp_cmnd->fcpCntl2 = task_mgmt_cmd; | 639 | fcp_cmnd->fcpCntl2 = task_mgmt_cmd; |
640 | 640 | ||
641 | piocb->ulpCommand = CMD_FCP_ICMND64_CR; | 641 | piocb->ulpCommand = CMD_FCP_ICMND64_CR; |
@@ -662,14 +662,16 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
662 | 662 | ||
663 | static int | 663 | static int |
664 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, | 664 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, |
665 | unsigned tgt_id, struct lpfc_rport_data *rdata) | 665 | unsigned tgt_id, unsigned int lun, |
666 | struct lpfc_rport_data *rdata) | ||
666 | { | 667 | { |
667 | struct lpfc_iocbq *iocbq; | 668 | struct lpfc_iocbq *iocbq; |
668 | struct lpfc_iocbq *iocbqrsp; | 669 | struct lpfc_iocbq *iocbqrsp; |
669 | int ret; | 670 | int ret; |
670 | 671 | ||
671 | lpfc_cmd->rdata = rdata; | 672 | lpfc_cmd->rdata = rdata; |
672 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); | 673 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, |
674 | FCP_TARGET_RESET); | ||
673 | if (!ret) | 675 | if (!ret) |
674 | return FAILED; | 676 | return FAILED; |
675 | 677 | ||
@@ -977,12 +979,12 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
977 | if (lpfc_cmd == NULL) | 979 | if (lpfc_cmd == NULL) |
978 | goto out; | 980 | goto out; |
979 | 981 | ||
980 | lpfc_cmd->pCmd = cmnd; | ||
981 | lpfc_cmd->timeout = 60; | 982 | lpfc_cmd->timeout = 60; |
982 | lpfc_cmd->scsi_hba = phba; | 983 | lpfc_cmd->scsi_hba = phba; |
983 | lpfc_cmd->rdata = rdata; | 984 | lpfc_cmd->rdata = rdata; |
984 | 985 | ||
985 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET); | 986 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun, |
987 | FCP_LUN_RESET); | ||
986 | if (!ret) | 988 | if (!ret) |
987 | goto out_free_scsi_buf; | 989 | goto out_free_scsi_buf; |
988 | 990 | ||
@@ -1009,7 +1011,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
1009 | cmd_status = iocbqrsp->iocb.ulpStatus; | 1011 | cmd_status = iocbqrsp->iocb.ulpStatus; |
1010 | 1012 | ||
1011 | lpfc_sli_release_iocbq(phba, iocbqrsp); | 1013 | lpfc_sli_release_iocbq(phba, iocbqrsp); |
1012 | lpfc_release_scsi_buf(phba, lpfc_cmd); | ||
1013 | 1014 | ||
1014 | /* | 1015 | /* |
1015 | * All outstanding txcmplq I/Os should have been aborted by the device. | 1016 | * All outstanding txcmplq I/Os should have been aborted by the device. |
@@ -1048,6 +1049,8 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
1048 | } | 1049 | } |
1049 | 1050 | ||
1050 | out_free_scsi_buf: | 1051 | out_free_scsi_buf: |
1052 | lpfc_release_scsi_buf(phba, lpfc_cmd); | ||
1053 | |||
1051 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1054 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
1052 | "%d:0713 SCSI layer issued LUN reset (%d, %d) " | 1055 | "%d:0713 SCSI layer issued LUN reset (%d, %d) " |
1053 | "Data: x%x x%x x%x\n", | 1056 | "Data: x%x x%x x%x\n", |
@@ -1078,7 +1081,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1078 | 1081 | ||
1079 | /* The lpfc_cmd storage is reused. Set all loop invariants. */ | 1082 | /* The lpfc_cmd storage is reused. Set all loop invariants. */ |
1080 | lpfc_cmd->timeout = 60; | 1083 | lpfc_cmd->timeout = 60; |
1081 | lpfc_cmd->pCmd = cmnd; | ||
1082 | lpfc_cmd->scsi_hba = phba; | 1084 | lpfc_cmd->scsi_hba = phba; |
1083 | 1085 | ||
1084 | /* | 1086 | /* |
@@ -1098,8 +1100,8 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1098 | if (!match) | 1100 | if (!match) |
1099 | continue; | 1101 | continue; |
1100 | 1102 | ||
1101 | ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, | 1103 | ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, i, cmnd->device->lun, |
1102 | i, ndlp->rport->dd_data); | 1104 | ndlp->rport->dd_data); |
1103 | if (ret != SUCCESS) { | 1105 | if (ret != SUCCESS) { |
1104 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1106 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
1105 | "%d:0713 Bus Reset on target %d failed\n", | 1107 | "%d:0713 Bus Reset on target %d failed\n", |