1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte 22fcf3ce44SJohn Forte /* 23291a2b48SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24*82527734SSukumar Swaminathan * Use is subject to license terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27*82527734SSukumar Swaminathan 2893c20f26SSukumar Swaminathan #include <emlxs.h> 29fcf3ce44SJohn Forte 30fcf3ce44SJohn Forte /* Timer period in seconds */ 31fcf3ce44SJohn Forte #define EMLXS_TIMER_PERIOD 1 /* secs */ 32fcf3ce44SJohn Forte #define EMLXS_PKT_PERIOD 5 /* secs */ 33fcf3ce44SJohn Forte #define EMLXS_UB_PERIOD 60 /* secs */ 34fcf3ce44SJohn Forte 35fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_CLOCK_C); 36fcf3ce44SJohn Forte 37fcf3ce44SJohn Forte 38fcf3ce44SJohn Forte static void emlxs_timer_check_loopback(emlxs_hba_t *hba); 39fcf3ce44SJohn Forte 40fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 41fcf3ce44SJohn Forte static void emlxs_timer_check_dhchap(emlxs_port_t *port); 42291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 43291a2b48SSukumar Swaminathan 44291a2b48SSukumar Swaminathan static void emlxs_timer(void *arg); 45291a2b48SSukumar Swaminathan static void emlxs_timer_check_heartbeat(emlxs_hba_t *hba); 46291a2b48SSukumar Swaminathan static uint32_t emlxs_timer_check_pkts(emlxs_hba_t *hba, uint8_t *flag); 47291a2b48SSukumar Swaminathan static void emlxs_timer_check_nodes(emlxs_port_t *port, uint8_t *flag); 48291a2b48SSukumar Swaminathan static void emlxs_timer_check_linkup(emlxs_hba_t *hba); 49291a2b48SSukumar Swaminathan static void emlxs_timer_check_discovery(emlxs_port_t *port); 50291a2b48SSukumar Swaminathan static void emlxs_timer_check_ub(emlxs_port_t *port); 51*82527734SSukumar Swaminathan static void emlxs_timer_check_channels(emlxs_hba_t *hba, uint8_t *flag); 52291a2b48SSukumar Swaminathan static uint32_t emlxs_pkt_chip_timeout(emlxs_port_t *port, emlxs_buf_t *sbp, 53291a2b48SSukumar Swaminathan Q *abortq, uint8_t *flag); 54fcf3ce44SJohn Forte 55fcf3ce44SJohn Forte #ifdef TX_WATCHDOG 56291a2b48SSukumar Swaminathan static void emlxs_tx_watchdog(emlxs_hba_t *hba); 57291a2b48SSukumar Swaminathan #endif /* TX_WATCHDOG */ 58fcf3ce44SJohn Forte 59fcf3ce44SJohn Forte extern clock_t 60fcf3ce44SJohn Forte emlxs_timeout(emlxs_hba_t *hba, uint32_t timeout) 61fcf3ce44SJohn Forte { 62fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 63fcf3ce44SJohn Forte clock_t time; 64fcf3ce44SJohn Forte 65fcf3ce44SJohn Forte /* Set thread timeout */ 66fcf3ce44SJohn Forte if (cfg[CFG_TIMEOUT_ENABLE].current) { 67fcf3ce44SJohn Forte (void) drv_getparm(LBOLT, &time); 68fcf3ce44SJohn Forte time += (timeout * drv_usectohz(1000000)); 69fcf3ce44SJohn Forte } else { 70fcf3ce44SJohn Forte time = -1; 71fcf3ce44SJohn Forte } 72fcf3ce44SJohn Forte 73fcf3ce44SJohn Forte return (time); 74fcf3ce44SJohn Forte 75*82527734SSukumar Swaminathan } /* emlxs_timeout() */ 76fcf3ce44SJohn Forte 77fcf3ce44SJohn Forte 78fcf3ce44SJohn Forte static void 79fcf3ce44SJohn Forte emlxs_timer(void *arg) 80fcf3ce44SJohn Forte { 81fcf3ce44SJohn Forte emlxs_hba_t *hba = (emlxs_hba_t *)arg; 82fcf3ce44SJohn Forte 83fcf3ce44SJohn Forte if (!hba->timer_id) { 84fcf3ce44SJohn Forte return; 85fcf3ce44SJohn Forte } 86291a2b48SSukumar Swaminathan 87fcf3ce44SJohn Forte mutex_enter(&EMLXS_TIMER_LOCK); 88fcf3ce44SJohn Forte 89*82527734SSukumar Swaminathan EMLXS_SLI_POLL_ERRATT(hba); 90*82527734SSukumar Swaminathan 91fcf3ce44SJohn Forte /* Only one timer thread is allowed */ 92fcf3ce44SJohn Forte if (hba->timer_flags & EMLXS_TIMER_BUSY) { 93fcf3ce44SJohn Forte mutex_exit(&EMLXS_TIMER_LOCK); 94fcf3ce44SJohn Forte return; 95fcf3ce44SJohn Forte } 96291a2b48SSukumar Swaminathan 97fcf3ce44SJohn Forte /* Check if a kill request has been made */ 98fcf3ce44SJohn Forte if (hba->timer_flags & EMLXS_TIMER_KILL) { 99fcf3ce44SJohn Forte hba->timer_id = 0; 100fcf3ce44SJohn Forte hba->timer_flags |= EMLXS_TIMER_ENDED; 101fcf3ce44SJohn Forte 102fcf3ce44SJohn Forte mutex_exit(&EMLXS_TIMER_LOCK); 103fcf3ce44SJohn Forte return; 104fcf3ce44SJohn Forte } 105291a2b48SSukumar Swaminathan 106fcf3ce44SJohn Forte hba->timer_flags |= (EMLXS_TIMER_BUSY | EMLXS_TIMER_STARTED); 107fcf3ce44SJohn Forte hba->timer_tics = DRV_TIME; 108fcf3ce44SJohn Forte 109fcf3ce44SJohn Forte mutex_exit(&EMLXS_TIMER_LOCK); 110fcf3ce44SJohn Forte 111291a2b48SSukumar Swaminathan /* Perform standard checks */ 112291a2b48SSukumar Swaminathan emlxs_timer_checks(hba); 113291a2b48SSukumar Swaminathan 114291a2b48SSukumar Swaminathan /* Restart the timer */ 115291a2b48SSukumar Swaminathan mutex_enter(&EMLXS_TIMER_LOCK); 116291a2b48SSukumar Swaminathan 117291a2b48SSukumar Swaminathan hba->timer_flags &= ~EMLXS_TIMER_BUSY; 118291a2b48SSukumar Swaminathan 119291a2b48SSukumar Swaminathan /* If timer is still enabled, restart it */ 120291a2b48SSukumar Swaminathan if (!(hba->timer_flags & EMLXS_TIMER_KILL)) { 121291a2b48SSukumar Swaminathan hba->timer_id = 122291a2b48SSukumar Swaminathan timeout(emlxs_timer, (void *)hba, 123291a2b48SSukumar Swaminathan (EMLXS_TIMER_PERIOD * drv_usectohz(1000000))); 124291a2b48SSukumar Swaminathan } else { 125291a2b48SSukumar Swaminathan hba->timer_id = 0; 126291a2b48SSukumar Swaminathan hba->timer_flags |= EMLXS_TIMER_ENDED; 127291a2b48SSukumar Swaminathan } 128291a2b48SSukumar Swaminathan 129291a2b48SSukumar Swaminathan mutex_exit(&EMLXS_TIMER_LOCK); 130291a2b48SSukumar Swaminathan 131291a2b48SSukumar Swaminathan return; 132291a2b48SSukumar Swaminathan 133*82527734SSukumar Swaminathan } /* emlxs_timer() */ 134291a2b48SSukumar Swaminathan 135291a2b48SSukumar Swaminathan 136291a2b48SSukumar Swaminathan extern void 137291a2b48SSukumar Swaminathan emlxs_timer_checks(emlxs_hba_t *hba) 138291a2b48SSukumar Swaminathan { 139291a2b48SSukumar Swaminathan emlxs_port_t *port = &PPORT; 140*82527734SSukumar Swaminathan uint8_t flag[MAX_CHANNEL]; 141291a2b48SSukumar Swaminathan uint32_t i; 142291a2b48SSukumar Swaminathan uint32_t rc; 143291a2b48SSukumar Swaminathan 144fcf3ce44SJohn Forte /* Exit if we are still initializing */ 145fcf3ce44SJohn Forte if (hba->state < FC_LINK_DOWN) { 146291a2b48SSukumar Swaminathan return; 147fcf3ce44SJohn Forte } 148291a2b48SSukumar Swaminathan 149*82527734SSukumar Swaminathan /* DEBUG - re-examine this path for SLI4 later */ 150*82527734SSukumar Swaminathan if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) { 151*82527734SSukumar Swaminathan /* Check for linkup timeout */ 152*82527734SSukumar Swaminathan emlxs_timer_check_linkup(hba); 153*82527734SSukumar Swaminathan 154*82527734SSukumar Swaminathan return; 155*82527734SSukumar Swaminathan } 156*82527734SSukumar Swaminathan 157291a2b48SSukumar Swaminathan bzero((void *)flag, sizeof (flag)); 158fcf3ce44SJohn Forte 159*82527734SSukumar Swaminathan /* Check SLI level timeouts */ 160*82527734SSukumar Swaminathan EMLXS_SLI_TIMER(hba); 161*82527734SSukumar Swaminathan 162*82527734SSukumar Swaminathan /* Check event queue */ 163*82527734SSukumar Swaminathan emlxs_timer_check_events(hba); 164fcf3ce44SJohn Forte 165fcf3ce44SJohn Forte /* Check heartbeat timer */ 166fcf3ce44SJohn Forte emlxs_timer_check_heartbeat(hba); 167fcf3ce44SJohn Forte 168fcf3ce44SJohn Forte #ifdef IDLE_TIMER 169fcf3ce44SJohn Forte emlxs_pm_idle_timer(hba); 170291a2b48SSukumar Swaminathan #endif /* IDLE_TIMER */ 171fcf3ce44SJohn Forte 172fcf3ce44SJohn Forte /* Check for loopback timeouts */ 173fcf3ce44SJohn Forte emlxs_timer_check_loopback(hba); 174fcf3ce44SJohn Forte 175fcf3ce44SJohn Forte /* Check for packet timeouts */ 176fcf3ce44SJohn Forte rc = emlxs_timer_check_pkts(hba, flag); 177fcf3ce44SJohn Forte 178fcf3ce44SJohn Forte if (rc) { 179fcf3ce44SJohn Forte /* Link or adapter is being reset */ 180291a2b48SSukumar Swaminathan return; 181fcf3ce44SJohn Forte } 182291a2b48SSukumar Swaminathan 183fcf3ce44SJohn Forte /* Check for linkup timeout */ 184fcf3ce44SJohn Forte emlxs_timer_check_linkup(hba); 185fcf3ce44SJohn Forte 186fcf3ce44SJohn Forte /* Check the ports */ 187fcf3ce44SJohn Forte for (i = 0; i < MAX_VPORTS; i++) { 188fcf3ce44SJohn Forte port = &VPORT(i); 189fcf3ce44SJohn Forte 190fcf3ce44SJohn Forte if (!(port->flag & EMLXS_PORT_BOUND)) { 191fcf3ce44SJohn Forte continue; 192fcf3ce44SJohn Forte } 193291a2b48SSukumar Swaminathan 194fcf3ce44SJohn Forte /* Check for node gate timeouts */ 195fcf3ce44SJohn Forte emlxs_timer_check_nodes(port, flag); 196fcf3ce44SJohn Forte 197fcf3ce44SJohn Forte /* Check for tape discovery timeout */ 198fcf3ce44SJohn Forte emlxs_timer_check_discovery(port); 199fcf3ce44SJohn Forte 200fcf3ce44SJohn Forte /* Check for UB timeouts */ 201fcf3ce44SJohn Forte emlxs_timer_check_ub(port); 202fcf3ce44SJohn Forte 203fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 204fcf3ce44SJohn Forte /* Check for DHCHAP authentication timeouts */ 205fcf3ce44SJohn Forte emlxs_timer_check_dhchap(port); 206291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 207fcf3ce44SJohn Forte 208fcf3ce44SJohn Forte } 209fcf3ce44SJohn Forte 210*82527734SSukumar Swaminathan /* Check for IO channel service timeouts */ 211fcf3ce44SJohn Forte /* Always do this last */ 212*82527734SSukumar Swaminathan emlxs_timer_check_channels(hba, flag); 213fcf3ce44SJohn Forte 214fcf3ce44SJohn Forte return; 215fcf3ce44SJohn Forte 216*82527734SSukumar Swaminathan } /* emlxs_timer_checks() */ 217fcf3ce44SJohn Forte 218fcf3ce44SJohn Forte 219fcf3ce44SJohn Forte extern void 220fcf3ce44SJohn Forte emlxs_timer_start(emlxs_hba_t *hba) 221fcf3ce44SJohn Forte { 222fcf3ce44SJohn Forte if (hba->timer_id) { 223fcf3ce44SJohn Forte return; 224fcf3ce44SJohn Forte } 225291a2b48SSukumar Swaminathan 226fcf3ce44SJohn Forte /* Restart the timer */ 227fcf3ce44SJohn Forte mutex_enter(&EMLXS_TIMER_LOCK); 228fcf3ce44SJohn Forte if (!hba->timer_id) { 229fcf3ce44SJohn Forte hba->timer_flags = 0; 230291a2b48SSukumar Swaminathan hba->timer_id = 231291a2b48SSukumar Swaminathan timeout(emlxs_timer, (void *)hba, drv_usectohz(1000000)); 232fcf3ce44SJohn Forte } 233fcf3ce44SJohn Forte mutex_exit(&EMLXS_TIMER_LOCK); 234fcf3ce44SJohn Forte 235*82527734SSukumar Swaminathan } /* emlxs_timer_start() */ 236fcf3ce44SJohn Forte 237fcf3ce44SJohn Forte 238fcf3ce44SJohn Forte extern void 239fcf3ce44SJohn Forte emlxs_timer_stop(emlxs_hba_t *hba) 240fcf3ce44SJohn Forte { 241fcf3ce44SJohn Forte if (!hba->timer_id) { 242fcf3ce44SJohn Forte return; 243fcf3ce44SJohn Forte } 244291a2b48SSukumar Swaminathan 245fcf3ce44SJohn Forte mutex_enter(&EMLXS_TIMER_LOCK); 246fcf3ce44SJohn Forte hba->timer_flags |= EMLXS_TIMER_KILL; 247fcf3ce44SJohn Forte 248fcf3ce44SJohn Forte while (hba->timer_id) { 249fcf3ce44SJohn Forte mutex_exit(&EMLXS_TIMER_LOCK); 250fcf3ce44SJohn Forte delay(drv_usectohz(500000)); 251fcf3ce44SJohn Forte mutex_enter(&EMLXS_TIMER_LOCK); 252fcf3ce44SJohn Forte } 253fcf3ce44SJohn Forte mutex_exit(&EMLXS_TIMER_LOCK); 254fcf3ce44SJohn Forte 255fcf3ce44SJohn Forte return; 256fcf3ce44SJohn Forte 257*82527734SSukumar Swaminathan } /* emlxs_timer_stop() */ 258fcf3ce44SJohn Forte 259fcf3ce44SJohn Forte 260fcf3ce44SJohn Forte static uint32_t 261fcf3ce44SJohn Forte emlxs_timer_check_pkts(emlxs_hba_t *hba, uint8_t *flag) 262fcf3ce44SJohn Forte { 263fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 264fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 265fcf3ce44SJohn Forte Q tmo; 266*82527734SSukumar Swaminathan int32_t channelno; 267*82527734SSukumar Swaminathan CHANNEL *cp; 268fcf3ce44SJohn Forte NODELIST *nlp; 269fcf3ce44SJohn Forte IOCBQ *prev; 270fcf3ce44SJohn Forte IOCBQ *next; 271fcf3ce44SJohn Forte IOCB *iocb; 272fcf3ce44SJohn Forte IOCBQ *iocbq; 273fcf3ce44SJohn Forte emlxs_buf_t *sbp; 274fcf3ce44SJohn Forte fc_packet_t *pkt; 275fcf3ce44SJohn Forte Q abort; 276fcf3ce44SJohn Forte uint32_t iotag; 277fcf3ce44SJohn Forte uint32_t rc; 278fcf3ce44SJohn Forte 279fcf3ce44SJohn Forte if (!cfg[CFG_TIMEOUT_ENABLE].current) { 280fcf3ce44SJohn Forte return (0); 281fcf3ce44SJohn Forte } 282291a2b48SSukumar Swaminathan 283fcf3ce44SJohn Forte if (hba->pkt_timer > hba->timer_tics) { 284fcf3ce44SJohn Forte return (0); 285fcf3ce44SJohn Forte } 286291a2b48SSukumar Swaminathan 287fcf3ce44SJohn Forte hba->pkt_timer = hba->timer_tics + EMLXS_PKT_PERIOD; 288fcf3ce44SJohn Forte 289fcf3ce44SJohn Forte 290291a2b48SSukumar Swaminathan bzero((void *)&tmo, sizeof (Q)); 291fcf3ce44SJohn Forte 292fcf3ce44SJohn Forte /* 293fcf3ce44SJohn Forte * We must hold the locks here because we never know when an iocb 294fcf3ce44SJohn Forte * will be removed out from under us 295fcf3ce44SJohn Forte */ 296fcf3ce44SJohn Forte 297*82527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 298fcf3ce44SJohn Forte 299*82527734SSukumar Swaminathan for (channelno = 0; channelno < hba->chan_count; channelno++) { 300*82527734SSukumar Swaminathan cp = &hba->chan[channelno]; 301fcf3ce44SJohn Forte 302*82527734SSukumar Swaminathan /* Scan the tx queues for each active node on the channel */ 303fcf3ce44SJohn Forte 304fcf3ce44SJohn Forte /* Get the first node */ 305*82527734SSukumar Swaminathan nlp = (NODELIST *)cp->nodeq.q_first; 306fcf3ce44SJohn Forte 307fcf3ce44SJohn Forte while (nlp) { 308fcf3ce44SJohn Forte /* Scan the node's priority tx queue */ 309fcf3ce44SJohn Forte prev = NULL; 310*82527734SSukumar Swaminathan iocbq = (IOCBQ *)nlp->nlp_ptx[channelno].q_first; 311fcf3ce44SJohn Forte 312fcf3ce44SJohn Forte while (iocbq) { 313fcf3ce44SJohn Forte next = (IOCBQ *)iocbq->next; 314fcf3ce44SJohn Forte iocb = &iocbq->iocb; 315fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 316fcf3ce44SJohn Forte 317fcf3ce44SJohn Forte /* Check if iocb has timed out */ 318fcf3ce44SJohn Forte if (sbp && hba->timer_tics >= sbp->ticks) { 319fcf3ce44SJohn Forte /* iocb timed out, now deque it */ 320fcf3ce44SJohn Forte if (next == NULL) { 321*82527734SSukumar Swaminathan nlp->nlp_ptx[channelno].q_last = 322fcf3ce44SJohn Forte (uint8_t *)prev; 323fcf3ce44SJohn Forte } 324291a2b48SSukumar Swaminathan 325fcf3ce44SJohn Forte if (prev == NULL) { 326*82527734SSukumar Swaminathan nlp->nlp_ptx[channelno]. 327*82527734SSukumar Swaminathan q_first = (uint8_t *)next; 328fcf3ce44SJohn Forte } else { 329fcf3ce44SJohn Forte prev->next = next; 330fcf3ce44SJohn Forte } 331fcf3ce44SJohn Forte 332fcf3ce44SJohn Forte iocbq->next = NULL; 333*82527734SSukumar Swaminathan nlp->nlp_ptx[channelno].q_cnt--; 334fcf3ce44SJohn Forte 335291a2b48SSukumar Swaminathan /* Add this iocb to our local */ 336291a2b48SSukumar Swaminathan /* timout queue */ 337fcf3ce44SJohn Forte 338fcf3ce44SJohn Forte /* 339*82527734SSukumar Swaminathan * This way we don't hold the TX_CHANNEL 340fcf3ce44SJohn Forte * lock too long 341fcf3ce44SJohn Forte */ 342fcf3ce44SJohn Forte 343fcf3ce44SJohn Forte if (tmo.q_first) { 344fcf3ce44SJohn Forte ((IOCBQ *)tmo.q_last)->next = 345fcf3ce44SJohn Forte iocbq; 346291a2b48SSukumar Swaminathan tmo.q_last = 347291a2b48SSukumar Swaminathan (uint8_t *)iocbq; 348fcf3ce44SJohn Forte tmo.q_cnt++; 349fcf3ce44SJohn Forte } else { 350291a2b48SSukumar Swaminathan tmo.q_first = 351291a2b48SSukumar Swaminathan (uint8_t *)iocbq; 352291a2b48SSukumar Swaminathan tmo.q_last = 353291a2b48SSukumar Swaminathan (uint8_t *)iocbq; 354fcf3ce44SJohn Forte tmo.q_cnt = 1; 355fcf3ce44SJohn Forte } 356fcf3ce44SJohn Forte iocbq->next = NULL; 357fcf3ce44SJohn Forte 358fcf3ce44SJohn Forte } else { 359fcf3ce44SJohn Forte prev = iocbq; 360fcf3ce44SJohn Forte } 361fcf3ce44SJohn Forte 362fcf3ce44SJohn Forte iocbq = next; 363fcf3ce44SJohn Forte 364fcf3ce44SJohn Forte } /* while (iocbq) */ 365fcf3ce44SJohn Forte 366fcf3ce44SJohn Forte 367fcf3ce44SJohn Forte /* Scan the node's tx queue */ 368fcf3ce44SJohn Forte prev = NULL; 369*82527734SSukumar Swaminathan iocbq = (IOCBQ *)nlp->nlp_tx[channelno].q_first; 370fcf3ce44SJohn Forte 371fcf3ce44SJohn Forte while (iocbq) { 372fcf3ce44SJohn Forte next = (IOCBQ *)iocbq->next; 373fcf3ce44SJohn Forte iocb = &iocbq->iocb; 374fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 375fcf3ce44SJohn Forte 376fcf3ce44SJohn Forte /* Check if iocb has timed out */ 377fcf3ce44SJohn Forte if (sbp && hba->timer_tics >= sbp->ticks) { 378fcf3ce44SJohn Forte /* iocb timed out, now deque it */ 379fcf3ce44SJohn Forte if (next == NULL) { 380*82527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_last = 381fcf3ce44SJohn Forte (uint8_t *)prev; 382fcf3ce44SJohn Forte } 383291a2b48SSukumar Swaminathan 384fcf3ce44SJohn Forte if (prev == NULL) { 385*82527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_first = 386fcf3ce44SJohn Forte (uint8_t *)next; 387fcf3ce44SJohn Forte } else { 388fcf3ce44SJohn Forte prev->next = next; 389fcf3ce44SJohn Forte } 390fcf3ce44SJohn Forte 391fcf3ce44SJohn Forte iocbq->next = NULL; 392*82527734SSukumar Swaminathan nlp->nlp_tx[channelno].q_cnt--; 393fcf3ce44SJohn Forte 394291a2b48SSukumar Swaminathan /* Add this iocb to our local */ 395291a2b48SSukumar Swaminathan /* timout queue */ 396fcf3ce44SJohn Forte 397fcf3ce44SJohn Forte /* 398*82527734SSukumar Swaminathan * This way we don't hold the TX_CHANNEL 399fcf3ce44SJohn Forte * lock too long 400fcf3ce44SJohn Forte */ 401fcf3ce44SJohn Forte 402fcf3ce44SJohn Forte if (tmo.q_first) { 403fcf3ce44SJohn Forte ((IOCBQ *)tmo.q_last)->next = 404fcf3ce44SJohn Forte iocbq; 405291a2b48SSukumar Swaminathan tmo.q_last = 406291a2b48SSukumar Swaminathan (uint8_t *)iocbq; 407fcf3ce44SJohn Forte tmo.q_cnt++; 408fcf3ce44SJohn Forte } else { 409291a2b48SSukumar Swaminathan tmo.q_first = 410291a2b48SSukumar Swaminathan (uint8_t *)iocbq; 411291a2b48SSukumar Swaminathan tmo.q_last = 412291a2b48SSukumar Swaminathan (uint8_t *)iocbq; 413fcf3ce44SJohn Forte tmo.q_cnt = 1; 414fcf3ce44SJohn Forte } 415fcf3ce44SJohn Forte iocbq->next = NULL; 416fcf3ce44SJohn Forte 417fcf3ce44SJohn Forte } else { 418fcf3ce44SJohn Forte prev = iocbq; 419fcf3ce44SJohn Forte } 420fcf3ce44SJohn Forte 421fcf3ce44SJohn Forte iocbq = next; 422fcf3ce44SJohn Forte 423fcf3ce44SJohn Forte } /* while (iocbq) */ 424fcf3ce44SJohn Forte 425*82527734SSukumar Swaminathan if (nlp == (NODELIST *)cp->nodeq.q_last) { 426fcf3ce44SJohn Forte nlp = NULL; 427fcf3ce44SJohn Forte } else { 428*82527734SSukumar Swaminathan nlp = nlp->nlp_next[channelno]; 429fcf3ce44SJohn Forte } 430fcf3ce44SJohn Forte 431*82527734SSukumar Swaminathan } /* while (nlp) */ 432fcf3ce44SJohn Forte 433fcf3ce44SJohn Forte } /* end of for */ 434fcf3ce44SJohn Forte 435fcf3ce44SJohn Forte /* Now cleanup the iocb's */ 436fcf3ce44SJohn Forte iocbq = (IOCBQ *)tmo.q_first; 437fcf3ce44SJohn Forte while (iocbq) { 438fcf3ce44SJohn Forte /* Free the IoTag and the bmp */ 439fcf3ce44SJohn Forte iocb = &iocbq->iocb; 440*82527734SSukumar Swaminathan channelno = ((CHANNEL *)iocbq->channel)->channelno; 441*82527734SSukumar Swaminathan sbp = iocbq->sbp; 442fcf3ce44SJohn Forte if (sbp && (sbp != STALE_PACKET)) { 443*82527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) { 444*82527734SSukumar Swaminathan hba->fc_table[sbp->iotag] = NULL; 445*82527734SSukumar Swaminathan emlxs_sli4_free_xri(hba, sbp, sbp->xp); 446*82527734SSukumar Swaminathan } else { 447*82527734SSukumar Swaminathan (void) emlxs_unregister_pkt( 448*82527734SSukumar Swaminathan (CHANNEL *)iocbq->channel, 449*82527734SSukumar Swaminathan iocb->ULPIOTAG, 0); 450fcf3ce44SJohn Forte } 451*82527734SSukumar Swaminathan 452*82527734SSukumar Swaminathan mutex_enter(&sbp->mtx); 453fcf3ce44SJohn Forte sbp->pkt_flags |= PACKET_IN_TIMEOUT; 454fcf3ce44SJohn Forte mutex_exit(&sbp->mtx); 455fcf3ce44SJohn Forte } 456291a2b48SSukumar Swaminathan 457fcf3ce44SJohn Forte iocbq = (IOCBQ *)iocbq->next; 458fcf3ce44SJohn Forte 459fcf3ce44SJohn Forte } /* end of while */ 460fcf3ce44SJohn Forte 461*82527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 462fcf3ce44SJohn Forte 463fcf3ce44SJohn Forte /* Now complete the transmit timeouts outside the locks */ 464fcf3ce44SJohn Forte iocbq = (IOCBQ *)tmo.q_first; 465fcf3ce44SJohn Forte while (iocbq) { 466fcf3ce44SJohn Forte /* Save the next iocbq for now */ 467fcf3ce44SJohn Forte next = (IOCBQ *)iocbq->next; 468fcf3ce44SJohn Forte 469fcf3ce44SJohn Forte /* Unlink this iocbq */ 470fcf3ce44SJohn Forte iocbq->next = NULL; 471fcf3ce44SJohn Forte 472fcf3ce44SJohn Forte /* Get the pkt */ 473fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 474fcf3ce44SJohn Forte 475fcf3ce44SJohn Forte if (sbp) { 476291a2b48SSukumar Swaminathan /* Warning: Some FCT sbp's don't have */ 477291a2b48SSukumar Swaminathan /* fc_packet objects */ 478fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 479fcf3ce44SJohn Forte 480fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_timeout_msg, 481fcf3ce44SJohn Forte "TXQ abort: sbp=%p iotag=%x tmo=%d", sbp, 482fcf3ce44SJohn Forte sbp->iotag, (pkt) ? pkt->pkt_timeout : 0); 483fcf3ce44SJohn Forte 484fcf3ce44SJohn Forte if (hba->state >= FC_LINK_UP) { 485fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 486fcf3ce44SJohn Forte IOERR_ABORT_TIMEOUT, 1); 487fcf3ce44SJohn Forte } else { 488fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, 489fcf3ce44SJohn Forte IOERR_LINK_DOWN, 1); 490fcf3ce44SJohn Forte } 491291a2b48SSukumar Swaminathan 492fcf3ce44SJohn Forte } 493291a2b48SSukumar Swaminathan 494fcf3ce44SJohn Forte iocbq = next; 495fcf3ce44SJohn Forte 496fcf3ce44SJohn Forte } /* end of while */ 497fcf3ce44SJohn Forte 498fcf3ce44SJohn Forte 499fcf3ce44SJohn Forte 500fcf3ce44SJohn Forte /* Now check the chip */ 501291a2b48SSukumar Swaminathan bzero((void *)&abort, sizeof (Q)); 502fcf3ce44SJohn Forte 503*82527734SSukumar Swaminathan /* Check the HBA for outstanding IOs */ 504fcf3ce44SJohn Forte rc = 0; 505*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 506*82527734SSukumar Swaminathan for (iotag = 1; iotag < hba->max_iotag; iotag++) { 507*82527734SSukumar Swaminathan sbp = hba->fc_table[iotag]; 508*82527734SSukumar Swaminathan if (sbp && (sbp != STALE_PACKET) && 509*82527734SSukumar Swaminathan (sbp->pkt_flags & PACKET_IN_CHIPQ) && 510*82527734SSukumar Swaminathan !(sbp->pkt_flags & (PACKET_IN_FLUSH | 511*82527734SSukumar Swaminathan PACKET_XRI_CLOSED)) && 512*82527734SSukumar Swaminathan (hba->timer_tics >= sbp->ticks)) { 513*82527734SSukumar Swaminathan rc = emlxs_pkt_chip_timeout(sbp->iocbq.port, 514*82527734SSukumar Swaminathan sbp, &abort, flag); 515*82527734SSukumar Swaminathan 516*82527734SSukumar Swaminathan if (rc) { 517*82527734SSukumar Swaminathan break; 518fcf3ce44SJohn Forte } 519fcf3ce44SJohn Forte } 520fcf3ce44SJohn Forte } 521*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 522fcf3ce44SJohn Forte 523fcf3ce44SJohn Forte /* Now put the iocb's on the tx queue */ 524fcf3ce44SJohn Forte iocbq = (IOCBQ *)abort.q_first; 525fcf3ce44SJohn Forte while (iocbq) { 526fcf3ce44SJohn Forte /* Save the next iocbq for now */ 527fcf3ce44SJohn Forte next = (IOCBQ *)iocbq->next; 528fcf3ce44SJohn Forte 529fcf3ce44SJohn Forte /* Unlink this iocbq */ 530fcf3ce44SJohn Forte iocbq->next = NULL; 531fcf3ce44SJohn Forte 532fcf3ce44SJohn Forte /* Send this iocbq */ 533fcf3ce44SJohn Forte emlxs_tx_put(iocbq, 1); 534fcf3ce44SJohn Forte 535fcf3ce44SJohn Forte iocbq = next; 536fcf3ce44SJohn Forte } 537fcf3ce44SJohn Forte 538*82527734SSukumar Swaminathan /* Now trigger IO channel service to send these abort iocbq */ 539*82527734SSukumar Swaminathan for (channelno = 0; channelno < hba->chan_count; channelno++) { 540*82527734SSukumar Swaminathan if (!flag[channelno]) { 541*82527734SSukumar Swaminathan continue; 542*82527734SSukumar Swaminathan } 543*82527734SSukumar Swaminathan cp = &hba->chan[channelno]; 544*82527734SSukumar Swaminathan 545*82527734SSukumar Swaminathan EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, 0); 546*82527734SSukumar Swaminathan } 547*82527734SSukumar Swaminathan 548fcf3ce44SJohn Forte if (rc == 1) { 549fcf3ce44SJohn Forte /* Spawn a thread to reset the link */ 550bb63f56eSSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_reset_link_thread, NULL, NULL); 551fcf3ce44SJohn Forte } else if (rc == 2) { 552fcf3ce44SJohn Forte /* Spawn a thread to reset the adapter */ 553bb63f56eSSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_restart_thread, NULL, NULL); 554fcf3ce44SJohn Forte } 555291a2b48SSukumar Swaminathan 556fcf3ce44SJohn Forte return (rc); 557fcf3ce44SJohn Forte 558*82527734SSukumar Swaminathan } /* emlxs_timer_check_pkts() */ 559fcf3ce44SJohn Forte 560fcf3ce44SJohn Forte 561fcf3ce44SJohn Forte static void 562*82527734SSukumar Swaminathan emlxs_timer_check_channels(emlxs_hba_t *hba, uint8_t *flag) 563fcf3ce44SJohn Forte { 564fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 565fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 566*82527734SSukumar Swaminathan int32_t channelno; 567*82527734SSukumar Swaminathan CHANNEL *cp; 568*82527734SSukumar Swaminathan uint32_t logit; 569fcf3ce44SJohn Forte 570fcf3ce44SJohn Forte if (!cfg[CFG_TIMEOUT_ENABLE].current) { 571fcf3ce44SJohn Forte return; 572fcf3ce44SJohn Forte } 573291a2b48SSukumar Swaminathan 574*82527734SSukumar Swaminathan for (channelno = 0; channelno < hba->chan_count; channelno++) { 575*82527734SSukumar Swaminathan cp = &hba->chan[channelno]; 576*82527734SSukumar Swaminathan 577*82527734SSukumar Swaminathan logit = 0; 578fcf3ce44SJohn Forte 579*82527734SSukumar Swaminathan /* Check for channel timeout now */ 580*82527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 581*82527734SSukumar Swaminathan if (cp->timeout && (hba->timer_tics >= cp->timeout)) { 582*82527734SSukumar Swaminathan /* Check if there is work to do on channel and */ 583fcf3ce44SJohn Forte /* the link is still up */ 584*82527734SSukumar Swaminathan if (cp->nodeq.q_first) { 585*82527734SSukumar Swaminathan flag[channelno] = 1; 586*82527734SSukumar Swaminathan cp->timeout = hba->timer_tics + 10; 587fcf3ce44SJohn Forte 588fcf3ce44SJohn Forte if (hba->state >= FC_LINK_UP) { 589728bdc9bSSukumar Swaminathan logit = 1; 590fcf3ce44SJohn Forte } 591fcf3ce44SJohn Forte } else { 592*82527734SSukumar Swaminathan cp->timeout = 0; 593fcf3ce44SJohn Forte } 594fcf3ce44SJohn Forte } 595*82527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 596fcf3ce44SJohn Forte 597728bdc9bSSukumar Swaminathan if (logit) { 598728bdc9bSSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 599*82527734SSukumar Swaminathan &emlxs_chan_watchdog_msg, 600*82527734SSukumar Swaminathan "IO Channel %d cnt=%d,%d", 601*82527734SSukumar Swaminathan channelno, 602*82527734SSukumar Swaminathan hba->channel_tx_count, 603*82527734SSukumar Swaminathan hba->io_count); 604728bdc9bSSukumar Swaminathan } 605728bdc9bSSukumar Swaminathan 606fcf3ce44SJohn Forte /* 607*82527734SSukumar Swaminathan * If IO channel flag is set, request iocb servicing 608*82527734SSukumar Swaminathan * here to send any iocb's that may still be queued 609fcf3ce44SJohn Forte */ 610*82527734SSukumar Swaminathan if (flag[channelno]) { 611*82527734SSukumar Swaminathan EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, 0); 612fcf3ce44SJohn Forte } 613fcf3ce44SJohn Forte } 614fcf3ce44SJohn Forte 615fcf3ce44SJohn Forte return; 616fcf3ce44SJohn Forte 617*82527734SSukumar Swaminathan } /* emlxs_timer_check_channels() */ 618fcf3ce44SJohn Forte 619fcf3ce44SJohn Forte 620fcf3ce44SJohn Forte static void 621fcf3ce44SJohn Forte emlxs_timer_check_nodes(emlxs_port_t *port, uint8_t *flag) 622fcf3ce44SJohn Forte { 623fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 624fcf3ce44SJohn Forte uint32_t found; 625fcf3ce44SJohn Forte uint32_t i; 626fcf3ce44SJohn Forte NODELIST *nlp; 627*82527734SSukumar Swaminathan int32_t channelno; 628fcf3ce44SJohn Forte 629fcf3ce44SJohn Forte for (;;) { 630fcf3ce44SJohn Forte /* Check node gate flag for expiration */ 631fcf3ce44SJohn Forte found = 0; 632fcf3ce44SJohn Forte 633fcf3ce44SJohn Forte /* 634291a2b48SSukumar Swaminathan * We need to lock, scan, and unlock because we can't hold the 635291a2b48SSukumar Swaminathan * lock while we call node_open 636fcf3ce44SJohn Forte */ 637fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_READER); 638fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 639fcf3ce44SJohn Forte nlp = port->node_table[i]; 640fcf3ce44SJohn Forte while (nlp != NULL) { 641*82527734SSukumar Swaminathan for (channelno = 0; 642*82527734SSukumar Swaminathan channelno < hba->chan_count; 643*82527734SSukumar Swaminathan channelno++) { 644291a2b48SSukumar Swaminathan /* Check if the node timer is active */ 645291a2b48SSukumar Swaminathan /* and if timer has expired */ 646*82527734SSukumar Swaminathan if (nlp->nlp_tics[channelno] && 647fcf3ce44SJohn Forte (hba->timer_tics >= 648*82527734SSukumar Swaminathan nlp->nlp_tics[channelno])) { 649291a2b48SSukumar Swaminathan /* If so, set the flag and */ 650291a2b48SSukumar Swaminathan /* break out */ 651fcf3ce44SJohn Forte found = 1; 652*82527734SSukumar Swaminathan flag[channelno] = 1; 653fcf3ce44SJohn Forte break; 654fcf3ce44SJohn Forte } 655fcf3ce44SJohn Forte } 656fcf3ce44SJohn Forte 657*82527734SSukumar Swaminathan if (nlp->nlp_force_rscn && 658*82527734SSukumar Swaminathan (hba->timer_tics >= nlp->nlp_force_rscn)) { 659*82527734SSukumar Swaminathan nlp->nlp_force_rscn = 0; 660*82527734SSukumar Swaminathan /* 661*82527734SSukumar Swaminathan * Generate an RSCN to 662*82527734SSukumar Swaminathan * wakeup ULP 663*82527734SSukumar Swaminathan */ 664*82527734SSukumar Swaminathan (void) emlxs_generate_rscn(port, 665*82527734SSukumar Swaminathan nlp->nlp_DID); 666*82527734SSukumar Swaminathan } 667*82527734SSukumar Swaminathan 668fcf3ce44SJohn Forte if (found) { 669fcf3ce44SJohn Forte break; 670fcf3ce44SJohn Forte } 671291a2b48SSukumar Swaminathan 672fcf3ce44SJohn Forte nlp = nlp->nlp_list_next; 673fcf3ce44SJohn Forte } 674fcf3ce44SJohn Forte 675fcf3ce44SJohn Forte if (found) { 676fcf3ce44SJohn Forte break; 677fcf3ce44SJohn Forte } 678291a2b48SSukumar Swaminathan 679fcf3ce44SJohn Forte } 680fcf3ce44SJohn Forte rw_exit(&port->node_rwlock); 681fcf3ce44SJohn Forte 682fcf3ce44SJohn Forte if (!found) { 683fcf3ce44SJohn Forte break; 684fcf3ce44SJohn Forte } 685291a2b48SSukumar Swaminathan 686*82527734SSukumar Swaminathan emlxs_node_timeout(port, nlp, channelno); 687fcf3ce44SJohn Forte } 688fcf3ce44SJohn Forte 689*82527734SSukumar Swaminathan } /* emlxs_timer_check_nodes() */ 690fcf3ce44SJohn Forte 691fcf3ce44SJohn Forte 692fcf3ce44SJohn Forte static void 693fcf3ce44SJohn Forte emlxs_timer_check_loopback(emlxs_hba_t *hba) 694fcf3ce44SJohn Forte { 695fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 696fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 697fcf3ce44SJohn Forte int32_t reset = 0; 698fcf3ce44SJohn Forte 699fcf3ce44SJohn Forte if (!cfg[CFG_TIMEOUT_ENABLE].current) { 700fcf3ce44SJohn Forte return; 701fcf3ce44SJohn Forte } 702291a2b48SSukumar Swaminathan 703fcf3ce44SJohn Forte /* Check the loopback timer for expiration */ 704fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 705fcf3ce44SJohn Forte 706291a2b48SSukumar Swaminathan if (!hba->loopback_tics || (hba->timer_tics < hba->loopback_tics)) { 707fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 708fcf3ce44SJohn Forte return; 709fcf3ce44SJohn Forte } 710291a2b48SSukumar Swaminathan 711fcf3ce44SJohn Forte hba->loopback_tics = 0; 712fcf3ce44SJohn Forte 713fcf3ce44SJohn Forte if (hba->flag & FC_LOOPBACK_MODE) { 714fcf3ce44SJohn Forte reset = 1; 715fcf3ce44SJohn Forte } 716291a2b48SSukumar Swaminathan 717fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 718fcf3ce44SJohn Forte 719fcf3ce44SJohn Forte if (reset) { 720fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_debug_msg, 721fcf3ce44SJohn Forte "LOOPBACK_MODE: Expired. Resetting..."); 722fcf3ce44SJohn Forte (void) emlxs_reset(port, FC_FCA_LINK_RESET); 723fcf3ce44SJohn Forte } 724291a2b48SSukumar Swaminathan 725fcf3ce44SJohn Forte return; 726fcf3ce44SJohn Forte 727*82527734SSukumar Swaminathan } /* emlxs_timer_check_loopback() */ 728fcf3ce44SJohn Forte 729fcf3ce44SJohn Forte 730fcf3ce44SJohn Forte static void 731fcf3ce44SJohn Forte emlxs_timer_check_linkup(emlxs_hba_t *hba) 732fcf3ce44SJohn Forte { 733fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 734fcf3ce44SJohn Forte uint32_t linkup; 735fcf3ce44SJohn Forte 736*82527734SSukumar Swaminathan /* Check if all mbox commands from previous activity are processed */ 737*82527734SSukumar Swaminathan if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) { 738*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MBOX_LOCK); 739*82527734SSukumar Swaminathan if (hba->mbox_queue.q_first) { 740*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MBOX_LOCK); 741*82527734SSukumar Swaminathan return; 742*82527734SSukumar Swaminathan } 743*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MBOX_LOCK); 744*82527734SSukumar Swaminathan } 745*82527734SSukumar Swaminathan 746fcf3ce44SJohn Forte /* Check the linkup timer for expiration */ 747fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 748fcf3ce44SJohn Forte linkup = 0; 749fcf3ce44SJohn Forte if (hba->linkup_timer && (hba->timer_tics >= hba->linkup_timer)) { 750fcf3ce44SJohn Forte hba->linkup_timer = 0; 751fcf3ce44SJohn Forte 752fcf3ce44SJohn Forte /* Make sure link is still ready */ 753fcf3ce44SJohn Forte if (hba->state >= FC_LINK_UP) { 754fcf3ce44SJohn Forte linkup = 1; 755fcf3ce44SJohn Forte } 756fcf3ce44SJohn Forte } 757fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 758fcf3ce44SJohn Forte 759fcf3ce44SJohn Forte /* Make the linkup callback */ 760fcf3ce44SJohn Forte if (linkup) { 761fcf3ce44SJohn Forte emlxs_port_online(port); 762fcf3ce44SJohn Forte } 763fcf3ce44SJohn Forte return; 764fcf3ce44SJohn Forte 765*82527734SSukumar Swaminathan } /* emlxs_timer_check_linkup() */ 766fcf3ce44SJohn Forte 767fcf3ce44SJohn Forte 768fcf3ce44SJohn Forte static void 769fcf3ce44SJohn Forte emlxs_timer_check_heartbeat(emlxs_hba_t *hba) 770fcf3ce44SJohn Forte { 771fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 772*82527734SSukumar Swaminathan MAILBOXQ *mbq; 773fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 774*82527734SSukumar Swaminathan int rc; 775fcf3ce44SJohn Forte 776fcf3ce44SJohn Forte if (!cfg[CFG_HEARTBEAT_ENABLE].current) { 777fcf3ce44SJohn Forte return; 778fcf3ce44SJohn Forte } 779291a2b48SSukumar Swaminathan 780fcf3ce44SJohn Forte if (hba->timer_tics < hba->heartbeat_timer) { 781fcf3ce44SJohn Forte return; 782fcf3ce44SJohn Forte } 783291a2b48SSukumar Swaminathan 784fcf3ce44SJohn Forte hba->heartbeat_timer = hba->timer_tics + 5; 785fcf3ce44SJohn Forte 786fcf3ce44SJohn Forte /* Return if adapter interrupts have occurred */ 787fcf3ce44SJohn Forte if (hba->heartbeat_flag) { 788fcf3ce44SJohn Forte hba->heartbeat_flag = 0; 789fcf3ce44SJohn Forte return; 790fcf3ce44SJohn Forte } 791fcf3ce44SJohn Forte /* No adapter interrupts have occured for 5 seconds now */ 792fcf3ce44SJohn Forte 793fcf3ce44SJohn Forte /* Return if mailbox is busy */ 794fcf3ce44SJohn Forte /* This means the mailbox timer routine is watching for problems */ 795fcf3ce44SJohn Forte if (hba->mbox_timer) { 796fcf3ce44SJohn Forte return; 797fcf3ce44SJohn Forte } 798291a2b48SSukumar Swaminathan 799fcf3ce44SJohn Forte /* Return if heartbeat is still outstanding */ 800fcf3ce44SJohn Forte if (hba->heartbeat_active) { 801fcf3ce44SJohn Forte return; 802fcf3ce44SJohn Forte } 803291a2b48SSukumar Swaminathan 804*82527734SSukumar Swaminathan if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1)) == 0) { 805fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 806fcf3ce44SJohn Forte "Unable to allocate heartbeat mailbox."); 807fcf3ce44SJohn Forte return; 808fcf3ce44SJohn Forte } 809291a2b48SSukumar Swaminathan 810*82527734SSukumar Swaminathan emlxs_mb_heartbeat(hba, mbq); 811fcf3ce44SJohn Forte hba->heartbeat_active = 1; 812fcf3ce44SJohn Forte 813*82527734SSukumar Swaminathan rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 814*82527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 815*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 816fcf3ce44SJohn Forte } 817fcf3ce44SJohn Forte 818fcf3ce44SJohn Forte return; 819fcf3ce44SJohn Forte 820*82527734SSukumar Swaminathan } /* emlxs_timer_check_heartbeat() */ 821fcf3ce44SJohn Forte 822fcf3ce44SJohn Forte 823fcf3ce44SJohn Forte static void 824fcf3ce44SJohn Forte emlxs_timer_check_discovery(emlxs_port_t *port) 825fcf3ce44SJohn Forte { 826fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 827fcf3ce44SJohn Forte emlxs_config_t *cfg = &CFG; 828fcf3ce44SJohn Forte int32_t send_clear_la; 829fcf3ce44SJohn Forte uint32_t found; 830fcf3ce44SJohn Forte uint32_t i; 831fcf3ce44SJohn Forte NODELIST *nlp; 832fcf3ce44SJohn Forte MAILBOXQ *mbox; 833*82527734SSukumar Swaminathan int rc; 834fcf3ce44SJohn Forte 835fcf3ce44SJohn Forte if (!cfg[CFG_TIMEOUT_ENABLE].current) { 836fcf3ce44SJohn Forte return; 837fcf3ce44SJohn Forte } 838291a2b48SSukumar Swaminathan 839fcf3ce44SJohn Forte /* Check the discovery timer for expiration */ 840fcf3ce44SJohn Forte send_clear_la = 0; 841fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 842fcf3ce44SJohn Forte while (hba->discovery_timer && 843fcf3ce44SJohn Forte (hba->timer_tics >= hba->discovery_timer) && 844fcf3ce44SJohn Forte (hba->state == FC_LINK_UP)) { 845fcf3ce44SJohn Forte send_clear_la = 1; 846fcf3ce44SJohn Forte 847fcf3ce44SJohn Forte /* Perform a flush on fcp2 nodes that are still closed */ 848fcf3ce44SJohn Forte found = 0; 849fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_READER); 850fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 851fcf3ce44SJohn Forte nlp = port->node_table[i]; 852fcf3ce44SJohn Forte while (nlp != NULL) { 853fcf3ce44SJohn Forte if ((nlp->nlp_fcp_info & NLP_FCP_2_DEVICE) && 854*82527734SSukumar Swaminathan (nlp->nlp_flag[hba->channel_fcp] & 855*82527734SSukumar Swaminathan NLP_CLOSED)) { 856fcf3ce44SJohn Forte found = 1; 857fcf3ce44SJohn Forte break; 858fcf3ce44SJohn Forte 859fcf3ce44SJohn Forte } 860fcf3ce44SJohn Forte nlp = nlp->nlp_list_next; 861fcf3ce44SJohn Forte } 862fcf3ce44SJohn Forte 863fcf3ce44SJohn Forte if (found) { 864fcf3ce44SJohn Forte break; 865fcf3ce44SJohn Forte } 866fcf3ce44SJohn Forte } 867fcf3ce44SJohn Forte rw_exit(&port->node_rwlock); 868fcf3ce44SJohn Forte 869fcf3ce44SJohn Forte if (!found) { 870fcf3ce44SJohn Forte break; 871fcf3ce44SJohn Forte } 872291a2b48SSukumar Swaminathan 873fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_missing_msg, 874fcf3ce44SJohn Forte "FCP2 device (did=%06x) missing. Flushing...", 875fcf3ce44SJohn Forte nlp->nlp_DID); 876fcf3ce44SJohn Forte 877fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 878fcf3ce44SJohn Forte 879fcf3ce44SJohn Forte (void) emlxs_mb_unreg_did(port, nlp->nlp_DID, NULL, NULL, NULL); 880fcf3ce44SJohn Forte 881fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 882fcf3ce44SJohn Forte 883fcf3ce44SJohn Forte } 884fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 885fcf3ce44SJohn Forte 886fcf3ce44SJohn Forte /* Try to send clear link attention, if needed */ 887fcf3ce44SJohn Forte if ((send_clear_la == 1) && 888*82527734SSukumar Swaminathan (mbox = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) { 889fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK); 890fcf3ce44SJohn Forte 891fcf3ce44SJohn Forte /* 892fcf3ce44SJohn Forte * If state is not FC_LINK_UP, then either the link has gone 893fcf3ce44SJohn Forte * down or a FC_CLEAR_LA has already been issued 894fcf3ce44SJohn Forte */ 895fcf3ce44SJohn Forte if (hba->state != FC_LINK_UP) { 896fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 897fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbox); 898fcf3ce44SJohn Forte } else { 899fcf3ce44SJohn Forte /* Change state and clear discovery timer */ 900*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_CLEAR_LA); 901fcf3ce44SJohn Forte 902fcf3ce44SJohn Forte hba->discovery_timer = 0; 903fcf3ce44SJohn Forte 904fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK); 905fcf3ce44SJohn Forte 906fcf3ce44SJohn Forte /* Prepare and send the CLEAR_LA command */ 907*82527734SSukumar Swaminathan emlxs_mb_clear_la(hba, mbox); 908fcf3ce44SJohn Forte 909*82527734SSukumar Swaminathan rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_NOWAIT, 0); 910*82527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 911fcf3ce44SJohn Forte (void) emlxs_mem_put(hba, MEM_MBOX, 912fcf3ce44SJohn Forte (uint8_t *)mbox); 913fcf3ce44SJohn Forte } 914fcf3ce44SJohn Forte } 915fcf3ce44SJohn Forte } 916291a2b48SSukumar Swaminathan 917fcf3ce44SJohn Forte return; 918fcf3ce44SJohn Forte 919*82527734SSukumar Swaminathan } /* emlxs_timer_check_discovery() */ 920fcf3ce44SJohn Forte 921fcf3ce44SJohn Forte 922fcf3ce44SJohn Forte static void 923fcf3ce44SJohn Forte emlxs_timer_check_ub(emlxs_port_t *port) 924fcf3ce44SJohn Forte { 925fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 926fcf3ce44SJohn Forte emlxs_unsol_buf_t *ulistp; 927fcf3ce44SJohn Forte fc_unsol_buf_t *ubp; 928fcf3ce44SJohn Forte emlxs_ub_priv_t *ub_priv; 929fcf3ce44SJohn Forte uint32_t i; 930fcf3ce44SJohn Forte 931fcf3ce44SJohn Forte if (port->ub_timer > hba->timer_tics) { 932fcf3ce44SJohn Forte return; 933fcf3ce44SJohn Forte } 934291a2b48SSukumar Swaminathan 935fcf3ce44SJohn Forte port->ub_timer = hba->timer_tics + EMLXS_UB_PERIOD; 936fcf3ce44SJohn Forte 937fcf3ce44SJohn Forte /* Check the unsolicited buffers */ 938fcf3ce44SJohn Forte mutex_enter(&EMLXS_UB_LOCK); 939fcf3ce44SJohn Forte 940fcf3ce44SJohn Forte ulistp = port->ub_pool; 941fcf3ce44SJohn Forte while (ulistp) { 942fcf3ce44SJohn Forte /* Check buffers in this pool */ 943fcf3ce44SJohn Forte for (i = 0; i < ulistp->pool_nentries; i++) { 944fcf3ce44SJohn Forte ubp = (fc_unsol_buf_t *)&ulistp->fc_ubufs[i]; 945fcf3ce44SJohn Forte ub_priv = ubp->ub_fca_private; 946fcf3ce44SJohn Forte 947fcf3ce44SJohn Forte if (!(ub_priv->flags & EMLXS_UB_IN_USE)) { 948fcf3ce44SJohn Forte continue; 949fcf3ce44SJohn Forte } 950291a2b48SSukumar Swaminathan 951291a2b48SSukumar Swaminathan /* If buffer has timed out, print message and */ 952291a2b48SSukumar Swaminathan /* increase timeout */ 953fcf3ce44SJohn Forte if ((ub_priv->time + ub_priv->timeout) <= 954fcf3ce44SJohn Forte hba->timer_tics) { 955fcf3ce44SJohn Forte ub_priv->flags |= EMLXS_UB_TIMEOUT; 956fcf3ce44SJohn Forte 957291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 958291a2b48SSukumar Swaminathan &emlxs_sfs_debug_msg, 959fcf3ce44SJohn Forte "Stale UB buffer detected (%d mins): " 960291a2b48SSukumar Swaminathan "buffer=%p (%x,%x,%x,%x)", 961291a2b48SSukumar Swaminathan (ub_priv->timeout / 60), ubp, 962291a2b48SSukumar Swaminathan ubp->ub_frame.type, ubp->ub_frame.s_id, 963291a2b48SSukumar Swaminathan ubp->ub_frame.ox_id, ubp->ub_frame.rx_id); 964fcf3ce44SJohn Forte 965fcf3ce44SJohn Forte /* Increase timeout period */ 966fcf3ce44SJohn Forte 967291a2b48SSukumar Swaminathan /* If timeout was 5 mins or less, */ 968291a2b48SSukumar Swaminathan /* increase it to 10 mins */ 969fcf3ce44SJohn Forte if (ub_priv->timeout <= (5 * 60)) { 970fcf3ce44SJohn Forte ub_priv->timeout = (10 * 60); 971fcf3ce44SJohn Forte } 972291a2b48SSukumar Swaminathan /* If timeout was 10 mins or less, */ 973291a2b48SSukumar Swaminathan /* increase it to 30 mins */ 974fcf3ce44SJohn Forte else if (ub_priv->timeout <= (10 * 60)) { 975fcf3ce44SJohn Forte ub_priv->timeout = (30 * 60); 976fcf3ce44SJohn Forte } 977fcf3ce44SJohn Forte /* Otherwise double it. */ 978fcf3ce44SJohn Forte else { 979fcf3ce44SJohn Forte ub_priv->timeout *= 2; 980fcf3ce44SJohn Forte } 981fcf3ce44SJohn Forte } 982fcf3ce44SJohn Forte } 983fcf3ce44SJohn Forte 984fcf3ce44SJohn Forte ulistp = ulistp->pool_next; 985fcf3ce44SJohn Forte } 986fcf3ce44SJohn Forte 987fcf3ce44SJohn Forte mutex_exit(&EMLXS_UB_LOCK); 988fcf3ce44SJohn Forte 989fcf3ce44SJohn Forte return; 990fcf3ce44SJohn Forte 991*82527734SSukumar Swaminathan } /* emlxs_timer_check_ub() */ 992fcf3ce44SJohn Forte 993fcf3ce44SJohn Forte 994fcf3ce44SJohn Forte /* EMLXS_FCTAB_LOCK must be held to call this */ 995fcf3ce44SJohn Forte static uint32_t 996291a2b48SSukumar Swaminathan emlxs_pkt_chip_timeout(emlxs_port_t *port, emlxs_buf_t *sbp, Q *abortq, 997291a2b48SSukumar Swaminathan uint8_t *flag) 998fcf3ce44SJohn Forte { 999fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1000*82527734SSukumar Swaminathan CHANNEL *cp = (CHANNEL *)sbp->channel; 1001fcf3ce44SJohn Forte IOCBQ *iocbq = NULL; 1002fcf3ce44SJohn Forte fc_packet_t *pkt; 1003fcf3ce44SJohn Forte uint32_t rc = 0; 1004fcf3ce44SJohn Forte 1005fcf3ce44SJohn Forte mutex_enter(&sbp->mtx); 1006fcf3ce44SJohn Forte 1007fcf3ce44SJohn Forte /* Warning: Some FCT sbp's don't have fc_packet objects */ 1008fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 1009fcf3ce44SJohn Forte 1010fcf3ce44SJohn Forte switch (sbp->abort_attempts) { 1011fcf3ce44SJohn Forte case 0: 1012fcf3ce44SJohn Forte 1013fcf3ce44SJohn Forte /* Create the abort IOCB */ 1014fcf3ce44SJohn Forte if (hba->state >= FC_LINK_UP) { 1015fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_timeout_msg, 1016291a2b48SSukumar Swaminathan "chipQ:1:Aborting. sbp=%p iotag=%x tmo=%d flags=%x", 1017291a2b48SSukumar Swaminathan sbp, sbp->iotag, 1018291a2b48SSukumar Swaminathan (pkt) ? pkt->pkt_timeout : 0, sbp->pkt_flags); 1019fcf3ce44SJohn Forte 1020291a2b48SSukumar Swaminathan iocbq = 1021291a2b48SSukumar Swaminathan emlxs_create_abort_xri_cn(port, sbp->node, 1022*82527734SSukumar Swaminathan sbp->iotag, cp, sbp->class, ABORT_TYPE_ABTS); 1023fcf3ce44SJohn Forte 1024291a2b48SSukumar Swaminathan /* The adapter will make 2 attempts to send ABTS */ 1025291a2b48SSukumar Swaminathan /* with 2*ratov timeout each time */ 1026291a2b48SSukumar Swaminathan sbp->ticks = 1027291a2b48SSukumar Swaminathan hba->timer_tics + (4 * hba->fc_ratov) + 10; 1028fcf3ce44SJohn Forte } else { 1029fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_timeout_msg, 1030291a2b48SSukumar Swaminathan "chipQ:1:Closing. sbp=%p iotag=%x tmo=%d flags=%x", 1031291a2b48SSukumar Swaminathan sbp, sbp->iotag, 1032291a2b48SSukumar Swaminathan (pkt) ? pkt->pkt_timeout : 0, sbp->pkt_flags); 1033fcf3ce44SJohn Forte 1034291a2b48SSukumar Swaminathan iocbq = 1035291a2b48SSukumar Swaminathan emlxs_create_close_xri_cn(port, sbp->node, 1036*82527734SSukumar Swaminathan sbp->iotag, cp); 1037fcf3ce44SJohn Forte 1038fcf3ce44SJohn Forte sbp->ticks = hba->timer_tics + 30; 1039fcf3ce44SJohn Forte } 1040fcf3ce44SJohn Forte 1041fcf3ce44SJohn Forte /* set the flags */ 1042fcf3ce44SJohn Forte sbp->pkt_flags |= (PACKET_IN_TIMEOUT | PACKET_XRI_CLOSED); 1043fcf3ce44SJohn Forte 1044*82527734SSukumar Swaminathan flag[cp->channelno] = 1; 1045fcf3ce44SJohn Forte rc = 0; 1046fcf3ce44SJohn Forte 1047fcf3ce44SJohn Forte break; 1048fcf3ce44SJohn Forte 1049fcf3ce44SJohn Forte case 1: 1050fcf3ce44SJohn Forte 1051fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_timeout_msg, 1052291a2b48SSukumar Swaminathan "chipQ: 2:Closing. sbp=%p iotag=%x", sbp, sbp->iotag); 1053fcf3ce44SJohn Forte 1054291a2b48SSukumar Swaminathan iocbq = 1055291a2b48SSukumar Swaminathan emlxs_create_close_xri_cn(port, sbp->node, sbp->iotag, 1056*82527734SSukumar Swaminathan cp); 1057fcf3ce44SJohn Forte 1058fcf3ce44SJohn Forte sbp->ticks = hba->timer_tics + 30; 1059fcf3ce44SJohn Forte 1060*82527734SSukumar Swaminathan flag[cp->channelno] = 1; 1061fcf3ce44SJohn Forte rc = 0; 1062fcf3ce44SJohn Forte 1063fcf3ce44SJohn Forte break; 1064fcf3ce44SJohn Forte 1065fcf3ce44SJohn Forte case 2: 1066fcf3ce44SJohn Forte 1067fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_timeout_msg, 1068291a2b48SSukumar Swaminathan "chipQ: 3:Resetting link. sbp=%p iotag=%x", sbp, 1069291a2b48SSukumar Swaminathan sbp->iotag); 1070fcf3ce44SJohn Forte 1071fcf3ce44SJohn Forte sbp->ticks = hba->timer_tics + 60; 1072fcf3ce44SJohn Forte rc = 1; 1073fcf3ce44SJohn Forte 1074fcf3ce44SJohn Forte break; 1075fcf3ce44SJohn Forte 1076fcf3ce44SJohn Forte default: 1077fcf3ce44SJohn Forte 1078fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_timeout_msg, 1079fcf3ce44SJohn Forte "chipQ: %d:Resetting adapter. sbp=%p iotag=%x", 1080fcf3ce44SJohn Forte sbp->abort_attempts, sbp, sbp->iotag); 1081fcf3ce44SJohn Forte 1082fcf3ce44SJohn Forte sbp->ticks = hba->timer_tics + 60; 1083fcf3ce44SJohn Forte rc = 2; 1084fcf3ce44SJohn Forte 1085fcf3ce44SJohn Forte break; 1086fcf3ce44SJohn Forte } 1087fcf3ce44SJohn Forte 1088fcf3ce44SJohn Forte sbp->abort_attempts++; 1089fcf3ce44SJohn Forte mutex_exit(&sbp->mtx); 1090fcf3ce44SJohn Forte 1091fcf3ce44SJohn Forte if (iocbq) { 1092fcf3ce44SJohn Forte if (abortq->q_first) { 1093291a2b48SSukumar Swaminathan ((IOCBQ *)abortq->q_last)->next = iocbq; 1094fcf3ce44SJohn Forte abortq->q_last = (uint8_t *)iocbq; 1095fcf3ce44SJohn Forte abortq->q_cnt++; 1096fcf3ce44SJohn Forte } else { 1097fcf3ce44SJohn Forte abortq->q_first = (uint8_t *)iocbq; 1098fcf3ce44SJohn Forte abortq->q_last = (uint8_t *)iocbq; 1099fcf3ce44SJohn Forte abortq->q_cnt = 1; 1100fcf3ce44SJohn Forte } 1101fcf3ce44SJohn Forte iocbq->next = NULL; 1102fcf3ce44SJohn Forte } 1103291a2b48SSukumar Swaminathan 1104fcf3ce44SJohn Forte return (rc); 1105fcf3ce44SJohn Forte 1106*82527734SSukumar Swaminathan } /* emlxs_pkt_chip_timeout() */ 1107fcf3ce44SJohn Forte 1108fcf3ce44SJohn Forte 1109fcf3ce44SJohn Forte #ifdef TX_WATCHDOG 1110fcf3ce44SJohn Forte 1111fcf3ce44SJohn Forte static void 1112fcf3ce44SJohn Forte emlxs_tx_watchdog(emlxs_hba_t *hba) 1113fcf3ce44SJohn Forte { 1114fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT; 1115fcf3ce44SJohn Forte NODELIST *nlp; 1116*82527734SSukumar Swaminathan uint32_t channelno; 1117*82527734SSukumar Swaminathan CHANNEL *cp; 1118fcf3ce44SJohn Forte IOCBQ *next; 1119fcf3ce44SJohn Forte IOCBQ *iocbq; 1120fcf3ce44SJohn Forte IOCB *iocb; 1121fcf3ce44SJohn Forte uint32_t found; 1122fcf3ce44SJohn Forte MATCHMAP *bmp; 1123fcf3ce44SJohn Forte Q abort; 1124fcf3ce44SJohn Forte uint32_t iotag; 1125fcf3ce44SJohn Forte emlxs_buf_t *sbp; 1126fcf3ce44SJohn Forte fc_packet_t *pkt = NULL; 1127fcf3ce44SJohn Forte uint32_t cmd; 1128fcf3ce44SJohn Forte uint32_t did; 1129fcf3ce44SJohn Forte 1130291a2b48SSukumar Swaminathan bzero((void *)&abort, sizeof (Q)); 1131fcf3ce44SJohn Forte 1132*82527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 1133*82527734SSukumar Swaminathan 1134*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 1135*82527734SSukumar Swaminathan for (iotag = 1; iotag < hba->max_iotag; iotag++) { 1136*82527734SSukumar Swaminathan sbp = hba->fc_table[iotag]; 1137*82527734SSukumar Swaminathan if (sbp && (sbp != STALE_PACKET) && 1138*82527734SSukumar Swaminathan (sbp->pkt_flags & PACKET_IN_TXQ)) { 1139*82527734SSukumar Swaminathan nlp = sbp->node; 1140*82527734SSukumar Swaminathan iocbq = &sbp->iocbq; 1141*82527734SSukumar Swaminathan 1142*82527734SSukumar Swaminathan channelno = (CHANNEL *)(sbp->channel)->channelno; 1143*82527734SSukumar Swaminathan if (iocbq->flag & IOCB_PRIORITY) { 1144*82527734SSukumar Swaminathan iocbq = 1145*82527734SSukumar Swaminathan (IOCBQ *)nlp->nlp_ptx[channelno]. 1146*82527734SSukumar Swaminathan q_first; 1147*82527734SSukumar Swaminathan } else { 1148*82527734SSukumar Swaminathan iocbq = 1149*82527734SSukumar Swaminathan (IOCBQ *)nlp->nlp_tx[channelno]. 1150*82527734SSukumar Swaminathan q_first; 1151*82527734SSukumar Swaminathan } 1152fcf3ce44SJohn Forte 1153*82527734SSukumar Swaminathan /* Find a matching entry */ 1154*82527734SSukumar Swaminathan found = 0; 1155*82527734SSukumar Swaminathan while (iocbq) { 1156*82527734SSukumar Swaminathan if (iocbq == &sbp->iocbq) { 1157*82527734SSukumar Swaminathan found = 1; 1158*82527734SSukumar Swaminathan break; 1159*82527734SSukumar Swaminathan } 1160fcf3ce44SJohn Forte 1161*82527734SSukumar Swaminathan iocbq = (IOCBQ *)iocbq->next; 1162*82527734SSukumar Swaminathan } 1163fcf3ce44SJohn Forte 1164*82527734SSukumar Swaminathan if (!found) { 1165*82527734SSukumar Swaminathan if (!(sbp->pkt_flags & PACKET_STALE)) { 1166*82527734SSukumar Swaminathan mutex_enter(&sbp->mtx); 1167*82527734SSukumar Swaminathan sbp->pkt_flags |= 1168*82527734SSukumar Swaminathan PACKET_STALE; 1169*82527734SSukumar Swaminathan mutex_exit(&sbp->mtx); 1170fcf3ce44SJohn Forte } else { 1171*82527734SSukumar Swaminathan if (abort.q_first == 0) { 1172*82527734SSukumar Swaminathan abort.q_first = 1173*82527734SSukumar Swaminathan &sbp->iocbq; 1174*82527734SSukumar Swaminathan } else { 1175*82527734SSukumar Swaminathan ((IOCBQ *)abort. 1176*82527734SSukumar Swaminathan q_last)->next = 1177*82527734SSukumar Swaminathan &sbp->iocbq; 1178fcf3ce44SJohn Forte } 1179291a2b48SSukumar Swaminathan 1180*82527734SSukumar Swaminathan abort.q_last = &sbp->iocbq; 1181*82527734SSukumar Swaminathan abort.q_cnt++; 1182fcf3ce44SJohn Forte } 1183fcf3ce44SJohn Forte 1184*82527734SSukumar Swaminathan } else { 1185*82527734SSukumar Swaminathan if ((sbp->pkt_flags & PACKET_STALE)) { 1186*82527734SSukumar Swaminathan mutex_enter(&sbp->mtx); 1187*82527734SSukumar Swaminathan sbp->pkt_flags &= 1188*82527734SSukumar Swaminathan ~PACKET_STALE; 1189*82527734SSukumar Swaminathan mutex_exit(&sbp->mtx); 1190fcf3ce44SJohn Forte } 1191fcf3ce44SJohn Forte } 1192fcf3ce44SJohn Forte } 1193fcf3ce44SJohn Forte } 1194*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 1195fcf3ce44SJohn Forte 1196291a2b48SSukumar Swaminathan iocbq = (IOCBQ *)abort.q_first; 1197fcf3ce44SJohn Forte while (iocbq) { 1198291a2b48SSukumar Swaminathan next = (IOCBQ *)iocbq->next; 1199fcf3ce44SJohn Forte iocbq->next = NULL; 1200fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp; 1201fcf3ce44SJohn Forte 1202fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp); 1203fcf3ce44SJohn Forte if (pkt) { 1204*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 1205fcf3ce44SJohn Forte cmd = *((uint32_t *)pkt->pkt_cmd); 1206*82527734SSukumar Swaminathan cmd = LE_SWAP32(cmd); 1207fcf3ce44SJohn Forte } 1208fcf3ce44SJohn Forte 1209fcf3ce44SJohn Forte 1210fcf3ce44SJohn Forte emlxs_tx_put(iocbq, 0); 1211fcf3ce44SJohn Forte 1212fcf3ce44SJohn Forte iocbq = next; 1213fcf3ce44SJohn Forte 1214fcf3ce44SJohn Forte } /* end of while */ 1215fcf3ce44SJohn Forte 1216*82527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 1217fcf3ce44SJohn Forte 1218fcf3ce44SJohn Forte return; 1219fcf3ce44SJohn Forte 1220*82527734SSukumar Swaminathan } /* emlxs_tx_watchdog() */ 1221fcf3ce44SJohn Forte 1222291a2b48SSukumar Swaminathan #endif /* TX_WATCHDOG */ 1223fcf3ce44SJohn Forte 1224fcf3ce44SJohn Forte 1225fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT 1226fcf3ce44SJohn Forte 1227fcf3ce44SJohn Forte static void 1228fcf3ce44SJohn Forte emlxs_timer_check_dhchap(emlxs_port_t *port) 1229fcf3ce44SJohn Forte { 1230fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1231fcf3ce44SJohn Forte uint32_t i; 1232fcf3ce44SJohn Forte NODELIST *ndlp = NULL; 1233fcf3ce44SJohn Forte 1234fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 1235fcf3ce44SJohn Forte ndlp = port->node_table[i]; 1236fcf3ce44SJohn Forte 1237fcf3ce44SJohn Forte if (!ndlp) { 1238fcf3ce44SJohn Forte continue; 1239fcf3ce44SJohn Forte } 1240291a2b48SSukumar Swaminathan 1241fcf3ce44SJohn Forte /* Check authentication response timeout */ 1242fcf3ce44SJohn Forte if (ndlp->node_dhc.nlp_authrsp_tmo && 1243fcf3ce44SJohn Forte (hba->timer_tics >= ndlp->node_dhc.nlp_authrsp_tmo)) { 1244fcf3ce44SJohn Forte /* Trigger authresp timeout handler */ 1245fcf3ce44SJohn Forte (void) emlxs_dhc_authrsp_timeout(port, ndlp, NULL); 1246fcf3ce44SJohn Forte } 1247291a2b48SSukumar Swaminathan 1248fcf3ce44SJohn Forte /* Check reauthentication timeout */ 1249fcf3ce44SJohn Forte if (ndlp->node_dhc.nlp_reauth_tmo && 1250fcf3ce44SJohn Forte (hba->timer_tics >= ndlp->node_dhc.nlp_reauth_tmo)) { 1251fcf3ce44SJohn Forte /* Trigger reauth timeout handler */ 1252fcf3ce44SJohn Forte emlxs_dhc_reauth_timeout(port, NULL, ndlp); 1253fcf3ce44SJohn Forte } 1254fcf3ce44SJohn Forte } 1255fcf3ce44SJohn Forte return; 1256fcf3ce44SJohn Forte 1257*82527734SSukumar Swaminathan } /* emlxs_timer_check_dhchap */ 1258fcf3ce44SJohn Forte 1259291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */ 1260