1*82527734SSukumar Swaminathan /* 2*82527734SSukumar Swaminathan * CDDL HEADER START 3*82527734SSukumar Swaminathan * 4*82527734SSukumar Swaminathan * The contents of this file are subject to the terms of the 5*82527734SSukumar Swaminathan * Common Development and Distribution License (the "License"). 6*82527734SSukumar Swaminathan * You may not use this file except in compliance with the License. 7*82527734SSukumar Swaminathan * 8*82527734SSukumar Swaminathan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*82527734SSukumar Swaminathan * or http://www.opensolaris.org/os/licensing. 10*82527734SSukumar Swaminathan * See the License for the specific language governing permissions 11*82527734SSukumar Swaminathan * and limitations under the License. 12*82527734SSukumar Swaminathan * 13*82527734SSukumar Swaminathan * When distributing Covered Code, include this CDDL HEADER in each 14*82527734SSukumar Swaminathan * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*82527734SSukumar Swaminathan * If applicable, add the following below this CDDL HEADER, with the 16*82527734SSukumar Swaminathan * fields enclosed by brackets "[]" replaced with your own identifying 17*82527734SSukumar Swaminathan * information: Portions Copyright [yyyy] [name of copyright owner] 18*82527734SSukumar Swaminathan * 19*82527734SSukumar Swaminathan * CDDL HEADER END 20*82527734SSukumar Swaminathan */ 21*82527734SSukumar Swaminathan 22*82527734SSukumar Swaminathan /* 23*82527734SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24*82527734SSukumar Swaminathan * Use is subject to license terms. 25*82527734SSukumar Swaminathan */ 26*82527734SSukumar Swaminathan 27*82527734SSukumar Swaminathan 28*82527734SSukumar Swaminathan #define DEF_EVENT_STRUCT /* Needed for emlxs_events.h in emlxs_event.h */ 29*82527734SSukumar Swaminathan #include <emlxs.h> 30*82527734SSukumar Swaminathan 31*82527734SSukumar Swaminathan 32*82527734SSukumar Swaminathan /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 33*82527734SSukumar Swaminathan EMLXS_MSG_DEF(EMLXS_EVENT_C); 34*82527734SSukumar Swaminathan 35*82527734SSukumar Swaminathan 36*82527734SSukumar Swaminathan static uint32_t emlxs_event_check(emlxs_port_t *port, emlxs_event_t *evt); 37*82527734SSukumar Swaminathan static void emlxs_event_destroy(emlxs_hba_t *hba, emlxs_event_entry_t *entry); 38*82527734SSukumar Swaminathan 39*82527734SSukumar Swaminathan extern void 40*82527734SSukumar Swaminathan emlxs_null_func() {} 41*82527734SSukumar Swaminathan 42*82527734SSukumar Swaminathan 43*82527734SSukumar Swaminathan static uint32_t 44*82527734SSukumar Swaminathan emlxs_event_check(emlxs_port_t *port, emlxs_event_t *evt) 45*82527734SSukumar Swaminathan { 46*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 47*82527734SSukumar Swaminathan 48*82527734SSukumar Swaminathan /* Check if the event is being requested */ 49*82527734SSukumar Swaminathan if ((hba->event_mask & evt->mask)) { 50*82527734SSukumar Swaminathan return (1); 51*82527734SSukumar Swaminathan } 52*82527734SSukumar Swaminathan 53*82527734SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 54*82527734SSukumar Swaminathan if ((port->sd_event_mask & evt->mask)) { 55*82527734SSukumar Swaminathan return (1); 56*82527734SSukumar Swaminathan } 57*82527734SSukumar Swaminathan #endif /* SAN_DIAG_SUPPORT */ 58*82527734SSukumar Swaminathan 59*82527734SSukumar Swaminathan return (0); 60*82527734SSukumar Swaminathan 61*82527734SSukumar Swaminathan } /* emlxs_event_check() */ 62*82527734SSukumar Swaminathan 63*82527734SSukumar Swaminathan 64*82527734SSukumar Swaminathan extern uint32_t 65*82527734SSukumar Swaminathan emlxs_event_queue_create(emlxs_hba_t *hba) 66*82527734SSukumar Swaminathan { 67*82527734SSukumar Swaminathan emlxs_event_queue_t *eventq = &EVENTQ; 68*82527734SSukumar Swaminathan char buf[40]; 69*82527734SSukumar Swaminathan #ifdef MSI_SUPPORT 70*82527734SSukumar Swaminathan ddi_intr_handle_t handle; 71*82527734SSukumar Swaminathan uint32_t intr_pri; 72*82527734SSukumar Swaminathan int32_t actual; 73*82527734SSukumar Swaminathan uint32_t ret; 74*82527734SSukumar Swaminathan #endif /* MSI_SUPPORT */ 75*82527734SSukumar Swaminathan ddi_iblock_cookie_t iblock; 76*82527734SSukumar Swaminathan 77*82527734SSukumar Swaminathan /* Clear the queue */ 78*82527734SSukumar Swaminathan bzero(eventq, sizeof (emlxs_event_queue_t)); 79*82527734SSukumar Swaminathan 80*82527734SSukumar Swaminathan /* Initialize */ 81*82527734SSukumar Swaminathan (void) sprintf(buf, "?%s%d_evt_lock control variable", DRIVER_NAME, 82*82527734SSukumar Swaminathan hba->ddiinst); 83*82527734SSukumar Swaminathan cv_init(&eventq->lock_cv, buf, CV_DRIVER, NULL); 84*82527734SSukumar Swaminathan 85*82527734SSukumar Swaminathan (void) sprintf(buf, "?%s%d_evt_lock mutex", DRIVER_NAME, hba->ddiinst); 86*82527734SSukumar Swaminathan 87*82527734SSukumar Swaminathan if (!(hba->intr_flags & EMLXS_MSI_ENABLED)) { 88*82527734SSukumar Swaminathan /* Get the current interrupt block cookie */ 89*82527734SSukumar Swaminathan (void) ddi_get_iblock_cookie(hba->dip, (uint_t)EMLXS_INUMBER, 90*82527734SSukumar Swaminathan &iblock); 91*82527734SSukumar Swaminathan 92*82527734SSukumar Swaminathan /* Create the mutex lock */ 93*82527734SSukumar Swaminathan mutex_init(&eventq->lock, buf, MUTEX_DRIVER, (void *)iblock); 94*82527734SSukumar Swaminathan } 95*82527734SSukumar Swaminathan #ifdef MSI_SUPPORT 96*82527734SSukumar Swaminathan else { 97*82527734SSukumar Swaminathan /* Allocate a temporary interrupt handle */ 98*82527734SSukumar Swaminathan actual = 0; 99*82527734SSukumar Swaminathan ret = 100*82527734SSukumar Swaminathan ddi_intr_alloc(hba->dip, &handle, DDI_INTR_TYPE_FIXED, 101*82527734SSukumar Swaminathan EMLXS_MSI_INUMBER, 1, &actual, DDI_INTR_ALLOC_NORMAL); 102*82527734SSukumar Swaminathan 103*82527734SSukumar Swaminathan if (ret != DDI_SUCCESS || actual == 0) { 104*82527734SSukumar Swaminathan cmn_err(CE_WARN, 105*82527734SSukumar Swaminathan "?%s%d: Unable to allocate temporary interrupt " 106*82527734SSukumar Swaminathan "handle. ret=%d actual=%d", DRIVER_NAME, 107*82527734SSukumar Swaminathan hba->ddiinst, ret, actual); 108*82527734SSukumar Swaminathan 109*82527734SSukumar Swaminathan bzero(eventq, sizeof (emlxs_event_queue_t)); 110*82527734SSukumar Swaminathan 111*82527734SSukumar Swaminathan return (0); 112*82527734SSukumar Swaminathan } 113*82527734SSukumar Swaminathan 114*82527734SSukumar Swaminathan /* Get the current interrupt priority */ 115*82527734SSukumar Swaminathan ret = ddi_intr_get_pri(handle, &intr_pri); 116*82527734SSukumar Swaminathan 117*82527734SSukumar Swaminathan if (ret != DDI_SUCCESS) { 118*82527734SSukumar Swaminathan cmn_err(CE_WARN, 119*82527734SSukumar Swaminathan "?%s%d: Unable to get interrupt priority. ret=%d", 120*82527734SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, ret); 121*82527734SSukumar Swaminathan 122*82527734SSukumar Swaminathan bzero(eventq, sizeof (emlxs_event_queue_t)); 123*82527734SSukumar Swaminathan 124*82527734SSukumar Swaminathan return (0); 125*82527734SSukumar Swaminathan } 126*82527734SSukumar Swaminathan 127*82527734SSukumar Swaminathan /* Create the log mutex lock */ 128*82527734SSukumar Swaminathan mutex_init(&eventq->lock, buf, MUTEX_DRIVER, 129*82527734SSukumar Swaminathan (void *)((unsigned long)intr_pri)); 130*82527734SSukumar Swaminathan 131*82527734SSukumar Swaminathan /* Free the temporary handle */ 132*82527734SSukumar Swaminathan (void) ddi_intr_free(handle); 133*82527734SSukumar Swaminathan } 134*82527734SSukumar Swaminathan #endif 135*82527734SSukumar Swaminathan 136*82527734SSukumar Swaminathan return (1); 137*82527734SSukumar Swaminathan 138*82527734SSukumar Swaminathan } /* emlxs_event_queue_create() */ 139*82527734SSukumar Swaminathan 140*82527734SSukumar Swaminathan 141*82527734SSukumar Swaminathan extern void 142*82527734SSukumar Swaminathan emlxs_event_queue_destroy(emlxs_hba_t *hba) 143*82527734SSukumar Swaminathan { 144*82527734SSukumar Swaminathan emlxs_port_t *vport; 145*82527734SSukumar Swaminathan emlxs_event_queue_t *eventq = &EVENTQ; 146*82527734SSukumar Swaminathan uint32_t i; 147*82527734SSukumar Swaminathan uint32_t wakeup = 0; 148*82527734SSukumar Swaminathan 149*82527734SSukumar Swaminathan mutex_enter(&eventq->lock); 150*82527734SSukumar Swaminathan 151*82527734SSukumar Swaminathan /* Clear all event masks and broadcast a wakeup */ 152*82527734SSukumar Swaminathan /* to clear any sleeping threads */ 153*82527734SSukumar Swaminathan if (hba->event_mask) { 154*82527734SSukumar Swaminathan hba->event_mask = 0; 155*82527734SSukumar Swaminathan hba->event_timer = 0; 156*82527734SSukumar Swaminathan wakeup = 1; 157*82527734SSukumar Swaminathan } 158*82527734SSukumar Swaminathan 159*82527734SSukumar Swaminathan for (i = 0; i < MAX_VPORTS; i++) { 160*82527734SSukumar Swaminathan vport = &VPORT(i); 161*82527734SSukumar Swaminathan 162*82527734SSukumar Swaminathan if (vport->sd_event_mask) { 163*82527734SSukumar Swaminathan vport->sd_event_mask = 0; 164*82527734SSukumar Swaminathan wakeup = 1; 165*82527734SSukumar Swaminathan } 166*82527734SSukumar Swaminathan } 167*82527734SSukumar Swaminathan 168*82527734SSukumar Swaminathan if (wakeup) { 169*82527734SSukumar Swaminathan cv_broadcast(&eventq->lock_cv); 170*82527734SSukumar Swaminathan 171*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 172*82527734SSukumar Swaminathan DELAYMS(10); 173*82527734SSukumar Swaminathan mutex_enter(&eventq->lock); 174*82527734SSukumar Swaminathan } 175*82527734SSukumar Swaminathan 176*82527734SSukumar Swaminathan /* Destroy the remaining events */ 177*82527734SSukumar Swaminathan while (eventq->first) { 178*82527734SSukumar Swaminathan emlxs_event_destroy(hba, eventq->first); 179*82527734SSukumar Swaminathan } 180*82527734SSukumar Swaminathan 181*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 182*82527734SSukumar Swaminathan 183*82527734SSukumar Swaminathan /* Destroy the queue lock */ 184*82527734SSukumar Swaminathan mutex_destroy(&eventq->lock); 185*82527734SSukumar Swaminathan cv_destroy(&eventq->lock_cv); 186*82527734SSukumar Swaminathan 187*82527734SSukumar Swaminathan /* Clear the queue */ 188*82527734SSukumar Swaminathan bzero(eventq, sizeof (emlxs_event_queue_t)); 189*82527734SSukumar Swaminathan 190*82527734SSukumar Swaminathan return; 191*82527734SSukumar Swaminathan 192*82527734SSukumar Swaminathan } /* emlxs_event_queue_destroy() */ 193*82527734SSukumar Swaminathan 194*82527734SSukumar Swaminathan 195*82527734SSukumar Swaminathan /* Event queue lock must be held */ 196*82527734SSukumar Swaminathan static void 197*82527734SSukumar Swaminathan emlxs_event_destroy(emlxs_hba_t *hba, emlxs_event_entry_t *entry) 198*82527734SSukumar Swaminathan { 199*82527734SSukumar Swaminathan emlxs_event_queue_t *eventq = &EVENTQ; 200*82527734SSukumar Swaminathan emlxs_port_t *port; 201*82527734SSukumar Swaminathan uint32_t missed = 0; 202*82527734SSukumar Swaminathan 203*82527734SSukumar Swaminathan port = (emlxs_port_t *)entry->port; 204*82527734SSukumar Swaminathan 205*82527734SSukumar Swaminathan eventq->count--; 206*82527734SSukumar Swaminathan if (eventq->count == 0) { 207*82527734SSukumar Swaminathan eventq->first = NULL; 208*82527734SSukumar Swaminathan eventq->last = NULL; 209*82527734SSukumar Swaminathan } else { 210*82527734SSukumar Swaminathan if (entry->prev) { 211*82527734SSukumar Swaminathan entry->prev->next = entry->next; 212*82527734SSukumar Swaminathan } 213*82527734SSukumar Swaminathan if (entry->next) { 214*82527734SSukumar Swaminathan entry->next->prev = entry->prev; 215*82527734SSukumar Swaminathan } 216*82527734SSukumar Swaminathan if (eventq->first == entry) { 217*82527734SSukumar Swaminathan eventq->first = entry->next; 218*82527734SSukumar Swaminathan } 219*82527734SSukumar Swaminathan if (eventq->last == entry) { 220*82527734SSukumar Swaminathan eventq->last = entry->prev; 221*82527734SSukumar Swaminathan } 222*82527734SSukumar Swaminathan } 223*82527734SSukumar Swaminathan 224*82527734SSukumar Swaminathan entry->prev = NULL; 225*82527734SSukumar Swaminathan entry->next = NULL; 226*82527734SSukumar Swaminathan 227*82527734SSukumar Swaminathan if ((entry->evt->mask == EVT_LINK) || 228*82527734SSukumar Swaminathan (entry->evt->mask == EVT_RSCN)) { 229*82527734SSukumar Swaminathan if (!(entry->flag & EMLXS_DFC_EVENT_DONE)) { 230*82527734SSukumar Swaminathan hba->hba_event.missed++; 231*82527734SSukumar Swaminathan missed = 1; 232*82527734SSukumar Swaminathan } 233*82527734SSukumar Swaminathan } 234*82527734SSukumar Swaminathan 235*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_dequeued_msg, 236*82527734SSukumar Swaminathan "%s[%d]: flag=%x missed=%d cnt=%d", 237*82527734SSukumar Swaminathan entry->evt->label, entry->id, entry->flag, missed, eventq->count); 238*82527734SSukumar Swaminathan 239*82527734SSukumar Swaminathan /* Call notification handler */ 240*82527734SSukumar Swaminathan entry->evt->destroy(entry); 241*82527734SSukumar Swaminathan 242*82527734SSukumar Swaminathan /* Free context buffer */ 243*82527734SSukumar Swaminathan if (entry->bp && entry->size) { 244*82527734SSukumar Swaminathan kmem_free(entry->bp, entry->size); 245*82527734SSukumar Swaminathan } 246*82527734SSukumar Swaminathan 247*82527734SSukumar Swaminathan /* Free entry buffer */ 248*82527734SSukumar Swaminathan kmem_free(entry, sizeof (emlxs_event_entry_t)); 249*82527734SSukumar Swaminathan 250*82527734SSukumar Swaminathan return; 251*82527734SSukumar Swaminathan 252*82527734SSukumar Swaminathan } /* emlxs_event_destroy() */ 253*82527734SSukumar Swaminathan 254*82527734SSukumar Swaminathan 255*82527734SSukumar Swaminathan extern void 256*82527734SSukumar Swaminathan emlxs_event(emlxs_port_t *port, emlxs_event_t *evt, void *bp, uint32_t size) 257*82527734SSukumar Swaminathan { 258*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 259*82527734SSukumar Swaminathan emlxs_event_queue_t *eventq = &EVENTQ; 260*82527734SSukumar Swaminathan emlxs_event_entry_t *entry; 261*82527734SSukumar Swaminathan uint32_t i; 262*82527734SSukumar Swaminathan uint32_t mask; 263*82527734SSukumar Swaminathan 264*82527734SSukumar Swaminathan if (emlxs_event_check(port, evt) == 0) { 265*82527734SSukumar Swaminathan goto failed; 266*82527734SSukumar Swaminathan } 267*82527734SSukumar Swaminathan 268*82527734SSukumar Swaminathan /* Create event entry */ 269*82527734SSukumar Swaminathan if (!(entry = (emlxs_event_entry_t *)kmem_alloc( 270*82527734SSukumar Swaminathan sizeof (emlxs_event_entry_t), KM_NOSLEEP))) { 271*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 272*82527734SSukumar Swaminathan "%s: Unable to allocate event entry.", evt->label); 273*82527734SSukumar Swaminathan 274*82527734SSukumar Swaminathan goto failed; 275*82527734SSukumar Swaminathan } 276*82527734SSukumar Swaminathan 277*82527734SSukumar Swaminathan /* Initialize */ 278*82527734SSukumar Swaminathan bzero(entry, sizeof (emlxs_event_entry_t)); 279*82527734SSukumar Swaminathan 280*82527734SSukumar Swaminathan entry->evt = evt; 281*82527734SSukumar Swaminathan entry->port = (void *)port; 282*82527734SSukumar Swaminathan entry->bp = bp; 283*82527734SSukumar Swaminathan entry->size = size; 284*82527734SSukumar Swaminathan 285*82527734SSukumar Swaminathan mutex_enter(&eventq->lock); 286*82527734SSukumar Swaminathan 287*82527734SSukumar Swaminathan /* Set the event timer */ 288*82527734SSukumar Swaminathan entry->timestamp = hba->timer_tics; 289*82527734SSukumar Swaminathan if (evt->timeout) { 290*82527734SSukumar Swaminathan entry->timer = entry->timestamp + evt->timeout; 291*82527734SSukumar Swaminathan } 292*82527734SSukumar Swaminathan 293*82527734SSukumar Swaminathan /* Set the event id */ 294*82527734SSukumar Swaminathan entry->id = eventq->next_id++; 295*82527734SSukumar Swaminathan 296*82527734SSukumar Swaminathan /* Set last event table */ 297*82527734SSukumar Swaminathan mask = evt->mask; 298*82527734SSukumar Swaminathan for (i = 0; i < 32; i++) { 299*82527734SSukumar Swaminathan if (mask & 0x01) { 300*82527734SSukumar Swaminathan eventq->last_id[i] = entry->id; 301*82527734SSukumar Swaminathan } 302*82527734SSukumar Swaminathan mask >>= 1; 303*82527734SSukumar Swaminathan } 304*82527734SSukumar Swaminathan 305*82527734SSukumar Swaminathan /* Put event on bottom of queue */ 306*82527734SSukumar Swaminathan entry->next = NULL; 307*82527734SSukumar Swaminathan if (eventq->count == 0) { 308*82527734SSukumar Swaminathan entry->prev = NULL; 309*82527734SSukumar Swaminathan eventq->first = entry; 310*82527734SSukumar Swaminathan eventq->last = entry; 311*82527734SSukumar Swaminathan } else { 312*82527734SSukumar Swaminathan entry->prev = eventq->last; 313*82527734SSukumar Swaminathan entry->prev->next = entry; 314*82527734SSukumar Swaminathan eventq->last = entry; 315*82527734SSukumar Swaminathan } 316*82527734SSukumar Swaminathan eventq->count++; 317*82527734SSukumar Swaminathan 318*82527734SSukumar Swaminathan if ((entry->evt->mask == EVT_LINK) || 319*82527734SSukumar Swaminathan (entry->evt->mask == EVT_RSCN)) { 320*82527734SSukumar Swaminathan hba->hba_event.new++; 321*82527734SSukumar Swaminathan } 322*82527734SSukumar Swaminathan 323*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_queued_msg, 324*82527734SSukumar Swaminathan "%s[%d]: bp=%p size=%d cnt=%d", entry->evt->label, 325*82527734SSukumar Swaminathan entry->id, bp, size, eventq->count); 326*82527734SSukumar Swaminathan 327*82527734SSukumar Swaminathan /* Broadcast the event */ 328*82527734SSukumar Swaminathan cv_broadcast(&eventq->lock_cv); 329*82527734SSukumar Swaminathan 330*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 331*82527734SSukumar Swaminathan 332*82527734SSukumar Swaminathan return; 333*82527734SSukumar Swaminathan 334*82527734SSukumar Swaminathan failed: 335*82527734SSukumar Swaminathan 336*82527734SSukumar Swaminathan /* Call notification handler */ 337*82527734SSukumar Swaminathan entry->evt->destroy(entry); 338*82527734SSukumar Swaminathan 339*82527734SSukumar Swaminathan if (entry->bp && entry->size) { 340*82527734SSukumar Swaminathan kmem_free(entry->bp, entry->size); 341*82527734SSukumar Swaminathan } 342*82527734SSukumar Swaminathan 343*82527734SSukumar Swaminathan return; 344*82527734SSukumar Swaminathan 345*82527734SSukumar Swaminathan } /* emlxs_event() */ 346*82527734SSukumar Swaminathan 347*82527734SSukumar Swaminathan 348*82527734SSukumar Swaminathan extern void 349*82527734SSukumar Swaminathan emlxs_timer_check_events(emlxs_hba_t *hba) 350*82527734SSukumar Swaminathan { 351*82527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 352*82527734SSukumar Swaminathan emlxs_event_queue_t *eventq = &EVENTQ; 353*82527734SSukumar Swaminathan emlxs_event_entry_t *entry; 354*82527734SSukumar Swaminathan emlxs_event_entry_t *next; 355*82527734SSukumar Swaminathan 356*82527734SSukumar Swaminathan if (!cfg[CFG_TIMEOUT_ENABLE].current) { 357*82527734SSukumar Swaminathan return; 358*82527734SSukumar Swaminathan } 359*82527734SSukumar Swaminathan 360*82527734SSukumar Swaminathan if ((hba->event_timer > hba->timer_tics)) { 361*82527734SSukumar Swaminathan return; 362*82527734SSukumar Swaminathan } 363*82527734SSukumar Swaminathan 364*82527734SSukumar Swaminathan if (eventq->count) { 365*82527734SSukumar Swaminathan mutex_enter(&eventq->lock); 366*82527734SSukumar Swaminathan 367*82527734SSukumar Swaminathan entry = eventq->first; 368*82527734SSukumar Swaminathan while (entry) { 369*82527734SSukumar Swaminathan if ((!entry->timer) || 370*82527734SSukumar Swaminathan (entry->timer > hba->timer_tics)) { 371*82527734SSukumar Swaminathan entry = entry->next; 372*82527734SSukumar Swaminathan continue; 373*82527734SSukumar Swaminathan } 374*82527734SSukumar Swaminathan 375*82527734SSukumar Swaminathan /* Event timed out, destroy it */ 376*82527734SSukumar Swaminathan next = entry->next; 377*82527734SSukumar Swaminathan emlxs_event_destroy(hba, entry); 378*82527734SSukumar Swaminathan entry = next; 379*82527734SSukumar Swaminathan } 380*82527734SSukumar Swaminathan 381*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 382*82527734SSukumar Swaminathan } 383*82527734SSukumar Swaminathan 384*82527734SSukumar Swaminathan /* Set next event timer check */ 385*82527734SSukumar Swaminathan hba->event_timer = hba->timer_tics + EMLXS_EVENT_PERIOD; 386*82527734SSukumar Swaminathan 387*82527734SSukumar Swaminathan return; 388*82527734SSukumar Swaminathan 389*82527734SSukumar Swaminathan } /* emlxs_timer_check_events() */ 390*82527734SSukumar Swaminathan 391*82527734SSukumar Swaminathan 392*82527734SSukumar Swaminathan extern void 393*82527734SSukumar Swaminathan emlxs_log_rscn_event(emlxs_port_t *port, uint8_t *payload, uint32_t size) 394*82527734SSukumar Swaminathan { 395*82527734SSukumar Swaminathan uint8_t *bp; 396*82527734SSukumar Swaminathan uint32_t *ptr; 397*82527734SSukumar Swaminathan 398*82527734SSukumar Swaminathan /* Check if the event is being requested */ 399*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_rscn_event) == 0) { 400*82527734SSukumar Swaminathan return; 401*82527734SSukumar Swaminathan } 402*82527734SSukumar Swaminathan 403*82527734SSukumar Swaminathan if (size > MAX_RSCN_PAYLOAD) { 404*82527734SSukumar Swaminathan size = MAX_RSCN_PAYLOAD; 405*82527734SSukumar Swaminathan } 406*82527734SSukumar Swaminathan 407*82527734SSukumar Swaminathan size += sizeof (uint32_t); 408*82527734SSukumar Swaminathan 409*82527734SSukumar Swaminathan /* Save a copy of the payload for the event log */ 410*82527734SSukumar Swaminathan if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 411*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 412*82527734SSukumar Swaminathan "%s: Unable to allocate buffer.", emlxs_rscn_event.label); 413*82527734SSukumar Swaminathan 414*82527734SSukumar Swaminathan return; 415*82527734SSukumar Swaminathan } 416*82527734SSukumar Swaminathan 417*82527734SSukumar Swaminathan /* 418*82527734SSukumar Swaminathan * Buffer Format: 419*82527734SSukumar Swaminathan * word[0] = DID of the RSCN 420*82527734SSukumar Swaminathan * word[1] = RSCN Payload 421*82527734SSukumar Swaminathan */ 422*82527734SSukumar Swaminathan ptr = (uint32_t *)bp; 423*82527734SSukumar Swaminathan *ptr++ = port->did; 424*82527734SSukumar Swaminathan bcopy(payload, (char *)ptr, (size - sizeof (uint32_t))); 425*82527734SSukumar Swaminathan 426*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_rscn_event, bp, size); 427*82527734SSukumar Swaminathan 428*82527734SSukumar Swaminathan return; 429*82527734SSukumar Swaminathan 430*82527734SSukumar Swaminathan } /* emlxs_log_rscn_event() */ 431*82527734SSukumar Swaminathan 432*82527734SSukumar Swaminathan 433*82527734SSukumar Swaminathan extern void 434*82527734SSukumar Swaminathan emlxs_log_vportrscn_event(emlxs_port_t *port, uint8_t *payload, uint32_t size) 435*82527734SSukumar Swaminathan { 436*82527734SSukumar Swaminathan uint8_t *bp; 437*82527734SSukumar Swaminathan uint8_t *ptr; 438*82527734SSukumar Swaminathan 439*82527734SSukumar Swaminathan /* Check if the event is being requested */ 440*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_vportrscn_event) == 0) { 441*82527734SSukumar Swaminathan return; 442*82527734SSukumar Swaminathan } 443*82527734SSukumar Swaminathan 444*82527734SSukumar Swaminathan if (size > MAX_RSCN_PAYLOAD) { 445*82527734SSukumar Swaminathan size = MAX_RSCN_PAYLOAD; 446*82527734SSukumar Swaminathan } 447*82527734SSukumar Swaminathan 448*82527734SSukumar Swaminathan size += sizeof (NAME_TYPE); 449*82527734SSukumar Swaminathan 450*82527734SSukumar Swaminathan /* Save a copy of the payload for the event log */ 451*82527734SSukumar Swaminathan if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 452*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 453*82527734SSukumar Swaminathan "%s: Unable to allocate buffer.", 454*82527734SSukumar Swaminathan emlxs_vportrscn_event.label); 455*82527734SSukumar Swaminathan 456*82527734SSukumar Swaminathan return; 457*82527734SSukumar Swaminathan } 458*82527734SSukumar Swaminathan 459*82527734SSukumar Swaminathan /* 460*82527734SSukumar Swaminathan * Buffer Format: 461*82527734SSukumar Swaminathan * word[0 - 4] = WWPN of the RSCN 462*82527734SSukumar Swaminathan * word[5] = RSCN Payload 463*82527734SSukumar Swaminathan */ 464*82527734SSukumar Swaminathan ptr = bp; 465*82527734SSukumar Swaminathan bcopy(&port->wwpn, ptr, sizeof (NAME_TYPE)); 466*82527734SSukumar Swaminathan ptr += sizeof (NAME_TYPE); 467*82527734SSukumar Swaminathan bcopy(payload, ptr, (size - sizeof (NAME_TYPE))); 468*82527734SSukumar Swaminathan 469*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_vportrscn_event, bp, size); 470*82527734SSukumar Swaminathan 471*82527734SSukumar Swaminathan return; 472*82527734SSukumar Swaminathan 473*82527734SSukumar Swaminathan } /* emlxs_log_vportrscn_event() */ 474*82527734SSukumar Swaminathan 475*82527734SSukumar Swaminathan 476*82527734SSukumar Swaminathan extern uint32_t 477*82527734SSukumar Swaminathan emlxs_log_ct_event(emlxs_port_t *port, uint8_t *payload, uint32_t size, 478*82527734SSukumar Swaminathan uint32_t rxid) 479*82527734SSukumar Swaminathan { 480*82527734SSukumar Swaminathan uint8_t *bp; 481*82527734SSukumar Swaminathan uint32_t *ptr; 482*82527734SSukumar Swaminathan 483*82527734SSukumar Swaminathan /* Check if the event is being requested */ 484*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_ct_event) == 0) { 485*82527734SSukumar Swaminathan return (1); 486*82527734SSukumar Swaminathan } 487*82527734SSukumar Swaminathan 488*82527734SSukumar Swaminathan if (size > MAX_CT_PAYLOAD) { 489*82527734SSukumar Swaminathan size = MAX_CT_PAYLOAD; 490*82527734SSukumar Swaminathan } 491*82527734SSukumar Swaminathan 492*82527734SSukumar Swaminathan size += sizeof (uint32_t); 493*82527734SSukumar Swaminathan 494*82527734SSukumar Swaminathan /* Save a copy of the payload for the event log */ 495*82527734SSukumar Swaminathan if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 496*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 497*82527734SSukumar Swaminathan "%s: Unable to allocate buffer.", emlxs_ct_event.label); 498*82527734SSukumar Swaminathan 499*82527734SSukumar Swaminathan return (1); 500*82527734SSukumar Swaminathan } 501*82527734SSukumar Swaminathan 502*82527734SSukumar Swaminathan /* 503*82527734SSukumar Swaminathan * Buffer Format: 504*82527734SSukumar Swaminathan * word[0] = RXID tag for outgoing reply to this CT request 505*82527734SSukumar Swaminathan * word[1] = CT Payload 506*82527734SSukumar Swaminathan */ 507*82527734SSukumar Swaminathan ptr = (uint32_t *)bp; 508*82527734SSukumar Swaminathan *ptr++ = rxid; 509*82527734SSukumar Swaminathan bcopy(payload, (char *)ptr, (size - sizeof (uint32_t))); 510*82527734SSukumar Swaminathan 511*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_ct_event, bp, size); 512*82527734SSukumar Swaminathan 513*82527734SSukumar Swaminathan return (0); 514*82527734SSukumar Swaminathan 515*82527734SSukumar Swaminathan } /* emlxs_log_ct_event() */ 516*82527734SSukumar Swaminathan 517*82527734SSukumar Swaminathan 518*82527734SSukumar Swaminathan extern void 519*82527734SSukumar Swaminathan emlxs_ct_event_destroy(emlxs_event_entry_t *entry) 520*82527734SSukumar Swaminathan { 521*82527734SSukumar Swaminathan emlxs_port_t *port = (emlxs_port_t *)entry->port; 522*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 523*82527734SSukumar Swaminathan uint32_t rxid; 524*82527734SSukumar Swaminathan 525*82527734SSukumar Swaminathan if (!(entry->flag & EMLXS_DFC_EVENT_DONE)) { 526*82527734SSukumar Swaminathan 527*82527734SSukumar Swaminathan rxid = *(uint32_t *)entry->bp; 528*82527734SSukumar Swaminathan 529*82527734SSukumar Swaminathan /* Abort exchange */ 530*82527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_abort_ct_exchange, 531*82527734SSukumar Swaminathan entry->port, (void *)(unsigned long)rxid); 532*82527734SSukumar Swaminathan } 533*82527734SSukumar Swaminathan 534*82527734SSukumar Swaminathan return; 535*82527734SSukumar Swaminathan 536*82527734SSukumar Swaminathan } /* emlxs_ct_event_destroy() */ 537*82527734SSukumar Swaminathan 538*82527734SSukumar Swaminathan 539*82527734SSukumar Swaminathan extern void 540*82527734SSukumar Swaminathan emlxs_log_link_event(emlxs_port_t *port) 541*82527734SSukumar Swaminathan { 542*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 543*82527734SSukumar Swaminathan uint8_t *bp; 544*82527734SSukumar Swaminathan dfc_linkinfo_t *linkinfo; 545*82527734SSukumar Swaminathan uint8_t *byte; 546*82527734SSukumar Swaminathan uint8_t *linkspeed; 547*82527734SSukumar Swaminathan uint8_t *liptype; 548*82527734SSukumar Swaminathan uint8_t *resv1; 549*82527734SSukumar Swaminathan uint8_t *resv2; 550*82527734SSukumar Swaminathan uint32_t size; 551*82527734SSukumar Swaminathan 552*82527734SSukumar Swaminathan /* Check if the event is being requested */ 553*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_link_event) == 0) { 554*82527734SSukumar Swaminathan return; 555*82527734SSukumar Swaminathan } 556*82527734SSukumar Swaminathan 557*82527734SSukumar Swaminathan size = sizeof (dfc_linkinfo_t) + sizeof (uint32_t); 558*82527734SSukumar Swaminathan 559*82527734SSukumar Swaminathan /* Save a copy of the buffer for the event log */ 560*82527734SSukumar Swaminathan if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 561*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 562*82527734SSukumar Swaminathan "%s: Unable to allocate buffer.", emlxs_link_event.label); 563*82527734SSukumar Swaminathan 564*82527734SSukumar Swaminathan return; 565*82527734SSukumar Swaminathan } 566*82527734SSukumar Swaminathan 567*82527734SSukumar Swaminathan /* 568*82527734SSukumar Swaminathan * Buffer Format: 569*82527734SSukumar Swaminathan * word[0] = Linkspeed:8 570*82527734SSukumar Swaminathan * word[0] = LIP_type:8 571*82527734SSukumar Swaminathan * word[0] = resv1:8 572*82527734SSukumar Swaminathan * word[0] = resv2:8 573*82527734SSukumar Swaminathan * word[1] = dfc_linkinfo_t data 574*82527734SSukumar Swaminathan */ 575*82527734SSukumar Swaminathan byte = (uint8_t *)bp; 576*82527734SSukumar Swaminathan linkspeed = &byte[0]; 577*82527734SSukumar Swaminathan liptype = &byte[1]; 578*82527734SSukumar Swaminathan resv1 = &byte[2]; 579*82527734SSukumar Swaminathan resv2 = &byte[3]; 580*82527734SSukumar Swaminathan linkinfo = (dfc_linkinfo_t *)&byte[4]; 581*82527734SSukumar Swaminathan 582*82527734SSukumar Swaminathan *resv1 = 0; 583*82527734SSukumar Swaminathan *resv2 = 0; 584*82527734SSukumar Swaminathan 585*82527734SSukumar Swaminathan if (hba->state <= FC_LINK_DOWN) { 586*82527734SSukumar Swaminathan *linkspeed = 0; 587*82527734SSukumar Swaminathan *liptype = 0; 588*82527734SSukumar Swaminathan } else { 589*82527734SSukumar Swaminathan /* Set linkspeed */ 590*82527734SSukumar Swaminathan if (hba->linkspeed == LA_2GHZ_LINK) { 591*82527734SSukumar Swaminathan *linkspeed = HBA_PORTSPEED_2GBIT; 592*82527734SSukumar Swaminathan } else if (hba->linkspeed == LA_4GHZ_LINK) { 593*82527734SSukumar Swaminathan *linkspeed = HBA_PORTSPEED_4GBIT; 594*82527734SSukumar Swaminathan } else if (hba->linkspeed == LA_8GHZ_LINK) { 595*82527734SSukumar Swaminathan *linkspeed = HBA_PORTSPEED_8GBIT; 596*82527734SSukumar Swaminathan } else if (hba->linkspeed == LA_10GHZ_LINK) { 597*82527734SSukumar Swaminathan *linkspeed = HBA_PORTSPEED_10GBIT; 598*82527734SSukumar Swaminathan } else { 599*82527734SSukumar Swaminathan *linkspeed = HBA_PORTSPEED_1GBIT; 600*82527734SSukumar Swaminathan } 601*82527734SSukumar Swaminathan 602*82527734SSukumar Swaminathan /* Set LIP type */ 603*82527734SSukumar Swaminathan *liptype = port->lip_type; 604*82527734SSukumar Swaminathan } 605*82527734SSukumar Swaminathan 606*82527734SSukumar Swaminathan bzero(linkinfo, sizeof (dfc_linkinfo_t)); 607*82527734SSukumar Swaminathan 608*82527734SSukumar Swaminathan linkinfo->a_linkEventTag = hba->link_event_tag; 609*82527734SSukumar Swaminathan linkinfo->a_linkUp = HBASTATS.LinkUp; 610*82527734SSukumar Swaminathan linkinfo->a_linkDown = HBASTATS.LinkDown; 611*82527734SSukumar Swaminathan linkinfo->a_linkMulti = HBASTATS.LinkMultiEvent; 612*82527734SSukumar Swaminathan 613*82527734SSukumar Swaminathan if (hba->state <= FC_LINK_DOWN) { 614*82527734SSukumar Swaminathan linkinfo->a_linkState = LNK_DOWN; 615*82527734SSukumar Swaminathan linkinfo->a_DID = port->prev_did; 616*82527734SSukumar Swaminathan } else if (hba->state < FC_READY) { 617*82527734SSukumar Swaminathan linkinfo->a_linkState = LNK_DISCOVERY; 618*82527734SSukumar Swaminathan } else { 619*82527734SSukumar Swaminathan linkinfo->a_linkState = LNK_READY; 620*82527734SSukumar Swaminathan } 621*82527734SSukumar Swaminathan 622*82527734SSukumar Swaminathan if (linkinfo->a_linkState != LNK_DOWN) { 623*82527734SSukumar Swaminathan if (hba->topology == TOPOLOGY_LOOP) { 624*82527734SSukumar Swaminathan if (hba->flag & FC_FABRIC_ATTACHED) { 625*82527734SSukumar Swaminathan linkinfo->a_topology = LNK_PUBLIC_LOOP; 626*82527734SSukumar Swaminathan } else { 627*82527734SSukumar Swaminathan linkinfo->a_topology = LNK_LOOP; 628*82527734SSukumar Swaminathan } 629*82527734SSukumar Swaminathan 630*82527734SSukumar Swaminathan linkinfo->a_alpa = port->did & 0xff; 631*82527734SSukumar Swaminathan linkinfo->a_DID = linkinfo->a_alpa; 632*82527734SSukumar Swaminathan linkinfo->a_alpaCnt = port->alpa_map[0]; 633*82527734SSukumar Swaminathan 634*82527734SSukumar Swaminathan if (linkinfo->a_alpaCnt > 127) { 635*82527734SSukumar Swaminathan linkinfo->a_alpaCnt = 127; 636*82527734SSukumar Swaminathan } 637*82527734SSukumar Swaminathan 638*82527734SSukumar Swaminathan bcopy((void *)&port->alpa_map[1], linkinfo->a_alpaMap, 639*82527734SSukumar Swaminathan linkinfo->a_alpaCnt); 640*82527734SSukumar Swaminathan } else { 641*82527734SSukumar Swaminathan if (port->node_count == 1) { 642*82527734SSukumar Swaminathan linkinfo->a_topology = LNK_PT2PT; 643*82527734SSukumar Swaminathan } else { 644*82527734SSukumar Swaminathan linkinfo->a_topology = LNK_FABRIC; 645*82527734SSukumar Swaminathan } 646*82527734SSukumar Swaminathan 647*82527734SSukumar Swaminathan linkinfo->a_DID = port->did; 648*82527734SSukumar Swaminathan } 649*82527734SSukumar Swaminathan } 650*82527734SSukumar Swaminathan 651*82527734SSukumar Swaminathan bcopy(&hba->wwpn, linkinfo->a_wwpName, 8); 652*82527734SSukumar Swaminathan bcopy(&hba->wwnn, linkinfo->a_wwnName, 8); 653*82527734SSukumar Swaminathan 654*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_link_event, bp, size); 655*82527734SSukumar Swaminathan 656*82527734SSukumar Swaminathan return; 657*82527734SSukumar Swaminathan 658*82527734SSukumar Swaminathan } /* emlxs_log_link_event() */ 659*82527734SSukumar Swaminathan 660*82527734SSukumar Swaminathan 661*82527734SSukumar Swaminathan extern void 662*82527734SSukumar Swaminathan emlxs_log_dump_event(emlxs_port_t *port, uint8_t *buffer, uint32_t size) 663*82527734SSukumar Swaminathan { 664*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 665*82527734SSukumar Swaminathan uint8_t *bp; 666*82527734SSukumar Swaminathan 667*82527734SSukumar Swaminathan /* Check if the event is being requested */ 668*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_dump_event) == 0) { 669*82527734SSukumar Swaminathan #ifdef DUMP_SUPPORT 670*82527734SSukumar Swaminathan /* Schedule a dump thread */ 671*82527734SSukumar Swaminathan emlxs_dump(hba, EMLXS_DRV_DUMP, 0, 0); 672*82527734SSukumar Swaminathan #endif /* DUMP_SUPPORT */ 673*82527734SSukumar Swaminathan return; 674*82527734SSukumar Swaminathan } 675*82527734SSukumar Swaminathan 676*82527734SSukumar Swaminathan if (buffer && size) { 677*82527734SSukumar Swaminathan /* Save a copy of the buffer for the event log */ 678*82527734SSukumar Swaminathan if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 679*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 680*82527734SSukumar Swaminathan "%s: Unable to allocate buffer.", 681*82527734SSukumar Swaminathan emlxs_dump_event.label); 682*82527734SSukumar Swaminathan 683*82527734SSukumar Swaminathan return; 684*82527734SSukumar Swaminathan } 685*82527734SSukumar Swaminathan 686*82527734SSukumar Swaminathan bcopy(buffer, bp, size); 687*82527734SSukumar Swaminathan } else { 688*82527734SSukumar Swaminathan bp = NULL; 689*82527734SSukumar Swaminathan size = 0; 690*82527734SSukumar Swaminathan } 691*82527734SSukumar Swaminathan 692*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_dump_event, bp, size); 693*82527734SSukumar Swaminathan 694*82527734SSukumar Swaminathan return; 695*82527734SSukumar Swaminathan 696*82527734SSukumar Swaminathan } /* emlxs_log_dump_event() */ 697*82527734SSukumar Swaminathan 698*82527734SSukumar Swaminathan 699*82527734SSukumar Swaminathan extern void 700*82527734SSukumar Swaminathan emlxs_log_temp_event(emlxs_port_t *port, uint32_t type, uint32_t temp) 701*82527734SSukumar Swaminathan { 702*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 703*82527734SSukumar Swaminathan uint32_t *bp; 704*82527734SSukumar Swaminathan uint32_t size; 705*82527734SSukumar Swaminathan 706*82527734SSukumar Swaminathan /* Check if the event is being requested */ 707*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_temp_event) == 0) { 708*82527734SSukumar Swaminathan #ifdef DUMP_SUPPORT 709*82527734SSukumar Swaminathan /* Schedule a dump thread */ 710*82527734SSukumar Swaminathan emlxs_dump(hba, EMLXS_TEMP_DUMP, type, temp); 711*82527734SSukumar Swaminathan #endif /* DUMP_SUPPORT */ 712*82527734SSukumar Swaminathan return; 713*82527734SSukumar Swaminathan } 714*82527734SSukumar Swaminathan 715*82527734SSukumar Swaminathan size = 2 * sizeof (uint32_t); 716*82527734SSukumar Swaminathan 717*82527734SSukumar Swaminathan if (!(bp = (uint32_t *)kmem_alloc(size, KM_NOSLEEP))) { 718*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 719*82527734SSukumar Swaminathan "%s: Unable to allocate buffer.", emlxs_temp_event.label); 720*82527734SSukumar Swaminathan 721*82527734SSukumar Swaminathan return; 722*82527734SSukumar Swaminathan } 723*82527734SSukumar Swaminathan 724*82527734SSukumar Swaminathan bp[0] = type; 725*82527734SSukumar Swaminathan bp[1] = temp; 726*82527734SSukumar Swaminathan 727*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_temp_event, bp, size); 728*82527734SSukumar Swaminathan 729*82527734SSukumar Swaminathan return; 730*82527734SSukumar Swaminathan 731*82527734SSukumar Swaminathan } /* emlxs_log_temp_event() */ 732*82527734SSukumar Swaminathan 733*82527734SSukumar Swaminathan 734*82527734SSukumar Swaminathan 735*82527734SSukumar Swaminathan extern void 736*82527734SSukumar Swaminathan emlxs_log_fcoe_event(emlxs_port_t *port, menlo_init_rsp_t *init_rsp) 737*82527734SSukumar Swaminathan { 738*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 739*82527734SSukumar Swaminathan uint8_t *bp; 740*82527734SSukumar Swaminathan uint32_t size; 741*82527734SSukumar Swaminathan 742*82527734SSukumar Swaminathan /* Check if the event is being requested */ 743*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_fcoe_event) == 0) { 744*82527734SSukumar Swaminathan return; 745*82527734SSukumar Swaminathan } 746*82527734SSukumar Swaminathan 747*82527734SSukumar Swaminathan /* Check if this is a FCOE adapter */ 748*82527734SSukumar Swaminathan if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 749*82527734SSukumar Swaminathan return; 750*82527734SSukumar Swaminathan } 751*82527734SSukumar Swaminathan 752*82527734SSukumar Swaminathan size = sizeof (menlo_init_rsp_t); 753*82527734SSukumar Swaminathan 754*82527734SSukumar Swaminathan if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 755*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 756*82527734SSukumar Swaminathan "%s: Unable to allocate buffer.", emlxs_fcoe_event.label); 757*82527734SSukumar Swaminathan 758*82527734SSukumar Swaminathan return; 759*82527734SSukumar Swaminathan } 760*82527734SSukumar Swaminathan 761*82527734SSukumar Swaminathan bcopy((uint8_t *)init_rsp, bp, size); 762*82527734SSukumar Swaminathan 763*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_fcoe_event, bp, size); 764*82527734SSukumar Swaminathan 765*82527734SSukumar Swaminathan return; 766*82527734SSukumar Swaminathan 767*82527734SSukumar Swaminathan } /* emlxs_log_fcoe_event() */ 768*82527734SSukumar Swaminathan 769*82527734SSukumar Swaminathan 770*82527734SSukumar Swaminathan extern void 771*82527734SSukumar Swaminathan emlxs_log_async_event(emlxs_port_t *port, IOCB *iocb) 772*82527734SSukumar Swaminathan { 773*82527734SSukumar Swaminathan uint8_t *bp; 774*82527734SSukumar Swaminathan uint32_t size; 775*82527734SSukumar Swaminathan 776*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_async_event) == 0) { 777*82527734SSukumar Swaminathan return; 778*82527734SSukumar Swaminathan } 779*82527734SSukumar Swaminathan 780*82527734SSukumar Swaminathan /* ASYNC_STATUS_CN response size */ 781*82527734SSukumar Swaminathan size = 64; 782*82527734SSukumar Swaminathan 783*82527734SSukumar Swaminathan if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 784*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 785*82527734SSukumar Swaminathan "%s: Unable to allocate buffer.", emlxs_async_event.label); 786*82527734SSukumar Swaminathan 787*82527734SSukumar Swaminathan return; 788*82527734SSukumar Swaminathan } 789*82527734SSukumar Swaminathan 790*82527734SSukumar Swaminathan bcopy((uint8_t *)iocb, bp, size); 791*82527734SSukumar Swaminathan 792*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_async_event, bp, size); 793*82527734SSukumar Swaminathan 794*82527734SSukumar Swaminathan return; 795*82527734SSukumar Swaminathan 796*82527734SSukumar Swaminathan } /* emlxs_log_async_event() */ 797*82527734SSukumar Swaminathan 798*82527734SSukumar Swaminathan 799*82527734SSukumar Swaminathan extern uint32_t 800*82527734SSukumar Swaminathan emlxs_get_dfc_eventinfo(emlxs_port_t *port, HBA_EVENTINFO *eventinfo, 801*82527734SSukumar Swaminathan uint32_t *eventcount, uint32_t *missed) 802*82527734SSukumar Swaminathan { 803*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 804*82527734SSukumar Swaminathan emlxs_event_queue_t *eventq = &EVENTQ; 805*82527734SSukumar Swaminathan emlxs_event_entry_t *entry; 806*82527734SSukumar Swaminathan uint32_t max_events; 807*82527734SSukumar Swaminathan dfc_linkinfo_t *linkinfo; 808*82527734SSukumar Swaminathan uint32_t *word; 809*82527734SSukumar Swaminathan uint8_t *byte; 810*82527734SSukumar Swaminathan uint8_t linkspeed; 811*82527734SSukumar Swaminathan uint8_t liptype; 812*82527734SSukumar Swaminathan fc_affected_id_t *aid; 813*82527734SSukumar Swaminathan uint32_t events; 814*82527734SSukumar Swaminathan uint8_t format; 815*82527734SSukumar Swaminathan 816*82527734SSukumar Swaminathan if (!eventinfo || !eventcount || !missed) { 817*82527734SSukumar Swaminathan return (DFC_ARG_NULL); 818*82527734SSukumar Swaminathan } 819*82527734SSukumar Swaminathan 820*82527734SSukumar Swaminathan max_events = *eventcount; 821*82527734SSukumar Swaminathan *eventcount = 0; 822*82527734SSukumar Swaminathan *missed = 0; 823*82527734SSukumar Swaminathan 824*82527734SSukumar Swaminathan mutex_enter(&eventq->lock); 825*82527734SSukumar Swaminathan 826*82527734SSukumar Swaminathan /* Account for missed events */ 827*82527734SSukumar Swaminathan if (hba->hba_event.new > hba->hba_event.missed) { 828*82527734SSukumar Swaminathan hba->hba_event.new -= hba->hba_event.missed; 829*82527734SSukumar Swaminathan } else { 830*82527734SSukumar Swaminathan hba->hba_event.new = 0; 831*82527734SSukumar Swaminathan } 832*82527734SSukumar Swaminathan 833*82527734SSukumar Swaminathan *missed = hba->hba_event.missed; 834*82527734SSukumar Swaminathan hba->hba_event.missed = 0; 835*82527734SSukumar Swaminathan 836*82527734SSukumar Swaminathan if (!hba->hba_event.new) { 837*82527734SSukumar Swaminathan hba->hba_event.last_id = eventq->next_id - 1; 838*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 839*82527734SSukumar Swaminathan return (0); 840*82527734SSukumar Swaminathan } 841*82527734SSukumar Swaminathan 842*82527734SSukumar Swaminathan /* A new event has occurred since last acquisition */ 843*82527734SSukumar Swaminathan 844*82527734SSukumar Swaminathan events = 0; 845*82527734SSukumar Swaminathan entry = eventq->first; 846*82527734SSukumar Swaminathan while (entry && (events < max_events)) { 847*82527734SSukumar Swaminathan 848*82527734SSukumar Swaminathan /* Skip old events */ 849*82527734SSukumar Swaminathan if (entry->id <= hba->hba_event.last_id) { 850*82527734SSukumar Swaminathan entry = entry->next; 851*82527734SSukumar Swaminathan continue; 852*82527734SSukumar Swaminathan } 853*82527734SSukumar Swaminathan 854*82527734SSukumar Swaminathan /* Process this entry */ 855*82527734SSukumar Swaminathan switch (entry->evt->mask) { 856*82527734SSukumar Swaminathan case EVT_LINK: 857*82527734SSukumar Swaminathan byte = (uint8_t *)entry->bp; 858*82527734SSukumar Swaminathan linkspeed = byte[0]; 859*82527734SSukumar Swaminathan liptype = byte[1]; 860*82527734SSukumar Swaminathan linkinfo = (dfc_linkinfo_t *)&byte[4]; 861*82527734SSukumar Swaminathan 862*82527734SSukumar Swaminathan if (linkinfo->a_linkState == LNK_DOWN) { 863*82527734SSukumar Swaminathan eventinfo->EventCode = 864*82527734SSukumar Swaminathan HBA_EVENT_LINK_DOWN; 865*82527734SSukumar Swaminathan eventinfo->Event.Link_EventInfo. 866*82527734SSukumar Swaminathan PortFcId = linkinfo->a_DID; 867*82527734SSukumar Swaminathan eventinfo->Event.Link_EventInfo. 868*82527734SSukumar Swaminathan Reserved[0] = 0; 869*82527734SSukumar Swaminathan eventinfo->Event.Link_EventInfo. 870*82527734SSukumar Swaminathan Reserved[1] = 0; 871*82527734SSukumar Swaminathan eventinfo->Event.Link_EventInfo. 872*82527734SSukumar Swaminathan Reserved[2] = 0; 873*82527734SSukumar Swaminathan } else { 874*82527734SSukumar Swaminathan eventinfo->EventCode = 875*82527734SSukumar Swaminathan HBA_EVENT_LINK_UP; 876*82527734SSukumar Swaminathan eventinfo->Event.Link_EventInfo. 877*82527734SSukumar Swaminathan PortFcId = linkinfo->a_DID; 878*82527734SSukumar Swaminathan 879*82527734SSukumar Swaminathan if ((linkinfo->a_topology == 880*82527734SSukumar Swaminathan LNK_PUBLIC_LOOP) || 881*82527734SSukumar Swaminathan (linkinfo->a_topology == 882*82527734SSukumar Swaminathan LNK_LOOP)) { 883*82527734SSukumar Swaminathan eventinfo->Event. 884*82527734SSukumar Swaminathan Link_EventInfo. 885*82527734SSukumar Swaminathan Reserved[0] = 2; 886*82527734SSukumar Swaminathan } else { 887*82527734SSukumar Swaminathan eventinfo->Event. 888*82527734SSukumar Swaminathan Link_EventInfo. 889*82527734SSukumar Swaminathan Reserved[0] = 1; 890*82527734SSukumar Swaminathan } 891*82527734SSukumar Swaminathan 892*82527734SSukumar Swaminathan eventinfo->Event.Link_EventInfo. 893*82527734SSukumar Swaminathan Reserved[1] = liptype; 894*82527734SSukumar Swaminathan eventinfo->Event.Link_EventInfo. 895*82527734SSukumar Swaminathan Reserved[2] = linkspeed; 896*82527734SSukumar Swaminathan } 897*82527734SSukumar Swaminathan 898*82527734SSukumar Swaminathan eventinfo++; 899*82527734SSukumar Swaminathan events++; 900*82527734SSukumar Swaminathan hba->hba_event.new--; 901*82527734SSukumar Swaminathan break; 902*82527734SSukumar Swaminathan 903*82527734SSukumar Swaminathan case EVT_RSCN: 904*82527734SSukumar Swaminathan word = (uint32_t *)entry->bp; 905*82527734SSukumar Swaminathan eventinfo->EventCode = HBA_EVENT_RSCN; 906*82527734SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo.PortFcId = 907*82527734SSukumar Swaminathan word[0] & 0xFFFFFF; 908*82527734SSukumar Swaminathan /* word[1] is the RSCN payload command */ 909*82527734SSukumar Swaminathan 910*82527734SSukumar Swaminathan aid = (fc_affected_id_t *)&word[2]; 911*82527734SSukumar Swaminathan format = aid->aff_format; 912*82527734SSukumar Swaminathan 913*82527734SSukumar Swaminathan switch (format) { 914*82527734SSukumar Swaminathan case 0: /* Port */ 915*82527734SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo. 916*82527734SSukumar Swaminathan NPortPage = 917*82527734SSukumar Swaminathan aid->aff_d_id & 0x00ffffff; 918*82527734SSukumar Swaminathan break; 919*82527734SSukumar Swaminathan 920*82527734SSukumar Swaminathan case 1: /* Area */ 921*82527734SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo. 922*82527734SSukumar Swaminathan NPortPage = 923*82527734SSukumar Swaminathan aid->aff_d_id & 0x00ffff00; 924*82527734SSukumar Swaminathan break; 925*82527734SSukumar Swaminathan 926*82527734SSukumar Swaminathan case 2: /* Domain */ 927*82527734SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo. 928*82527734SSukumar Swaminathan NPortPage = 929*82527734SSukumar Swaminathan aid->aff_d_id & 0x00ff0000; 930*82527734SSukumar Swaminathan break; 931*82527734SSukumar Swaminathan 932*82527734SSukumar Swaminathan case 3: /* Network */ 933*82527734SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo. 934*82527734SSukumar Swaminathan NPortPage = 0; 935*82527734SSukumar Swaminathan break; 936*82527734SSukumar Swaminathan } 937*82527734SSukumar Swaminathan 938*82527734SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo.Reserved[0] = 939*82527734SSukumar Swaminathan 0; 940*82527734SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo.Reserved[1] = 941*82527734SSukumar Swaminathan 0; 942*82527734SSukumar Swaminathan 943*82527734SSukumar Swaminathan eventinfo++; 944*82527734SSukumar Swaminathan events++; 945*82527734SSukumar Swaminathan hba->hba_event.new--; 946*82527734SSukumar Swaminathan break; 947*82527734SSukumar Swaminathan } 948*82527734SSukumar Swaminathan 949*82527734SSukumar Swaminathan hba->hba_event.last_id = entry->id; 950*82527734SSukumar Swaminathan entry = entry->next; 951*82527734SSukumar Swaminathan } 952*82527734SSukumar Swaminathan 953*82527734SSukumar Swaminathan /* Return number of events acquired */ 954*82527734SSukumar Swaminathan *eventcount = events; 955*82527734SSukumar Swaminathan 956*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 957*82527734SSukumar Swaminathan 958*82527734SSukumar Swaminathan return (0); 959*82527734SSukumar Swaminathan 960*82527734SSukumar Swaminathan } /* emlxs_get_dfc_eventinfo() */ 961*82527734SSukumar Swaminathan 962*82527734SSukumar Swaminathan 963*82527734SSukumar Swaminathan uint32_t 964*82527734SSukumar Swaminathan emlxs_get_dfc_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event, 965*82527734SSukumar Swaminathan uint32_t sleep) 966*82527734SSukumar Swaminathan { 967*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 968*82527734SSukumar Swaminathan emlxs_event_queue_t *eventq = &EVENTQ; 969*82527734SSukumar Swaminathan emlxs_event_entry_t *entry; 970*82527734SSukumar Swaminathan uint32_t found; 971*82527734SSukumar Swaminathan uint32_t mask; 972*82527734SSukumar Swaminathan uint32_t i; 973*82527734SSukumar Swaminathan uint32_t size = 0; 974*82527734SSukumar Swaminathan uint32_t rc; 975*82527734SSukumar Swaminathan 976*82527734SSukumar Swaminathan if (dfc_event->dataout && dfc_event->size) { 977*82527734SSukumar Swaminathan size = dfc_event->size; 978*82527734SSukumar Swaminathan } 979*82527734SSukumar Swaminathan dfc_event->size = 0; 980*82527734SSukumar Swaminathan 981*82527734SSukumar Swaminathan if (!dfc_event->event) { 982*82527734SSukumar Swaminathan return (DFC_ARG_INVALID); 983*82527734SSukumar Swaminathan } 984*82527734SSukumar Swaminathan 985*82527734SSukumar Swaminathan /* Calculate the event index */ 986*82527734SSukumar Swaminathan mask = dfc_event->event; 987*82527734SSukumar Swaminathan for (i = 0; i < 32; i++) { 988*82527734SSukumar Swaminathan if (mask & 0x01) { 989*82527734SSukumar Swaminathan break; 990*82527734SSukumar Swaminathan } 991*82527734SSukumar Swaminathan 992*82527734SSukumar Swaminathan mask >>= 1; 993*82527734SSukumar Swaminathan } 994*82527734SSukumar Swaminathan 995*82527734SSukumar Swaminathan mutex_enter(&eventq->lock); 996*82527734SSukumar Swaminathan 997*82527734SSukumar Swaminathan wait_for_event: 998*82527734SSukumar Swaminathan 999*82527734SSukumar Swaminathan /* Check if no new event has occurred */ 1000*82527734SSukumar Swaminathan if (dfc_event->last_id == eventq->last_id[i]) { 1001*82527734SSukumar Swaminathan if (!sleep) { 1002*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1003*82527734SSukumar Swaminathan return (0); 1004*82527734SSukumar Swaminathan } 1005*82527734SSukumar Swaminathan 1006*82527734SSukumar Swaminathan /* While event is still active and */ 1007*82527734SSukumar Swaminathan /* no new event has been logged */ 1008*82527734SSukumar Swaminathan while ((dfc_event->event & hba->event_mask) && 1009*82527734SSukumar Swaminathan (dfc_event->last_id == eventq->last_id[i])) { 1010*82527734SSukumar Swaminathan 1011*82527734SSukumar Swaminathan rc = cv_wait_sig(&eventq->lock_cv, &eventq->lock); 1012*82527734SSukumar Swaminathan 1013*82527734SSukumar Swaminathan /* Check if thread was killed by kernel */ 1014*82527734SSukumar Swaminathan if (rc == 0) { 1015*82527734SSukumar Swaminathan dfc_event->pid = 0; 1016*82527734SSukumar Swaminathan dfc_event->event = 0; 1017*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1018*82527734SSukumar Swaminathan return (0); 1019*82527734SSukumar Swaminathan } 1020*82527734SSukumar Swaminathan } 1021*82527734SSukumar Swaminathan 1022*82527734SSukumar Swaminathan /* If the event is no longer registered then */ 1023*82527734SSukumar Swaminathan /* return immediately */ 1024*82527734SSukumar Swaminathan if (!(dfc_event->event & hba->event_mask)) { 1025*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1026*82527734SSukumar Swaminathan return (0); 1027*82527734SSukumar Swaminathan } 1028*82527734SSukumar Swaminathan } 1029*82527734SSukumar Swaminathan 1030*82527734SSukumar Swaminathan /* !!! An event has occurred since last_id !!! */ 1031*82527734SSukumar Swaminathan 1032*82527734SSukumar Swaminathan /* Check if event data is not being requested */ 1033*82527734SSukumar Swaminathan if (!size) { 1034*82527734SSukumar Swaminathan /* If so, then just return the last event id */ 1035*82527734SSukumar Swaminathan dfc_event->last_id = eventq->last_id[i]; 1036*82527734SSukumar Swaminathan 1037*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1038*82527734SSukumar Swaminathan return (0); 1039*82527734SSukumar Swaminathan } 1040*82527734SSukumar Swaminathan 1041*82527734SSukumar Swaminathan /* !!! The requester wants the next event buffer !!! */ 1042*82527734SSukumar Swaminathan 1043*82527734SSukumar Swaminathan found = 0; 1044*82527734SSukumar Swaminathan entry = eventq->first; 1045*82527734SSukumar Swaminathan while (entry) { 1046*82527734SSukumar Swaminathan if ((entry->id > dfc_event->last_id) && 1047*82527734SSukumar Swaminathan (entry->evt->mask == dfc_event->event)) { 1048*82527734SSukumar Swaminathan found = 1; 1049*82527734SSukumar Swaminathan break; 1050*82527734SSukumar Swaminathan } 1051*82527734SSukumar Swaminathan 1052*82527734SSukumar Swaminathan entry = entry->next; 1053*82527734SSukumar Swaminathan } 1054*82527734SSukumar Swaminathan 1055*82527734SSukumar Swaminathan if (!found) { 1056*82527734SSukumar Swaminathan /* Update last_id to the last known event */ 1057*82527734SSukumar Swaminathan dfc_event->last_id = eventq->last_id[i]; 1058*82527734SSukumar Swaminathan 1059*82527734SSukumar Swaminathan /* Try waiting again if we can */ 1060*82527734SSukumar Swaminathan goto wait_for_event; 1061*82527734SSukumar Swaminathan } 1062*82527734SSukumar Swaminathan 1063*82527734SSukumar Swaminathan /* !!! Next event found !!! */ 1064*82527734SSukumar Swaminathan 1065*82527734SSukumar Swaminathan /* Copy the context buffer to the buffer provided */ 1066*82527734SSukumar Swaminathan if (entry->bp && entry->size) { 1067*82527734SSukumar Swaminathan if (entry->size < size) { 1068*82527734SSukumar Swaminathan size = entry->size; 1069*82527734SSukumar Swaminathan } 1070*82527734SSukumar Swaminathan 1071*82527734SSukumar Swaminathan if (ddi_copyout((void *)entry->bp, dfc_event->dataout, size, 1072*82527734SSukumar Swaminathan dfc_event->mode) != 0) { 1073*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1074*82527734SSukumar Swaminathan 1075*82527734SSukumar Swaminathan return (DFC_COPYOUT_ERROR); 1076*82527734SSukumar Swaminathan } 1077*82527734SSukumar Swaminathan 1078*82527734SSukumar Swaminathan /* Event has been retrieved by DFCLIB */ 1079*82527734SSukumar Swaminathan entry->flag |= EMLXS_DFC_EVENT_DONE; 1080*82527734SSukumar Swaminathan 1081*82527734SSukumar Swaminathan dfc_event->size = size; 1082*82527734SSukumar Swaminathan } 1083*82527734SSukumar Swaminathan 1084*82527734SSukumar Swaminathan dfc_event->last_id = entry->id; 1085*82527734SSukumar Swaminathan 1086*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1087*82527734SSukumar Swaminathan 1088*82527734SSukumar Swaminathan return (0); 1089*82527734SSukumar Swaminathan 1090*82527734SSukumar Swaminathan } /* emlxs_get_dfc_event() */ 1091*82527734SSukumar Swaminathan 1092*82527734SSukumar Swaminathan 1093*82527734SSukumar Swaminathan uint32_t 1094*82527734SSukumar Swaminathan emlxs_kill_dfc_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event) 1095*82527734SSukumar Swaminathan { 1096*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 1097*82527734SSukumar Swaminathan emlxs_event_queue_t *eventq = &EVENTQ; 1098*82527734SSukumar Swaminathan 1099*82527734SSukumar Swaminathan mutex_enter(&eventq->lock); 1100*82527734SSukumar Swaminathan dfc_event->pid = 0; 1101*82527734SSukumar Swaminathan dfc_event->event = 0; 1102*82527734SSukumar Swaminathan cv_broadcast(&eventq->lock_cv); 1103*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1104*82527734SSukumar Swaminathan 1105*82527734SSukumar Swaminathan return (0); 1106*82527734SSukumar Swaminathan 1107*82527734SSukumar Swaminathan } /* emlxs_kill_dfc_event() */ 1108*82527734SSukumar Swaminathan 1109*82527734SSukumar Swaminathan 1110*82527734SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1111*82527734SSukumar Swaminathan extern void 1112*82527734SSukumar Swaminathan emlxs_log_sd_basic_els_event(emlxs_port_t *port, uint32_t subcat, 1113*82527734SSukumar Swaminathan HBA_WWN *portname, HBA_WWN *nodename) 1114*82527734SSukumar Swaminathan { 1115*82527734SSukumar Swaminathan struct sd_plogi_rcv_v0 *bp; 1116*82527734SSukumar Swaminathan uint32_t size; 1117*82527734SSukumar Swaminathan 1118*82527734SSukumar Swaminathan /* Check if the event is being requested */ 1119*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_sd_els_event) == 0) { 1120*82527734SSukumar Swaminathan return; 1121*82527734SSukumar Swaminathan } 1122*82527734SSukumar Swaminathan 1123*82527734SSukumar Swaminathan size = sizeof (struct sd_plogi_rcv_v0); 1124*82527734SSukumar Swaminathan 1125*82527734SSukumar Swaminathan if (!(bp = (struct sd_plogi_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP))) { 1126*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 1127*82527734SSukumar Swaminathan "%s: Unable to allocate buffer.", emlxs_sd_els_event.label); 1128*82527734SSukumar Swaminathan 1129*82527734SSukumar Swaminathan return; 1130*82527734SSukumar Swaminathan } 1131*82527734SSukumar Swaminathan 1132*82527734SSukumar Swaminathan /* 1133*82527734SSukumar Swaminathan * we are using version field to store subtype, libdfc 1134*82527734SSukumar Swaminathan * will fix this up before returning data to app. 1135*82527734SSukumar Swaminathan */ 1136*82527734SSukumar Swaminathan bp->sd_plogir_version = subcat; 1137*82527734SSukumar Swaminathan bcopy((uint8_t *)portname, (uint8_t *)&bp->sd_plogir_portname, 1138*82527734SSukumar Swaminathan sizeof (HBA_WWN)); 1139*82527734SSukumar Swaminathan bcopy((uint8_t *)nodename, (uint8_t *)&bp->sd_plogir_nodename, 1140*82527734SSukumar Swaminathan sizeof (HBA_WWN)); 1141*82527734SSukumar Swaminathan 1142*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_sd_els_event, bp, size); 1143*82527734SSukumar Swaminathan 1144*82527734SSukumar Swaminathan return; 1145*82527734SSukumar Swaminathan 1146*82527734SSukumar Swaminathan } /* emlxs_log_sd_basic_els_event() */ 1147*82527734SSukumar Swaminathan 1148*82527734SSukumar Swaminathan 1149*82527734SSukumar Swaminathan extern void 1150*82527734SSukumar Swaminathan emlxs_log_sd_prlo_event(emlxs_port_t *port, HBA_WWN *remoteport) 1151*82527734SSukumar Swaminathan { 1152*82527734SSukumar Swaminathan struct sd_prlo_rcv_v0 *bp; 1153*82527734SSukumar Swaminathan uint32_t size; 1154*82527734SSukumar Swaminathan 1155*82527734SSukumar Swaminathan /* Check if the event is being requested */ 1156*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_sd_els_event) == 0) { 1157*82527734SSukumar Swaminathan return; 1158*82527734SSukumar Swaminathan } 1159*82527734SSukumar Swaminathan 1160*82527734SSukumar Swaminathan size = sizeof (struct sd_prlo_rcv_v0); 1161*82527734SSukumar Swaminathan 1162*82527734SSukumar Swaminathan if (!(bp = (struct sd_prlo_rcv_v0 *)kmem_alloc(size, 1163*82527734SSukumar Swaminathan KM_NOSLEEP))) { 1164*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 1165*82527734SSukumar Swaminathan "%s PRLO: Unable to allocate buffer.", 1166*82527734SSukumar Swaminathan emlxs_sd_els_event.label); 1167*82527734SSukumar Swaminathan 1168*82527734SSukumar Swaminathan return; 1169*82527734SSukumar Swaminathan } 1170*82527734SSukumar Swaminathan 1171*82527734SSukumar Swaminathan /* 1172*82527734SSukumar Swaminathan * we are using version field to store subtype, libdfc 1173*82527734SSukumar Swaminathan * will fix this up before returning data to app. 1174*82527734SSukumar Swaminathan */ 1175*82527734SSukumar Swaminathan bp->sd_prlor_version = SD_ELS_SUBCATEGORY_PRLO_RCV; 1176*82527734SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_prlor_remoteport, 1177*82527734SSukumar Swaminathan sizeof (HBA_WWN)); 1178*82527734SSukumar Swaminathan 1179*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_sd_els_event, bp, size); 1180*82527734SSukumar Swaminathan 1181*82527734SSukumar Swaminathan return; 1182*82527734SSukumar Swaminathan 1183*82527734SSukumar Swaminathan } /* emlxs_log_sd_prlo_event() */ 1184*82527734SSukumar Swaminathan 1185*82527734SSukumar Swaminathan 1186*82527734SSukumar Swaminathan extern void 1187*82527734SSukumar Swaminathan emlxs_log_sd_lsrjt_event(emlxs_port_t *port, HBA_WWN *remoteport, 1188*82527734SSukumar Swaminathan uint32_t orig_cmd, uint32_t reason, uint32_t reason_expl) 1189*82527734SSukumar Swaminathan { 1190*82527734SSukumar Swaminathan struct sd_lsrjt_rcv_v0 *bp; 1191*82527734SSukumar Swaminathan uint32_t size; 1192*82527734SSukumar Swaminathan 1193*82527734SSukumar Swaminathan /* Check if the event is being requested */ 1194*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_sd_els_event) == 0) { 1195*82527734SSukumar Swaminathan return; 1196*82527734SSukumar Swaminathan } 1197*82527734SSukumar Swaminathan 1198*82527734SSukumar Swaminathan size = sizeof (struct sd_lsrjt_rcv_v0); 1199*82527734SSukumar Swaminathan 1200*82527734SSukumar Swaminathan if (!(bp = (struct sd_lsrjt_rcv_v0 *)kmem_alloc(size, 1201*82527734SSukumar Swaminathan KM_NOSLEEP))) { 1202*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 1203*82527734SSukumar Swaminathan "%s LSRJT: Unable to allocate buffer.", 1204*82527734SSukumar Swaminathan emlxs_sd_els_event.label); 1205*82527734SSukumar Swaminathan 1206*82527734SSukumar Swaminathan return; 1207*82527734SSukumar Swaminathan } 1208*82527734SSukumar Swaminathan 1209*82527734SSukumar Swaminathan /* 1210*82527734SSukumar Swaminathan * we are using version field to store subtype, libdfc 1211*82527734SSukumar Swaminathan * will fix this up before returning data to app. 1212*82527734SSukumar Swaminathan */ 1213*82527734SSukumar Swaminathan bp->sd_lsrjtr_version = SD_ELS_SUBCATEGORY_LSRJT_RCV; 1214*82527734SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_lsrjtr_remoteport, 1215*82527734SSukumar Swaminathan sizeof (HBA_WWN)); 1216*82527734SSukumar Swaminathan bp->sd_lsrjtr_original_cmd = orig_cmd; 1217*82527734SSukumar Swaminathan bp->sd_lsrjtr_reasoncode = reason; 1218*82527734SSukumar Swaminathan bp->sd_lsrjtr_reasoncodeexpl = reason_expl; 1219*82527734SSukumar Swaminathan 1220*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_sd_els_event, bp, size); 1221*82527734SSukumar Swaminathan 1222*82527734SSukumar Swaminathan return; 1223*82527734SSukumar Swaminathan 1224*82527734SSukumar Swaminathan } /* emlxs_log_sd_lsrjt_event() */ 1225*82527734SSukumar Swaminathan 1226*82527734SSukumar Swaminathan 1227*82527734SSukumar Swaminathan extern void 1228*82527734SSukumar Swaminathan emlxs_log_sd_fc_bsy_event(emlxs_port_t *port, HBA_WWN *remoteport) 1229*82527734SSukumar Swaminathan { 1230*82527734SSukumar Swaminathan struct sd_pbsy_rcv_v0 *bp; 1231*82527734SSukumar Swaminathan uint32_t size; 1232*82527734SSukumar Swaminathan 1233*82527734SSukumar Swaminathan /* Check if the event is being requested */ 1234*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_sd_fabric_event) == 0) { 1235*82527734SSukumar Swaminathan return; 1236*82527734SSukumar Swaminathan } 1237*82527734SSukumar Swaminathan 1238*82527734SSukumar Swaminathan size = sizeof (struct sd_pbsy_rcv_v0); 1239*82527734SSukumar Swaminathan 1240*82527734SSukumar Swaminathan if (!(bp = (struct sd_pbsy_rcv_v0 *)kmem_alloc(size, 1241*82527734SSukumar Swaminathan KM_NOSLEEP))) { 1242*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 1243*82527734SSukumar Swaminathan "%s BSY: Unable to allocate buffer.", 1244*82527734SSukumar Swaminathan emlxs_sd_fabric_event.label); 1245*82527734SSukumar Swaminathan 1246*82527734SSukumar Swaminathan return; 1247*82527734SSukumar Swaminathan } 1248*82527734SSukumar Swaminathan 1249*82527734SSukumar Swaminathan /* 1250*82527734SSukumar Swaminathan * we are using version field to store subtype, libdfc 1251*82527734SSukumar Swaminathan * will fix this up before returning data to app. 1252*82527734SSukumar Swaminathan */ 1253*82527734SSukumar Swaminathan if (remoteport == NULL) 1254*82527734SSukumar Swaminathan bp->sd_pbsyr_evt_version = SD_FABRIC_SUBCATEGORY_FABRIC_BUSY; 1255*82527734SSukumar Swaminathan else 1256*82527734SSukumar Swaminathan { 1257*82527734SSukumar Swaminathan bp->sd_pbsyr_evt_version = SD_FABRIC_SUBCATEGORY_PORT_BUSY; 1258*82527734SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_pbsyr_rport, 1259*82527734SSukumar Swaminathan sizeof (HBA_WWN)); 1260*82527734SSukumar Swaminathan } 1261*82527734SSukumar Swaminathan 1262*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_sd_fabric_event, bp, size); 1263*82527734SSukumar Swaminathan 1264*82527734SSukumar Swaminathan return; 1265*82527734SSukumar Swaminathan 1266*82527734SSukumar Swaminathan } /* emlxs_log_sd_fc_bsy_event() */ 1267*82527734SSukumar Swaminathan 1268*82527734SSukumar Swaminathan 1269*82527734SSukumar Swaminathan extern void 1270*82527734SSukumar Swaminathan emlxs_log_sd_fc_rdchk_event(emlxs_port_t *port, HBA_WWN *remoteport, 1271*82527734SSukumar Swaminathan uint32_t lun, uint32_t opcode, uint32_t fcp_param) 1272*82527734SSukumar Swaminathan { 1273*82527734SSukumar Swaminathan struct sd_fcprdchkerr_v0 *bp; 1274*82527734SSukumar Swaminathan uint32_t size; 1275*82527734SSukumar Swaminathan 1276*82527734SSukumar Swaminathan /* Check if the event is being requested */ 1277*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_sd_fabric_event) == 0) { 1278*82527734SSukumar Swaminathan return; 1279*82527734SSukumar Swaminathan } 1280*82527734SSukumar Swaminathan 1281*82527734SSukumar Swaminathan size = sizeof (struct sd_fcprdchkerr_v0); 1282*82527734SSukumar Swaminathan 1283*82527734SSukumar Swaminathan if (!(bp = (struct sd_fcprdchkerr_v0 *)kmem_alloc(size, 1284*82527734SSukumar Swaminathan KM_NOSLEEP))) { 1285*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 1286*82527734SSukumar Swaminathan "%s RDCHK: Unable to allocate buffer.", 1287*82527734SSukumar Swaminathan emlxs_sd_fabric_event.label); 1288*82527734SSukumar Swaminathan 1289*82527734SSukumar Swaminathan return; 1290*82527734SSukumar Swaminathan } 1291*82527734SSukumar Swaminathan 1292*82527734SSukumar Swaminathan /* 1293*82527734SSukumar Swaminathan * we are using version field to store subtype, libdfc 1294*82527734SSukumar Swaminathan * will fix this up before returning data to app. 1295*82527734SSukumar Swaminathan */ 1296*82527734SSukumar Swaminathan bp->sd_fcprdchkerr_version = SD_FABRIC_SUBCATEGORY_FCPRDCHKERR; 1297*82527734SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_fcprdchkerr_rport, 1298*82527734SSukumar Swaminathan sizeof (HBA_WWN)); 1299*82527734SSukumar Swaminathan bp->sd_fcprdchkerr_lun = lun; 1300*82527734SSukumar Swaminathan bp->sd_fcprdchkerr_opcode = opcode; 1301*82527734SSukumar Swaminathan bp->sd_fcprdchkerr_fcpiparam = fcp_param; 1302*82527734SSukumar Swaminathan 1303*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_sd_fabric_event, bp, size); 1304*82527734SSukumar Swaminathan 1305*82527734SSukumar Swaminathan return; 1306*82527734SSukumar Swaminathan 1307*82527734SSukumar Swaminathan } /* emlxs_log_sd_rdchk_event() */ 1308*82527734SSukumar Swaminathan 1309*82527734SSukumar Swaminathan 1310*82527734SSukumar Swaminathan extern void 1311*82527734SSukumar Swaminathan emlxs_log_sd_scsi_event(emlxs_port_t *port, uint32_t type, 1312*82527734SSukumar Swaminathan HBA_WWN *remoteport, int32_t lun) 1313*82527734SSukumar Swaminathan { 1314*82527734SSukumar Swaminathan struct sd_scsi_generic_v0 *bp; 1315*82527734SSukumar Swaminathan uint32_t size; 1316*82527734SSukumar Swaminathan 1317*82527734SSukumar Swaminathan /* Check if the event is being requested */ 1318*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_sd_scsi_event) == 0) { 1319*82527734SSukumar Swaminathan return; 1320*82527734SSukumar Swaminathan } 1321*82527734SSukumar Swaminathan 1322*82527734SSukumar Swaminathan size = sizeof (struct sd_scsi_generic_v0); 1323*82527734SSukumar Swaminathan 1324*82527734SSukumar Swaminathan if (!(bp = (struct sd_scsi_generic_v0 *)kmem_alloc(size, 1325*82527734SSukumar Swaminathan KM_NOSLEEP))) { 1326*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 1327*82527734SSukumar Swaminathan "%s: Unable to allocate buffer.", 1328*82527734SSukumar Swaminathan emlxs_sd_scsi_event.label); 1329*82527734SSukumar Swaminathan 1330*82527734SSukumar Swaminathan return; 1331*82527734SSukumar Swaminathan } 1332*82527734SSukumar Swaminathan 1333*82527734SSukumar Swaminathan /* 1334*82527734SSukumar Swaminathan * we are using version field to store subtype, libdfc 1335*82527734SSukumar Swaminathan * will fix this up before returning data to app. 1336*82527734SSukumar Swaminathan */ 1337*82527734SSukumar Swaminathan bp->sd_scsi_generic_version = type; 1338*82527734SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_scsi_generic_rport, 1339*82527734SSukumar Swaminathan sizeof (HBA_WWN)); 1340*82527734SSukumar Swaminathan bp->sd_scsi_generic_lun = lun; 1341*82527734SSukumar Swaminathan 1342*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_sd_scsi_event, bp, size); 1343*82527734SSukumar Swaminathan 1344*82527734SSukumar Swaminathan return; 1345*82527734SSukumar Swaminathan 1346*82527734SSukumar Swaminathan } /* emlxs_log_sd_scsi_event() */ 1347*82527734SSukumar Swaminathan 1348*82527734SSukumar Swaminathan 1349*82527734SSukumar Swaminathan extern void 1350*82527734SSukumar Swaminathan emlxs_log_sd_scsi_check_event(emlxs_port_t *port, HBA_WWN *remoteport, 1351*82527734SSukumar Swaminathan uint32_t lun, uint32_t cmdcode, uint32_t sensekey, 1352*82527734SSukumar Swaminathan uint32_t asc, uint32_t ascq) 1353*82527734SSukumar Swaminathan { 1354*82527734SSukumar Swaminathan struct sd_scsi_checkcond_v0 *bp; 1355*82527734SSukumar Swaminathan uint32_t size; 1356*82527734SSukumar Swaminathan 1357*82527734SSukumar Swaminathan /* Check if the event is being requested */ 1358*82527734SSukumar Swaminathan if (emlxs_event_check(port, &emlxs_sd_scsi_event) == 0) { 1359*82527734SSukumar Swaminathan return; 1360*82527734SSukumar Swaminathan } 1361*82527734SSukumar Swaminathan 1362*82527734SSukumar Swaminathan size = sizeof (struct sd_scsi_checkcond_v0); 1363*82527734SSukumar Swaminathan 1364*82527734SSukumar Swaminathan if (!(bp = (struct sd_scsi_checkcond_v0 *)kmem_alloc(size, 1365*82527734SSukumar Swaminathan KM_NOSLEEP))) { 1366*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_event_debug_msg, 1367*82527734SSukumar Swaminathan "%s CHECK: Unable to allocate buffer.", 1368*82527734SSukumar Swaminathan emlxs_sd_scsi_event.label); 1369*82527734SSukumar Swaminathan 1370*82527734SSukumar Swaminathan return; 1371*82527734SSukumar Swaminathan } 1372*82527734SSukumar Swaminathan 1373*82527734SSukumar Swaminathan /* 1374*82527734SSukumar Swaminathan * we are using version field to store subtype, libdfc 1375*82527734SSukumar Swaminathan * will fix this up before returning data to app. 1376*82527734SSukumar Swaminathan */ 1377*82527734SSukumar Swaminathan bp->sd_scsi_checkcond_version = SD_SCSI_SUBCATEGORY_CHECKCONDITION; 1378*82527734SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_scsi_checkcond_rport, 1379*82527734SSukumar Swaminathan sizeof (HBA_WWN)); 1380*82527734SSukumar Swaminathan bp->sd_scsi_checkcond_lun = lun; 1381*82527734SSukumar Swaminathan bp->sd_scsi_checkcond_cmdcode = cmdcode; 1382*82527734SSukumar Swaminathan bp->sd_scsi_checkcond_sensekey = sensekey; 1383*82527734SSukumar Swaminathan bp->sd_scsi_checkcond_asc = asc; 1384*82527734SSukumar Swaminathan bp->sd_scsi_checkcond_ascq = ascq; 1385*82527734SSukumar Swaminathan 1386*82527734SSukumar Swaminathan emlxs_event(port, &emlxs_sd_scsi_event, bp, size); 1387*82527734SSukumar Swaminathan 1388*82527734SSukumar Swaminathan return; 1389*82527734SSukumar Swaminathan 1390*82527734SSukumar Swaminathan } /* emlxs_log_sd_scsi_check_event() */ 1391*82527734SSukumar Swaminathan 1392*82527734SSukumar Swaminathan 1393*82527734SSukumar Swaminathan uint32_t 1394*82527734SSukumar Swaminathan emlxs_get_sd_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event, 1395*82527734SSukumar Swaminathan uint32_t sleep) 1396*82527734SSukumar Swaminathan { 1397*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 1398*82527734SSukumar Swaminathan emlxs_event_queue_t *eventq = &EVENTQ; 1399*82527734SSukumar Swaminathan emlxs_event_entry_t *entry; 1400*82527734SSukumar Swaminathan uint32_t found; 1401*82527734SSukumar Swaminathan uint32_t mask; 1402*82527734SSukumar Swaminathan uint32_t i; 1403*82527734SSukumar Swaminathan uint32_t size = 0; 1404*82527734SSukumar Swaminathan uint32_t rc; 1405*82527734SSukumar Swaminathan 1406*82527734SSukumar Swaminathan if (dfc_event->dataout && dfc_event->size) { 1407*82527734SSukumar Swaminathan size = dfc_event->size; 1408*82527734SSukumar Swaminathan } 1409*82527734SSukumar Swaminathan dfc_event->size = 0; 1410*82527734SSukumar Swaminathan 1411*82527734SSukumar Swaminathan if (!dfc_event->event) { 1412*82527734SSukumar Swaminathan return (DFC_ARG_INVALID); 1413*82527734SSukumar Swaminathan } 1414*82527734SSukumar Swaminathan 1415*82527734SSukumar Swaminathan /* Calculate the event index */ 1416*82527734SSukumar Swaminathan mask = dfc_event->event; 1417*82527734SSukumar Swaminathan for (i = 0; i < 32; i++) { 1418*82527734SSukumar Swaminathan if (mask & 0x01) { 1419*82527734SSukumar Swaminathan break; 1420*82527734SSukumar Swaminathan } 1421*82527734SSukumar Swaminathan 1422*82527734SSukumar Swaminathan mask >>= 1; 1423*82527734SSukumar Swaminathan } 1424*82527734SSukumar Swaminathan 1425*82527734SSukumar Swaminathan mutex_enter(&eventq->lock); 1426*82527734SSukumar Swaminathan 1427*82527734SSukumar Swaminathan wait_for_event: 1428*82527734SSukumar Swaminathan 1429*82527734SSukumar Swaminathan /* Check if no new event has ocurred */ 1430*82527734SSukumar Swaminathan if (dfc_event->last_id == eventq->last_id[i]) { 1431*82527734SSukumar Swaminathan if (!sleep) { 1432*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1433*82527734SSukumar Swaminathan return (0); 1434*82527734SSukumar Swaminathan } 1435*82527734SSukumar Swaminathan 1436*82527734SSukumar Swaminathan /* While event is active and no new event has been logged */ 1437*82527734SSukumar Swaminathan while ((dfc_event->event & port->sd_event_mask) && 1438*82527734SSukumar Swaminathan (dfc_event->last_id == eventq->last_id[i])) { 1439*82527734SSukumar Swaminathan rc = cv_wait_sig(&eventq->lock_cv, &eventq->lock); 1440*82527734SSukumar Swaminathan 1441*82527734SSukumar Swaminathan /* Check if thread was killed by kernel */ 1442*82527734SSukumar Swaminathan if (rc == 0) { 1443*82527734SSukumar Swaminathan dfc_event->pid = 0; 1444*82527734SSukumar Swaminathan dfc_event->event = 0; 1445*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1446*82527734SSukumar Swaminathan return (0); 1447*82527734SSukumar Swaminathan } 1448*82527734SSukumar Swaminathan } 1449*82527734SSukumar Swaminathan 1450*82527734SSukumar Swaminathan /* If the event is no longer registered then return */ 1451*82527734SSukumar Swaminathan if (!(dfc_event->event & port->sd_event_mask)) { 1452*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1453*82527734SSukumar Swaminathan return (0); 1454*82527734SSukumar Swaminathan } 1455*82527734SSukumar Swaminathan } 1456*82527734SSukumar Swaminathan 1457*82527734SSukumar Swaminathan /* !!! An event has occurred since last_id !!! */ 1458*82527734SSukumar Swaminathan 1459*82527734SSukumar Swaminathan /* Check if event data is not being requested */ 1460*82527734SSukumar Swaminathan if (!size) { 1461*82527734SSukumar Swaminathan /* If so, then just return the last event id */ 1462*82527734SSukumar Swaminathan dfc_event->last_id = eventq->last_id[i]; 1463*82527734SSukumar Swaminathan 1464*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1465*82527734SSukumar Swaminathan return (0); 1466*82527734SSukumar Swaminathan } 1467*82527734SSukumar Swaminathan 1468*82527734SSukumar Swaminathan /* !!! The requester wants the next event buffer !!! */ 1469*82527734SSukumar Swaminathan 1470*82527734SSukumar Swaminathan found = 0; 1471*82527734SSukumar Swaminathan entry = eventq->first; 1472*82527734SSukumar Swaminathan while (entry) { 1473*82527734SSukumar Swaminathan if ((entry->id > dfc_event->last_id) && 1474*82527734SSukumar Swaminathan (entry->port == (void *)port) && 1475*82527734SSukumar Swaminathan (entry->evt->mask == dfc_event->event)) { 1476*82527734SSukumar Swaminathan found = 1; 1477*82527734SSukumar Swaminathan break; 1478*82527734SSukumar Swaminathan } 1479*82527734SSukumar Swaminathan 1480*82527734SSukumar Swaminathan entry = entry->next; 1481*82527734SSukumar Swaminathan } 1482*82527734SSukumar Swaminathan 1483*82527734SSukumar Swaminathan if (!found) { 1484*82527734SSukumar Swaminathan /* Update last_id to the last known event */ 1485*82527734SSukumar Swaminathan dfc_event->last_id = eventq->last_id[i]; 1486*82527734SSukumar Swaminathan 1487*82527734SSukumar Swaminathan /* Try waiting again if we can */ 1488*82527734SSukumar Swaminathan goto wait_for_event; 1489*82527734SSukumar Swaminathan } 1490*82527734SSukumar Swaminathan 1491*82527734SSukumar Swaminathan /* !!! Next event found !!! */ 1492*82527734SSukumar Swaminathan 1493*82527734SSukumar Swaminathan /* Copy the context buffer to the buffer provided */ 1494*82527734SSukumar Swaminathan if (entry->bp && entry->size) { 1495*82527734SSukumar Swaminathan if (entry->size < size) { 1496*82527734SSukumar Swaminathan size = entry->size; 1497*82527734SSukumar Swaminathan } 1498*82527734SSukumar Swaminathan 1499*82527734SSukumar Swaminathan if (ddi_copyout((void *) entry->bp, dfc_event->dataout, 1500*82527734SSukumar Swaminathan size, dfc_event->mode) != 0) { 1501*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1502*82527734SSukumar Swaminathan 1503*82527734SSukumar Swaminathan return (DFC_COPYOUT_ERROR); 1504*82527734SSukumar Swaminathan } 1505*82527734SSukumar Swaminathan 1506*82527734SSukumar Swaminathan /* Event has been retrieved by SANDIAG */ 1507*82527734SSukumar Swaminathan entry->flag |= EMLXS_SD_EVENT_DONE; 1508*82527734SSukumar Swaminathan 1509*82527734SSukumar Swaminathan dfc_event->size = size; 1510*82527734SSukumar Swaminathan } 1511*82527734SSukumar Swaminathan 1512*82527734SSukumar Swaminathan dfc_event->last_id = entry->id; 1513*82527734SSukumar Swaminathan 1514*82527734SSukumar Swaminathan mutex_exit(&eventq->lock); 1515*82527734SSukumar Swaminathan 1516*82527734SSukumar Swaminathan return (0); 1517*82527734SSukumar Swaminathan 1518*82527734SSukumar Swaminathan } /* emlxs_get_sd_event */ 1519*82527734SSukumar Swaminathan #endif /* SAN_DIAG_SUPPORT */ 1520