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 /* 23*291a2b48SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24fcf3ce44SJohn Forte * Use is subject to License terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27*291a2b48SSukumar Swaminathan #define DEF_MSG_STRUCT /* Needed for emlxs_messages.h in emlxs_msg.h */ 28*291a2b48SSukumar Swaminathan #include <emlxs.h> 29fcf3ce44SJohn Forte 30fcf3ce44SJohn Forte 31fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 32fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_MSG_C); 33fcf3ce44SJohn Forte 34*291a2b48SSukumar Swaminathan uint32_t emlxs_log_size = 2048; 35*291a2b48SSukumar Swaminathan uint32_t emlxs_log_debugs = 0x7FFFFFFF; 36*291a2b48SSukumar Swaminathan uint32_t emlxs_log_notices = 0xFFFFFFFF; 37*291a2b48SSukumar Swaminathan uint32_t emlxs_log_warnings = 0xFFFFFFFF; 38*291a2b48SSukumar Swaminathan uint32_t emlxs_log_errors = 0xFFFFFFFF; 39fcf3ce44SJohn Forte 40*291a2b48SSukumar Swaminathan static uint32_t emlxs_msg_log_check(emlxs_port_t *port, emlxs_msg_t *msg); 41*291a2b48SSukumar Swaminathan static uint32_t emlxs_msg_print_check(emlxs_port_t *port, emlxs_msg_t *msg); 42*291a2b48SSukumar Swaminathan static void emlxs_msg_sprintf(char *buffer, emlxs_msg_entry_t *entry); 43fcf3ce44SJohn Forte 44fcf3ce44SJohn Forte 45fcf3ce44SJohn Forte uint32_t 46fcf3ce44SJohn Forte emlxs_msg_log_create(emlxs_hba_t *hba) 47fcf3ce44SJohn Forte { 48fcf3ce44SJohn Forte emlxs_msg_log_t *log = &LOG; 49fcf3ce44SJohn Forte uint32_t size = sizeof (emlxs_msg_entry_t) * emlxs_log_size; 50fcf3ce44SJohn Forte char buf[40]; 51fcf3ce44SJohn Forte #ifdef MSI_SUPPORT 52fcf3ce44SJohn Forte ddi_intr_handle_t handle; 53fcf3ce44SJohn Forte uint32_t intr_pri; 54fcf3ce44SJohn Forte int32_t actual; 55fcf3ce44SJohn Forte uint32_t ret; 56*291a2b48SSukumar Swaminathan #endif /* MSI_SUPPORT */ 57fcf3ce44SJohn Forte ddi_iblock_cookie_t iblock; 58fcf3ce44SJohn Forte 59fcf3ce44SJohn Forte /* Check if log is already created */ 60fcf3ce44SJohn Forte if (log->entry) { 61fcf3ce44SJohn Forte cmn_err(CE_WARN, "?%s%d: message log already created. log=%p", 62*291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, (void *)log); 63fcf3ce44SJohn Forte return (0); 64fcf3ce44SJohn Forte } 65*291a2b48SSukumar Swaminathan 66fcf3ce44SJohn Forte /* Clear the log */ 67fcf3ce44SJohn Forte bzero(log, sizeof (emlxs_msg_log_t)); 68fcf3ce44SJohn Forte 69fcf3ce44SJohn Forte /* Allocate the memory needed for the log file */ 70fcf3ce44SJohn Forte if (!(log->entry = (emlxs_msg_entry_t *)kmem_zalloc(size, KM_SLEEP))) { 71*291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 72*291a2b48SSukumar Swaminathan "?%s%d: Unable to allocate log memory. log=%p", 73*291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, (void *)log); 74fcf3ce44SJohn Forte return (0); 75fcf3ce44SJohn Forte } 76*291a2b48SSukumar Swaminathan 77fcf3ce44SJohn Forte /* Initialize */ 78fcf3ce44SJohn Forte log->size = emlxs_log_size; 79fcf3ce44SJohn Forte log->instance = hba->ddiinst; 80fcf3ce44SJohn Forte log->start_time = emlxs_device.log_timestamp; 81fcf3ce44SJohn Forte 82fcf3ce44SJohn Forte (void) sprintf(buf, "?%s%d_log_lock control variable", DRIVER_NAME, 83fcf3ce44SJohn Forte hba->ddiinst); 84fcf3ce44SJohn Forte cv_init(&log->lock_cv, buf, CV_DRIVER, NULL); 85fcf3ce44SJohn Forte 86fcf3ce44SJohn Forte (void) sprintf(buf, "?%s%d_log_lock mutex", DRIVER_NAME, hba->ddiinst); 87fcf3ce44SJohn Forte 88fcf3ce44SJohn Forte if (!(hba->intr_flags & EMLXS_MSI_ENABLED)) { 89fcf3ce44SJohn Forte /* Get the current interrupt block cookie */ 90fcf3ce44SJohn Forte (void) ddi_get_iblock_cookie(hba->dip, (uint_t)EMLXS_INUMBER, 91fcf3ce44SJohn Forte &iblock); 92fcf3ce44SJohn Forte 93fcf3ce44SJohn Forte /* Create the log mutex lock */ 94*291a2b48SSukumar Swaminathan mutex_init(&log->lock, buf, MUTEX_DRIVER, (void *)iblock); 95fcf3ce44SJohn Forte } 96fcf3ce44SJohn Forte #ifdef MSI_SUPPORT 97fcf3ce44SJohn Forte else { 98fcf3ce44SJohn Forte /* Allocate a temporary interrupt handle */ 99fcf3ce44SJohn Forte actual = 0; 100*291a2b48SSukumar Swaminathan ret = 101*291a2b48SSukumar Swaminathan ddi_intr_alloc(hba->dip, &handle, DDI_INTR_TYPE_FIXED, 102fcf3ce44SJohn Forte EMLXS_MSI_INUMBER, 1, &actual, DDI_INTR_ALLOC_NORMAL); 103fcf3ce44SJohn Forte 104fcf3ce44SJohn Forte if (ret != DDI_SUCCESS || actual == 0) { 105*291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 106*291a2b48SSukumar Swaminathan "?%s%d: Unable to allocate temporary interrupt " 107*291a2b48SSukumar Swaminathan "handle. ret=%d actual=%d", DRIVER_NAME, 108*291a2b48SSukumar Swaminathan hba->ddiinst, ret, actual); 109fcf3ce44SJohn Forte 110fcf3ce44SJohn Forte /* Free the log buffer */ 111fcf3ce44SJohn Forte kmem_free(log->entry, size); 112fcf3ce44SJohn Forte bzero(log, sizeof (emlxs_msg_log_t)); 113fcf3ce44SJohn Forte 114fcf3ce44SJohn Forte return (0); 115fcf3ce44SJohn Forte } 116*291a2b48SSukumar Swaminathan 117fcf3ce44SJohn Forte /* Get the current interrupt priority */ 118fcf3ce44SJohn Forte ret = ddi_intr_get_pri(handle, &intr_pri); 119fcf3ce44SJohn Forte 120fcf3ce44SJohn Forte if (ret != DDI_SUCCESS) { 121*291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 122*291a2b48SSukumar Swaminathan "?%s%d: Unable to get interrupt priority. ret=%d", 123*291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, ret); 124fcf3ce44SJohn Forte 125fcf3ce44SJohn Forte /* Free the log buffer */ 126fcf3ce44SJohn Forte kmem_free(log->entry, size); 127fcf3ce44SJohn Forte bzero(log, sizeof (emlxs_msg_log_t)); 128fcf3ce44SJohn Forte 129fcf3ce44SJohn Forte return (0); 130fcf3ce44SJohn Forte } 131*291a2b48SSukumar Swaminathan 132fcf3ce44SJohn Forte /* Create the log mutex lock */ 133fcf3ce44SJohn Forte mutex_init(&log->lock, buf, MUTEX_DRIVER, 134*291a2b48SSukumar Swaminathan (void *)((unsigned long)intr_pri)); 135fcf3ce44SJohn Forte 136fcf3ce44SJohn Forte /* Free the temporary handle */ 137fcf3ce44SJohn Forte (void) ddi_intr_free(handle); 138fcf3ce44SJohn Forte } 139fcf3ce44SJohn Forte #endif 140fcf3ce44SJohn Forte 141fcf3ce44SJohn Forte return (1); 142fcf3ce44SJohn Forte 143*291a2b48SSukumar Swaminathan } /* emlxs_msg_log_create() */ 144fcf3ce44SJohn Forte 145fcf3ce44SJohn Forte 146fcf3ce44SJohn Forte uint32_t 147fcf3ce44SJohn Forte emlxs_msg_log_destroy(emlxs_hba_t *hba) 148fcf3ce44SJohn Forte { 149fcf3ce44SJohn Forte emlxs_msg_log_t *log = &LOG; 150fcf3ce44SJohn Forte uint32_t size; 151fcf3ce44SJohn Forte emlxs_msg_entry_t *entry; 152fcf3ce44SJohn Forte uint32_t i; 153fcf3ce44SJohn Forte 154fcf3ce44SJohn Forte /* Check if log is already destroyed */ 155fcf3ce44SJohn Forte if (!log->entry) { 156*291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 157*291a2b48SSukumar Swaminathan "?%s%d: message log already destroyed. log=%p", 158*291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, (void *)log); 159fcf3ce44SJohn Forte 160fcf3ce44SJohn Forte return (1); 161fcf3ce44SJohn Forte } 162*291a2b48SSukumar Swaminathan 163*291a2b48SSukumar Swaminathan /* If events are being logged there might be */ 164*291a2b48SSukumar Swaminathan /* threads waiting so release them */ 165fcf3ce44SJohn Forte if (hba->log_events) { 166fcf3ce44SJohn Forte mutex_enter(&log->lock); 167fcf3ce44SJohn Forte hba->log_events = 0; 168fcf3ce44SJohn Forte cv_broadcast(&log->lock_cv); 169fcf3ce44SJohn Forte mutex_exit(&log->lock); 170fcf3ce44SJohn Forte 171fcf3ce44SJohn Forte DELAYMS(1); 172fcf3ce44SJohn Forte } 173*291a2b48SSukumar Swaminathan 174fcf3ce44SJohn Forte /* Destroy the lock */ 175fcf3ce44SJohn Forte mutex_destroy(&log->lock); 176fcf3ce44SJohn Forte cv_destroy(&log->lock_cv); 177fcf3ce44SJohn Forte 178fcf3ce44SJohn Forte /* Free the context buffers */ 179fcf3ce44SJohn Forte for (i = 0; i < log->size; i++) { 180fcf3ce44SJohn Forte entry = &log->entry[i]; 181fcf3ce44SJohn Forte 182fcf3ce44SJohn Forte if (entry->bp && entry->size) { 183fcf3ce44SJohn Forte kmem_free(entry->bp, entry->size); 184fcf3ce44SJohn Forte } 185fcf3ce44SJohn Forte } 186fcf3ce44SJohn Forte 187fcf3ce44SJohn Forte /* Free the log buffer */ 188fcf3ce44SJohn Forte size = sizeof (emlxs_msg_entry_t) * log->size; 189fcf3ce44SJohn Forte kmem_free(log->entry, size); 190fcf3ce44SJohn Forte 191fcf3ce44SJohn Forte /* Clear the log */ 192fcf3ce44SJohn Forte bzero(log, sizeof (emlxs_msg_log_t)); 193fcf3ce44SJohn Forte 194fcf3ce44SJohn Forte return (1); 195fcf3ce44SJohn Forte 196*291a2b48SSukumar Swaminathan } /* emlxs_msg_log_destroy() */ 197*291a2b48SSukumar Swaminathan 198*291a2b48SSukumar Swaminathan void 199*291a2b48SSukumar Swaminathan emlxs_setup_abts_ct(emlxs_thread_t *et, void (*func) (), 200*291a2b48SSukumar Swaminathan emlxs_port_t *port, uint32_t rxid) 201*291a2b48SSukumar Swaminathan { 202*291a2b48SSukumar Swaminathan et->func = func; 203*291a2b48SSukumar Swaminathan et->arg1 = (void *)port; 204*291a2b48SSukumar Swaminathan et->arg2 = (void *)((unsigned long)rxid); 205*291a2b48SSukumar Swaminathan 206*291a2b48SSukumar Swaminathan } /* emlxs_setup_abts_ct */ 207fcf3ce44SJohn Forte 208*291a2b48SSukumar Swaminathan void 209*291a2b48SSukumar Swaminathan emlxs_abts_ct_thread(void *arg) 210*291a2b48SSukumar Swaminathan { 211*291a2b48SSukumar Swaminathan emlxs_thread_t *et = (emlxs_thread_t *)arg; 212*291a2b48SSukumar Swaminathan emlxs_port_t *port; 213*291a2b48SSukumar Swaminathan void (*func) (); 214*291a2b48SSukumar Swaminathan uint32_t rxid = 0; 215*291a2b48SSukumar Swaminathan 216*291a2b48SSukumar Swaminathan func = et->func; 217*291a2b48SSukumar Swaminathan port = (emlxs_port_t *)et->arg1; 218*291a2b48SSukumar Swaminathan rxid = (uint32_t)((unsigned long)et->arg2); 219*291a2b48SSukumar Swaminathan 220*291a2b48SSukumar Swaminathan func(port, rxid); 221*291a2b48SSukumar Swaminathan 222*291a2b48SSukumar Swaminathan /* 223*291a2b48SSukumar Swaminathan * Allocated by the emlxs_msg_log() 224*291a2b48SSukumar Swaminathan */ 225*291a2b48SSukumar Swaminathan kmem_free(et, sizeof (emlxs_thread_t)); 226fcf3ce44SJohn Forte 227*291a2b48SSukumar Swaminathan thread_exit(); 228*291a2b48SSukumar Swaminathan 229*291a2b48SSukumar Swaminathan } /* emlxs_abts_ct_thread */ 230fcf3ce44SJohn Forte 231fcf3ce44SJohn Forte uint32_t 232fcf3ce44SJohn Forte emlxs_msg_log(emlxs_port_t *port, const uint32_t fileno, const uint32_t line, 233fcf3ce44SJohn Forte void *bp, uint32_t size, emlxs_msg_t *msg, char *buffer) 234fcf3ce44SJohn Forte { 235fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 236fcf3ce44SJohn Forte emlxs_msg_entry_t *entry; 237fcf3ce44SJohn Forte emlxs_msg_entry_t *entry2; 238fcf3ce44SJohn Forte clock_t time; 239fcf3ce44SJohn Forte emlxs_msg_log_t *log; 240fcf3ce44SJohn Forte uint32_t last; 241fcf3ce44SJohn Forte uint32_t mask; 242fcf3ce44SJohn Forte emlxs_msg_t *msg2; 243*291a2b48SSukumar Swaminathan uint32_t rxid = 0; 244*291a2b48SSukumar Swaminathan emlxs_thread_t *abts_ct_thread = NULL; 245fcf3ce44SJohn Forte uint32_t i; 246fcf3ce44SJohn Forte 247fcf3ce44SJohn Forte /* Get the log file for this instance */ 248fcf3ce44SJohn Forte log = &LOG; 249fcf3ce44SJohn Forte 250fcf3ce44SJohn Forte /* Check if log is initialized */ 251fcf3ce44SJohn Forte if (log->entry == NULL) { 252fcf3ce44SJohn Forte 253fcf3ce44SJohn Forte if (port->vpi == 0) { 254*291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 255*291a2b48SSukumar Swaminathan "?%s%d: message log not created. log=%p", 256*291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, (void *)log); 257fcf3ce44SJohn Forte } else { 258*291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 259*291a2b48SSukumar Swaminathan "?%s%d.%d: message log not created. log=%p", 260*291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, port->vpi, 261*291a2b48SSukumar Swaminathan (void *)log); 262fcf3ce44SJohn Forte } 263fcf3ce44SJohn Forte 264fcf3ce44SJohn Forte if (bp && size) { 265fcf3ce44SJohn Forte kmem_free(bp, size); 266fcf3ce44SJohn Forte } 267*291a2b48SSukumar Swaminathan 268fcf3ce44SJohn Forte return (1); 269fcf3ce44SJohn Forte } 270*291a2b48SSukumar Swaminathan 271fcf3ce44SJohn Forte mutex_enter(&log->lock); 272fcf3ce44SJohn Forte 273fcf3ce44SJohn Forte /* Get the pointer to the last log entry */ 274fcf3ce44SJohn Forte if (log->next == 0) { 275fcf3ce44SJohn Forte last = log->size - 1; 276fcf3ce44SJohn Forte } else { 277fcf3ce44SJohn Forte last = log->next - 1; 278fcf3ce44SJohn Forte } 279fcf3ce44SJohn Forte entry = &log->entry[last]; 280fcf3ce44SJohn Forte 281fcf3ce44SJohn Forte /* Check if this matches the last message */ 282fcf3ce44SJohn Forte if ((entry->instance == log->instance) && 283fcf3ce44SJohn Forte (entry->vpi == port->vpi) && 284fcf3ce44SJohn Forte (entry->fileno == fileno) && 285fcf3ce44SJohn Forte (entry->line == line) && 286fcf3ce44SJohn Forte (entry->bp == bp) && 287fcf3ce44SJohn Forte (entry->size == size) && 288fcf3ce44SJohn Forte (entry->msg == msg) && 289fcf3ce44SJohn Forte (strcmp(entry->buffer, buffer) == 0)) { 290fcf3ce44SJohn Forte /* If the same message is being logged then increment */ 291fcf3ce44SJohn Forte log->repeat++; 292fcf3ce44SJohn Forte 293fcf3ce44SJohn Forte mutex_exit(&log->lock); 294fcf3ce44SJohn Forte 295fcf3ce44SJohn Forte return (0); 296fcf3ce44SJohn Forte } else if (log->repeat) { 297fcf3ce44SJohn Forte /* Get the pointer to the next log entry */ 298fcf3ce44SJohn Forte entry2 = &log->entry[log->next]; 299fcf3ce44SJohn Forte 300fcf3ce44SJohn Forte /* Increment and check the next entry index */ 301fcf3ce44SJohn Forte if (++(log->next) >= log->size) { 302fcf3ce44SJohn Forte log->next = 0; 303fcf3ce44SJohn Forte } 304*291a2b48SSukumar Swaminathan 305fcf3ce44SJohn Forte switch (entry->msg->level) { 306fcf3ce44SJohn Forte case EMLXS_DEBUG: 307fcf3ce44SJohn Forte msg2 = &emlxs_debug_msg; 308fcf3ce44SJohn Forte break; 309fcf3ce44SJohn Forte 310fcf3ce44SJohn Forte case EMLXS_NOTICE: 311fcf3ce44SJohn Forte msg2 = &emlxs_notice_msg; 312fcf3ce44SJohn Forte break; 313fcf3ce44SJohn Forte 314fcf3ce44SJohn Forte case EMLXS_WARNING: 315fcf3ce44SJohn Forte msg2 = &emlxs_warning_msg; 316fcf3ce44SJohn Forte break; 317fcf3ce44SJohn Forte 318fcf3ce44SJohn Forte case EMLXS_ERROR: 319fcf3ce44SJohn Forte msg2 = &emlxs_error_msg; 320fcf3ce44SJohn Forte break; 321fcf3ce44SJohn Forte 322fcf3ce44SJohn Forte case EMLXS_PANIC: 323fcf3ce44SJohn Forte msg2 = &emlxs_panic_msg; 324fcf3ce44SJohn Forte break; 325fcf3ce44SJohn Forte 326fcf3ce44SJohn Forte case EMLXS_EVENT: 327fcf3ce44SJohn Forte msg2 = &emlxs_event_msg; 328fcf3ce44SJohn Forte break; 329fcf3ce44SJohn Forte } 330fcf3ce44SJohn Forte 331fcf3ce44SJohn Forte /* Check if we are about to overwrite an event entry */ 332fcf3ce44SJohn Forte if (entry2->msg && (entry2->msg->level == EMLXS_EVENT)) { 333fcf3ce44SJohn Forte /* Check if this event has not been acquired */ 334fcf3ce44SJohn Forte if (log->count > (hba->hba_event.last_id + log->size)) { 335fcf3ce44SJohn Forte hba->hba_event.missed++; 336728bdc9bSSukumar Swaminathan 337*291a2b48SSukumar Swaminathan if ((entry2->msg->mask == EVT_CT) && 338*291a2b48SSukumar Swaminathan !(entry2->flag & EMLX_EVENT_DONE)) { 339728bdc9bSSukumar Swaminathan /* Abort exchange */ 340728bdc9bSSukumar Swaminathan rxid = *((uint32_t *)entry2->bp); 341728bdc9bSSukumar Swaminathan } 342fcf3ce44SJohn Forte } 343fcf3ce44SJohn Forte } 344*291a2b48SSukumar Swaminathan 345fcf3ce44SJohn Forte /* Free the old context buffer since we are about to erase it */ 346fcf3ce44SJohn Forte if (entry2->bp && entry2->size) { 347fcf3ce44SJohn Forte kmem_free(entry2->bp, entry2->size); 348fcf3ce44SJohn Forte } 349*291a2b48SSukumar Swaminathan 350fcf3ce44SJohn Forte /* Initialize */ 351fcf3ce44SJohn Forte entry2->id = log->count++; 352fcf3ce44SJohn Forte entry2->fileno = entry->fileno; 353fcf3ce44SJohn Forte entry2->line = entry->line; 354fcf3ce44SJohn Forte entry2->bp = 0; 355fcf3ce44SJohn Forte entry2->size = 0; 356fcf3ce44SJohn Forte entry2->msg = msg2; 357fcf3ce44SJohn Forte entry2->instance = log->instance; 358fcf3ce44SJohn Forte entry2->vpi = port->vpi; 359*291a2b48SSukumar Swaminathan entry2->flag = 0; 360fcf3ce44SJohn Forte 361fcf3ce44SJohn Forte /* Save the additional info buffer */ 362fcf3ce44SJohn Forte (void) sprintf(entry2->buffer, 363fcf3ce44SJohn Forte "Last message repeated %d time(s).", 364fcf3ce44SJohn Forte log->repeat); 365fcf3ce44SJohn Forte 366fcf3ce44SJohn Forte /* Set the entry time stamp */ 367fcf3ce44SJohn Forte (void) drv_getparm(LBOLT, &time); 368fcf3ce44SJohn Forte entry2->time = time - log->start_time; 369fcf3ce44SJohn Forte 370fcf3ce44SJohn Forte log->repeat = 0; 371fcf3ce44SJohn Forte } 372*291a2b48SSukumar Swaminathan 373fcf3ce44SJohn Forte /* Get the pointer to the next log entry */ 374fcf3ce44SJohn Forte entry = &log->entry[log->next]; 375fcf3ce44SJohn Forte 376fcf3ce44SJohn Forte /* Increment and check the next entry index */ 377fcf3ce44SJohn Forte if (++(log->next) >= log->size) { 378fcf3ce44SJohn Forte log->next = 0; 379fcf3ce44SJohn Forte } 380*291a2b48SSukumar Swaminathan 381fcf3ce44SJohn Forte /* Check if we are about to overwrite an event entry */ 382fcf3ce44SJohn Forte if (entry->msg && (entry->msg->level == EMLXS_EVENT)) { 383fcf3ce44SJohn Forte /* Check if this event has not been acquired */ 384fcf3ce44SJohn Forte if (log->count > (hba->hba_event.last_id + log->size)) { 385fcf3ce44SJohn Forte hba->hba_event.missed++; 386728bdc9bSSukumar Swaminathan 387*291a2b48SSukumar Swaminathan if ((entry->msg->mask == EVT_CT) && 388*291a2b48SSukumar Swaminathan !(entry->flag & EMLX_EVENT_DONE)) { 389*291a2b48SSukumar Swaminathan 390728bdc9bSSukumar Swaminathan /* Abort exchange */ 391728bdc9bSSukumar Swaminathan rxid = *((uint32_t *)entry->bp); 392728bdc9bSSukumar Swaminathan } 393fcf3ce44SJohn Forte } 394fcf3ce44SJohn Forte } 395*291a2b48SSukumar Swaminathan 396fcf3ce44SJohn Forte /* Free the old context buffer since we are about to erase it */ 397fcf3ce44SJohn Forte if (entry->bp && entry->size) { 398fcf3ce44SJohn Forte kmem_free(entry->bp, entry->size); 399fcf3ce44SJohn Forte } 400*291a2b48SSukumar Swaminathan 401fcf3ce44SJohn Forte /* Initialize */ 402fcf3ce44SJohn Forte entry->id = log->count++; 403fcf3ce44SJohn Forte entry->fileno = fileno; 404fcf3ce44SJohn Forte entry->line = line; 405fcf3ce44SJohn Forte entry->bp = bp; 406fcf3ce44SJohn Forte entry->size = size; 407fcf3ce44SJohn Forte entry->msg = msg; 408fcf3ce44SJohn Forte entry->instance = log->instance; 409fcf3ce44SJohn Forte entry->vpi = port->vpi; 410*291a2b48SSukumar Swaminathan entry->flag = 0; 411fcf3ce44SJohn Forte 412fcf3ce44SJohn Forte /* Save the additional info buffer */ 413fcf3ce44SJohn Forte (void) strncpy(entry->buffer, buffer, (MAX_LOG_INFO_LENGTH - 1)); 414fcf3ce44SJohn Forte entry->buffer[MAX_LOG_INFO_LENGTH - 1] = 0; 415fcf3ce44SJohn Forte 416fcf3ce44SJohn Forte /* Set the entry time stamp */ 417fcf3ce44SJohn Forte (void) drv_getparm(LBOLT, &time); 418fcf3ce44SJohn Forte entry->time = time - log->start_time; 419fcf3ce44SJohn Forte 420fcf3ce44SJohn Forte /* Check for a new event */ 421fcf3ce44SJohn Forte if (msg->level == EMLXS_EVENT) { 422fcf3ce44SJohn Forte /* Update the event id */ 423fcf3ce44SJohn Forte mask = msg->mask; 424fcf3ce44SJohn Forte for (i = 0; i < 32; i++) { 425fcf3ce44SJohn Forte if (mask & 0x01) { 426fcf3ce44SJohn Forte hba->hba_event.new++; 427fcf3ce44SJohn Forte log->event_id[i] = entry->id; 428fcf3ce44SJohn Forte cv_broadcast(&log->lock_cv); 429fcf3ce44SJohn Forte break; 430fcf3ce44SJohn Forte } 431*291a2b48SSukumar Swaminathan 432fcf3ce44SJohn Forte mask >>= 1; 433fcf3ce44SJohn Forte } 434fcf3ce44SJohn Forte } 435*291a2b48SSukumar Swaminathan 436fcf3ce44SJohn Forte mutex_exit(&log->lock); 437fcf3ce44SJohn Forte 438*291a2b48SSukumar Swaminathan if (rxid) { 439*291a2b48SSukumar Swaminathan if (abts_ct_thread = (emlxs_thread_t *) 440*291a2b48SSukumar Swaminathan kmem_alloc(sizeof (emlxs_thread_t), KM_NOSLEEP)) { 441*291a2b48SSukumar Swaminathan 442*291a2b48SSukumar Swaminathan emlxs_setup_abts_ct(abts_ct_thread, 443*291a2b48SSukumar Swaminathan emlxs_abort_ct_exchange, port, rxid); 444*291a2b48SSukumar Swaminathan 445*291a2b48SSukumar Swaminathan /* 446*291a2b48SSukumar Swaminathan * The abts_ct_thread will be released by 447*291a2b48SSukumar Swaminathan * the emlxs_abts_ct_thread(). 448*291a2b48SSukumar Swaminathan */ 449*291a2b48SSukumar Swaminathan thread_create(NULL, 0, emlxs_abts_ct_thread, 450*291a2b48SSukumar Swaminathan (char *)abts_ct_thread, 0, 451*291a2b48SSukumar Swaminathan &p0, TS_RUN, v.v_maxsyspri - 2); 452*291a2b48SSukumar Swaminathan } 453*291a2b48SSukumar Swaminathan } 454*291a2b48SSukumar Swaminathan 455fcf3ce44SJohn Forte return (0); 456fcf3ce44SJohn Forte 457*291a2b48SSukumar Swaminathan } /* emlxs_msg_log() */ 458fcf3ce44SJohn Forte 459fcf3ce44SJohn Forte 460fcf3ce44SJohn Forte static uint32_t 461fcf3ce44SJohn Forte emlxs_msg_log_check(emlxs_port_t *port, emlxs_msg_t *msg) 462fcf3ce44SJohn Forte { 463fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 464fcf3ce44SJohn Forte 465fcf3ce44SJohn Forte switch (msg->level) { 466fcf3ce44SJohn Forte case EMLXS_DEBUG: 467fcf3ce44SJohn Forte if (msg->mask & emlxs_log_debugs) { 468fcf3ce44SJohn Forte return (1); 469fcf3ce44SJohn Forte } 470fcf3ce44SJohn Forte break; 471fcf3ce44SJohn Forte 472fcf3ce44SJohn Forte case EMLXS_NOTICE: 473fcf3ce44SJohn Forte if (msg->mask & emlxs_log_notices) { 474fcf3ce44SJohn Forte return (1); 475fcf3ce44SJohn Forte } 476fcf3ce44SJohn Forte break; 477fcf3ce44SJohn Forte 478fcf3ce44SJohn Forte case EMLXS_WARNING: 479fcf3ce44SJohn Forte if (msg->mask & emlxs_log_warnings) { 480fcf3ce44SJohn Forte return (1); 481fcf3ce44SJohn Forte } 482fcf3ce44SJohn Forte break; 483fcf3ce44SJohn Forte 484fcf3ce44SJohn Forte case EMLXS_ERROR: 485fcf3ce44SJohn Forte if (msg->mask & emlxs_log_errors) { 486fcf3ce44SJohn Forte return (1); 487fcf3ce44SJohn Forte } 488fcf3ce44SJohn Forte break; 489fcf3ce44SJohn Forte 490fcf3ce44SJohn Forte case EMLXS_EVENT: 491fcf3ce44SJohn Forte if (msg->mask & hba->log_events) { 492fcf3ce44SJohn Forte return (1); 493fcf3ce44SJohn Forte } 494*291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 495*291a2b48SSukumar Swaminathan if (msg->mask & port->sd_reg_events) { 496*291a2b48SSukumar Swaminathan return (1); 497*291a2b48SSukumar Swaminathan } 498*291a2b48SSukumar Swaminathan #endif /* SAN_DIAG_SUPPORT */ 499fcf3ce44SJohn Forte break; 500fcf3ce44SJohn Forte 501fcf3ce44SJohn Forte case EMLXS_PANIC: 502fcf3ce44SJohn Forte return (1); 503fcf3ce44SJohn Forte } 504fcf3ce44SJohn Forte 505fcf3ce44SJohn Forte return (0); 506fcf3ce44SJohn Forte 507*291a2b48SSukumar Swaminathan } /* emlxs_msg_log_check() */ 508fcf3ce44SJohn Forte 509fcf3ce44SJohn Forte 510fcf3ce44SJohn Forte static uint32_t 511fcf3ce44SJohn Forte emlxs_msg_print_check(emlxs_port_t *port, emlxs_msg_t *msg) 512fcf3ce44SJohn Forte { 513fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 514fcf3ce44SJohn Forte emlxs_config_t *cfg; 515fcf3ce44SJohn Forte uint32_t rval = 0; 516fcf3ce44SJohn Forte 517fcf3ce44SJohn Forte cfg = &CFG; 518fcf3ce44SJohn Forte 519fcf3ce44SJohn Forte switch (msg->level) { 520fcf3ce44SJohn Forte case EMLXS_DEBUG: 521fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_CONSOLE_DEBUGS].current) { 522fcf3ce44SJohn Forte rval |= 2; 523fcf3ce44SJohn Forte } 524*291a2b48SSukumar Swaminathan 525fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_LOG_DEBUGS].current) { 526fcf3ce44SJohn Forte rval |= 1; 527fcf3ce44SJohn Forte } 528*291a2b48SSukumar Swaminathan 529fcf3ce44SJohn Forte break; 530fcf3ce44SJohn Forte 531fcf3ce44SJohn Forte case EMLXS_NOTICE: 532fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_CONSOLE_NOTICES].current) { 533fcf3ce44SJohn Forte rval |= 2; 534fcf3ce44SJohn Forte } 535*291a2b48SSukumar Swaminathan 536fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_LOG_NOTICES].current) { 537fcf3ce44SJohn Forte rval |= 1; 538fcf3ce44SJohn Forte } 539*291a2b48SSukumar Swaminathan 540fcf3ce44SJohn Forte break; 541fcf3ce44SJohn Forte 542fcf3ce44SJohn Forte case EMLXS_WARNING: 543fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_CONSOLE_WARNINGS].current) { 544fcf3ce44SJohn Forte rval |= 2; 545fcf3ce44SJohn Forte } 546*291a2b48SSukumar Swaminathan 547fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_LOG_WARNINGS].current) { 548fcf3ce44SJohn Forte rval |= 1; 549fcf3ce44SJohn Forte } 550*291a2b48SSukumar Swaminathan 551fcf3ce44SJohn Forte break; 552fcf3ce44SJohn Forte 553fcf3ce44SJohn Forte case EMLXS_ERROR: 554fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_CONSOLE_ERRORS].current) { 555fcf3ce44SJohn Forte rval |= 2; 556fcf3ce44SJohn Forte } 557*291a2b48SSukumar Swaminathan 558fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_LOG_ERRORS].current) { 559fcf3ce44SJohn Forte rval |= 1; 560fcf3ce44SJohn Forte } 561fcf3ce44SJohn Forte break; 562fcf3ce44SJohn Forte 563fcf3ce44SJohn Forte case EMLXS_EVENT: 564fcf3ce44SJohn Forte /* Only print an event if it is being logged internally */ 565fcf3ce44SJohn Forte if (msg->mask & hba->log_events) { 566fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_CONSOLE_EVENTS].current) { 567fcf3ce44SJohn Forte rval |= 2; 568fcf3ce44SJohn Forte } 569*291a2b48SSukumar Swaminathan 570fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_LOG_EVENTS].current) { 571fcf3ce44SJohn Forte rval |= 1; 572fcf3ce44SJohn Forte } 573fcf3ce44SJohn Forte } 574fcf3ce44SJohn Forte break; 575fcf3ce44SJohn Forte 576fcf3ce44SJohn Forte case EMLXS_PANIC: 577fcf3ce44SJohn Forte default: 578fcf3ce44SJohn Forte rval |= 1; 579fcf3ce44SJohn Forte 580fcf3ce44SJohn Forte } 581fcf3ce44SJohn Forte 582fcf3ce44SJohn Forte return (rval); 583fcf3ce44SJohn Forte 584*291a2b48SSukumar Swaminathan } /* emlxs_msg_print_check() */ 585fcf3ce44SJohn Forte 586fcf3ce44SJohn Forte 587fcf3ce44SJohn Forte void 588*291a2b48SSukumar Swaminathan emlxs_msg_printf(emlxs_port_t *port, const uint32_t fileno, 589*291a2b48SSukumar Swaminathan const uint32_t line, void *bp, uint32_t size, emlxs_msg_t *msg, 590*291a2b48SSukumar Swaminathan const char *fmt, ...) 591fcf3ce44SJohn Forte { 592fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 593*291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT 594*291a2b48SSukumar Swaminathan emlxs_port_t *phyport = &PPORT; 595*291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */ 596fcf3ce44SJohn Forte va_list valist; 597fcf3ce44SJohn Forte char va_str[256]; 598fcf3ce44SJohn Forte char msg_str[512]; 599fcf3ce44SJohn Forte char *level; 600fcf3ce44SJohn Forte int32_t cmn_level; 601fcf3ce44SJohn Forte uint32_t rval; 602fcf3ce44SJohn Forte uint32_t logged; 603fcf3ce44SJohn Forte char driver[32]; 604fcf3ce44SJohn Forte 605fcf3ce44SJohn Forte va_str[0] = 0; 606fcf3ce44SJohn Forte 607fcf3ce44SJohn Forte if (fmt) { 608fcf3ce44SJohn Forte va_start(valist, fmt); 609fcf3ce44SJohn Forte (void) vsprintf(va_str, fmt, valist); 610fcf3ce44SJohn Forte va_end(valist); 611fcf3ce44SJohn Forte } 612*291a2b48SSukumar Swaminathan 613*291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT 614*291a2b48SSukumar Swaminathan /* 615*291a2b48SSukumar Swaminathan * Don't post fault event or/and error event to fmd 616*291a2b48SSukumar Swaminathan * if physical port was not bounded yet. 617*291a2b48SSukumar Swaminathan */ 618*291a2b48SSukumar Swaminathan if (phyport->flag & EMLXS_PORT_BOUND) { 619*291a2b48SSukumar Swaminathan if (msg->fm_ereport_code) { 620*291a2b48SSukumar Swaminathan emlxs_fm_ereport(hba, msg->fm_ereport_code); 621*291a2b48SSukumar Swaminathan } 622*291a2b48SSukumar Swaminathan 623*291a2b48SSukumar Swaminathan if (msg->fm_impact_code) { 624*291a2b48SSukumar Swaminathan ddi_fm_service_impact(hba->dip, msg->fm_impact_code); 625*291a2b48SSukumar Swaminathan } 626*291a2b48SSukumar Swaminathan } 627*291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */ 628*291a2b48SSukumar Swaminathan 629fcf3ce44SJohn Forte /* Check if msg should be logged */ 630fcf3ce44SJohn Forte if ((logged = emlxs_msg_log_check(port, msg))) { 631fcf3ce44SJohn Forte /* Log the message */ 632fcf3ce44SJohn Forte if (emlxs_msg_log(port, fileno, line, bp, size, msg, va_str)) { 633fcf3ce44SJohn Forte return; 634fcf3ce44SJohn Forte } 635fcf3ce44SJohn Forte } 636*291a2b48SSukumar Swaminathan 637fcf3ce44SJohn Forte /* Check if msg should be printed */ 638fcf3ce44SJohn Forte if (rval = emlxs_msg_print_check(port, msg)) { 639fcf3ce44SJohn Forte cmn_level = CE_CONT; 640fcf3ce44SJohn Forte 641fcf3ce44SJohn Forte switch (msg->level) { 642fcf3ce44SJohn Forte case EMLXS_DEBUG: 643fcf3ce44SJohn Forte level = " DEBUG"; 644fcf3ce44SJohn Forte break; 645fcf3ce44SJohn Forte 646fcf3ce44SJohn Forte case EMLXS_NOTICE: 647fcf3ce44SJohn Forte level = " NOTICE"; 648fcf3ce44SJohn Forte break; 649fcf3ce44SJohn Forte 650fcf3ce44SJohn Forte case EMLXS_WARNING: 651fcf3ce44SJohn Forte level = "WARNING"; 652fcf3ce44SJohn Forte break; 653fcf3ce44SJohn Forte 654fcf3ce44SJohn Forte case EMLXS_ERROR: 655fcf3ce44SJohn Forte level = " ERROR"; 656fcf3ce44SJohn Forte break; 657fcf3ce44SJohn Forte 658fcf3ce44SJohn Forte case EMLXS_PANIC: 659fcf3ce44SJohn Forte cmn_level = CE_PANIC; 660fcf3ce44SJohn Forte level = " PANIC"; 661fcf3ce44SJohn Forte break; 662fcf3ce44SJohn Forte 663fcf3ce44SJohn Forte case EMLXS_EVENT: 664fcf3ce44SJohn Forte level = " EVENT"; 665fcf3ce44SJohn Forte break; 666fcf3ce44SJohn Forte 667fcf3ce44SJohn Forte default: 668fcf3ce44SJohn Forte level = "UNKNOWN"; 669fcf3ce44SJohn Forte break; 670fcf3ce44SJohn Forte } 671fcf3ce44SJohn Forte 672fcf3ce44SJohn Forte if (port->vpi == 0) { 673fcf3ce44SJohn Forte (void) sprintf(driver, "%s%d", DRIVER_NAME, 674fcf3ce44SJohn Forte hba->ddiinst); 675fcf3ce44SJohn Forte } else { 676fcf3ce44SJohn Forte (void) sprintf(driver, "%s%d.%d", DRIVER_NAME, 677fcf3ce44SJohn Forte hba->ddiinst, port->vpi); 678fcf3ce44SJohn Forte } 679fcf3ce44SJohn Forte 680fcf3ce44SJohn Forte /* Generate the message string */ 681fcf3ce44SJohn Forte if (msg->buffer[0] != 0) { 682fcf3ce44SJohn Forte if (va_str[0] != 0) { 683fcf3ce44SJohn Forte (void) sprintf(msg_str, 684*291a2b48SSukumar Swaminathan "[%2X.%04X]%s:%7s:%4d: %s (%s)\n", fileno, 685*291a2b48SSukumar Swaminathan line, driver, level, msg->id, msg->buffer, 686*291a2b48SSukumar Swaminathan va_str); 687fcf3ce44SJohn Forte } else { 688fcf3ce44SJohn Forte (void) sprintf(msg_str, 689fcf3ce44SJohn Forte "[%2X.%04X]%s:%7s:%4d: %s\n", 690fcf3ce44SJohn Forte fileno, line, driver, level, msg->id, 691fcf3ce44SJohn Forte msg->buffer); 692fcf3ce44SJohn Forte } 693fcf3ce44SJohn Forte } else { 694fcf3ce44SJohn Forte if (va_str[0] != 0) { 695fcf3ce44SJohn Forte (void) sprintf(msg_str, 696*291a2b48SSukumar Swaminathan "[%2X.%04X]%s:%7s:%4d: (%s)\n", fileno, 697*291a2b48SSukumar Swaminathan line, driver, level, msg->id, va_str); 698fcf3ce44SJohn Forte } else { 699fcf3ce44SJohn Forte (void) sprintf(msg_str, 700fcf3ce44SJohn Forte "[%2X.%04X]%s:%7s:%4d\n", 701fcf3ce44SJohn Forte fileno, line, driver, level, msg->id); 702fcf3ce44SJohn Forte } 703fcf3ce44SJohn Forte } 704fcf3ce44SJohn Forte 705fcf3ce44SJohn Forte switch (rval) { 706fcf3ce44SJohn Forte case 1: /* MESSAGE LOG ONLY */ 707*291a2b48SSukumar Swaminathan /* Message log & console, if system booted in */ 708*291a2b48SSukumar Swaminathan /* verbose mode (CE_CONT only) */ 709fcf3ce44SJohn Forte cmn_err(cmn_level, "?%s", msg_str); 710fcf3ce44SJohn Forte break; 711fcf3ce44SJohn Forte 712fcf3ce44SJohn Forte case 2: /* CONSOLE ONLY */ 713fcf3ce44SJohn Forte cmn_err(cmn_level, "^%s", msg_str); 714fcf3ce44SJohn Forte break; 715fcf3ce44SJohn Forte 716fcf3ce44SJohn Forte case 3: /* CONSOLE AND MESSAGE LOG */ 717fcf3ce44SJohn Forte cmn_err(cmn_level, "%s", msg_str); 718fcf3ce44SJohn Forte break; 719fcf3ce44SJohn Forte 720fcf3ce44SJohn Forte } 721fcf3ce44SJohn Forte 722fcf3ce44SJohn Forte } 723*291a2b48SSukumar Swaminathan 724fcf3ce44SJohn Forte /* If message was not logged, then free any context buffer provided */ 725fcf3ce44SJohn Forte if (!logged && bp && size) { 726fcf3ce44SJohn Forte kmem_free(bp, size); 727fcf3ce44SJohn Forte } 728*291a2b48SSukumar Swaminathan 729fcf3ce44SJohn Forte return; 730fcf3ce44SJohn Forte 731*291a2b48SSukumar Swaminathan } /* emlxs_msg_printf() */ 732fcf3ce44SJohn Forte 733fcf3ce44SJohn Forte 734fcf3ce44SJohn Forte uint32_t 735fcf3ce44SJohn Forte emlxs_msg_log_get(emlxs_hba_t *hba, emlxs_log_req_t *req, 736fcf3ce44SJohn Forte emlxs_log_resp_t *resp) 737fcf3ce44SJohn Forte { 738fcf3ce44SJohn Forte emlxs_msg_log_t *log; 739fcf3ce44SJohn Forte uint32_t first; 740fcf3ce44SJohn Forte uint32_t last; 741fcf3ce44SJohn Forte uint32_t count; 742fcf3ce44SJohn Forte uint32_t index; 743fcf3ce44SJohn Forte uint32_t i; 744fcf3ce44SJohn Forte char *resp_buf; 745fcf3ce44SJohn Forte 746fcf3ce44SJohn Forte log = &LOG; 747fcf3ce44SJohn Forte 748fcf3ce44SJohn Forte mutex_enter(&log->lock); 749fcf3ce44SJohn Forte 750fcf3ce44SJohn Forte /* Check if buffer is empty */ 751fcf3ce44SJohn Forte if (log->count == 0) { 752fcf3ce44SJohn Forte /* If so, exit now */ 753fcf3ce44SJohn Forte resp->first = 0; 754fcf3ce44SJohn Forte resp->last = 0; 755fcf3ce44SJohn Forte resp->count = 0; 756fcf3ce44SJohn Forte mutex_exit(&log->lock); 757fcf3ce44SJohn Forte 758fcf3ce44SJohn Forte return (1); 759fcf3ce44SJohn Forte } 760*291a2b48SSukumar Swaminathan 761fcf3ce44SJohn Forte /* Get current log entry ranges */ 762fcf3ce44SJohn Forte 763fcf3ce44SJohn Forte /* Get last entry id saved */ 764fcf3ce44SJohn Forte last = log->count - 1; 765fcf3ce44SJohn Forte 766fcf3ce44SJohn Forte /* Check if request is out of current range */ 767fcf3ce44SJohn Forte if (req->first > last) { 768fcf3ce44SJohn Forte /* if so, exit now */ 769fcf3ce44SJohn Forte resp->first = last; 770fcf3ce44SJohn Forte resp->last = last; 771fcf3ce44SJohn Forte resp->count = 0; 772fcf3ce44SJohn Forte mutex_exit(&log->lock); 773fcf3ce44SJohn Forte 774fcf3ce44SJohn Forte return (0); 775fcf3ce44SJohn Forte } 776*291a2b48SSukumar Swaminathan 777fcf3ce44SJohn Forte /* Get oldest entry id and its index */ 778fcf3ce44SJohn Forte 779fcf3ce44SJohn Forte /* Check if buffer has already been filled once */ 780fcf3ce44SJohn Forte if (log->count >= log->size) { 781fcf3ce44SJohn Forte first = log->count - log->size; 782fcf3ce44SJohn Forte index = log->next; 783fcf3ce44SJohn Forte } else { /* Buffer not yet filled */ 784*291a2b48SSukumar Swaminathan 785fcf3ce44SJohn Forte first = 0; 786fcf3ce44SJohn Forte index = 0; 787fcf3ce44SJohn Forte } 788fcf3ce44SJohn Forte 789*291a2b48SSukumar Swaminathan /* Check if requested first message is greater than actual. */ 790*291a2b48SSukumar Swaminathan /* If so, adjust for it. */ 791fcf3ce44SJohn Forte if (req->first > first) { 792fcf3ce44SJohn Forte /* Adjust entry index to first requested message */ 793fcf3ce44SJohn Forte index += (req->first - first); 794fcf3ce44SJohn Forte if (index >= log->size) { 795fcf3ce44SJohn Forte index -= log->size; 796fcf3ce44SJohn Forte } 797*291a2b48SSukumar Swaminathan 798fcf3ce44SJohn Forte first = req->first; 799fcf3ce44SJohn Forte } 800*291a2b48SSukumar Swaminathan 801fcf3ce44SJohn Forte /* Get the total number of messages available for return */ 802fcf3ce44SJohn Forte count = last - first + 1; 803fcf3ce44SJohn Forte 804fcf3ce44SJohn Forte /* Check if requested count is less than actual. If so, adjust it. */ 805fcf3ce44SJohn Forte if (req->count < count) { 806fcf3ce44SJohn Forte count = req->count; 807fcf3ce44SJohn Forte } 808*291a2b48SSukumar Swaminathan 809fcf3ce44SJohn Forte /* Fill in the response header */ 810fcf3ce44SJohn Forte resp->count = count; 811fcf3ce44SJohn Forte resp->first = first; 812fcf3ce44SJohn Forte resp->last = last; 813fcf3ce44SJohn Forte 814fcf3ce44SJohn Forte /* Fill the response buffer */ 815fcf3ce44SJohn Forte resp_buf = (char *)resp + sizeof (emlxs_log_resp_t); 816fcf3ce44SJohn Forte for (i = 0; i < count; i++) { 817fcf3ce44SJohn Forte emlxs_msg_sprintf(resp_buf, &log->entry[index]); 818fcf3ce44SJohn Forte 819fcf3ce44SJohn Forte /* Increment the response buffer */ 820fcf3ce44SJohn Forte resp_buf += MAX_LOG_MSG_LENGTH; 821fcf3ce44SJohn Forte 822fcf3ce44SJohn Forte /* Increment index */ 823fcf3ce44SJohn Forte if (++index >= log->size) { 824fcf3ce44SJohn Forte index = 0; 825fcf3ce44SJohn Forte } 826fcf3ce44SJohn Forte } 827fcf3ce44SJohn Forte 828fcf3ce44SJohn Forte mutex_exit(&log->lock); 829fcf3ce44SJohn Forte 830fcf3ce44SJohn Forte return (1); 831fcf3ce44SJohn Forte 832*291a2b48SSukumar Swaminathan } /* emlxs_msg_log_get() */ 833fcf3ce44SJohn Forte 834fcf3ce44SJohn Forte 835fcf3ce44SJohn Forte 836fcf3ce44SJohn Forte static void 837fcf3ce44SJohn Forte emlxs_msg_sprintf(char *buffer, emlxs_msg_entry_t *entry) 838fcf3ce44SJohn Forte { 839fcf3ce44SJohn Forte char *level; 840fcf3ce44SJohn Forte emlxs_msg_t *msg; 841fcf3ce44SJohn Forte uint32_t secs; 842fcf3ce44SJohn Forte uint32_t hsecs; 843fcf3ce44SJohn Forte char buf[256]; 844fcf3ce44SJohn Forte uint32_t buflen; 845fcf3ce44SJohn Forte char driver[32]; 846fcf3ce44SJohn Forte 847fcf3ce44SJohn Forte msg = entry->msg; 848fcf3ce44SJohn Forte hsecs = (entry->time % 100); 849fcf3ce44SJohn Forte secs = entry->time / 100; 850fcf3ce44SJohn Forte 851fcf3ce44SJohn Forte switch (msg->level) { 852fcf3ce44SJohn Forte case EMLXS_DEBUG: 853fcf3ce44SJohn Forte level = " DEBUG"; 854fcf3ce44SJohn Forte break; 855fcf3ce44SJohn Forte 856fcf3ce44SJohn Forte case EMLXS_NOTICE: 857fcf3ce44SJohn Forte level = " NOTICE"; 858fcf3ce44SJohn Forte break; 859fcf3ce44SJohn Forte 860fcf3ce44SJohn Forte case EMLXS_WARNING: 861fcf3ce44SJohn Forte level = "WARNING"; 862fcf3ce44SJohn Forte break; 863fcf3ce44SJohn Forte 864fcf3ce44SJohn Forte case EMLXS_ERROR: 865fcf3ce44SJohn Forte level = " ERROR"; 866fcf3ce44SJohn Forte break; 867fcf3ce44SJohn Forte 868fcf3ce44SJohn Forte case EMLXS_PANIC: 869fcf3ce44SJohn Forte level = " PANIC"; 870fcf3ce44SJohn Forte break; 871fcf3ce44SJohn Forte 872fcf3ce44SJohn Forte case EMLXS_EVENT: 873fcf3ce44SJohn Forte level = " EVENT"; 874fcf3ce44SJohn Forte break; 875fcf3ce44SJohn Forte 876fcf3ce44SJohn Forte default: 877fcf3ce44SJohn Forte level = "UNKNOWN"; 878fcf3ce44SJohn Forte break; 879fcf3ce44SJohn Forte } 880fcf3ce44SJohn Forte 881fcf3ce44SJohn Forte if (entry->vpi == 0) { 882fcf3ce44SJohn Forte (void) sprintf(driver, "%s%d", DRIVER_NAME, entry->instance); 883fcf3ce44SJohn Forte } else { 884fcf3ce44SJohn Forte (void) sprintf(driver, "%s%d.%d", DRIVER_NAME, entry->instance, 885fcf3ce44SJohn Forte entry->vpi); 886fcf3ce44SJohn Forte } 887fcf3ce44SJohn Forte 888fcf3ce44SJohn Forte /* Generate the message string */ 889fcf3ce44SJohn Forte if (msg->buffer[0] != 0) { 890fcf3ce44SJohn Forte if (entry->buffer[0] != 0) { 891fcf3ce44SJohn Forte (void) sprintf(buf, 892fcf3ce44SJohn Forte "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: %s (%s)\n", 893*291a2b48SSukumar Swaminathan secs, hsecs, entry->id, entry->fileno, 894*291a2b48SSukumar Swaminathan entry->line, driver, level, msg->id, msg->buffer, 895*291a2b48SSukumar Swaminathan entry->buffer); 896fcf3ce44SJohn Forte 897fcf3ce44SJohn Forte } else { 898fcf3ce44SJohn Forte (void) sprintf(buf, 899*291a2b48SSukumar Swaminathan "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: %s\n", secs, 900*291a2b48SSukumar Swaminathan hsecs, entry->id, entry->fileno, entry->line, 901fcf3ce44SJohn Forte driver, level, msg->id, msg->buffer); 902fcf3ce44SJohn Forte } 903fcf3ce44SJohn Forte } else { 904fcf3ce44SJohn Forte if (entry->buffer[0] != 0) { 905fcf3ce44SJohn Forte (void) sprintf(buf, 906fcf3ce44SJohn Forte "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: (%s)\n", 907*291a2b48SSukumar Swaminathan secs, hsecs, entry->id, entry->fileno, 908*291a2b48SSukumar Swaminathan entry->line, driver, level, msg->id, 909*291a2b48SSukumar Swaminathan entry->buffer); 910fcf3ce44SJohn Forte } else { 911fcf3ce44SJohn Forte (void) sprintf(buf, 912fcf3ce44SJohn Forte "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d\n", 913*291a2b48SSukumar Swaminathan secs, hsecs, entry->id, entry->fileno, 914*291a2b48SSukumar Swaminathan entry->line, driver, level, msg->id); 915fcf3ce44SJohn Forte } 916fcf3ce44SJohn Forte } 917fcf3ce44SJohn Forte 918fcf3ce44SJohn Forte bzero(buffer, MAX_LOG_MSG_LENGTH); 919fcf3ce44SJohn Forte buflen = strlen(buf); 920fcf3ce44SJohn Forte 921fcf3ce44SJohn Forte if (buflen > (MAX_LOG_MSG_LENGTH - 1)) { 922fcf3ce44SJohn Forte (void) strncpy(buffer, buf, (MAX_LOG_MSG_LENGTH - 2)); 923fcf3ce44SJohn Forte buffer[MAX_LOG_MSG_LENGTH - 2] = '\n'; 924fcf3ce44SJohn Forte } else { 925fcf3ce44SJohn Forte (void) strncpy(buffer, buf, buflen); 926fcf3ce44SJohn Forte } 927fcf3ce44SJohn Forte 928fcf3ce44SJohn Forte return; 929fcf3ce44SJohn Forte 930*291a2b48SSukumar Swaminathan } /* emlxs_msg_sprintf() */ 931fcf3ce44SJohn Forte 932fcf3ce44SJohn Forte 933fcf3ce44SJohn Forte 934fcf3ce44SJohn Forte 935fcf3ce44SJohn Forte void 936fcf3ce44SJohn Forte emlxs_log_rscn_event(emlxs_port_t *port, uint8_t *payload, uint32_t size) 937fcf3ce44SJohn Forte { 938fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 939*291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA; 940fcf3ce44SJohn Forte uint8_t *bp; 941fcf3ce44SJohn Forte uint32_t *ptr; 942fcf3ce44SJohn Forte 943fcf3ce44SJohn Forte /* Check if the event is being requested */ 944*291a2b48SSukumar Swaminathan if (!(hba->log_events & EVT_RSCN)) { 945*291a2b48SSukumar Swaminathan return; 946*291a2b48SSukumar Swaminathan } 947fcf3ce44SJohn Forte 948fcf3ce44SJohn Forte if (size > MAX_RSCN_PAYLOAD) { 949fcf3ce44SJohn Forte size = MAX_RSCN_PAYLOAD; 950fcf3ce44SJohn Forte } 951*291a2b48SSukumar Swaminathan 952fcf3ce44SJohn Forte size += sizeof (uint32_t); 953fcf3ce44SJohn Forte 954fcf3ce44SJohn Forte /* Save a copy of the payload for the event log */ 955fcf3ce44SJohn Forte if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 956fcf3ce44SJohn Forte return; 957fcf3ce44SJohn Forte } 958*291a2b48SSukumar Swaminathan 959*291a2b48SSukumar Swaminathan 960fcf3ce44SJohn Forte /* 961*291a2b48SSukumar Swaminathan * Buffer Format: 962*291a2b48SSukumar Swaminathan * word[0] = DID of the RSCN 963*291a2b48SSukumar Swaminathan * word[1] = RSCN Payload 964fcf3ce44SJohn Forte */ 965fcf3ce44SJohn Forte ptr = (uint32_t *)bp; 966fcf3ce44SJohn Forte *ptr++ = port->did; 967fcf3ce44SJohn Forte bcopy(payload, (char *)ptr, (size - sizeof (uint32_t))); 968fcf3ce44SJohn Forte 969fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_rscn_event, 970fcf3ce44SJohn Forte "bp=%p size=%d", bp, size); 971fcf3ce44SJohn Forte 972*291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 973fcf3ce44SJohn Forte return; 974fcf3ce44SJohn Forte 975*291a2b48SSukumar Swaminathan } /* emlxs_log_rscn_event() */ 976*291a2b48SSukumar Swaminathan 977*291a2b48SSukumar Swaminathan 978*291a2b48SSukumar Swaminathan void 979*291a2b48SSukumar Swaminathan emlxs_log_vportrscn_event(emlxs_port_t *port, uint8_t *payload, uint32_t size) 980*291a2b48SSukumar Swaminathan { 981*291a2b48SSukumar Swaminathan #ifdef DFC_SUPPORT 982*291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA; 983*291a2b48SSukumar Swaminathan uint8_t *bp; 984*291a2b48SSukumar Swaminathan uint8_t *ptr; 985*291a2b48SSukumar Swaminathan 986*291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 987*291a2b48SSukumar Swaminathan if (!(hba->log_events & EVT_VPORTRSCN)) { 988*291a2b48SSukumar Swaminathan return; 989*291a2b48SSukumar Swaminathan } 990*291a2b48SSukumar Swaminathan 991*291a2b48SSukumar Swaminathan if (size > MAX_RSCN_PAYLOAD) { 992*291a2b48SSukumar Swaminathan size = MAX_RSCN_PAYLOAD; 993*291a2b48SSukumar Swaminathan } 994*291a2b48SSukumar Swaminathan 995*291a2b48SSukumar Swaminathan /* Save a copy of the payload for the event log */ 996*291a2b48SSukumar Swaminathan if (!(bp = 997*291a2b48SSukumar Swaminathan (uint8_t *)kmem_alloc(size + sizeof (NAME_TYPE), KM_NOSLEEP))) { 998*291a2b48SSukumar Swaminathan return; 999*291a2b48SSukumar Swaminathan } 1000*291a2b48SSukumar Swaminathan 1001*291a2b48SSukumar Swaminathan 1002*291a2b48SSukumar Swaminathan /* 1003*291a2b48SSukumar Swaminathan * Buffer Format: 1004*291a2b48SSukumar Swaminathan * word[0 - 4] = WWPN of the RSCN 1005*291a2b48SSukumar Swaminathan * word[5] = RSCN Payload 1006*291a2b48SSukumar Swaminathan */ 1007*291a2b48SSukumar Swaminathan ptr = bp; 1008*291a2b48SSukumar Swaminathan bcopy(&port->wwpn, ptr, sizeof (NAME_TYPE)); 1009*291a2b48SSukumar Swaminathan ptr += sizeof (NAME_TYPE); 1010*291a2b48SSukumar Swaminathan bcopy(payload, ptr, size); 1011*291a2b48SSukumar Swaminathan 1012*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size + sizeof (NAME_TYPE), 1013*291a2b48SSukumar Swaminathan &emlxs_vportrscn_event, "bp=%p size=%d", bp, size); 1014*291a2b48SSukumar Swaminathan 1015*291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1016*291a2b48SSukumar Swaminathan return; 1017*291a2b48SSukumar Swaminathan 1018*291a2b48SSukumar Swaminathan } /* emlxs_log_vportrscn_event() */ 1019fcf3ce44SJohn Forte 1020fcf3ce44SJohn Forte 1021728bdc9bSSukumar Swaminathan uint32_t 1022fcf3ce44SJohn Forte emlxs_log_ct_event(emlxs_port_t *port, uint8_t *payload, uint32_t size, 1023fcf3ce44SJohn Forte uint32_t rxid) 1024fcf3ce44SJohn Forte { 1025fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 1026fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1027fcf3ce44SJohn Forte uint8_t *bp; 1028fcf3ce44SJohn Forte uint32_t *ptr; 1029fcf3ce44SJohn Forte 1030fcf3ce44SJohn Forte /* Check if the event is being requested */ 1031fcf3ce44SJohn Forte if (!(hba->log_events & EVT_CT)) { 1032728bdc9bSSukumar Swaminathan return (1); 1033fcf3ce44SJohn Forte } 1034*291a2b48SSukumar Swaminathan 1035fcf3ce44SJohn Forte if (size > MAX_CT_PAYLOAD) { 1036fcf3ce44SJohn Forte size = MAX_CT_PAYLOAD; 1037fcf3ce44SJohn Forte } 1038*291a2b48SSukumar Swaminathan 1039fcf3ce44SJohn Forte size += sizeof (uint32_t); 1040fcf3ce44SJohn Forte 1041fcf3ce44SJohn Forte /* Save a copy of the payload for the event log */ 1042fcf3ce44SJohn Forte if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 1043728bdc9bSSukumar Swaminathan return (1); 1044fcf3ce44SJohn Forte } 1045*291a2b48SSukumar Swaminathan 1046fcf3ce44SJohn Forte /* 1047*291a2b48SSukumar Swaminathan * Buffer Format: 1048*291a2b48SSukumar Swaminathan * word[0] = RXID tag for outgoing reply to this CT request 1049*291a2b48SSukumar Swaminathan * word[1] = CT Payload 1050fcf3ce44SJohn Forte */ 1051fcf3ce44SJohn Forte ptr = (uint32_t *)bp; 1052fcf3ce44SJohn Forte *ptr++ = rxid; 1053fcf3ce44SJohn Forte 1054fcf3ce44SJohn Forte bcopy(payload, (char *)ptr, (size - sizeof (uint32_t))); 1055fcf3ce44SJohn Forte 1056fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_ct_event, 1057fcf3ce44SJohn Forte "bp=%p size=%d rxid=%x", bp, size, rxid); 1058fcf3ce44SJohn Forte 1059728bdc9bSSukumar Swaminathan 1060*291a2b48SSukumar Swaminathan return (0); 1061728bdc9bSSukumar Swaminathan #else 1062728bdc9bSSukumar Swaminathan 1063*291a2b48SSukumar Swaminathan return (1); 1064fcf3ce44SJohn Forte 1065*291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1066fcf3ce44SJohn Forte 1067*291a2b48SSukumar Swaminathan } /* emlxs_log_ct_event() */ 1068fcf3ce44SJohn Forte 1069fcf3ce44SJohn Forte 1070fcf3ce44SJohn Forte void 1071fcf3ce44SJohn Forte emlxs_log_link_event(emlxs_port_t *port) 1072fcf3ce44SJohn Forte { 1073fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 1074fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1075fcf3ce44SJohn Forte uint8_t *bp; 1076fcf3ce44SJohn Forte dfc_linkinfo_t *linkinfo; 1077fcf3ce44SJohn Forte uint8_t *byte; 1078fcf3ce44SJohn Forte uint8_t *linkspeed; 1079fcf3ce44SJohn Forte uint8_t *liptype; 1080fcf3ce44SJohn Forte uint8_t *resv1; 1081fcf3ce44SJohn Forte uint8_t *resv2; 1082fcf3ce44SJohn Forte uint32_t size; 1083fcf3ce44SJohn Forte 1084fcf3ce44SJohn Forte /* Check if the event is being requested */ 1085fcf3ce44SJohn Forte /* 1086fcf3ce44SJohn Forte * if(!(hba->log_events & EVT_LINK)) { return; } 1087fcf3ce44SJohn Forte */ 1088fcf3ce44SJohn Forte size = sizeof (dfc_linkinfo_t) + sizeof (uint32_t); 1089fcf3ce44SJohn Forte 1090fcf3ce44SJohn Forte /* Save a copy of the buffer for the event log */ 1091fcf3ce44SJohn Forte if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 1092fcf3ce44SJohn Forte return; 1093fcf3ce44SJohn Forte } 1094*291a2b48SSukumar Swaminathan 1095fcf3ce44SJohn Forte /* 1096*291a2b48SSukumar Swaminathan * Buffer Format: 1097*291a2b48SSukumar Swaminathan * word[0] = Linkspeed:8 1098*291a2b48SSukumar Swaminathan * word[0] = LIP_type:8 1099*291a2b48SSukumar Swaminathan * word[0] = resv1:8 1100*291a2b48SSukumar Swaminathan * word[0] = resv2:8 1101*291a2b48SSukumar Swaminathan * word[1] = dfc_linkinfo_t data 1102fcf3ce44SJohn Forte */ 1103fcf3ce44SJohn Forte byte = (uint8_t *)bp; 1104fcf3ce44SJohn Forte linkspeed = &byte[0]; 1105fcf3ce44SJohn Forte liptype = &byte[1]; 1106fcf3ce44SJohn Forte resv1 = &byte[2]; 1107fcf3ce44SJohn Forte resv2 = &byte[3]; 1108*291a2b48SSukumar Swaminathan linkinfo = (dfc_linkinfo_t *)&byte[4]; 1109fcf3ce44SJohn Forte 1110fcf3ce44SJohn Forte *resv1 = 0; 1111fcf3ce44SJohn Forte *resv2 = 0; 1112fcf3ce44SJohn Forte 1113fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1114fcf3ce44SJohn Forte *linkspeed = 0; 1115fcf3ce44SJohn Forte *liptype = 0; 1116fcf3ce44SJohn Forte } else { 1117fcf3ce44SJohn Forte /* Set linkspeed */ 1118fcf3ce44SJohn Forte if (hba->linkspeed == LA_2GHZ_LINK) { 1119fcf3ce44SJohn Forte *linkspeed = HBA_PORTSPEED_2GBIT; 1120fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_4GHZ_LINK) { 1121fcf3ce44SJohn Forte *linkspeed = HBA_PORTSPEED_4GBIT; 1122fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_8GHZ_LINK) { 1123fcf3ce44SJohn Forte *linkspeed = HBA_PORTSPEED_8GBIT; 1124fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_10GHZ_LINK) { 1125fcf3ce44SJohn Forte *linkspeed = HBA_PORTSPEED_10GBIT; 1126fcf3ce44SJohn Forte } else { 1127fcf3ce44SJohn Forte *linkspeed = HBA_PORTSPEED_1GBIT; 1128fcf3ce44SJohn Forte } 1129fcf3ce44SJohn Forte 1130fcf3ce44SJohn Forte /* Set LIP type */ 1131fcf3ce44SJohn Forte *liptype = port->lip_type; 1132fcf3ce44SJohn Forte } 1133fcf3ce44SJohn Forte 1134fcf3ce44SJohn Forte bzero(linkinfo, sizeof (dfc_linkinfo_t)); 1135fcf3ce44SJohn Forte 1136fcf3ce44SJohn Forte linkinfo->a_linkEventTag = hba->link_event_tag; 1137fcf3ce44SJohn Forte linkinfo->a_linkUp = HBASTATS.LinkUp; 1138fcf3ce44SJohn Forte linkinfo->a_linkDown = HBASTATS.LinkDown; 1139fcf3ce44SJohn Forte linkinfo->a_linkMulti = HBASTATS.LinkMultiEvent; 1140fcf3ce44SJohn Forte 1141fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1142fcf3ce44SJohn Forte linkinfo->a_linkState = LNK_DOWN; 1143fcf3ce44SJohn Forte linkinfo->a_DID = port->prev_did; 1144fcf3ce44SJohn Forte } else if (hba->state < FC_READY) { 1145fcf3ce44SJohn Forte linkinfo->a_linkState = LNK_DISCOVERY; 1146fcf3ce44SJohn Forte } else { 1147fcf3ce44SJohn Forte linkinfo->a_linkState = LNK_READY; 1148fcf3ce44SJohn Forte } 1149fcf3ce44SJohn Forte 1150fcf3ce44SJohn Forte if (linkinfo->a_linkState != LNK_DOWN) { 1151fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 1152fcf3ce44SJohn Forte if (hba->flag & FC_FABRIC_ATTACHED) { 1153fcf3ce44SJohn Forte linkinfo->a_topology = LNK_PUBLIC_LOOP; 1154fcf3ce44SJohn Forte } else { 1155fcf3ce44SJohn Forte linkinfo->a_topology = LNK_LOOP; 1156fcf3ce44SJohn Forte } 1157fcf3ce44SJohn Forte 1158fcf3ce44SJohn Forte linkinfo->a_alpa = port->did & 0xff; 1159fcf3ce44SJohn Forte linkinfo->a_DID = linkinfo->a_alpa; 1160fcf3ce44SJohn Forte linkinfo->a_alpaCnt = port->alpa_map[0]; 1161fcf3ce44SJohn Forte 1162fcf3ce44SJohn Forte if (linkinfo->a_alpaCnt > 127) { 1163fcf3ce44SJohn Forte linkinfo->a_alpaCnt = 127; 1164fcf3ce44SJohn Forte } 1165*291a2b48SSukumar Swaminathan 1166*291a2b48SSukumar Swaminathan bcopy((void *)&port->alpa_map[1], linkinfo->a_alpaMap, 1167fcf3ce44SJohn Forte linkinfo->a_alpaCnt); 1168fcf3ce44SJohn Forte } else { 1169fcf3ce44SJohn Forte if (port->node_count == 1) { 1170fcf3ce44SJohn Forte linkinfo->a_topology = LNK_PT2PT; 1171fcf3ce44SJohn Forte } else { 1172fcf3ce44SJohn Forte linkinfo->a_topology = LNK_FABRIC; 1173fcf3ce44SJohn Forte } 1174fcf3ce44SJohn Forte 1175fcf3ce44SJohn Forte linkinfo->a_DID = port->did; 1176fcf3ce44SJohn Forte } 1177fcf3ce44SJohn Forte } 1178*291a2b48SSukumar Swaminathan 1179fcf3ce44SJohn Forte bcopy(&hba->wwpn, linkinfo->a_wwpName, 8); 1180fcf3ce44SJohn Forte bcopy(&hba->wwnn, linkinfo->a_wwnName, 8); 1181fcf3ce44SJohn Forte 1182fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_link_event, 1183fcf3ce44SJohn Forte "bp=%p size=%d tag=%x", bp, size, hba->link_event_tag); 1184fcf3ce44SJohn Forte 1185*291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1186fcf3ce44SJohn Forte 1187fcf3ce44SJohn Forte return; 1188fcf3ce44SJohn Forte 1189*291a2b48SSukumar Swaminathan } /* emlxs_log_link_event() */ 1190fcf3ce44SJohn Forte 1191fcf3ce44SJohn Forte 1192fcf3ce44SJohn Forte void 1193fcf3ce44SJohn Forte emlxs_log_dump_event(emlxs_port_t *port, uint8_t *buffer, uint32_t size) 1194fcf3ce44SJohn Forte { 1195fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 1196fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1197fcf3ce44SJohn Forte uint8_t *bp; 1198fcf3ce44SJohn Forte 1199fcf3ce44SJohn Forte /* Check if the event is being requested */ 1200fcf3ce44SJohn Forte if (!(hba->log_events & EVT_DUMP)) { 1201*291a2b48SSukumar Swaminathan #ifdef DUMP_SUPPORT 1202*291a2b48SSukumar Swaminathan /* Schedule a dump thread */ 1203*291a2b48SSukumar Swaminathan emlxs_dump(hba, EMLXS_DRV_DUMP, 0, 0); 1204*291a2b48SSukumar Swaminathan #endif /* DUMP_SUPPORT */ 1205fcf3ce44SJohn Forte return; 1206fcf3ce44SJohn Forte } 1207*291a2b48SSukumar Swaminathan 1208fcf3ce44SJohn Forte if (buffer && size) { 1209fcf3ce44SJohn Forte /* Save a copy of the buffer for the event log */ 1210fcf3ce44SJohn Forte if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 1211fcf3ce44SJohn Forte return; 1212fcf3ce44SJohn Forte } 1213*291a2b48SSukumar Swaminathan 1214fcf3ce44SJohn Forte bcopy(buffer, bp, size); 1215fcf3ce44SJohn Forte } else { 1216fcf3ce44SJohn Forte bp = NULL; 1217fcf3ce44SJohn Forte size = 0; 1218fcf3ce44SJohn Forte } 1219fcf3ce44SJohn Forte 1220fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_dump_event, 1221fcf3ce44SJohn Forte "bp=%p size=%d", bp, size); 1222*291a2b48SSukumar Swaminathan #else 1223*291a2b48SSukumar Swaminathan 1224*291a2b48SSukumar Swaminathan #ifdef DUMP_SUPPORT 1225*291a2b48SSukumar Swaminathan /* Schedule a dump thread */ 1226*291a2b48SSukumar Swaminathan emlxs_dump(hba, EMLXS_DRV_DUMP, 0, 0); 1227*291a2b48SSukumar Swaminathan #endif /* DUMP_SUPPORT */ 1228fcf3ce44SJohn Forte 1229*291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1230fcf3ce44SJohn Forte 1231fcf3ce44SJohn Forte return; 1232fcf3ce44SJohn Forte 1233*291a2b48SSukumar Swaminathan } /* emlxs_log_dump_event() */ 1234fcf3ce44SJohn Forte 1235fcf3ce44SJohn Forte 1236fcf3ce44SJohn Forte extern void 1237fcf3ce44SJohn Forte emlxs_log_temp_event(emlxs_port_t *port, uint32_t type, uint32_t temp) 1238fcf3ce44SJohn Forte { 1239fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1240*291a2b48SSukumar Swaminathan 1241*291a2b48SSukumar Swaminathan #ifdef DFC_SUPPORT 1242fcf3ce44SJohn Forte uint32_t *bp; 1243fcf3ce44SJohn Forte uint32_t size; 1244fcf3ce44SJohn Forte 1245fcf3ce44SJohn Forte /* Check if the event is being requested */ 1246fcf3ce44SJohn Forte if (!(hba->log_events & EVT_TEMP)) { 1247*291a2b48SSukumar Swaminathan #ifdef DUMP_SUPPORT 1248*291a2b48SSukumar Swaminathan /* Schedule a dump thread */ 1249*291a2b48SSukumar Swaminathan emlxs_dump(hba, EMLXS_TEMP_DUMP, type, temp); 1250*291a2b48SSukumar Swaminathan #endif /* DUMP_SUPPORT */ 1251fcf3ce44SJohn Forte return; 1252fcf3ce44SJohn Forte } 1253*291a2b48SSukumar Swaminathan 1254fcf3ce44SJohn Forte size = 2 * sizeof (uint32_t); 1255fcf3ce44SJohn Forte 1256fcf3ce44SJohn Forte if (!(bp = (uint32_t *)kmem_alloc(size, KM_NOSLEEP))) { 1257fcf3ce44SJohn Forte return; 1258fcf3ce44SJohn Forte } 1259*291a2b48SSukumar Swaminathan 1260fcf3ce44SJohn Forte bp[0] = type; 1261fcf3ce44SJohn Forte bp[1] = temp; 1262fcf3ce44SJohn Forte 1263fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_temp_event, 1264fcf3ce44SJohn Forte "type=%x temp=%d bp=%p size=%d", type, temp, bp, size); 1265fcf3ce44SJohn Forte 1266*291a2b48SSukumar Swaminathan #else /* !DFC_SUPPORT */ 1267*291a2b48SSukumar Swaminathan 1268*291a2b48SSukumar Swaminathan #ifdef DUMP_SUPPORT 1269*291a2b48SSukumar Swaminathan /* Schedule a dump thread */ 1270*291a2b48SSukumar Swaminathan emlxs_dump(hba, EMLXS_TEMP_DUMP, type, temp); 1271*291a2b48SSukumar Swaminathan #endif /* DUMP_SUPPORT */ 1272*291a2b48SSukumar Swaminathan 1273*291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1274fcf3ce44SJohn Forte 1275fcf3ce44SJohn Forte return; 1276fcf3ce44SJohn Forte 1277*291a2b48SSukumar Swaminathan } /* emlxs_log_temp_event() */ 1278fcf3ce44SJohn Forte 1279fcf3ce44SJohn Forte 1280fcf3ce44SJohn Forte 1281fcf3ce44SJohn Forte extern void 1282fcf3ce44SJohn Forte emlxs_log_fcoe_event(emlxs_port_t *port, menlo_init_rsp_t *init_rsp) 1283fcf3ce44SJohn Forte { 1284fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 1285fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1286fcf3ce44SJohn Forte uint8_t *bp; 1287fcf3ce44SJohn Forte uint32_t size; 1288fcf3ce44SJohn Forte 1289fcf3ce44SJohn Forte /* Check if the event is being requested */ 1290fcf3ce44SJohn Forte if (!(hba->log_events & EVT_FCOE)) { 1291fcf3ce44SJohn Forte return; 1292fcf3ce44SJohn Forte } 1293*291a2b48SSukumar Swaminathan 1294fcf3ce44SJohn Forte /* Check if this is a FCOE adapter */ 1295fcf3ce44SJohn Forte if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 1296fcf3ce44SJohn Forte return; 1297fcf3ce44SJohn Forte } 1298*291a2b48SSukumar Swaminathan 1299fcf3ce44SJohn Forte size = sizeof (menlo_init_rsp_t); 1300fcf3ce44SJohn Forte 1301fcf3ce44SJohn Forte if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 1302fcf3ce44SJohn Forte return; 1303fcf3ce44SJohn Forte } 1304*291a2b48SSukumar Swaminathan 1305fcf3ce44SJohn Forte bcopy((uint8_t *)init_rsp, bp, size); 1306fcf3ce44SJohn Forte 1307fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_fcoe_event, 1308fcf3ce44SJohn Forte "bp=%p size=%d", bp, size); 1309*291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1310*291a2b48SSukumar Swaminathan 1311*291a2b48SSukumar Swaminathan return; 1312*291a2b48SSukumar Swaminathan 1313*291a2b48SSukumar Swaminathan } /* emlxs_log_fcoe_event() */ 1314*291a2b48SSukumar Swaminathan 1315*291a2b48SSukumar Swaminathan 1316*291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1317*291a2b48SSukumar Swaminathan extern void 1318*291a2b48SSukumar Swaminathan emlxs_log_sd_basic_els_event(emlxs_port_t *port, uint32_t subcat, 1319*291a2b48SSukumar Swaminathan HBA_WWN *portname, HBA_WWN *nodename) 1320*291a2b48SSukumar Swaminathan { 1321*291a2b48SSukumar Swaminathan struct sd_plogi_rcv_v0 *bp; 1322*291a2b48SSukumar Swaminathan uint32_t size; 1323*291a2b48SSukumar Swaminathan 1324*291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1325*291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_ELS)) 1326*291a2b48SSukumar Swaminathan return; 1327*291a2b48SSukumar Swaminathan 1328*291a2b48SSukumar Swaminathan size = sizeof (struct sd_plogi_rcv_v0); 1329*291a2b48SSukumar Swaminathan 1330*291a2b48SSukumar Swaminathan if (!(bp = (struct sd_plogi_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1331*291a2b48SSukumar Swaminathan return; 1332*291a2b48SSukumar Swaminathan 1333*291a2b48SSukumar Swaminathan /* 1334*291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1335*291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1336*291a2b48SSukumar Swaminathan */ 1337*291a2b48SSukumar Swaminathan bp->sd_plogir_version = subcat; 1338*291a2b48SSukumar Swaminathan bcopy((uint8_t *)portname, (uint8_t *)&bp->sd_plogir_portname, 1339*291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1340*291a2b48SSukumar Swaminathan bcopy((uint8_t *)nodename, (uint8_t *)&bp->sd_plogir_nodename, 1341*291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1342*291a2b48SSukumar Swaminathan 1343*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_els_event, 1344*291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1345*291a2b48SSukumar Swaminathan 1346*291a2b48SSukumar Swaminathan return; 1347*291a2b48SSukumar Swaminathan 1348*291a2b48SSukumar Swaminathan } /* emlxs_log_sd_basic_els_event() */ 1349*291a2b48SSukumar Swaminathan 1350*291a2b48SSukumar Swaminathan 1351*291a2b48SSukumar Swaminathan extern void 1352*291a2b48SSukumar Swaminathan emlxs_log_sd_prlo_event(emlxs_port_t *port, HBA_WWN *remoteport) 1353*291a2b48SSukumar Swaminathan { 1354*291a2b48SSukumar Swaminathan struct sd_prlo_rcv_v0 *bp; 1355*291a2b48SSukumar Swaminathan uint32_t size; 1356*291a2b48SSukumar Swaminathan 1357*291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1358*291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_ELS)) 1359*291a2b48SSukumar Swaminathan return; 1360*291a2b48SSukumar Swaminathan 1361*291a2b48SSukumar Swaminathan size = sizeof (struct sd_prlo_rcv_v0); 1362*291a2b48SSukumar Swaminathan 1363*291a2b48SSukumar Swaminathan if (!(bp = (struct sd_prlo_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1364*291a2b48SSukumar Swaminathan return; 1365*291a2b48SSukumar Swaminathan 1366*291a2b48SSukumar Swaminathan /* 1367*291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1368*291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1369*291a2b48SSukumar Swaminathan */ 1370*291a2b48SSukumar Swaminathan bp->sd_prlor_version = SD_ELS_SUBCATEGORY_PRLO_RCV; 1371*291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_prlor_remoteport, 1372*291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1373*291a2b48SSukumar Swaminathan 1374*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_els_event, 1375*291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1376*291a2b48SSukumar Swaminathan 1377*291a2b48SSukumar Swaminathan return; 1378*291a2b48SSukumar Swaminathan 1379*291a2b48SSukumar Swaminathan } /* emlxs_log_sd_prlo_event() */ 1380*291a2b48SSukumar Swaminathan 1381*291a2b48SSukumar Swaminathan 1382*291a2b48SSukumar Swaminathan extern void 1383*291a2b48SSukumar Swaminathan emlxs_log_sd_lsrjt_event(emlxs_port_t *port, HBA_WWN *remoteport, 1384*291a2b48SSukumar Swaminathan uint32_t orig_cmd, uint32_t reason, uint32_t reason_expl) 1385*291a2b48SSukumar Swaminathan { 1386*291a2b48SSukumar Swaminathan struct sd_lsrjt_rcv_v0 *bp; 1387*291a2b48SSukumar Swaminathan uint32_t size; 1388*291a2b48SSukumar Swaminathan 1389*291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1390*291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_ELS)) 1391*291a2b48SSukumar Swaminathan return; 1392*291a2b48SSukumar Swaminathan 1393*291a2b48SSukumar Swaminathan size = sizeof (struct sd_lsrjt_rcv_v0); 1394*291a2b48SSukumar Swaminathan 1395*291a2b48SSukumar Swaminathan if (!(bp = (struct sd_lsrjt_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1396*291a2b48SSukumar Swaminathan return; 1397*291a2b48SSukumar Swaminathan 1398*291a2b48SSukumar Swaminathan /* 1399*291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1400*291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1401*291a2b48SSukumar Swaminathan */ 1402*291a2b48SSukumar Swaminathan bp->sd_lsrjtr_version = SD_ELS_SUBCATEGORY_LSRJT_RCV; 1403*291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_lsrjtr_remoteport, 1404*291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1405*291a2b48SSukumar Swaminathan bp->sd_lsrjtr_original_cmd = orig_cmd; 1406*291a2b48SSukumar Swaminathan bp->sd_lsrjtr_reasoncode = reason; 1407*291a2b48SSukumar Swaminathan bp->sd_lsrjtr_reasoncodeexpl = reason_expl; 1408*291a2b48SSukumar Swaminathan 1409*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_els_event, 1410*291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1411*291a2b48SSukumar Swaminathan 1412*291a2b48SSukumar Swaminathan return; 1413*291a2b48SSukumar Swaminathan 1414*291a2b48SSukumar Swaminathan } /* emlxs_log_sd_lsrjt_event() */ 1415*291a2b48SSukumar Swaminathan 1416*291a2b48SSukumar Swaminathan 1417*291a2b48SSukumar Swaminathan 1418*291a2b48SSukumar Swaminathan extern void 1419*291a2b48SSukumar Swaminathan emlxs_log_sd_fc_bsy_event(emlxs_port_t *port, HBA_WWN *remoteport) 1420*291a2b48SSukumar Swaminathan { 1421*291a2b48SSukumar Swaminathan struct sd_pbsy_rcv_v0 *bp; 1422*291a2b48SSukumar Swaminathan uint32_t size; 1423*291a2b48SSukumar Swaminathan 1424*291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1425*291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_FABRIC)) 1426*291a2b48SSukumar Swaminathan return; 1427*291a2b48SSukumar Swaminathan 1428*291a2b48SSukumar Swaminathan size = sizeof (struct sd_pbsy_rcv_v0); 1429*291a2b48SSukumar Swaminathan 1430*291a2b48SSukumar Swaminathan if (!(bp = (struct sd_pbsy_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1431*291a2b48SSukumar Swaminathan return; 1432*291a2b48SSukumar Swaminathan 1433*291a2b48SSukumar Swaminathan /* 1434*291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1435*291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1436*291a2b48SSukumar Swaminathan */ 1437*291a2b48SSukumar Swaminathan if (remoteport == NULL) 1438*291a2b48SSukumar Swaminathan bp->sd_pbsyr_evt_version = SD_FABRIC_SUBCATEGORY_FABRIC_BUSY; 1439*291a2b48SSukumar Swaminathan else 1440*291a2b48SSukumar Swaminathan { 1441*291a2b48SSukumar Swaminathan bp->sd_pbsyr_evt_version = SD_FABRIC_SUBCATEGORY_PORT_BUSY; 1442*291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_pbsyr_rport, 1443*291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1444*291a2b48SSukumar Swaminathan } 1445*291a2b48SSukumar Swaminathan 1446*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_fabric_event, 1447*291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1448*291a2b48SSukumar Swaminathan 1449*291a2b48SSukumar Swaminathan return; 1450*291a2b48SSukumar Swaminathan 1451*291a2b48SSukumar Swaminathan } /* emlxs_log_sd_fc_bsy_event() */ 1452*291a2b48SSukumar Swaminathan 1453*291a2b48SSukumar Swaminathan 1454*291a2b48SSukumar Swaminathan extern void 1455*291a2b48SSukumar Swaminathan emlxs_log_sd_fc_rdchk_event(emlxs_port_t *port, HBA_WWN *remoteport, 1456*291a2b48SSukumar Swaminathan uint32_t lun, uint32_t opcode, uint32_t fcp_param) 1457*291a2b48SSukumar Swaminathan { 1458*291a2b48SSukumar Swaminathan struct sd_fcprdchkerr_v0 *bp; 1459*291a2b48SSukumar Swaminathan uint32_t size; 1460*291a2b48SSukumar Swaminathan 1461*291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1462*291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_FABRIC)) 1463*291a2b48SSukumar Swaminathan return; 1464*291a2b48SSukumar Swaminathan 1465*291a2b48SSukumar Swaminathan size = sizeof (struct sd_fcprdchkerr_v0); 1466*291a2b48SSukumar Swaminathan 1467*291a2b48SSukumar Swaminathan if (!(bp = (struct sd_fcprdchkerr_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1468*291a2b48SSukumar Swaminathan return; 1469*291a2b48SSukumar Swaminathan 1470*291a2b48SSukumar Swaminathan /* 1471*291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1472*291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1473*291a2b48SSukumar Swaminathan */ 1474*291a2b48SSukumar Swaminathan bp->sd_fcprdchkerr_version = SD_FABRIC_SUBCATEGORY_FCPRDCHKERR; 1475*291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_fcprdchkerr_rport, 1476*291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1477*291a2b48SSukumar Swaminathan bp->sd_fcprdchkerr_lun = lun; 1478*291a2b48SSukumar Swaminathan bp->sd_fcprdchkerr_opcode = opcode; 1479*291a2b48SSukumar Swaminathan bp->sd_fcprdchkerr_fcpiparam = fcp_param; 1480*291a2b48SSukumar Swaminathan 1481*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_fabric_event, 1482*291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1483*291a2b48SSukumar Swaminathan 1484*291a2b48SSukumar Swaminathan return; 1485*291a2b48SSukumar Swaminathan 1486*291a2b48SSukumar Swaminathan } /* emlxs_log_sd_rdchk_event() */ 1487*291a2b48SSukumar Swaminathan 1488*291a2b48SSukumar Swaminathan 1489*291a2b48SSukumar Swaminathan extern void 1490*291a2b48SSukumar Swaminathan emlxs_log_sd_scsi_event(emlxs_port_t *port, uint32_t type, 1491*291a2b48SSukumar Swaminathan HBA_WWN *remoteport, int32_t lun) 1492*291a2b48SSukumar Swaminathan { 1493*291a2b48SSukumar Swaminathan struct sd_scsi_generic_v0 *bp; 1494*291a2b48SSukumar Swaminathan uint32_t size; 1495*291a2b48SSukumar Swaminathan 1496*291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1497*291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_SCSI)) 1498*291a2b48SSukumar Swaminathan return; 1499*291a2b48SSukumar Swaminathan 1500*291a2b48SSukumar Swaminathan size = sizeof (struct sd_scsi_generic_v0); 1501*291a2b48SSukumar Swaminathan 1502*291a2b48SSukumar Swaminathan if (!(bp = (struct sd_scsi_generic_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1503*291a2b48SSukumar Swaminathan return; 1504fcf3ce44SJohn Forte 1505*291a2b48SSukumar Swaminathan /* 1506*291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1507*291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1508*291a2b48SSukumar Swaminathan */ 1509*291a2b48SSukumar Swaminathan bp->sd_scsi_generic_version = type; 1510*291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_scsi_generic_rport, 1511*291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1512*291a2b48SSukumar Swaminathan bp->sd_scsi_generic_lun = lun; 1513*291a2b48SSukumar Swaminathan 1514*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_scsi_event, 1515*291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1516fcf3ce44SJohn Forte 1517fcf3ce44SJohn Forte return; 1518fcf3ce44SJohn Forte 1519*291a2b48SSukumar Swaminathan } /* emlxs_log_sd_scsi_event() */ 1520*291a2b48SSukumar Swaminathan 1521*291a2b48SSukumar Swaminathan 1522*291a2b48SSukumar Swaminathan extern void 1523*291a2b48SSukumar Swaminathan emlxs_log_sd_scsi_check_event(emlxs_port_t *port, HBA_WWN *remoteport, 1524*291a2b48SSukumar Swaminathan uint32_t lun, uint32_t cmdcode, uint32_t sensekey, 1525*291a2b48SSukumar Swaminathan uint32_t asc, uint32_t ascq) 1526*291a2b48SSukumar Swaminathan { 1527*291a2b48SSukumar Swaminathan struct sd_scsi_checkcond_v0 *bp; 1528*291a2b48SSukumar Swaminathan uint32_t size; 1529*291a2b48SSukumar Swaminathan 1530*291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1531*291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_SCSI)) 1532*291a2b48SSukumar Swaminathan return; 1533*291a2b48SSukumar Swaminathan 1534*291a2b48SSukumar Swaminathan size = sizeof (struct sd_scsi_checkcond_v0); 1535*291a2b48SSukumar Swaminathan 1536*291a2b48SSukumar Swaminathan if (!(bp = (struct sd_scsi_checkcond_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1537*291a2b48SSukumar Swaminathan return; 1538*291a2b48SSukumar Swaminathan 1539*291a2b48SSukumar Swaminathan /* 1540*291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1541*291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1542*291a2b48SSukumar Swaminathan */ 1543*291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_version = SD_SCSI_SUBCATEGORY_CHECKCONDITION; 1544*291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_scsi_checkcond_rport, 1545*291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1546*291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_lun = lun; 1547*291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_cmdcode = cmdcode; 1548*291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_sensekey = sensekey; 1549*291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_asc = asc; 1550*291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_ascq = ascq; 1551*291a2b48SSukumar Swaminathan 1552*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_scsi_event, 1553*291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1554*291a2b48SSukumar Swaminathan 1555*291a2b48SSukumar Swaminathan } 1556*291a2b48SSukumar Swaminathan #endif /* SAN_DIAG_SUPPORT */ 1557*291a2b48SSukumar Swaminathan 1558*291a2b48SSukumar Swaminathan 1559*291a2b48SSukumar Swaminathan extern void 1560*291a2b48SSukumar Swaminathan emlxs_log_async_event(emlxs_port_t *port, IOCB *iocb) 1561*291a2b48SSukumar Swaminathan { 1562*291a2b48SSukumar Swaminathan uint8_t *bp; 1563*291a2b48SSukumar Swaminathan uint32_t size; 1564*291a2b48SSukumar Swaminathan 1565*291a2b48SSukumar Swaminathan /* ASYNC_STATUS_CN response size */ 1566*291a2b48SSukumar Swaminathan size = 64; 1567*291a2b48SSukumar Swaminathan 1568*291a2b48SSukumar Swaminathan if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 1569*291a2b48SSukumar Swaminathan return; 1570*291a2b48SSukumar Swaminathan } 1571fcf3ce44SJohn Forte 1572*291a2b48SSukumar Swaminathan bcopy((uint8_t *)iocb, bp, size); 1573fcf3ce44SJohn Forte 1574*291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_async_event, 1575*291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1576*291a2b48SSukumar Swaminathan 1577*291a2b48SSukumar Swaminathan } /* emlxs_log_async_event() */ 1578fcf3ce44SJohn Forte 1579fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 1580fcf3ce44SJohn Forte 1581fcf3ce44SJohn Forte extern uint32_t 1582fcf3ce44SJohn Forte emlxs_get_dfc_eventinfo(emlxs_port_t *port, HBA_EVENTINFO *eventinfo, 1583fcf3ce44SJohn Forte uint32_t *eventcount, uint32_t *missed) 1584fcf3ce44SJohn Forte { 1585fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1586fcf3ce44SJohn Forte emlxs_msg_log_t *log; 1587fcf3ce44SJohn Forte uint32_t first; 1588fcf3ce44SJohn Forte uint32_t last; 1589fcf3ce44SJohn Forte uint32_t count; 1590fcf3ce44SJohn Forte uint32_t index; 1591fcf3ce44SJohn Forte emlxs_msg_entry_t *entry; 1592fcf3ce44SJohn Forte dfc_linkinfo_t *linkinfo; 1593fcf3ce44SJohn Forte uint32_t *word; 1594fcf3ce44SJohn Forte uint8_t *byte; 1595fcf3ce44SJohn Forte uint8_t linkspeed; 1596fcf3ce44SJohn Forte uint8_t liptype; 1597fcf3ce44SJohn Forte fc_affected_id_t *aid; 1598fcf3ce44SJohn Forte uint32_t max_events; 1599fcf3ce44SJohn Forte uint32_t events; 1600fcf3ce44SJohn Forte emlxs_hba_event_t *hba_event; 1601fcf3ce44SJohn Forte 1602fcf3ce44SJohn Forte if (!eventinfo || !eventcount || !missed) { 1603fcf3ce44SJohn Forte return (DFC_ARG_NULL); 1604fcf3ce44SJohn Forte } 1605*291a2b48SSukumar Swaminathan 1606fcf3ce44SJohn Forte hba_event = &hba->hba_event; 1607fcf3ce44SJohn Forte max_events = *eventcount; 1608fcf3ce44SJohn Forte *eventcount = 0; 1609fcf3ce44SJohn Forte 1610fcf3ce44SJohn Forte log = &LOG; 1611fcf3ce44SJohn Forte 1612fcf3ce44SJohn Forte mutex_enter(&log->lock); 1613fcf3ce44SJohn Forte 1614fcf3ce44SJohn Forte /* Check if log is empty */ 1615fcf3ce44SJohn Forte if (log->count == 0) { 1616fcf3ce44SJohn Forte /* Make sure everything is initialized */ 1617fcf3ce44SJohn Forte hba_event->new = 0; 1618fcf3ce44SJohn Forte hba_event->missed = 0; 1619fcf3ce44SJohn Forte hba_event->last_id = 0; 1620fcf3ce44SJohn Forte 1621fcf3ce44SJohn Forte mutex_exit(&log->lock); 1622fcf3ce44SJohn Forte return (0); 1623fcf3ce44SJohn Forte } 1624*291a2b48SSukumar Swaminathan 1625fcf3ce44SJohn Forte /* Safety check */ 1626fcf3ce44SJohn Forte if (hba_event->last_id > (log->count - 1)) { 1627fcf3ce44SJohn Forte hba_event->last_id = log->count - 1; 1628fcf3ce44SJohn Forte } 1629*291a2b48SSukumar Swaminathan 1630fcf3ce44SJohn Forte /* Account for missed events */ 1631fcf3ce44SJohn Forte if (hba_event->new > hba_event->missed) { 1632fcf3ce44SJohn Forte hba_event->new -= hba_event->missed; 1633fcf3ce44SJohn Forte } else { 1634fcf3ce44SJohn Forte hba_event->new = 0; 1635fcf3ce44SJohn Forte } 1636fcf3ce44SJohn Forte 1637fcf3ce44SJohn Forte *missed = hba_event->missed; 1638fcf3ce44SJohn Forte hba_event->missed = 0; 1639fcf3ce44SJohn Forte 1640fcf3ce44SJohn Forte if (!hba_event->new) { 1641fcf3ce44SJohn Forte hba_event->last_id = log->count; 1642fcf3ce44SJohn Forte mutex_exit(&log->lock); 1643fcf3ce44SJohn Forte return (0); 1644fcf3ce44SJohn Forte } 1645*291a2b48SSukumar Swaminathan 1646fcf3ce44SJohn Forte /* A new event has occurred since last acquisition */ 1647fcf3ce44SJohn Forte /* Calculate the current buffer boundaries */ 1648fcf3ce44SJohn Forte 1649fcf3ce44SJohn Forte /* Get last entry id saved */ 1650fcf3ce44SJohn Forte last = log->count - 1; 1651fcf3ce44SJohn Forte 1652fcf3ce44SJohn Forte /* Get oldest entry id and its index */ 1653fcf3ce44SJohn Forte /* Check if buffer has already been filled once */ 1654fcf3ce44SJohn Forte if (log->count >= log->size) { 1655fcf3ce44SJohn Forte first = log->count - log->size; 1656fcf3ce44SJohn Forte index = log->next; 1657fcf3ce44SJohn Forte } else { /* Buffer not yet filled */ 1658*291a2b48SSukumar Swaminathan 1659fcf3ce44SJohn Forte first = 0; 1660fcf3ce44SJohn Forte index = 0; 1661fcf3ce44SJohn Forte } 1662fcf3ce44SJohn Forte 1663*291a2b48SSukumar Swaminathan /* Check if requested first event is greater than actual. */ 1664*291a2b48SSukumar Swaminathan /* If so, adjust for it. */ 1665fcf3ce44SJohn Forte if (hba_event->last_id > first) { 1666fcf3ce44SJohn Forte /* Adjust entry index to first requested message */ 1667fcf3ce44SJohn Forte index += (hba_event->last_id - first); 1668fcf3ce44SJohn Forte if (index >= log->size) { 1669fcf3ce44SJohn Forte index -= log->size; 1670fcf3ce44SJohn Forte } 1671*291a2b48SSukumar Swaminathan 1672fcf3ce44SJohn Forte first = hba_event->last_id; 1673fcf3ce44SJohn Forte } 1674*291a2b48SSukumar Swaminathan 1675fcf3ce44SJohn Forte /* Get the total number of new messages */ 1676fcf3ce44SJohn Forte count = last - first; 1677fcf3ce44SJohn Forte 1678fcf3ce44SJohn Forte /* Scan log for next event */ 1679fcf3ce44SJohn Forte events = 0; 1680fcf3ce44SJohn Forte while (count-- && (events < max_events)) { 1681fcf3ce44SJohn Forte if (++index >= log->size) { 1682fcf3ce44SJohn Forte index = 0; 1683fcf3ce44SJohn Forte } 1684*291a2b48SSukumar Swaminathan 1685fcf3ce44SJohn Forte entry = &log->entry[index]; 1686fcf3ce44SJohn Forte 1687fcf3ce44SJohn Forte if (!entry->msg) { 1688fcf3ce44SJohn Forte break; 1689fcf3ce44SJohn Forte } 1690*291a2b48SSukumar Swaminathan 1691fcf3ce44SJohn Forte if ((entry->msg->level == EMLXS_EVENT) && 1692fcf3ce44SJohn Forte (entry->msg->mask & (EVT_LINK | EVT_RSCN))) { 1693fcf3ce44SJohn Forte /* Process this event */ 1694fcf3ce44SJohn Forte switch (entry->msg->mask) { 1695fcf3ce44SJohn Forte case EVT_LINK: 1696fcf3ce44SJohn Forte byte = (uint8_t *)entry->bp; 1697fcf3ce44SJohn Forte linkspeed = byte[0]; 1698fcf3ce44SJohn Forte liptype = byte[1]; 1699*291a2b48SSukumar Swaminathan linkinfo = (dfc_linkinfo_t *)&byte[4]; 1700fcf3ce44SJohn Forte 1701fcf3ce44SJohn Forte if (linkinfo->a_linkState == LNK_DOWN) { 1702fcf3ce44SJohn Forte eventinfo->EventCode = 1703fcf3ce44SJohn Forte HBA_EVENT_LINK_DOWN; 1704fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1705fcf3ce44SJohn Forte PortFcId = linkinfo->a_DID; 1706fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1707fcf3ce44SJohn Forte Reserved[0] = 0; 1708fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1709fcf3ce44SJohn Forte Reserved[1] = 0; 1710fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1711fcf3ce44SJohn Forte Reserved[2] = 0; 1712fcf3ce44SJohn Forte } else { 1713fcf3ce44SJohn Forte eventinfo->EventCode = 1714fcf3ce44SJohn Forte HBA_EVENT_LINK_UP; 1715fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1716fcf3ce44SJohn Forte PortFcId = linkinfo->a_DID; 1717fcf3ce44SJohn Forte 1718fcf3ce44SJohn Forte if ((linkinfo->a_topology == 1719fcf3ce44SJohn Forte LNK_PUBLIC_LOOP) || 1720fcf3ce44SJohn Forte (linkinfo->a_topology == 1721fcf3ce44SJohn Forte LNK_LOOP)) { 1722*291a2b48SSukumar Swaminathan eventinfo->Event. 1723*291a2b48SSukumar Swaminathan Link_EventInfo. 1724fcf3ce44SJohn Forte Reserved[0] = 2; 1725fcf3ce44SJohn Forte } else { 1726*291a2b48SSukumar Swaminathan eventinfo->Event. 1727*291a2b48SSukumar Swaminathan Link_EventInfo. 1728fcf3ce44SJohn Forte Reserved[0] = 1; 1729fcf3ce44SJohn Forte } 1730fcf3ce44SJohn Forte 1731fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1732fcf3ce44SJohn Forte Reserved[1] = liptype; 1733fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1734fcf3ce44SJohn Forte Reserved[2] = linkspeed; 1735fcf3ce44SJohn Forte } 1736fcf3ce44SJohn Forte 1737fcf3ce44SJohn Forte break; 1738fcf3ce44SJohn Forte 1739fcf3ce44SJohn Forte case EVT_RSCN: 1740fcf3ce44SJohn Forte word = (uint32_t *)entry->bp; 1741fcf3ce44SJohn Forte eventinfo->EventCode = HBA_EVENT_RSCN; 1742fcf3ce44SJohn Forte eventinfo->Event.RSCN_EventInfo.PortFcId = 1743fcf3ce44SJohn Forte word[0] & 0xFFFFFF; 1744fcf3ce44SJohn Forte /* word[1] is the RSCN payload command */ 1745fcf3ce44SJohn Forte 1746*291a2b48SSukumar Swaminathan aid = (fc_affected_id_t *)&word[2]; 1747fcf3ce44SJohn Forte 1748fcf3ce44SJohn Forte switch (aid->aff_format) { 1749fcf3ce44SJohn Forte case 0: /* Port */ 1750fcf3ce44SJohn Forte eventinfo->Event.RSCN_EventInfo. 1751fcf3ce44SJohn Forte NPortPage = 1752fcf3ce44SJohn Forte aid->aff_d_id & 0x00ffffff; 1753fcf3ce44SJohn Forte break; 1754fcf3ce44SJohn Forte 1755fcf3ce44SJohn Forte case 1: /* Area */ 1756fcf3ce44SJohn Forte eventinfo->Event.RSCN_EventInfo. 1757fcf3ce44SJohn Forte NPortPage = 1758fcf3ce44SJohn Forte aid->aff_d_id & 0x00ffff00; 1759fcf3ce44SJohn Forte break; 1760fcf3ce44SJohn Forte 1761fcf3ce44SJohn Forte case 2: /* Domain */ 1762fcf3ce44SJohn Forte eventinfo->Event.RSCN_EventInfo. 1763fcf3ce44SJohn Forte NPortPage = 1764fcf3ce44SJohn Forte aid->aff_d_id & 0x00ff0000; 1765fcf3ce44SJohn Forte break; 1766fcf3ce44SJohn Forte 1767fcf3ce44SJohn Forte case 3: /* Network */ 1768fcf3ce44SJohn Forte eventinfo->Event.RSCN_EventInfo. 1769fcf3ce44SJohn Forte NPortPage = 0; 1770fcf3ce44SJohn Forte break; 1771fcf3ce44SJohn Forte } 1772fcf3ce44SJohn Forte 1773*291a2b48SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo.Reserved[0] = 1774*291a2b48SSukumar Swaminathan 0; 1775*291a2b48SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo.Reserved[1] = 1776*291a2b48SSukumar Swaminathan 0; 1777fcf3ce44SJohn Forte 1778fcf3ce44SJohn Forte break; 1779fcf3ce44SJohn Forte } 1780fcf3ce44SJohn Forte 1781fcf3ce44SJohn Forte eventinfo++; 1782fcf3ce44SJohn Forte events++; 1783fcf3ce44SJohn Forte } 1784*291a2b48SSukumar Swaminathan 1785fcf3ce44SJohn Forte hba_event->last_id = entry->id; 1786fcf3ce44SJohn Forte } 1787fcf3ce44SJohn Forte 1788fcf3ce44SJohn Forte /* Adjust new count */ 1789fcf3ce44SJohn Forte if (!count || (events >= hba_event->new)) { 1790fcf3ce44SJohn Forte hba_event->new = 0; 1791fcf3ce44SJohn Forte } else { 1792fcf3ce44SJohn Forte hba_event->new -= events; 1793fcf3ce44SJohn Forte } 1794fcf3ce44SJohn Forte 1795fcf3ce44SJohn Forte /* Return number of events acquired */ 1796fcf3ce44SJohn Forte *eventcount = events; 1797fcf3ce44SJohn Forte 1798fcf3ce44SJohn Forte mutex_exit(&log->lock); 1799fcf3ce44SJohn Forte 1800fcf3ce44SJohn Forte return (0); 1801fcf3ce44SJohn Forte 1802*291a2b48SSukumar Swaminathan } /* emlxs_get_dfc_eventinfo() */ 1803fcf3ce44SJohn Forte 1804fcf3ce44SJohn Forte 1805fcf3ce44SJohn Forte uint32_t 1806fcf3ce44SJohn Forte emlxs_get_dfc_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event, 1807fcf3ce44SJohn Forte uint32_t sleep) 1808fcf3ce44SJohn Forte { 1809fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1810fcf3ce44SJohn Forte emlxs_msg_log_t *log; 1811fcf3ce44SJohn Forte uint32_t first; 1812fcf3ce44SJohn Forte uint32_t last; 1813fcf3ce44SJohn Forte uint32_t count; 1814fcf3ce44SJohn Forte uint32_t index; 1815fcf3ce44SJohn Forte uint32_t mask; 1816fcf3ce44SJohn Forte uint32_t i; 1817fcf3ce44SJohn Forte emlxs_msg_entry_t *entry; 1818fcf3ce44SJohn Forte uint32_t size; 1819fcf3ce44SJohn Forte uint32_t rc; 1820fcf3ce44SJohn Forte 1821fcf3ce44SJohn Forte size = 0; 1822fcf3ce44SJohn Forte 1823fcf3ce44SJohn Forte if (dfc_event->dataout && dfc_event->size) { 1824fcf3ce44SJohn Forte size = dfc_event->size; 1825fcf3ce44SJohn Forte } 1826fcf3ce44SJohn Forte dfc_event->size = 0; 1827fcf3ce44SJohn Forte 1828fcf3ce44SJohn Forte /* Get the log file pointer */ 1829fcf3ce44SJohn Forte log = &LOG; 1830fcf3ce44SJohn Forte 1831fcf3ce44SJohn Forte /* Calculate the event index */ 1832fcf3ce44SJohn Forte mask = dfc_event->event; 1833fcf3ce44SJohn Forte for (i = 0; i < 32; i++) { 1834fcf3ce44SJohn Forte if (mask & 0x01) { 1835fcf3ce44SJohn Forte break; 1836fcf3ce44SJohn Forte } 1837*291a2b48SSukumar Swaminathan 1838fcf3ce44SJohn Forte mask >>= 1; 1839fcf3ce44SJohn Forte } 1840fcf3ce44SJohn Forte if (i == 32) { 1841fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 1842fcf3ce44SJohn Forte } 1843*291a2b48SSukumar Swaminathan 1844fcf3ce44SJohn Forte mutex_enter(&log->lock); 1845fcf3ce44SJohn Forte 1846fcf3ce44SJohn Forte /* Check if log is empty */ 1847fcf3ce44SJohn Forte if (log->count == 0) { 1848fcf3ce44SJohn Forte /* Make sure everything is initialized */ 1849fcf3ce44SJohn Forte log->event_id[i] = 0; 1850fcf3ce44SJohn Forte dfc_event->last_id = 0; 1851fcf3ce44SJohn Forte } else { 1852fcf3ce44SJohn Forte /* Check ranges for safety */ 1853fcf3ce44SJohn Forte if (log->event_id[i] > (log->count - 1)) { 1854fcf3ce44SJohn Forte log->event_id[i] = log->count - 1; 1855fcf3ce44SJohn Forte } 1856*291a2b48SSukumar Swaminathan 1857fcf3ce44SJohn Forte if (dfc_event->last_id > log->event_id[i]) { 1858fcf3ce44SJohn Forte dfc_event->last_id = log->event_id[i]; 1859fcf3ce44SJohn Forte } 1860fcf3ce44SJohn Forte } 1861fcf3ce44SJohn Forte 1862fcf3ce44SJohn Forte wait_for_event: 1863fcf3ce44SJohn Forte 1864fcf3ce44SJohn Forte /* Check if no new event has ocurred */ 1865fcf3ce44SJohn Forte if (dfc_event->last_id == log->event_id[i]) { 1866fcf3ce44SJohn Forte if (!sleep) { 1867fcf3ce44SJohn Forte mutex_exit(&log->lock); 1868fcf3ce44SJohn Forte return (0); 1869fcf3ce44SJohn Forte } 1870*291a2b48SSukumar Swaminathan 1871*291a2b48SSukumar Swaminathan /* While event is still active and */ 1872*291a2b48SSukumar Swaminathan /* no new event has been logged */ 1873fcf3ce44SJohn Forte while ((dfc_event->event & hba->log_events) && 1874fcf3ce44SJohn Forte (dfc_event->last_id == log->event_id[i])) { 1875fcf3ce44SJohn Forte rc = cv_wait_sig(&log->lock_cv, &log->lock); 1876fcf3ce44SJohn Forte 1877fcf3ce44SJohn Forte /* Check if thread was killed by kernel */ 1878fcf3ce44SJohn Forte if (rc == 0) { 1879fcf3ce44SJohn Forte dfc_event->pid = 0; 1880fcf3ce44SJohn Forte dfc_event->event = 0; 1881fcf3ce44SJohn Forte mutex_exit(&log->lock); 1882fcf3ce44SJohn Forte return (0); 1883fcf3ce44SJohn Forte } 1884fcf3ce44SJohn Forte } 1885fcf3ce44SJohn Forte 1886*291a2b48SSukumar Swaminathan /* If the event is no longer registered then */ 1887*291a2b48SSukumar Swaminathan /* return immediately */ 1888fcf3ce44SJohn Forte if (!(dfc_event->event & hba->log_events)) { 1889fcf3ce44SJohn Forte mutex_exit(&log->lock); 1890fcf3ce44SJohn Forte return (0); 1891fcf3ce44SJohn Forte } 1892fcf3ce44SJohn Forte } 1893*291a2b48SSukumar Swaminathan 1894fcf3ce44SJohn Forte /* !!! An event has occurred since last_id !!! */ 1895fcf3ce44SJohn Forte 1896fcf3ce44SJohn Forte /* Check if event data is not being requested */ 1897fcf3ce44SJohn Forte if (!size) { 1898fcf3ce44SJohn Forte /* If so, then just return the last event id */ 1899fcf3ce44SJohn Forte dfc_event->last_id = log->event_id[i]; 1900fcf3ce44SJohn Forte 1901fcf3ce44SJohn Forte mutex_exit(&log->lock); 1902fcf3ce44SJohn Forte return (0); 1903fcf3ce44SJohn Forte } 1904*291a2b48SSukumar Swaminathan 1905fcf3ce44SJohn Forte /* !!! The requester wants the next event buffer !!! */ 1906fcf3ce44SJohn Forte 1907fcf3ce44SJohn Forte /* Calculate the current buffer boundaries */ 1908fcf3ce44SJohn Forte 1909fcf3ce44SJohn Forte /* Get last entry id saved */ 1910fcf3ce44SJohn Forte last = log->count - 1; 1911fcf3ce44SJohn Forte 1912fcf3ce44SJohn Forte /* Get oldest entry id and its index */ 1913fcf3ce44SJohn Forte /* Check if buffer has already been filled once */ 1914fcf3ce44SJohn Forte if (log->count >= log->size) { 1915fcf3ce44SJohn Forte first = log->count - log->size; 1916fcf3ce44SJohn Forte index = log->next; 1917fcf3ce44SJohn Forte } else { /* Buffer not yet filled */ 1918*291a2b48SSukumar Swaminathan 1919fcf3ce44SJohn Forte first = 0; 1920fcf3ce44SJohn Forte index = 0; 1921fcf3ce44SJohn Forte } 1922fcf3ce44SJohn Forte 1923fcf3ce44SJohn Forte /* Check to see if the buffer has wrapped since the last event */ 1924fcf3ce44SJohn Forte if (first > log->event_id[i]) { 1925fcf3ce44SJohn Forte /* Update last_id to the last known event */ 1926fcf3ce44SJohn Forte dfc_event->last_id = log->event_id[i]; 1927fcf3ce44SJohn Forte 1928fcf3ce44SJohn Forte /* Try waiting again if we can */ 1929fcf3ce44SJohn Forte goto wait_for_event; 1930fcf3ce44SJohn Forte } 1931*291a2b48SSukumar Swaminathan 1932*291a2b48SSukumar Swaminathan /* Check if requested first event is greater than actual. */ 1933*291a2b48SSukumar Swaminathan /* If so, adjust for it. */ 1934fcf3ce44SJohn Forte if (dfc_event->last_id > first) { 1935fcf3ce44SJohn Forte /* Adjust entry index to first requested message */ 1936fcf3ce44SJohn Forte index += (dfc_event->last_id - first); 1937fcf3ce44SJohn Forte if (index >= log->size) { 1938fcf3ce44SJohn Forte index -= log->size; 1939fcf3ce44SJohn Forte } 1940*291a2b48SSukumar Swaminathan 1941fcf3ce44SJohn Forte first = dfc_event->last_id; 1942fcf3ce44SJohn Forte } 1943*291a2b48SSukumar Swaminathan 1944fcf3ce44SJohn Forte /* Get the total number of new messages */ 1945fcf3ce44SJohn Forte count = last - first + 1; 1946fcf3ce44SJohn Forte 1947fcf3ce44SJohn Forte /* Scan log for next event */ 1948fcf3ce44SJohn Forte while (count--) { 1949fcf3ce44SJohn Forte if (++index >= log->size) { 1950fcf3ce44SJohn Forte index = 0; 1951fcf3ce44SJohn Forte } 1952*291a2b48SSukumar Swaminathan 1953fcf3ce44SJohn Forte entry = &log->entry[index]; 1954fcf3ce44SJohn Forte 1955fcf3ce44SJohn Forte if ((entry->msg->level == EMLXS_EVENT) && 1956fcf3ce44SJohn Forte (entry->msg->mask == dfc_event->event)) { 1957fcf3ce44SJohn Forte break; 1958fcf3ce44SJohn Forte } 1959fcf3ce44SJohn Forte } 1960fcf3ce44SJohn Forte 1961*291a2b48SSukumar Swaminathan /* Check if no new event was found in the current log buffer */ 1962*291a2b48SSukumar Swaminathan /* This would indicate that the buffer wrapped since that last event */ 1963fcf3ce44SJohn Forte if (!count) { 1964fcf3ce44SJohn Forte /* Update last_id to the last known event */ 1965fcf3ce44SJohn Forte dfc_event->last_id = log->event_id[i]; 1966fcf3ce44SJohn Forte 1967fcf3ce44SJohn Forte /* Try waiting again if we can */ 1968fcf3ce44SJohn Forte goto wait_for_event; 1969fcf3ce44SJohn Forte } 1970*291a2b48SSukumar Swaminathan 1971fcf3ce44SJohn Forte /* !!! Next event found !!! */ 1972fcf3ce44SJohn Forte 1973fcf3ce44SJohn Forte /* Copy the context buffer to the buffer provided */ 1974fcf3ce44SJohn Forte if (entry->bp && entry->size) { 1975fcf3ce44SJohn Forte if (entry->size < size) { 1976fcf3ce44SJohn Forte size = entry->size; 1977fcf3ce44SJohn Forte } 1978*291a2b48SSukumar Swaminathan 1979*291a2b48SSukumar Swaminathan if (ddi_copyout((void *)entry->bp, dfc_event->dataout, size, 1980fcf3ce44SJohn Forte dfc_event->mode) != 0) { 1981fcf3ce44SJohn Forte mutex_exit(&log->lock); 1982fcf3ce44SJohn Forte 1983fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 1984fcf3ce44SJohn Forte } 1985*291a2b48SSukumar Swaminathan 1986*291a2b48SSukumar Swaminathan /* Data has been retrieved by the apps */ 1987*291a2b48SSukumar Swaminathan entry->flag |= EMLX_EVENT_DONE; 1988*291a2b48SSukumar Swaminathan 1989fcf3ce44SJohn Forte dfc_event->size = size; 1990fcf3ce44SJohn Forte } 1991*291a2b48SSukumar Swaminathan 1992fcf3ce44SJohn Forte dfc_event->last_id = entry->id; 1993fcf3ce44SJohn Forte 1994fcf3ce44SJohn Forte mutex_exit(&log->lock); 1995fcf3ce44SJohn Forte return (0); 1996fcf3ce44SJohn Forte 1997*291a2b48SSukumar Swaminathan } /* emlxs_get_dfc_event() */ 1998fcf3ce44SJohn Forte 1999fcf3ce44SJohn Forte 2000fcf3ce44SJohn Forte uint32_t 2001fcf3ce44SJohn Forte emlxs_kill_dfc_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event) 2002fcf3ce44SJohn Forte { 2003fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 2004fcf3ce44SJohn Forte emlxs_msg_log_t *log; 2005fcf3ce44SJohn Forte 2006fcf3ce44SJohn Forte /* Get the log file pointer */ 2007fcf3ce44SJohn Forte log = &LOG; 2008fcf3ce44SJohn Forte 2009fcf3ce44SJohn Forte mutex_enter(&log->lock); 2010fcf3ce44SJohn Forte dfc_event->pid = 0; 2011fcf3ce44SJohn Forte dfc_event->event = 0; 2012fcf3ce44SJohn Forte cv_broadcast(&log->lock_cv); 2013fcf3ce44SJohn Forte mutex_exit(&log->lock); 2014fcf3ce44SJohn Forte 2015fcf3ce44SJohn Forte return (0); 2016fcf3ce44SJohn Forte 2017*291a2b48SSukumar Swaminathan } /* emlxs_kill_dfc_event() */ 2018*291a2b48SSukumar Swaminathan 2019*291a2b48SSukumar Swaminathan 2020*291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 2021*291a2b48SSukumar Swaminathan uint32_t 2022*291a2b48SSukumar Swaminathan emlxs_get_sd_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event, 2023*291a2b48SSukumar Swaminathan uint32_t sleep) 2024*291a2b48SSukumar Swaminathan { 2025*291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA; 2026*291a2b48SSukumar Swaminathan emlxs_msg_log_t *log; 2027*291a2b48SSukumar Swaminathan emlxs_msg_entry_t *entry; 2028*291a2b48SSukumar Swaminathan uint32_t size; 2029*291a2b48SSukumar Swaminathan uint32_t rc; 2030*291a2b48SSukumar Swaminathan uint32_t first; 2031*291a2b48SSukumar Swaminathan uint32_t last; 2032*291a2b48SSukumar Swaminathan uint32_t count; 2033*291a2b48SSukumar Swaminathan uint32_t index; 2034*291a2b48SSukumar Swaminathan uint32_t mask; 2035*291a2b48SSukumar Swaminathan uint32_t i; 2036*291a2b48SSukumar Swaminathan 2037*291a2b48SSukumar Swaminathan size = 0; 2038*291a2b48SSukumar Swaminathan 2039*291a2b48SSukumar Swaminathan if (dfc_event->dataout && dfc_event->size) { 2040*291a2b48SSukumar Swaminathan size = dfc_event->size; 2041*291a2b48SSukumar Swaminathan } 2042*291a2b48SSukumar Swaminathan dfc_event->size = 0; 2043*291a2b48SSukumar Swaminathan 2044*291a2b48SSukumar Swaminathan /* Get the log file pointer */ 2045*291a2b48SSukumar Swaminathan log = &LOG; 2046*291a2b48SSukumar Swaminathan 2047*291a2b48SSukumar Swaminathan /* Calculate the event index */ 2048*291a2b48SSukumar Swaminathan mask = dfc_event->event; 2049*291a2b48SSukumar Swaminathan for (i = 0; i < 32; i++) { 2050*291a2b48SSukumar Swaminathan if (mask & 0x01) 2051*291a2b48SSukumar Swaminathan break; 2052*291a2b48SSukumar Swaminathan 2053*291a2b48SSukumar Swaminathan mask >>= 1; 2054*291a2b48SSukumar Swaminathan } 2055*291a2b48SSukumar Swaminathan if (i == 32) 2056*291a2b48SSukumar Swaminathan return (DFC_ARG_INVALID); 2057*291a2b48SSukumar Swaminathan 2058*291a2b48SSukumar Swaminathan mutex_enter(&log->lock); 2059fcf3ce44SJohn Forte 2060*291a2b48SSukumar Swaminathan /* Check if log is empty */ 2061*291a2b48SSukumar Swaminathan if (log->count == 0) { 2062*291a2b48SSukumar Swaminathan /* Make sure everything is initialized */ 2063*291a2b48SSukumar Swaminathan log->event_id[i] = 0; 2064*291a2b48SSukumar Swaminathan dfc_event->last_id = 0; 2065*291a2b48SSukumar Swaminathan } else { 2066*291a2b48SSukumar Swaminathan /* Check ranges for safety */ 2067*291a2b48SSukumar Swaminathan if (log->event_id[i] > (log->count - 1)) 2068*291a2b48SSukumar Swaminathan log->event_id[i] = log->count - 1; 2069*291a2b48SSukumar Swaminathan 2070*291a2b48SSukumar Swaminathan if (dfc_event->last_id > log->event_id[i]) 2071*291a2b48SSukumar Swaminathan dfc_event->last_id = log->event_id[i]; 2072*291a2b48SSukumar Swaminathan } 2073*291a2b48SSukumar Swaminathan 2074*291a2b48SSukumar Swaminathan wait_for_sd_event: 2075*291a2b48SSukumar Swaminathan /* Check if no new event has ocurred */ 2076*291a2b48SSukumar Swaminathan if (dfc_event->last_id == log->event_id[i]) { 2077*291a2b48SSukumar Swaminathan if (!sleep) { 2078*291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2079*291a2b48SSukumar Swaminathan return (0); 2080*291a2b48SSukumar Swaminathan } 2081*291a2b48SSukumar Swaminathan 2082*291a2b48SSukumar Swaminathan /* While event is active and no new event has been logged */ 2083*291a2b48SSukumar Swaminathan while ((dfc_event->event & port->sd_reg_events) && 2084*291a2b48SSukumar Swaminathan (dfc_event->last_id == log->event_id[i])) { 2085*291a2b48SSukumar Swaminathan rc = cv_wait_sig(&log->lock_cv, &log->lock); 2086*291a2b48SSukumar Swaminathan 2087*291a2b48SSukumar Swaminathan /* Check if thread was killed by kernel */ 2088*291a2b48SSukumar Swaminathan if (rc == 0) { 2089*291a2b48SSukumar Swaminathan dfc_event->pid = 0; 2090*291a2b48SSukumar Swaminathan dfc_event->event = 0; 2091*291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2092*291a2b48SSukumar Swaminathan return (0); 2093*291a2b48SSukumar Swaminathan } 2094*291a2b48SSukumar Swaminathan } 2095*291a2b48SSukumar Swaminathan 2096*291a2b48SSukumar Swaminathan /* If the event is no longer registered then return */ 2097*291a2b48SSukumar Swaminathan if (!(dfc_event->event & port->sd_reg_events)) { 2098*291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2099*291a2b48SSukumar Swaminathan return (0); 2100*291a2b48SSukumar Swaminathan } 2101*291a2b48SSukumar Swaminathan } 2102*291a2b48SSukumar Swaminathan 2103*291a2b48SSukumar Swaminathan /* !!! An event has occurred since last_id !!! */ 2104*291a2b48SSukumar Swaminathan 2105*291a2b48SSukumar Swaminathan /* Check if event data is not being requested */ 2106*291a2b48SSukumar Swaminathan if (!size) { 2107*291a2b48SSukumar Swaminathan /* If so, then just return the last event id */ 2108*291a2b48SSukumar Swaminathan dfc_event->last_id = log->event_id[i]; 2109*291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2110*291a2b48SSukumar Swaminathan return (0); 2111*291a2b48SSukumar Swaminathan } 2112*291a2b48SSukumar Swaminathan 2113*291a2b48SSukumar Swaminathan /* !!! The requester wants the next event buffer !!! */ 2114*291a2b48SSukumar Swaminathan 2115*291a2b48SSukumar Swaminathan /* Calculate the current buffer boundaries */ 2116*291a2b48SSukumar Swaminathan 2117*291a2b48SSukumar Swaminathan /* Get last entry id saved */ 2118*291a2b48SSukumar Swaminathan last = log->count - 1; 2119*291a2b48SSukumar Swaminathan 2120*291a2b48SSukumar Swaminathan /* Get oldest entry id and its index */ 2121*291a2b48SSukumar Swaminathan /* Check if buffer has already been filled once */ 2122*291a2b48SSukumar Swaminathan if (log->count >= log->size) { 2123*291a2b48SSukumar Swaminathan first = log->count - log->size; 2124*291a2b48SSukumar Swaminathan index = log->next; 2125*291a2b48SSukumar Swaminathan } else { /* Buffer not yet filled */ 2126*291a2b48SSukumar Swaminathan first = 0; 2127*291a2b48SSukumar Swaminathan index = 0; 2128*291a2b48SSukumar Swaminathan } 2129*291a2b48SSukumar Swaminathan 2130*291a2b48SSukumar Swaminathan /* Check to see if the buffer has wrapped since the last event */ 2131*291a2b48SSukumar Swaminathan if (first > log->event_id[i]) { 2132*291a2b48SSukumar Swaminathan /* Update last_id to the last known event */ 2133*291a2b48SSukumar Swaminathan dfc_event->last_id = log->event_id[i]; 2134*291a2b48SSukumar Swaminathan 2135*291a2b48SSukumar Swaminathan /* Try waiting again if we can */ 2136*291a2b48SSukumar Swaminathan goto wait_for_sd_event; 2137*291a2b48SSukumar Swaminathan } 2138*291a2b48SSukumar Swaminathan 2139*291a2b48SSukumar Swaminathan /* if requested first event is greater than actual, adjust for it. */ 2140*291a2b48SSukumar Swaminathan if (dfc_event->last_id > first) { 2141*291a2b48SSukumar Swaminathan /* Adjust entry index to first requested message */ 2142*291a2b48SSukumar Swaminathan index += (dfc_event->last_id - first); 2143*291a2b48SSukumar Swaminathan if (index >= log->size) { 2144*291a2b48SSukumar Swaminathan index -= log->size; 2145*291a2b48SSukumar Swaminathan } 2146*291a2b48SSukumar Swaminathan 2147*291a2b48SSukumar Swaminathan first = dfc_event->last_id; 2148*291a2b48SSukumar Swaminathan } 2149*291a2b48SSukumar Swaminathan 2150*291a2b48SSukumar Swaminathan /* Get the total number of new messages */ 2151*291a2b48SSukumar Swaminathan count = last - first + 1; 2152*291a2b48SSukumar Swaminathan 2153*291a2b48SSukumar Swaminathan /* Scan log for next event */ 2154*291a2b48SSukumar Swaminathan while (count--) { 2155*291a2b48SSukumar Swaminathan if (++index >= log->size) 2156*291a2b48SSukumar Swaminathan index = 0; 2157*291a2b48SSukumar Swaminathan 2158*291a2b48SSukumar Swaminathan entry = &log->entry[index]; 2159*291a2b48SSukumar Swaminathan 2160*291a2b48SSukumar Swaminathan if ((entry->msg->level == EMLXS_EVENT) && 2161*291a2b48SSukumar Swaminathan (entry->vpi == port->vpi) && 2162*291a2b48SSukumar Swaminathan (entry->msg->mask == dfc_event->event)) 2163*291a2b48SSukumar Swaminathan break; 2164*291a2b48SSukumar Swaminathan } 2165*291a2b48SSukumar Swaminathan 2166*291a2b48SSukumar Swaminathan /* Check if no new event was found in the current log buffer */ 2167*291a2b48SSukumar Swaminathan /* This would indicate that the buffer wrapped since that last event */ 2168*291a2b48SSukumar Swaminathan if (!count) { 2169*291a2b48SSukumar Swaminathan /* Update last_id to the last known event */ 2170*291a2b48SSukumar Swaminathan dfc_event->last_id = log->event_id[i]; 2171*291a2b48SSukumar Swaminathan 2172*291a2b48SSukumar Swaminathan /* Try waiting again if we can */ 2173*291a2b48SSukumar Swaminathan goto wait_for_sd_event; 2174*291a2b48SSukumar Swaminathan } 2175*291a2b48SSukumar Swaminathan 2176*291a2b48SSukumar Swaminathan /* !!! Next event found !!! */ 2177*291a2b48SSukumar Swaminathan 2178*291a2b48SSukumar Swaminathan /* Copy the context buffer to the buffer provided */ 2179*291a2b48SSukumar Swaminathan if (entry->bp && entry->size) { 2180*291a2b48SSukumar Swaminathan if (entry->size < size) 2181*291a2b48SSukumar Swaminathan size = entry->size; 2182*291a2b48SSukumar Swaminathan 2183*291a2b48SSukumar Swaminathan if (ddi_copyout((void *) entry->bp, dfc_event->dataout, 2184*291a2b48SSukumar Swaminathan size, dfc_event->mode) != 0) { 2185*291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2186*291a2b48SSukumar Swaminathan 2187*291a2b48SSukumar Swaminathan return (DFC_COPYOUT_ERROR); 2188*291a2b48SSukumar Swaminathan } 2189*291a2b48SSukumar Swaminathan 2190*291a2b48SSukumar Swaminathan dfc_event->size = size; 2191*291a2b48SSukumar Swaminathan } 2192*291a2b48SSukumar Swaminathan 2193*291a2b48SSukumar Swaminathan dfc_event->last_id = entry->id; 2194*291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2195*291a2b48SSukumar Swaminathan 2196*291a2b48SSukumar Swaminathan return (0); 2197*291a2b48SSukumar Swaminathan } /* emlxs_get_sd_event */ 2198*291a2b48SSukumar Swaminathan #endif /* SAN_DIAG_SUPPORT */ 2199fcf3ce44SJohn Forte 2200fcf3ce44SJohn Forte 2201*291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 2202