aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c28
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c19
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c83
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h3
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c26
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c21
-rw-r--r--drivers/scsi/qla2xxx/qla_rscn.c3
-rw-r--r--drivers/scsi/scsi_transport_fc.c446
-rw-r--r--include/scsi/scsi_transport_fc.h31
9 files changed, 384 insertions, 276 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 56052f4510c3..6c846ad373bc 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1028,6 +1028,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
1028 if (ndlp->nlp_type & NLP_FCP_INITIATOR) 1028 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
1029 rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR; 1029 rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
1030 1030
1031 scsi_block_requests(phba->host);
1031 ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids); 1032 ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids);
1032 if (!rport) { 1033 if (!rport) {
1033 dev_printk(KERN_WARNING, &phba->pcidev->dev, 1034 dev_printk(KERN_WARNING, &phba->pcidev->dev,
@@ -1044,6 +1045,23 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
1044 } 1045 }
1045 rdata = rport->dd_data; 1046 rdata = rport->dd_data;
1046 rdata->pnode = ndlp; 1047 rdata->pnode = ndlp;
1048 scsi_unblock_requests(phba->host);
1049
1050 return;
1051}
1052
1053static void
1054lpfc_unregister_remote_port(struct lpfc_hba * phba,
1055 struct lpfc_nodelist * ndlp)
1056{
1057 struct fc_rport *rport = ndlp->rport;
1058 struct lpfc_rport_data *rdata = rport->dd_data;
1059
1060 ndlp->rport = NULL;
1061 rdata->pnode = NULL;
1062 scsi_block_requests(phba->host);
1063 fc_remote_port_delete(rport);
1064 scsi_unblock_requests(phba->host);
1047 1065
1048 return; 1066 return;
1049} 1067}
@@ -1260,7 +1278,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1260 * may have removed the remote port. 1278 * may have removed the remote port.
1261 */ 1279 */
1262 if ((rport_del != none) && nlp->rport) 1280 if ((rport_del != none) && nlp->rport)
1263 fc_remote_port_block(nlp->rport); 1281 lpfc_unregister_remote_port(phba, nlp);
1264 1282
1265 if (rport_add != none) { 1283 if (rport_add != none) {
1266 /* 1284 /*
@@ -1270,8 +1288,6 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1270 */ 1288 */
1271 if (!nlp->rport) 1289 if (!nlp->rport)
1272 lpfc_register_remote_port(phba, nlp); 1290 lpfc_register_remote_port(phba, nlp);
1273 else
1274 fc_remote_port_unblock(nlp->rport);
1275 1291
1276 /* 1292 /*
1277 * if we added to Mapped list, but the remote port 1293 * if we added to Mapped list, but the remote port
@@ -1490,7 +1506,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1490 LPFC_MBOXQ_t *mb; 1506 LPFC_MBOXQ_t *mb;
1491 LPFC_MBOXQ_t *nextmb; 1507 LPFC_MBOXQ_t *nextmb;
1492 struct lpfc_dmabuf *mp; 1508 struct lpfc_dmabuf *mp;
1493 struct fc_rport *rport;
1494 1509
1495 /* Cleanup node for NPort <nlp_DID> */ 1510 /* Cleanup node for NPort <nlp_DID> */
1496 lpfc_printf_log(phba, KERN_INFO, LOG_NODE, 1511 lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
@@ -1507,10 +1522,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1507 * and flush cache's w/o generating flush errors. 1522 * and flush cache's w/o generating flush errors.
1508 */ 1523 */
1509 if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { 1524 if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
1510 rport = ndlp->rport; 1525 lpfc_unregister_remote_port(phba, ndlp);
1511 ndlp->rport = NULL;
1512 fc_remote_port_unblock(rport);
1513 fc_remote_port_delete(rport);
1514 ndlp->nlp_sid = NLP_NO_SID; 1526 ndlp->nlp_sid = NLP_NO_SID;
1515 } 1527 }
1516 1528
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 0856ff7d3b33..25d55f40424f 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -537,12 +537,6 @@ lpfc_handle_eratt(struct lpfc_hba * phba)
537 537
538 lpfc_offline(phba); 538 lpfc_offline(phba);
539 539
540 /*
541 * Restart all traffic to this host. Since the fc_transport
542 * block functions (future) were not called in lpfc_offline,
543 * don't call them here.
544 */
545 scsi_unblock_requests(phba->host);
546 } 540 }
547} 541}
548 542
@@ -1226,12 +1220,6 @@ lpfc_online(struct lpfc_hba * phba)
1226 phba->fc_flag &= ~FC_OFFLINE_MODE; 1220 phba->fc_flag &= ~FC_OFFLINE_MODE;
1227 spin_unlock_irq(phba->host->host_lock); 1221 spin_unlock_irq(phba->host->host_lock);
1228 1222
1229 /*
1230 * Restart all traffic to this host. Since the fc_transport block
1231 * functions (future) were not called in lpfc_offline, don't call them
1232 * here.
1233 */
1234 scsi_unblock_requests(phba->host);
1235 return 0; 1223 return 0;
1236} 1224}
1237 1225
@@ -1249,13 +1237,6 @@ lpfc_offline(struct lpfc_hba * phba)
1249 if (phba->fc_flag & FC_OFFLINE_MODE) 1237 if (phba->fc_flag & FC_OFFLINE_MODE)
1250 return 0; 1238 return 0;
1251 1239
1252 /*
1253 * Don't call the fc_transport block api (future). The device is
1254 * going offline and causing a timer to fire in the midlayer is
1255 * unproductive. Just block all new requests until the driver
1256 * comes back online.
1257 */
1258 scsi_block_requests(phba->host);
1259 psli = &phba->sli; 1240 psli = &phba->sli;
1260 pring = &psli->ring[psli->fcp_ring]; 1241 pring = &psli->ring[psli->fcp_ring];
1261 1242
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
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index fc3234c3625b..7096945ea234 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -21,6 +21,7 @@
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/completion.h> 22#include <linux/completion.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/workqueue.h>
24#include <asm/semaphore.h> 25#include <asm/semaphore.h>
25 26
26#include <scsi/scsi.h> 27#include <scsi/scsi.h>
@@ -1665,6 +1666,8 @@ typedef struct fc_port {
1665 1666
1666 struct fc_rport *rport; 1667 struct fc_rport *rport;
1667 u32 supported_classes; 1668 u32 supported_classes;
1669 struct work_struct rport_add_work;
1670 struct work_struct rport_del_work;
1668} fc_port_t; 1671} fc_port_t;
1669 1672
1670/* 1673/*
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index ce7e712ebe8d..290a6b92616c 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1668,6 +1668,24 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
1668 return (rval); 1668 return (rval);
1669} 1669}
1670 1670
1671static void
1672qla2x00_rport_add(void *data)
1673{
1674 fc_port_t *fcport = data;
1675
1676 qla2x00_reg_remote_port(fcport->ha, fcport);
1677}
1678
1679static void
1680qla2x00_rport_del(void *data)
1681{
1682 fc_port_t *fcport = data;
1683
1684 if (fcport->rport)
1685 fc_remote_port_delete(fcport->rport);
1686 fcport->rport = NULL;
1687}
1688
1671/** 1689/**
1672 * qla2x00_alloc_fcport() - Allocate a generic fcport. 1690 * qla2x00_alloc_fcport() - Allocate a generic fcport.
1673 * @ha: HA context 1691 * @ha: HA context
@@ -1693,6 +1711,8 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
1693 atomic_set(&fcport->state, FCS_UNCONFIGURED); 1711 atomic_set(&fcport->state, FCS_UNCONFIGURED);
1694 fcport->flags = FCF_RLC_SUPPORT; 1712 fcport->flags = FCF_RLC_SUPPORT;
1695 fcport->supported_classes = FC_COS_UNSPECIFIED; 1713 fcport->supported_classes = FC_COS_UNSPECIFIED;
1714 INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport);
1715 INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport);
1696 1716
1697 return (fcport); 1717 return (fcport);
1698} 1718}
@@ -2056,8 +2076,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
2056 struct fc_rport *rport; 2076 struct fc_rport *rport;
2057 2077
2058 if (fcport->rport) { 2078 if (fcport->rport) {
2059 fc_remote_port_unblock(fcport->rport); 2079 fc_remote_port_delete(fcport->rport);
2060 return; 2080 fcport->rport = NULL;
2061 } 2081 }
2062 2082
2063 rport_ids.node_name = wwn_to_u64(fcport->node_name); 2083 rport_ids.node_name = wwn_to_u64(fcport->node_name);
@@ -2071,7 +2091,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
2071 "Unable to allocate fc remote port!\n"); 2091 "Unable to allocate fc remote port!\n");
2072 return; 2092 return;
2073 } 2093 }
2074 rport->dd_data = fcport; 2094 *((fc_port_t **)rport->dd_data) = fcport;
2075 rport->supported_classes = fcport->supported_classes; 2095 rport->supported_classes = fcport->supported_classes;
2076 2096
2077 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; 2097 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index b899282a856e..c58c9d97b041 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -348,11 +348,13 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
348{ 348{
349 scsi_qla_host_t *ha = to_qla_host(cmd->device->host); 349 scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
350 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; 350 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
351 struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
351 srb_t *sp; 352 srb_t *sp;
352 int rval; 353 int rval;
353 354
354 if (!fcport) { 355 rval = fc_remote_port_chkready(rport);
355 cmd->result = DID_NO_CONNECT << 16; 356 if (rval) {
357 cmd->result = rval;
356 goto qc_fail_command; 358 goto qc_fail_command;
357 } 359 }
358 360
@@ -401,11 +403,13 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
401{ 403{
402 scsi_qla_host_t *ha = to_qla_host(cmd->device->host); 404 scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
403 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; 405 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
406 struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
404 srb_t *sp; 407 srb_t *sp;
405 int rval; 408 int rval;
406 409
407 if (!fcport) { 410 rval = fc_remote_port_chkready(rport);
408 cmd->result = DID_NO_CONNECT << 16; 411 if (rval) {
412 cmd->result = rval;
409 goto qc24_fail_command; 413 goto qc24_fail_command;
410 } 414 }
411 415
@@ -1041,10 +1045,10 @@ qla2xxx_slave_alloc(struct scsi_device *sdev)
1041{ 1045{
1042 struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); 1046 struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
1043 1047
1044 if (!rport) 1048 if (!rport || fc_remote_port_chkready(rport))
1045 return -ENXIO; 1049 return -ENXIO;
1046 1050
1047 sdev->hostdata = rport->dd_data; 1051 sdev->hostdata = *(fc_port_t **)rport->dd_data;
1048 1052
1049 return 0; 1053 return 0;
1050} 1054}
@@ -1636,7 +1640,8 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
1636 int do_login) 1640 int do_login)
1637{ 1641{
1638 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) 1642 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
1639 fc_remote_port_block(fcport->rport); 1643 schedule_work(&fcport->rport_del_work);
1644
1640 /* 1645 /*
1641 * We may need to retry the login, so don't change the state of the 1646 * We may need to retry the login, so don't change the state of the
1642 * port but do the retries. 1647 * port but do the retries.
@@ -1697,7 +1702,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha)
1697 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) 1702 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
1698 continue; 1703 continue;
1699 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) 1704 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
1700 fc_remote_port_block(fcport->rport); 1705 schedule_work(&fcport->rport_del_work);
1701 atomic_set(&fcport->state, FCS_DEVICE_LOST); 1706 atomic_set(&fcport->state, FCS_DEVICE_LOST);
1702 } 1707 }
1703} 1708}
diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c
index 3e53f62d640d..2c3342108dd8 100644
--- a/drivers/scsi/qla2xxx/qla_rscn.c
+++ b/drivers/scsi/qla2xxx/qla_rscn.c
@@ -320,8 +320,7 @@ qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat,
320 fcport->flags &= ~FCF_FAILOVER_NEEDED; 320 fcport->flags &= ~FCF_FAILOVER_NEEDED;
321 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX; 321 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
322 atomic_set(&fcport->state, FCS_ONLINE); 322 atomic_set(&fcport->state, FCS_ONLINE);
323 if (fcport->rport) 323 schedule_work(&fcport->rport_add_work);
324 fc_remote_port_unblock(fcport->rport);
325} 324}
326 325
327 326
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 27702097b7fc..ca098fc2a607 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -210,7 +210,7 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names)
210#define FC_MGMTSRVR_PORTID 0x00000a 210#define FC_MGMTSRVR_PORTID 0x00000a
211 211
212 212
213static void fc_timeout_blocked_rport(void *data); 213static void fc_timeout_deleted_rport(void *data);
214static void fc_scsi_scan_rport(void *data); 214static void fc_scsi_scan_rport(void *data);
215static void fc_rport_terminate(struct fc_rport *rport); 215static void fc_rport_terminate(struct fc_rport *rport);
216 216
@@ -384,7 +384,9 @@ show_fc_rport_##field (struct class_device *cdev, char *buf) \
384 struct fc_rport *rport = transport_class_to_rport(cdev); \ 384 struct fc_rport *rport = transport_class_to_rport(cdev); \
385 struct Scsi_Host *shost = rport_to_shost(rport); \ 385 struct Scsi_Host *shost = rport_to_shost(rport); \
386 struct fc_internal *i = to_fc_internal(shost->transportt); \ 386 struct fc_internal *i = to_fc_internal(shost->transportt); \
387 if (i->f->get_rport_##field) \ 387 if ((i->f->get_rport_##field) && \
388 !((rport->port_state == FC_PORTSTATE_BLOCKED) || \
389 (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \
388 i->f->get_rport_##field(rport); \ 390 i->f->get_rport_##field(rport); \
389 return snprintf(buf, sz, format_string, cast rport->field); \ 391 return snprintf(buf, sz, format_string, cast rport->field); \
390} 392}
@@ -398,6 +400,9 @@ store_fc_rport_##field(struct class_device *cdev, const char *buf, \
398 struct fc_rport *rport = transport_class_to_rport(cdev); \ 400 struct fc_rport *rport = transport_class_to_rport(cdev); \
399 struct Scsi_Host *shost = rport_to_shost(rport); \ 401 struct Scsi_Host *shost = rport_to_shost(rport); \
400 struct fc_internal *i = to_fc_internal(shost->transportt); \ 402 struct fc_internal *i = to_fc_internal(shost->transportt); \
403 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \
404 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \
405 return -EBUSY; \
401 val = simple_strtoul(buf, NULL, 0); \ 406 val = simple_strtoul(buf, NULL, 0); \
402 i->f->set_rport_##field(rport, val); \ 407 i->f->set_rport_##field(rport, val); \
403 return count; \ 408 return count; \
@@ -500,7 +505,29 @@ static FC_CLASS_DEVICE_ATTR(rport, supported_classes, S_IRUGO,
500 505
501/* Dynamic Remote Port Attributes */ 506/* Dynamic Remote Port Attributes */
502 507
503fc_rport_rw_attr(dev_loss_tmo, "%d\n", 20); 508/*
509 * dev_loss_tmo attribute
510 */
511fc_rport_show_function(dev_loss_tmo, "%d\n", 20, )
512static ssize_t
513store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf,
514 size_t count)
515{
516 int val;
517 struct fc_rport *rport = transport_class_to_rport(cdev);
518 struct Scsi_Host *shost = rport_to_shost(rport);
519 struct fc_internal *i = to_fc_internal(shost->transportt);
520 if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
521 (rport->port_state == FC_PORTSTATE_NOTPRESENT))
522 return -EBUSY;
523 val = simple_strtoul(buf, NULL, 0);
524 if ((val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
525 return -EINVAL;
526 i->f->set_rport_dev_loss_tmo(rport, val);
527 return count;
528}
529static FC_CLASS_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR,
530 show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo);
504 531
505 532
506/* Private Remote Port Attributes */ 533/* Private Remote Port Attributes */
@@ -1214,6 +1241,25 @@ fc_remove_host(struct Scsi_Host *shost)
1214} 1241}
1215EXPORT_SYMBOL(fc_remove_host); 1242EXPORT_SYMBOL(fc_remove_host);
1216 1243
1244/*
1245 * fc_rport_tgt_remove - Removes the scsi target on the remote port
1246 * @rport: The remote port to be operated on
1247 */
1248static void
1249fc_rport_tgt_remove(struct fc_rport *rport)
1250{
1251 struct Scsi_Host *shost = rport_to_shost(rport);
1252
1253 scsi_target_unblock(&rport->dev);
1254
1255 /* Stop anything on the workq */
1256 if (!cancel_delayed_work(&rport->dev_loss_work))
1257 flush_scheduled_work();
1258 scsi_flush_work(shost);
1259
1260 scsi_remove_target(&rport->dev);
1261}
1262
1217/** 1263/**
1218 * fc_rport_create - allocates and creates a remote FC port. 1264 * fc_rport_create - allocates and creates a remote FC port.
1219 * @shost: scsi host the remote port is connected to. 1265 * @shost: scsi host the remote port is connected to.
@@ -1260,7 +1306,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
1260 rport->dd_data = &rport[1]; 1306 rport->dd_data = &rport[1];
1261 rport->channel = channel; 1307 rport->channel = channel;
1262 1308
1263 INIT_WORK(&rport->dev_loss_work, fc_timeout_blocked_rport, rport); 1309 INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport);
1264 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport); 1310 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport);
1265 1311
1266 spin_lock_irqsave(shost->host_lock, flags); 1312 spin_lock_irqsave(shost->host_lock, flags);
@@ -1352,17 +1398,93 @@ struct fc_rport *
1352fc_remote_port_add(struct Scsi_Host *shost, int channel, 1398fc_remote_port_add(struct Scsi_Host *shost, int channel,
1353 struct fc_rport_identifiers *ids) 1399 struct fc_rport_identifiers *ids)
1354{ 1400{
1401 struct fc_internal *fci = to_fc_internal(shost->transportt);
1355 struct fc_rport *rport; 1402 struct fc_rport *rport;
1356 unsigned long flags; 1403 unsigned long flags;
1357 int match = 0; 1404 int match = 0;
1358 1405
1406 /*
1407 * Search the list of "active" rports, for an rport that has been
1408 * deleted, but we've held off the real delete while the target
1409 * is in a "blocked" state.
1410 */
1411 spin_lock_irqsave(shost->host_lock, flags);
1412
1413 list_for_each_entry(rport, &fc_host_rports(shost), peers) {
1414
1415 if ((rport->port_state == FC_PORTSTATE_BLOCKED) &&
1416 (rport->channel == channel)) {
1417
1418 switch (fc_host_tgtid_bind_type(shost)) {
1419 case FC_TGTID_BIND_BY_WWPN:
1420 case FC_TGTID_BIND_NONE:
1421 if (rport->port_name == ids->port_name)
1422 match = 1;
1423 break;
1424 case FC_TGTID_BIND_BY_WWNN:
1425 if (rport->node_name == ids->node_name)
1426 match = 1;
1427 break;
1428 case FC_TGTID_BIND_BY_ID:
1429 if (rport->port_id == ids->port_id)
1430 match = 1;
1431 break;
1432 }
1433
1434 if (match) {
1435 struct work_struct *work =
1436 &rport->dev_loss_work;
1437
1438 memcpy(&rport->node_name, &ids->node_name,
1439 sizeof(rport->node_name));
1440 memcpy(&rport->port_name, &ids->port_name,
1441 sizeof(rport->port_name));
1442 rport->port_id = ids->port_id;
1443
1444 rport->port_state = FC_PORTSTATE_ONLINE;
1445 rport->roles = ids->roles;
1446
1447 spin_unlock_irqrestore(shost->host_lock, flags);
1448
1449 if (fci->f->dd_fcrport_size)
1450 memset(rport->dd_data, 0,
1451 fci->f->dd_fcrport_size);
1452
1453 /*
1454 * If we were blocked, we were a target.
1455 * If no longer a target, we leave the timer
1456 * running in case the port changes roles
1457 * prior to the timer expiring. If the timer
1458 * fires, the target will be torn down.
1459 */
1460 if (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET))
1461 return rport;
1462
1463 /* restart the target */
1464
1465 /*
1466 * Stop the target timer first. Take no action
1467 * on the del_timer failure as the state
1468 * machine state change will validate the
1469 * transaction.
1470 */
1471 if (!cancel_delayed_work(work))
1472 flush_scheduled_work();
1473
1474 /* initiate a scan of the target */
1475 scsi_queue_work(shost, &rport->scan_work);
1476
1477 return rport;
1478 }
1479 }
1480 }
1481
1482 /* Search the bindings array */
1359 if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) && 1483 if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) &&
1360 (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) { 1484 (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) {
1361 1485
1362 /* search for a matching consistent binding */ 1486 /* search for a matching consistent binding */
1363 1487
1364 spin_lock_irqsave(shost->host_lock, flags);
1365
1366 list_for_each_entry(rport, &fc_host_rport_bindings(shost), 1488 list_for_each_entry(rport, &fc_host_rport_bindings(shost),
1367 peers) { 1489 peers) {
1368 if (rport->channel != channel) 1490 if (rport->channel != channel)
@@ -1392,8 +1514,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1392 } 1514 }
1393 } 1515 }
1394 1516
1395 spin_unlock_irqrestore(shost->host_lock, flags);
1396
1397 if (match) { 1517 if (match) {
1398 memcpy(&rport->node_name, &ids->node_name, 1518 memcpy(&rport->node_name, &ids->node_name,
1399 sizeof(rport->node_name)); 1519 sizeof(rport->node_name));
@@ -1403,6 +1523,12 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1403 rport->roles = ids->roles; 1523 rport->roles = ids->roles;
1404 rport->port_state = FC_PORTSTATE_ONLINE; 1524 rport->port_state = FC_PORTSTATE_ONLINE;
1405 1525
1526 spin_unlock_irqrestore(shost->host_lock, flags);
1527
1528 if (fci->f->dd_fcrport_size)
1529 memset(rport->dd_data, 0,
1530 fci->f->dd_fcrport_size);
1531
1406 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 1532 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
1407 /* initiate a scan of the target */ 1533 /* initiate a scan of the target */
1408 scsi_queue_work(shost, &rport->scan_work); 1534 scsi_queue_work(shost, &rport->scan_work);
@@ -1411,6 +1537,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1411 } 1537 }
1412 } 1538 }
1413 1539
1540 spin_unlock_irqrestore(shost->host_lock, flags);
1541
1414 /* No consistent binding found - create new remote port entry */ 1542 /* No consistent binding found - create new remote port entry */
1415 rport = fc_rport_create(shost, channel, ids); 1543 rport = fc_rport_create(shost, channel, ids);
1416 1544
@@ -1419,25 +1547,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1419EXPORT_SYMBOL(fc_remote_port_add); 1547EXPORT_SYMBOL(fc_remote_port_add);
1420 1548
1421/* 1549/*
1422 * fc_rport_tgt_remove - Removes the scsi target on the remote port
1423 * @rport: The remote port to be operated on
1424 */
1425static void
1426fc_rport_tgt_remove(struct fc_rport *rport)
1427{
1428 struct Scsi_Host *shost = rport_to_shost(rport);
1429
1430 scsi_target_unblock(&rport->dev);
1431
1432 /* Stop anything on the workq */
1433 if (!cancel_delayed_work(&rport->dev_loss_work))
1434 flush_scheduled_work();
1435 scsi_flush_work(shost);
1436
1437 scsi_remove_target(&rport->dev);
1438}
1439
1440/*
1441 * fc_rport_terminate - this routine tears down and deallocates a remote port. 1550 * fc_rport_terminate - this routine tears down and deallocates a remote port.
1442 * @rport: The remote port to be terminated 1551 * @rport: The remote port to be terminated
1443 * 1552 *
@@ -1470,24 +1579,44 @@ fc_rport_terminate(struct fc_rport *rport)
1470 * The LLDD calls this routine to notify the transport that a remote 1579 * The LLDD calls this routine to notify the transport that a remote
1471 * port is no longer part of the topology. Note: Although a port 1580 * port is no longer part of the topology. Note: Although a port
1472 * may no longer be part of the topology, it may persist in the remote 1581 * may no longer be part of the topology, it may persist in the remote
1473 * ports displayed by the fc_host. This is done so that target id 1582 * ports displayed by the fc_host. We do this under 2 conditions:
1474 * mappings (managed via the remote port structures), are always visible 1583 * - If the port was a scsi target, we delay its deletion by "blocking" it.
1475 * as long as the mapping is valid, regardless of port state, 1584 * This allows the port to temporarily disappear, then reappear without
1585 * disrupting the SCSI device tree attached to it. During the "blocked"
1586 * period the port will still exist.
1587 * - If the port was a scsi target and disappears for longer than we
1588 * expect, we'll delete the port and the tear down the SCSI device tree
1589 * attached to it. However, we want to semi-persist the target id assigned
1590 * to that port if it eventually does exist. The port structure will
1591 * remain (although with minimal information) so that the target id
1592 * bindings remails.
1476 * 1593 *
1477 * If the remote port is not an FCP Target, it will be fully torn down 1594 * If the remote port is not an FCP Target, it will be fully torn down
1478 * and deallocated, including the fc_remote_port class device. 1595 * and deallocated, including the fc_remote_port class device.
1479 * 1596 *
1480 * If the remote port is an FCP Target, the port structure will be 1597 * If the remote port is an FCP Target, the port will be placed in a
1481 * marked as Not Present, but will remain as long as there is a valid 1598 * temporary blocked state. From the LLDD's perspective, the rport no
1482 * SCSI target id mapping associated with the port structure. Validity 1599 * longer exists. From the SCSI midlayer's perspective, the SCSI target
1483 * is determined by the binding type. If binding by wwpn, then the port 1600 * exists, but all sdevs on it are blocked from further I/O. The following
1484 * structure is always valid and will not be deallocated until the host 1601 * is then expected:
1485 * is removed. If binding by wwnn, then the port structure is valid 1602 * If the remote port does not return (signaled by a LLDD call to
1486 * until another port with the same node name is found in the topology. 1603 * fc_remote_port_add()) within the dev_loss_tmo timeout, then the
1487 * If binding by port id (fc address), then the port structure is valid 1604 * scsi target is removed - killing all outstanding i/o and removing the
1488 * valid until another port with the same address is identified. 1605 * scsi devices attached ot it. The port structure will be marked Not
1606 * Present and be partially cleared, leaving only enough information to
1607 * recognize the remote port relative to the scsi target id binding if
1608 * it later appears. The port will remain as long as there is a valid
1609 * binding (e.g. until the user changes the binding type or unloads the
1610 * scsi host with the binding).
1489 * 1611 *
1490 * Called from interrupt or normal process context. 1612 * If the remote port returns within the dev_loss_tmo value (and matches
1613 * according to the target id binding type), the port structure will be
1614 * reused. If it is no longer a SCSI target, the target will be torn
1615 * down. If it continues to be a SCSI target, then the target will be
1616 * unblocked (allowing i/o to be resumed), and a scan will be activated
1617 * to ensure that all luns are detected.
1618 *
1619 * Called from normal process context only - cannot be called from interrupt.
1491 * 1620 *
1492 * Notes: 1621 * Notes:
1493 * This routine assumes no locks are held on entry. 1622 * This routine assumes no locks are held on entry.
@@ -1495,53 +1624,20 @@ fc_rport_terminate(struct fc_rport *rport)
1495void 1624void
1496fc_remote_port_delete(struct fc_rport *rport) 1625fc_remote_port_delete(struct fc_rport *rport)
1497{ 1626{
1498 struct Scsi_Host *shost = rport_to_shost(rport); 1627 int timeout = rport->dev_loss_tmo;
1499 unsigned long flags;
1500 1628
1501 /* If no scsi target id mapping or consistent binding type, delete it */ 1629 /* If no scsi target id mapping, delete it */
1502 if ((rport->scsi_target_id == -1) || 1630 if (rport->scsi_target_id == -1) {
1503 (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE)) {
1504 fc_rport_terminate(rport); 1631 fc_rport_terminate(rport);
1505 return; 1632 return;
1506 } 1633 }
1507 1634
1508 fc_rport_tgt_remove(rport); 1635 scsi_target_block(&rport->dev);
1509
1510 spin_lock_irqsave(shost->host_lock, flags);
1511 list_move_tail(&rport->peers, &fc_host_rport_bindings(shost));
1512 spin_unlock_irqrestore(shost->host_lock, flags);
1513
1514 /*
1515 * Note: We do not remove or clear the hostdata area. This allows
1516 * host-specific target data to persist along with the
1517 * scsi_target_id. It's up to the host to manage it's hostdata area.
1518 */
1519 1636
1520 /* 1637 /* cap the length the devices can be blocked until they are deleted */
1521 * Reinitialize port attributes that may change if the port comes back. 1638 schedule_delayed_work(&rport->dev_loss_work, timeout * HZ);
1522 */
1523 rport->maxframe_size = -1;
1524 rport->supported_classes = FC_COS_UNSPECIFIED;
1525 rport->roles = FC_RPORT_ROLE_UNKNOWN;
1526 rport->port_state = FC_PORTSTATE_NOTPRESENT;
1527 1639
1528 /* remove the identifiers that aren't used in the consisting binding */ 1640 rport->port_state = FC_PORTSTATE_BLOCKED;
1529 switch (fc_host_tgtid_bind_type(shost)) {
1530 case FC_TGTID_BIND_BY_WWPN:
1531 rport->node_name = -1;
1532 rport->port_id = -1;
1533 break;
1534 case FC_TGTID_BIND_BY_WWNN:
1535 rport->port_name = -1;
1536 rport->port_id = -1;
1537 break;
1538 case FC_TGTID_BIND_BY_ID:
1539 rport->node_name = -1;
1540 rport->port_name = -1;
1541 break;
1542 case FC_TGTID_BIND_NONE: /* to keep compiler happy */
1543 break;
1544 }
1545} 1641}
1546EXPORT_SYMBOL(fc_remote_port_delete); 1642EXPORT_SYMBOL(fc_remote_port_delete);
1547 1643
@@ -1574,127 +1670,140 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
1574 unsigned long flags; 1670 unsigned long flags;
1575 int create = 0; 1671 int create = 0;
1576 1672
1577 rport->roles = roles;
1578
1579 spin_lock_irqsave(shost->host_lock, flags); 1673 spin_lock_irqsave(shost->host_lock, flags);
1580 if ((rport->scsi_target_id == -1) && 1674 if (roles & FC_RPORT_ROLE_FCP_TARGET) {
1581 (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { 1675 if (rport->scsi_target_id == -1) {
1582 rport->scsi_target_id = fc_host->next_target_id++; 1676 rport->scsi_target_id = fc_host->next_target_id++;
1583 create = 1; 1677 create = 1;
1678 } else if (!(rport->roles & FC_RPORT_ROLE_FCP_TARGET))
1679 create = 1;
1584 } 1680 }
1585 spin_unlock_irqrestore(shost->host_lock, flags); 1681 spin_unlock_irqrestore(shost->host_lock, flags);
1586 1682
1587 if (create) 1683 rport->roles = roles;
1684
1685 if (create) {
1686 /*
1687 * There may have been a delete timer running on the
1688 * port. Ensure that it is cancelled as we now know
1689 * the port is an FCP Target.
1690 * Note: we know the rport is exists and in an online
1691 * state as the LLDD would not have had an rport
1692 * reference to pass us.
1693 *
1694 * Take no action on the del_timer failure as the state
1695 * machine state change will validate the
1696 * transaction.
1697 */
1698 if (!cancel_delayed_work(&rport->dev_loss_work))
1699 flush_scheduled_work();
1700
1588 /* initiate a scan of the target */ 1701 /* initiate a scan of the target */
1589 scsi_queue_work(shost, &rport->scan_work); 1702 scsi_queue_work(shost, &rport->scan_work);
1703 }
1590} 1704}
1591EXPORT_SYMBOL(fc_remote_port_rolechg); 1705EXPORT_SYMBOL(fc_remote_port_rolechg);
1592 1706
1593/** 1707/**
1594 * fc_timeout_blocked_rport - Timeout handler for blocked remote port 1708 * fc_timeout_deleted_rport - Timeout handler for a deleted remote port that
1595 * that fails to return in the alloted time. 1709 * was a SCSI target (thus was blocked), and failed
1596 * @data: scsi target that failed to reappear in the alloted time. 1710 * to return in the alloted time.
1711 *
1712 * @data: rport target that failed to reappear in the alloted time.
1597 **/ 1713 **/
1598static void 1714static void
1599fc_timeout_blocked_rport(void *data) 1715fc_timeout_deleted_rport(void *data)
1600{ 1716{
1601 struct fc_rport *rport = (struct fc_rport *)data; 1717 struct fc_rport *rport = (struct fc_rport *)data;
1718 struct Scsi_Host *shost = rport_to_shost(rport);
1719 unsigned long flags;
1602 1720
1603 rport->port_state = FC_PORTSTATE_OFFLINE; 1721 spin_lock_irqsave(shost->host_lock, flags);
1604
1605 dev_printk(KERN_ERR, &rport->dev,
1606 "blocked FC remote port time out: removing target\n");
1607 1722
1608 /* 1723 /*
1609 * As this only occurs if the remote port (scsi target) 1724 * If the port is ONLINE, then it came back, but was no longer an
1610 * went away and didn't come back - we'll remove 1725 * FCP target. Thus we need to tear down the scsi_target on it.
1611 * all attached scsi devices.
1612 */ 1726 */
1613 scsi_target_unblock(&rport->dev); 1727 if (rport->port_state == FC_PORTSTATE_ONLINE) {
1614 scsi_remove_target(&rport->dev); 1728 spin_unlock_irqrestore(shost->host_lock, flags);
1615}
1616 1729
1617/** 1730 dev_printk(KERN_ERR, &rport->dev,
1618 * fc_remote_port_block - temporarily block any scsi traffic to a remote port. 1731 "blocked FC remote port time out: removing target\n");
1619 * @rport: remote port to be blocked.
1620 *
1621 * scsi lldd's with a FC transport call this routine to temporarily stop
1622 * all scsi traffic to a remote port. If the port is not a SCSI target,
1623 * no action is taken. If the port is a SCSI target, all attached devices
1624 * are placed into a SDEV_BLOCK state and a timer is started. The timer is
1625 * represents the maximum amount of time the port may be blocked. If the
1626 * timer expires, the port is considered non-existent and the attached
1627 * scsi devices will be removed.
1628 *
1629 * Called from interrupt or normal process context.
1630 *
1631 * Returns zero if successful or error if not
1632 *
1633 * Notes:
1634 * This routine assumes no locks are held on entry.
1635 *
1636 * The timeout and timer types are extracted from the fc transport
1637 * attributes from the caller's rport pointer.
1638 **/
1639int
1640fc_remote_port_block(struct fc_rport *rport)
1641{
1642 int timeout = rport->dev_loss_tmo;
1643 struct work_struct *work = &rport->dev_loss_work;
1644 1732
1645 if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT) 1733 fc_rport_tgt_remove(rport);
1646 return -EINVAL;
1647 1734
1648 scsi_target_block(&rport->dev); 1735 return;
1736 }
1649 1737
1650 /* cap the length the devices can be blocked */ 1738 if (rport->port_state != FC_PORTSTATE_BLOCKED) {
1651 schedule_delayed_work(work, timeout * HZ); 1739 spin_unlock_irqrestore(shost->host_lock, flags);
1740 dev_printk(KERN_ERR, &rport->dev,
1741 "blocked FC remote port time out: leaving target alone\n");
1742 return;
1743 }
1652 1744
1653 rport->port_state = FC_PORTSTATE_BLOCKED; 1745 if (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE) {
1654 return 0; 1746 spin_unlock_irqrestore(shost->host_lock, flags);
1655} 1747 dev_printk(KERN_ERR, &rport->dev,
1656EXPORT_SYMBOL(fc_remote_port_block); 1748 "blocked FC remote port time out: removing target\n");
1749 fc_rport_terminate(rport);
1750 return;
1751 }
1657 1752
1658/** 1753 dev_printk(KERN_ERR, &rport->dev,
1659 * fc_remote_port_unblock - restart any blocked scsi traffic to a remote port. 1754 "blocked FC remote port time out: removing target and "
1660 * @rport: remote port to be unblocked. 1755 "saving binding\n");
1661 * 1756
1662 * scsi lld's with a FC transport call this routine to restart IO to all 1757 list_move_tail(&rport->peers, &fc_host_rport_bindings(shost));
1663 * devices associated with the caller's scsi target following a fc_target_block
1664 * request. Called from interrupt or normal process context.
1665 *
1666 * Notes:
1667 * This routine assumes no locks are held on entry.
1668 **/
1669 void
1670fc_remote_port_unblock(struct fc_rport *rport)
1671{
1672 struct work_struct *work = &rport->dev_loss_work;
1673 struct Scsi_Host *shost = rport_to_shost(rport);
1674 1758
1675 /* 1759 /*
1676 * Stop the target timer first. Take no action on the del_timer 1760 * Note: We do not remove or clear the hostdata area. This allows
1677 * failure as the state machine state change will validate the 1761 * host-specific target data to persist along with the
1678 * transaction. 1762 * scsi_target_id. It's up to the host to manage it's hostdata area.
1679 */ 1763 */
1680 if (!cancel_delayed_work(work))
1681 flush_scheduled_work();
1682 1764
1683 if (rport->port_state == FC_PORTSTATE_OFFLINE) 1765 /*
1684 /* 1766 * Reinitialize port attributes that may change if the port comes back.
1685 * initiate a scan of the target as the target has 1767 */
1686 * been torn down. 1768 rport->maxframe_size = -1;
1687 */ 1769 rport->supported_classes = FC_COS_UNSPECIFIED;
1688 scsi_queue_work(shost, &rport->scan_work); 1770 rport->roles = FC_RPORT_ROLE_UNKNOWN;
1689 else 1771 rport->port_state = FC_PORTSTATE_NOTPRESENT;
1690 scsi_target_unblock(&rport->dev);
1691 1772
1692 rport->port_state = FC_PORTSTATE_ONLINE; 1773 /* remove the identifiers that aren't used in the consisting binding */
1774 switch (fc_host_tgtid_bind_type(shost)) {
1775 case FC_TGTID_BIND_BY_WWPN:
1776 rport->node_name = -1;
1777 rport->port_id = -1;
1778 break;
1779 case FC_TGTID_BIND_BY_WWNN:
1780 rport->port_name = -1;
1781 rport->port_id = -1;
1782 break;
1783 case FC_TGTID_BIND_BY_ID:
1784 rport->node_name = -1;
1785 rport->port_name = -1;
1786 break;
1787 case FC_TGTID_BIND_NONE: /* to keep compiler happy */
1788 break;
1789 }
1790
1791 spin_unlock_irqrestore(shost->host_lock, flags);
1792
1793 /*
1794 * As this only occurs if the remote port (scsi target)
1795 * went away and didn't come back - we'll remove
1796 * all attached scsi devices.
1797 */
1798 fc_rport_tgt_remove(rport);
1693} 1799}
1694EXPORT_SYMBOL(fc_remote_port_unblock);
1695 1800
1696/** 1801/**
1697 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. 1802 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port.
1803 *
1804 * Will unblock the target (in case it went away and has now come back),
1805 * then invoke a scan.
1806 *
1698 * @data: remote port to be scanned. 1807 * @data: remote port to be scanned.
1699 **/ 1808 **/
1700static void 1809static void
@@ -1702,6 +1811,7 @@ fc_scsi_scan_rport(void *data)
1702{ 1811{
1703 struct fc_rport *rport = (struct fc_rport *)data; 1812 struct fc_rport *rport = (struct fc_rport *)data;
1704 1813
1814 scsi_target_unblock(&rport->dev);
1705 scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id, 1815 scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id,
1706 SCAN_WILD_CARD, 1); 1816 SCAN_WILD_CARD, 1);
1707} 1817}
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 4496b32972e5..319ff7a60dfe 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -28,6 +28,7 @@
28#define SCSI_TRANSPORT_FC_H 28#define SCSI_TRANSPORT_FC_H
29 29
30#include <linux/config.h> 30#include <linux/config.h>
31#include <scsi/scsi.h>
31 32
32struct scsi_transport_template; 33struct scsi_transport_template;
33 34
@@ -429,6 +430,34 @@ struct fc_function_template {
429}; 430};
430 431
431 432
433/**
434 * fc_remote_port_chkready - called to validate the remote port state
435 * prior to initiating io to the port.
436 *
437 * Returns a scsi result code that can be returned by the LLDD.
438 *
439 * @rport: remote port to be checked
440 **/
441static inline int
442fc_remote_port_chkready(struct fc_rport *rport)
443{
444 int result;
445
446 switch (rport->port_state) {
447 case FC_PORTSTATE_ONLINE:
448 result = 0;
449 break;
450 case FC_PORTSTATE_BLOCKED:
451 result = DID_BUS_BUSY << 16;
452 break;
453 default:
454 result = DID_NO_CONNECT << 16;
455 break;
456 }
457 return result;
458}
459
460
432struct scsi_transport_template *fc_attach_transport( 461struct scsi_transport_template *fc_attach_transport(
433 struct fc_function_template *); 462 struct fc_function_template *);
434void fc_release_transport(struct scsi_transport_template *); 463void fc_release_transport(struct scsi_transport_template *);
@@ -437,8 +466,6 @@ struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost,
437 int channel, struct fc_rport_identifiers *ids); 466 int channel, struct fc_rport_identifiers *ids);
438void fc_remote_port_delete(struct fc_rport *rport); 467void fc_remote_port_delete(struct fc_rport *rport);
439void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles); 468void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles);
440int fc_remote_port_block(struct fc_rport *rport);
441void fc_remote_port_unblock(struct fc_rport *rport);
442int scsi_is_fc_rport(const struct device *); 469int scsi_is_fc_rport(const struct device *);
443 470
444static inline u64 wwn_to_u64(u8 *wwn) 471static inline u64 wwn_to_u64(u8 *wwn)