diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 4e46045dea6d..6483c62730b3 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -130,7 +130,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) | |||
130 | 130 | ||
131 | vports = lpfc_create_vport_work_array(phba); | 131 | vports = lpfc_create_vport_work_array(phba); |
132 | if (vports != NULL) | 132 | if (vports != NULL) |
133 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 133 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
134 | shost = lpfc_shost_from_vport(vports[i]); | 134 | shost = lpfc_shost_from_vport(vports[i]); |
135 | shost_for_each_device(sdev, shost) { | 135 | shost_for_each_device(sdev, shost) { |
136 | new_queue_depth = | 136 | new_queue_depth = |
@@ -151,7 +151,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) | |||
151 | new_queue_depth); | 151 | new_queue_depth); |
152 | } | 152 | } |
153 | } | 153 | } |
154 | lpfc_destroy_vport_work_array(vports); | 154 | lpfc_destroy_vport_work_array(phba, vports); |
155 | atomic_set(&phba->num_rsrc_err, 0); | 155 | atomic_set(&phba->num_rsrc_err, 0); |
156 | atomic_set(&phba->num_cmd_success, 0); | 156 | atomic_set(&phba->num_cmd_success, 0); |
157 | } | 157 | } |
@@ -166,7 +166,7 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) | |||
166 | 166 | ||
167 | vports = lpfc_create_vport_work_array(phba); | 167 | vports = lpfc_create_vport_work_array(phba); |
168 | if (vports != NULL) | 168 | if (vports != NULL) |
169 | for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { | 169 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
170 | shost = lpfc_shost_from_vport(vports[i]); | 170 | shost = lpfc_shost_from_vport(vports[i]); |
171 | shost_for_each_device(sdev, shost) { | 171 | shost_for_each_device(sdev, shost) { |
172 | if (sdev->ordered_tags) | 172 | if (sdev->ordered_tags) |
@@ -179,7 +179,7 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) | |||
179 | sdev->queue_depth+1); | 179 | sdev->queue_depth+1); |
180 | } | 180 | } |
181 | } | 181 | } |
182 | lpfc_destroy_vport_work_array(vports); | 182 | lpfc_destroy_vport_work_array(phba, vports); |
183 | atomic_set(&phba->num_rsrc_err, 0); | 183 | atomic_set(&phba->num_rsrc_err, 0); |
184 | atomic_set(&phba->num_cmd_success, 0); | 184 | atomic_set(&phba->num_cmd_success, 0); |
185 | } | 185 | } |
@@ -380,7 +380,7 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
380 | (num_bde * sizeof (struct ulp_bde64)); | 380 | (num_bde * sizeof (struct ulp_bde64)); |
381 | iocb_cmd->ulpBdeCount = 1; | 381 | iocb_cmd->ulpBdeCount = 1; |
382 | iocb_cmd->ulpLe = 1; | 382 | iocb_cmd->ulpLe = 1; |
383 | fcp_cmnd->fcpDl = be32_to_cpu(scsi_bufflen(scsi_cmnd)); | 383 | fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); |
384 | return 0; | 384 | return 0; |
385 | } | 385 | } |
386 | 386 | ||
@@ -542,6 +542,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
542 | int result; | 542 | int result; |
543 | struct scsi_device *sdev, *tmp_sdev; | 543 | struct scsi_device *sdev, *tmp_sdev; |
544 | int depth = 0; | 544 | int depth = 0; |
545 | unsigned long flags; | ||
545 | 546 | ||
546 | lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; | 547 | lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; |
547 | lpfc_cmd->status = pIocbOut->iocb.ulpStatus; | 548 | lpfc_cmd->status = pIocbOut->iocb.ulpStatus; |
@@ -608,6 +609,15 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
608 | cmd->scsi_done(cmd); | 609 | cmd->scsi_done(cmd); |
609 | 610 | ||
610 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 611 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
612 | /* | ||
613 | * If there is a thread waiting for command completion | ||
614 | * wake up the thread. | ||
615 | */ | ||
616 | spin_lock_irqsave(sdev->host->host_lock, flags); | ||
617 | lpfc_cmd->pCmd = NULL; | ||
618 | if (lpfc_cmd->waitq) | ||
619 | wake_up(lpfc_cmd->waitq); | ||
620 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | ||
611 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 621 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
612 | return; | 622 | return; |
613 | } | 623 | } |
@@ -669,6 +679,16 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
669 | } | 679 | } |
670 | } | 680 | } |
671 | 681 | ||
682 | /* | ||
683 | * If there is a thread waiting for command completion | ||
684 | * wake up the thread. | ||
685 | */ | ||
686 | spin_lock_irqsave(sdev->host->host_lock, flags); | ||
687 | lpfc_cmd->pCmd = NULL; | ||
688 | if (lpfc_cmd->waitq) | ||
689 | wake_up(lpfc_cmd->waitq); | ||
690 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | ||
691 | |||
672 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 692 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
673 | } | 693 | } |
674 | 694 | ||
@@ -743,6 +763,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
743 | piocbq->iocb.ulpContext = pnode->nlp_rpi; | 763 | piocbq->iocb.ulpContext = pnode->nlp_rpi; |
744 | if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE) | 764 | if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE) |
745 | piocbq->iocb.ulpFCP2Rcvy = 1; | 765 | piocbq->iocb.ulpFCP2Rcvy = 1; |
766 | else | ||
767 | piocbq->iocb.ulpFCP2Rcvy = 0; | ||
746 | 768 | ||
747 | piocbq->iocb.ulpClass = (pnode->nlp_fcp_info & 0x0f); | 769 | piocbq->iocb.ulpClass = (pnode->nlp_fcp_info & 0x0f); |
748 | piocbq->context1 = lpfc_cmd; | 770 | piocbq->context1 = lpfc_cmd; |
@@ -1018,8 +1040,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
1018 | struct lpfc_iocbq *abtsiocb; | 1040 | struct lpfc_iocbq *abtsiocb; |
1019 | struct lpfc_scsi_buf *lpfc_cmd; | 1041 | struct lpfc_scsi_buf *lpfc_cmd; |
1020 | IOCB_t *cmd, *icmd; | 1042 | IOCB_t *cmd, *icmd; |
1021 | unsigned int loop_count = 0; | ||
1022 | int ret = SUCCESS; | 1043 | int ret = SUCCESS; |
1044 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); | ||
1023 | 1045 | ||
1024 | lpfc_block_error_handler(cmnd); | 1046 | lpfc_block_error_handler(cmnd); |
1025 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; | 1047 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
@@ -1074,17 +1096,15 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
1074 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) | 1096 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) |
1075 | lpfc_sli_poll_fcp_ring (phba); | 1097 | lpfc_sli_poll_fcp_ring (phba); |
1076 | 1098 | ||
1099 | lpfc_cmd->waitq = &waitq; | ||
1077 | /* Wait for abort to complete */ | 1100 | /* Wait for abort to complete */ |
1078 | while (lpfc_cmd->pCmd == cmnd) | 1101 | wait_event_timeout(waitq, |
1079 | { | 1102 | (lpfc_cmd->pCmd != cmnd), |
1080 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) | 1103 | (2*vport->cfg_devloss_tmo*HZ)); |
1081 | lpfc_sli_poll_fcp_ring (phba); | ||
1082 | 1104 | ||
1083 | schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ); | 1105 | spin_lock_irq(shost->host_lock); |
1084 | if (++loop_count | 1106 | lpfc_cmd->waitq = NULL; |
1085 | > (2 * vport->cfg_devloss_tmo)/LPFC_ABORT_WAIT) | 1107 | spin_unlock_irq(shost->host_lock); |
1086 | break; | ||
1087 | } | ||
1088 | 1108 | ||
1089 | if (lpfc_cmd->pCmd == cmnd) { | 1109 | if (lpfc_cmd->pCmd == cmnd) { |
1090 | ret = FAILED; | 1110 | ret = FAILED; |
@@ -1438,7 +1458,7 @@ struct scsi_host_template lpfc_template = { | |||
1438 | .slave_destroy = lpfc_slave_destroy, | 1458 | .slave_destroy = lpfc_slave_destroy, |
1439 | .scan_finished = lpfc_scan_finished, | 1459 | .scan_finished = lpfc_scan_finished, |
1440 | .this_id = -1, | 1460 | .this_id = -1, |
1441 | .sg_tablesize = LPFC_SG_SEG_CNT, | 1461 | .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, |
1442 | .use_sg_chaining = ENABLE_SG_CHAINING, | 1462 | .use_sg_chaining = ENABLE_SG_CHAINING, |
1443 | .cmd_per_lun = LPFC_CMD_PER_LUN, | 1463 | .cmd_per_lun = LPFC_CMD_PER_LUN, |
1444 | .use_clustering = ENABLE_CLUSTERING, | 1464 | .use_clustering = ENABLE_CLUSTERING, |
@@ -1459,7 +1479,7 @@ struct scsi_host_template lpfc_vport_template = { | |||
1459 | .slave_destroy = lpfc_slave_destroy, | 1479 | .slave_destroy = lpfc_slave_destroy, |
1460 | .scan_finished = lpfc_scan_finished, | 1480 | .scan_finished = lpfc_scan_finished, |
1461 | .this_id = -1, | 1481 | .this_id = -1, |
1462 | .sg_tablesize = LPFC_SG_SEG_CNT, | 1482 | .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, |
1463 | .cmd_per_lun = LPFC_CMD_PER_LUN, | 1483 | .cmd_per_lun = LPFC_CMD_PER_LUN, |
1464 | .use_clustering = ENABLE_CLUSTERING, | 1484 | .use_clustering = ENABLE_CLUSTERING, |
1465 | .use_sg_chaining = ENABLE_SG_CHAINING, | 1485 | .use_sg_chaining = ENABLE_SG_CHAINING, |