aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2006-08-18 17:47:08 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-04 22:25:21 -0400
commitc01f32087960edd60a302ad62ad6b8b525e4aeec (patch)
treeabefc5afc051d379802de42175e14df37d79b4ae /drivers/scsi/lpfc/lpfc_hbadisc.c
parent0f29b966d60e9a4f5ecff9f3832257b38aea4f13 (diff)
[SCSI] lpfc 8.1.10 : Add support for dev_loss_tmo_callbk and fast_io_fail_tmo_callbk
Add support for new dev_loss_tmo callback Goodness is that it removes code for a parallel nodev timer that existed in the driver Add support for the new fast_io_fail callback Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c178
1 files changed, 69 insertions, 109 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 53821e5778b3..97973af980a0 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -56,28 +56,63 @@ static uint8_t lpfcAlpaArray[] = {
56 56
57static void lpfc_disc_timeout_handler(struct lpfc_hba *); 57static void lpfc_disc_timeout_handler(struct lpfc_hba *);
58 58
59static void 59void
60lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) 60lpfc_terminate_rport_io(struct fc_rport *rport)
61{ 61{
62 uint8_t *name = (uint8_t *)&ndlp->nlp_portname; 62 struct lpfc_rport_data *rdata;
63 int warn_on = 0; 63 struct lpfc_nodelist * ndlp;
64 struct lpfc_hba *phba;
64 65
65 spin_lock_irq(phba->host->host_lock); 66 rdata = rport->dd_data;
66 if (!(ndlp->nlp_flag & NLP_NODEV_TMO)) { 67 ndlp = rdata->pnode;
67 spin_unlock_irq(phba->host->host_lock); 68
69 if (!ndlp) {
70 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
71 printk(KERN_ERR "Cannot find remote node"
72 " to terminate I/O Data x%x\n",
73 rport->port_id);
68 return; 74 return;
69 } 75 }
70 76
71 /* 77 phba = ndlp->nlp_phba;
72 * If a discovery event readded nodev_timer after timer 78
73 * firing and before processing the timer, cancel the
74 * nlp_tmofunc.
75 */
76 spin_unlock_irq(phba->host->host_lock);
77 del_timer_sync(&ndlp->nlp_tmofunc);
78 spin_lock_irq(phba->host->host_lock); 79 spin_lock_irq(phba->host->host_lock);
80 if (ndlp->nlp_sid != NLP_NO_SID) {
81 lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
82 ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
83 }
84 spin_unlock_irq(phba->host->host_lock);
85
86 return;
87}
88
89/*
90 * This function will be called when dev_loss_tmo fire.
91 */
92void
93lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
94{
95 struct lpfc_rport_data *rdata;
96 struct lpfc_nodelist * ndlp;
97 uint8_t *name;
98 int warn_on = 0;
99 struct lpfc_hba *phba;
100
101 rdata = rport->dd_data;
102 ndlp = rdata->pnode;
79 103
80 ndlp->nlp_flag &= ~NLP_NODEV_TMO; 104 if (!ndlp) {
105 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
106 printk(KERN_ERR "Cannot find remote node"
107 " for rport in dev_loss_tmo_callbk x%x\n",
108 rport->port_id);
109 return;
110 }
111
112 name = (uint8_t *)&ndlp->nlp_portname;
113 phba = ndlp->nlp_phba;
114
115 spin_lock_irq(phba->host->host_lock);
81 116
82 if (ndlp->nlp_sid != NLP_NO_SID) { 117 if (ndlp->nlp_sid != NLP_NO_SID) {
83 warn_on = 1; 118 warn_on = 1;
@@ -85,11 +120,14 @@ lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
85 lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], 120 lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
86 ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); 121 ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
87 } 122 }
123 if (phba->fc_flag & FC_UNLOADING)
124 warn_on = 0;
125
88 spin_unlock_irq(phba->host->host_lock); 126 spin_unlock_irq(phba->host->host_lock);
89 127
90 if (warn_on) { 128 if (warn_on) {
91 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, 129 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
92 "%d:0203 Nodev timeout on " 130 "%d:0203 Devloss timeout on "
93 "WWPN %x:%x:%x:%x:%x:%x:%x:%x " 131 "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
94 "NPort x%x Data: x%x x%x x%x\n", 132 "NPort x%x Data: x%x x%x x%x\n",
95 phba->brd_no, 133 phba->brd_no,
@@ -99,7 +137,7 @@ lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
99 ndlp->nlp_state, ndlp->nlp_rpi); 137 ndlp->nlp_state, ndlp->nlp_rpi);
100 } else { 138 } else {
101 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, 139 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
102 "%d:0204 Nodev timeout on " 140 "%d:0204 Devloss timeout on "
103 "WWPN %x:%x:%x:%x:%x:%x:%x:%x " 141 "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
104 "NPort x%x Data: x%x x%x x%x\n", 142 "NPort x%x Data: x%x x%x x%x\n",
105 phba->brd_no, 143 phba->brd_no,
@@ -109,7 +147,12 @@ lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
109 ndlp->nlp_state, ndlp->nlp_rpi); 147 ndlp->nlp_state, ndlp->nlp_rpi);
110 } 148 }
111 149
112 lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM); 150 ndlp->rport = NULL;
151 rdata->pnode = NULL;
152
153 if (!(phba->fc_flag & FC_UNLOADING))
154 lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM);
155
113 return; 156 return;
114} 157}
115 158
@@ -127,11 +170,6 @@ lpfc_work_list_done(struct lpfc_hba * phba)
127 spin_unlock_irq(phba->host->host_lock); 170 spin_unlock_irq(phba->host->host_lock);
128 free_evt = 1; 171 free_evt = 1;
129 switch (evtp->evt) { 172 switch (evtp->evt) {
130 case LPFC_EVT_NODEV_TMO:
131 ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
132 lpfc_process_nodev_timeout(phba, ndlp);
133 free_evt = 0;
134 break;
135 case LPFC_EVT_ELS_RETRY: 173 case LPFC_EVT_ELS_RETRY:
136 ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); 174 ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
137 lpfc_els_retry_delay_handler(ndlp); 175 lpfc_els_retry_delay_handler(ndlp);
@@ -377,16 +415,6 @@ lpfc_linkdown(struct lpfc_hba * phba)
377 rc = lpfc_disc_state_machine(phba, ndlp, NULL, 415 rc = lpfc_disc_state_machine(phba, ndlp, NULL,
378 NLP_EVT_DEVICE_RECOVERY); 416 NLP_EVT_DEVICE_RECOVERY);
379 417
380 /* Check config parameter use-adisc or FCP-2 */
381 if ((rc != NLP_STE_FREED_NODE) &&
382 (phba->cfg_use_adisc == 0) &&
383 !(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) {
384 /* We know we will have to relogin, so
385 * unreglogin the rpi right now to fail
386 * any outstanding I/Os quickly.
387 */
388 lpfc_unreg_rpi(phba, ndlp);
389 }
390 } 418 }
391 } 419 }
392 420
@@ -1104,8 +1132,11 @@ lpfc_unregister_remote_port(struct lpfc_hba * phba,
1104 struct fc_rport *rport = ndlp->rport; 1132 struct fc_rport *rport = ndlp->rport;
1105 struct lpfc_rport_data *rdata = rport->dd_data; 1133 struct lpfc_rport_data *rdata = rport->dd_data;
1106 1134
1107 ndlp->rport = NULL; 1135 if (rport->scsi_target_id == -1) {
1108 rdata->pnode = NULL; 1136 ndlp->rport = NULL;
1137 rdata->pnode = NULL;
1138 }
1139
1109 fc_remote_port_delete(rport); 1140 fc_remote_port_delete(rport);
1110 1141
1111 return; 1142 return;
@@ -1233,17 +1264,6 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1233 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpunmap_list); 1264 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpunmap_list);
1234 phba->fc_unmap_cnt++; 1265 phba->fc_unmap_cnt++;
1235 phba->nport_event_cnt++; 1266 phba->nport_event_cnt++;
1236 /* stop nodev tmo if running */
1237 if (nlp->nlp_flag & NLP_NODEV_TMO) {
1238 nlp->nlp_flag &= ~NLP_NODEV_TMO;
1239 spin_unlock_irq(phba->host->host_lock);
1240 del_timer_sync(&nlp->nlp_tmofunc);
1241 spin_lock_irq(phba->host->host_lock);
1242 if (!list_empty(&nlp->nodev_timeout_evt.evt_listp))
1243 list_del_init(&nlp->nodev_timeout_evt.
1244 evt_listp);
1245
1246 }
1247 nlp->nlp_flag &= ~NLP_NODEV_REMOVE; 1267 nlp->nlp_flag &= ~NLP_NODEV_REMOVE;
1248 nlp->nlp_type |= NLP_FC_NODE; 1268 nlp->nlp_type |= NLP_FC_NODE;
1249 break; 1269 break;
@@ -1254,17 +1274,6 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1254 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpmap_list); 1274 list_add_tail(&nlp->nlp_listp, &phba->fc_nlpmap_list);
1255 phba->fc_map_cnt++; 1275 phba->fc_map_cnt++;
1256 phba->nport_event_cnt++; 1276 phba->nport_event_cnt++;
1257 /* stop nodev tmo if running */
1258 if (nlp->nlp_flag & NLP_NODEV_TMO) {
1259 nlp->nlp_flag &= ~NLP_NODEV_TMO;
1260 spin_unlock_irq(phba->host->host_lock);
1261 del_timer_sync(&nlp->nlp_tmofunc);
1262 spin_lock_irq(phba->host->host_lock);
1263 if (!list_empty(&nlp->nodev_timeout_evt.evt_listp))
1264 list_del_init(&nlp->nodev_timeout_evt.
1265 evt_listp);
1266
1267 }
1268 nlp->nlp_flag &= ~NLP_NODEV_REMOVE; 1277 nlp->nlp_flag &= ~NLP_NODEV_REMOVE;
1269 break; 1278 break;
1270 case NLP_NPR_LIST: 1279 case NLP_NPR_LIST:
@@ -1273,11 +1282,6 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1273 list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list); 1282 list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list);
1274 phba->fc_npr_cnt++; 1283 phba->fc_npr_cnt++;
1275 1284
1276 if (!(nlp->nlp_flag & NLP_NODEV_TMO))
1277 mod_timer(&nlp->nlp_tmofunc,
1278 jiffies + HZ * phba->cfg_nodev_tmo);
1279
1280 nlp->nlp_flag |= NLP_NODEV_TMO;
1281 nlp->nlp_flag &= ~NLP_RCV_PLOGI; 1285 nlp->nlp_flag &= ~NLP_RCV_PLOGI;
1282 break; 1286 break;
1283 case NLP_JUST_DQ: 1287 case NLP_JUST_DQ:
@@ -1307,7 +1311,8 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
1307 * already. If we have, and it's a scsi entity, be 1311 * already. If we have, and it's a scsi entity, be
1308 * sure to unblock any attached scsi devices 1312 * sure to unblock any attached scsi devices
1309 */ 1313 */
1310 if (!nlp->rport) 1314 if ((!nlp->rport) || (nlp->rport->port_state ==
1315 FC_PORTSTATE_BLOCKED))
1311 lpfc_register_remote_port(phba, nlp); 1316 lpfc_register_remote_port(phba, nlp);
1312 1317
1313 /* 1318 /*
@@ -1581,15 +1586,12 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1581 1586
1582 lpfc_els_abort(phba,ndlp,0); 1587 lpfc_els_abort(phba,ndlp,0);
1583 spin_lock_irq(phba->host->host_lock); 1588 spin_lock_irq(phba->host->host_lock);
1584 ndlp->nlp_flag &= ~(NLP_NODEV_TMO|NLP_DELAY_TMO); 1589 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
1585 spin_unlock_irq(phba->host->host_lock); 1590 spin_unlock_irq(phba->host->host_lock);
1586 del_timer_sync(&ndlp->nlp_tmofunc);
1587 1591
1588 ndlp->nlp_last_elscmd = 0; 1592 ndlp->nlp_last_elscmd = 0;
1589 del_timer_sync(&ndlp->nlp_delayfunc); 1593 del_timer_sync(&ndlp->nlp_delayfunc);
1590 1594
1591 if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp))
1592 list_del_init(&ndlp->nodev_timeout_evt.evt_listp);
1593 if (!list_empty(&ndlp->els_retry_evt.evt_listp)) 1595 if (!list_empty(&ndlp->els_retry_evt.evt_listp))
1594 list_del_init(&ndlp->els_retry_evt.evt_listp); 1596 list_del_init(&ndlp->els_retry_evt.evt_listp);
1595 1597
@@ -1606,16 +1608,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1606int 1608int
1607lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) 1609lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
1608{ 1610{
1609 if (ndlp->nlp_flag & NLP_NODEV_TMO) {
1610 spin_lock_irq(phba->host->host_lock);
1611 ndlp->nlp_flag &= ~NLP_NODEV_TMO;
1612 spin_unlock_irq(phba->host->host_lock);
1613 del_timer_sync(&ndlp->nlp_tmofunc);
1614 if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp))
1615 list_del_init(&ndlp->nodev_timeout_evt.evt_listp);
1616
1617 }
1618
1619 1611
1620 if (ndlp->nlp_flag & NLP_DELAY_TMO) { 1612 if (ndlp->nlp_flag & NLP_DELAY_TMO) {
1621 lpfc_cancel_retry_delay_tmo(phba, ndlp); 1613 lpfc_cancel_retry_delay_tmo(phba, ndlp);
@@ -2430,34 +2422,6 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
2430 return; 2422 return;
2431} 2423}
2432 2424
2433static void
2434lpfc_nodev_timeout(unsigned long ptr)
2435{
2436 struct lpfc_hba *phba;
2437 struct lpfc_nodelist *ndlp;
2438 unsigned long iflag;
2439 struct lpfc_work_evt *evtp;
2440
2441 ndlp = (struct lpfc_nodelist *)ptr;
2442 phba = ndlp->nlp_phba;
2443 evtp = &ndlp->nodev_timeout_evt;
2444 spin_lock_irqsave(phba->host->host_lock, iflag);
2445
2446 if (!list_empty(&evtp->evt_listp)) {
2447 spin_unlock_irqrestore(phba->host->host_lock, iflag);
2448 return;
2449 }
2450 evtp->evt_arg1 = ndlp;
2451 evtp->evt = LPFC_EVT_NODEV_TMO;
2452 list_add_tail(&evtp->evt_listp, &phba->work_list);
2453 if (phba->work_wait)
2454 wake_up(phba->work_wait);
2455
2456 spin_unlock_irqrestore(phba->host->host_lock, iflag);
2457 return;
2458}
2459
2460
2461/* 2425/*
2462 * This routine handles processing a NameServer REG_LOGIN mailbox 2426 * This routine handles processing a NameServer REG_LOGIN mailbox
2463 * command upon completion. It is setup in the LPFC_MBOXQ 2427 * command upon completion. It is setup in the LPFC_MBOXQ
@@ -2581,11 +2545,7 @@ lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
2581 uint32_t did) 2545 uint32_t did)
2582{ 2546{
2583 memset(ndlp, 0, sizeof (struct lpfc_nodelist)); 2547 memset(ndlp, 0, sizeof (struct lpfc_nodelist));
2584 INIT_LIST_HEAD(&ndlp->nodev_timeout_evt.evt_listp);
2585 INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); 2548 INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
2586 init_timer(&ndlp->nlp_tmofunc);
2587 ndlp->nlp_tmofunc.function = lpfc_nodev_timeout;
2588 ndlp->nlp_tmofunc.data = (unsigned long)ndlp;
2589 init_timer(&ndlp->nlp_delayfunc); 2549 init_timer(&ndlp->nlp_delayfunc);
2590 ndlp->nlp_delayfunc.function = lpfc_els_retry_delay; 2550 ndlp->nlp_delayfunc.function = lpfc_els_retry_delay;
2591 ndlp->nlp_delayfunc.data = (unsigned long)ndlp; 2551 ndlp->nlp_delayfunc.data = (unsigned long)ndlp;