diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 83 |
1 files changed, 17 insertions, 66 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index b5ad1871d34b..c55ab1a630e5 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -403,14 +403,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
403 | break; | 403 | break; |
404 | } | 404 | } |
405 | 405 | ||
406 | if (pnode) { | 406 | if ((pnode == NULL ) |
407 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) | 407 | || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) |
408 | cmd->result = ScsiResult(DID_BUS_BUSY, | 408 | cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY); |
409 | SAM_STAT_BUSY); | ||
410 | } | ||
411 | else { | ||
412 | cmd->result = ScsiResult(DID_NO_CONNECT, 0); | ||
413 | } | ||
414 | } else { | 409 | } else { |
415 | cmd->result = ScsiResult(DID_OK, 0); | 410 | cmd->result = ScsiResult(DID_OK, 0); |
416 | } | 411 | } |
@@ -539,7 +534,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
539 | struct lpfc_rport_data *rdata = scsi_dev->hostdata; | 534 | struct lpfc_rport_data *rdata = scsi_dev->hostdata; |
540 | struct lpfc_nodelist *ndlp = rdata->pnode; | 535 | struct lpfc_nodelist *ndlp = rdata->pnode; |
541 | 536 | ||
542 | if ((ndlp == 0) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { | 537 | if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { |
543 | return 0; | 538 | return 0; |
544 | } | 539 | } |
545 | 540 | ||
@@ -727,39 +722,23 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
727 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; | 722 | struct lpfc_rport_data *rdata = cmnd->device->hostdata; |
728 | struct lpfc_nodelist *ndlp = rdata->pnode; | 723 | struct lpfc_nodelist *ndlp = rdata->pnode; |
729 | struct lpfc_scsi_buf *lpfc_cmd = NULL; | 724 | struct lpfc_scsi_buf *lpfc_cmd = NULL; |
725 | struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); | ||
730 | struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; | 726 | struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; |
731 | int err = 0; | 727 | int err; |
732 | 728 | ||
733 | /* | 729 | err = fc_remote_port_chkready(rport); |
734 | * The target pointer is guaranteed not to be NULL because the driver | 730 | if (err) { |
735 | * only clears the device->hostdata field in lpfc_slave_destroy. This | 731 | cmnd->result = err; |
736 | * approach guarantees no further IO calls on this target. | ||
737 | */ | ||
738 | if (!ndlp) { | ||
739 | cmnd->result = ScsiResult(DID_NO_CONNECT, 0); | ||
740 | goto out_fail_command; | 732 | goto out_fail_command; |
741 | } | 733 | } |
742 | 734 | ||
743 | /* | 735 | /* |
744 | * A Fibre Channel target is present and functioning only when the node | 736 | * Catch race where our node has transitioned, but the |
745 | * state is MAPPED. Any other state is a failure. | 737 | * transport is still transitioning. |
746 | */ | 738 | */ |
747 | if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) { | 739 | if (!ndlp) { |
748 | if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) || | 740 | cmnd->result = ScsiResult(DID_BUS_BUSY, 0); |
749 | (ndlp->nlp_state == NLP_STE_UNUSED_NODE)) { | 741 | goto out_fail_command; |
750 | cmnd->result = ScsiResult(DID_NO_CONNECT, 0); | ||
751 | goto out_fail_command; | ||
752 | } | ||
753 | else if (ndlp->nlp_state == NLP_STE_NPR_NODE) { | ||
754 | cmnd->result = ScsiResult(DID_BUS_BUSY, 0); | ||
755 | goto out_fail_command; | ||
756 | } | ||
757 | /* | ||
758 | * The device is most likely recovered and the driver | ||
759 | * needs a bit more time to finish. Ask the midlayer | ||
760 | * to retry. | ||
761 | */ | ||
762 | goto out_host_busy; | ||
763 | } | 742 | } |
764 | 743 | ||
765 | list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); | 744 | list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); |
@@ -1163,44 +1142,16 @@ static int | |||
1163 | lpfc_slave_alloc(struct scsi_device *sdev) | 1142 | lpfc_slave_alloc(struct scsi_device *sdev) |
1164 | { | 1143 | { |
1165 | struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0]; | 1144 | struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0]; |
1166 | struct lpfc_nodelist *ndlp = NULL; | ||
1167 | int match = 0; | ||
1168 | struct lpfc_scsi_buf *scsi_buf = NULL; | 1145 | struct lpfc_scsi_buf *scsi_buf = NULL; |
1146 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); | ||
1169 | uint32_t total = 0, i; | 1147 | uint32_t total = 0, i; |
1170 | uint32_t num_to_alloc = 0; | 1148 | uint32_t num_to_alloc = 0; |
1171 | unsigned long flags; | 1149 | unsigned long flags; |
1172 | struct list_head *listp; | ||
1173 | struct list_head *node_list[6]; | ||
1174 | |||
1175 | /* | ||
1176 | * Store the target pointer in the scsi_device hostdata pointer provided | ||
1177 | * the driver has already discovered the target id. | ||
1178 | */ | ||
1179 | |||
1180 | /* Search the nlp lists other than unmap_list for this target ID */ | ||
1181 | node_list[0] = &phba->fc_npr_list; | ||
1182 | node_list[1] = &phba->fc_nlpmap_list; | ||
1183 | node_list[2] = &phba->fc_prli_list; | ||
1184 | node_list[3] = &phba->fc_reglogin_list; | ||
1185 | node_list[4] = &phba->fc_adisc_list; | ||
1186 | node_list[5] = &phba->fc_plogi_list; | ||
1187 | |||
1188 | for (i = 0; i < 6 && !match; i++) { | ||
1189 | listp = node_list[i]; | ||
1190 | if (list_empty(listp)) | ||
1191 | continue; | ||
1192 | list_for_each_entry(ndlp, listp, nlp_listp) { | ||
1193 | if ((sdev->id == ndlp->nlp_sid) && ndlp->rport) { | ||
1194 | match = 1; | ||
1195 | break; | ||
1196 | } | ||
1197 | } | ||
1198 | } | ||
1199 | 1150 | ||
1200 | if (!match) | 1151 | if (!rport || fc_remote_port_chkready(rport)) |
1201 | return -ENXIO; | 1152 | return -ENXIO; |
1202 | 1153 | ||
1203 | sdev->hostdata = ndlp->rport->dd_data; | 1154 | sdev->hostdata = rport->dd_data; |
1204 | 1155 | ||
1205 | /* | 1156 | /* |
1206 | * Populate the cmds_per_lun count scsi_bufs into this host's globally | 1157 | * Populate the cmds_per_lun count scsi_bufs into this host's globally |