aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c83
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
1163lpfc_slave_alloc(struct scsi_device *sdev) 1142lpfc_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