1fcf3ce44SJohn Forte /* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte 22fcf3ce44SJohn Forte /* 23291a2b48SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24fcf3ce44SJohn Forte * Use is subject to License terms. 25fcf3ce44SJohn Forte */ 26fcf3ce44SJohn Forte 27291a2b48SSukumar Swaminathan #define DEF_MSG_STRUCT /* Needed for emlxs_messages.h in emlxs_msg.h */ 28291a2b48SSukumar 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 34291a2b48SSukumar Swaminathan uint32_t emlxs_log_size = 2048; 35291a2b48SSukumar Swaminathan uint32_t emlxs_log_debugs = 0x7FFFFFFF; 36291a2b48SSukumar Swaminathan uint32_t emlxs_log_notices = 0xFFFFFFFF; 37291a2b48SSukumar Swaminathan uint32_t emlxs_log_warnings = 0xFFFFFFFF; 38291a2b48SSukumar Swaminathan uint32_t emlxs_log_errors = 0xFFFFFFFF; 39fcf3ce44SJohn Forte 40291a2b48SSukumar Swaminathan static uint32_t emlxs_msg_log_check(emlxs_port_t *port, emlxs_msg_t *msg); 41291a2b48SSukumar Swaminathan static uint32_t emlxs_msg_print_check(emlxs_port_t *port, emlxs_msg_t *msg); 42291a2b48SSukumar 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; 56291a2b48SSukumar 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", 62291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, (void *)log); 63fcf3ce44SJohn Forte return (0); 64fcf3ce44SJohn Forte } 65291a2b48SSukumar 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))) { 71291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 72291a2b48SSukumar Swaminathan "?%s%d: Unable to allocate log memory. log=%p", 73291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, (void *)log); 74fcf3ce44SJohn Forte return (0); 75fcf3ce44SJohn Forte } 76291a2b48SSukumar 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 */ 94291a2b48SSukumar 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; 100291a2b48SSukumar Swaminathan ret = 101291a2b48SSukumar 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) { 105291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 106291a2b48SSukumar Swaminathan "?%s%d: Unable to allocate temporary interrupt " 107291a2b48SSukumar Swaminathan "handle. ret=%d actual=%d", DRIVER_NAME, 108291a2b48SSukumar 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 } 116291a2b48SSukumar 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) { 121291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 122291a2b48SSukumar Swaminathan "?%s%d: Unable to get interrupt priority. ret=%d", 123291a2b48SSukumar 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 } 131291a2b48SSukumar Swaminathan 132fcf3ce44SJohn Forte /* Create the log mutex lock */ 133fcf3ce44SJohn Forte mutex_init(&log->lock, buf, MUTEX_DRIVER, 134291a2b48SSukumar 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 143291a2b48SSukumar 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) { 156291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 157291a2b48SSukumar Swaminathan "?%s%d: message log already destroyed. log=%p", 158291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, (void *)log); 159fcf3ce44SJohn Forte 160fcf3ce44SJohn Forte return (1); 161fcf3ce44SJohn Forte } 162291a2b48SSukumar Swaminathan 163291a2b48SSukumar Swaminathan /* If events are being logged there might be */ 164291a2b48SSukumar 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 } 173291a2b48SSukumar 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 196291a2b48SSukumar Swaminathan } /* emlxs_msg_log_destroy() */ 197291a2b48SSukumar Swaminathan 198fcf3ce44SJohn Forte 199fcf3ce44SJohn Forte uint32_t 200fcf3ce44SJohn Forte emlxs_msg_log(emlxs_port_t *port, const uint32_t fileno, const uint32_t line, 201fcf3ce44SJohn Forte void *bp, uint32_t size, emlxs_msg_t *msg, char *buffer) 202fcf3ce44SJohn Forte { 203fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 204fcf3ce44SJohn Forte emlxs_msg_entry_t *entry; 205fcf3ce44SJohn Forte emlxs_msg_entry_t *entry2; 206fcf3ce44SJohn Forte clock_t time; 207fcf3ce44SJohn Forte emlxs_msg_log_t *log; 208fcf3ce44SJohn Forte uint32_t last; 209fcf3ce44SJohn Forte uint32_t mask; 210fcf3ce44SJohn Forte emlxs_msg_t *msg2; 211291a2b48SSukumar Swaminathan uint32_t rxid = 0; 212fcf3ce44SJohn Forte uint32_t i; 213fcf3ce44SJohn Forte 214fcf3ce44SJohn Forte /* Get the log file for this instance */ 215fcf3ce44SJohn Forte log = &LOG; 216fcf3ce44SJohn Forte 217fcf3ce44SJohn Forte /* Check if log is initialized */ 218fcf3ce44SJohn Forte if (log->entry == NULL) { 219fcf3ce44SJohn Forte 220fcf3ce44SJohn Forte if (port->vpi == 0) { 221291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 222291a2b48SSukumar Swaminathan "?%s%d: message log not created. log=%p", 223291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, (void *)log); 224fcf3ce44SJohn Forte } else { 225291a2b48SSukumar Swaminathan cmn_err(CE_WARN, 226291a2b48SSukumar Swaminathan "?%s%d.%d: message log not created. log=%p", 227291a2b48SSukumar Swaminathan DRIVER_NAME, hba->ddiinst, port->vpi, 228291a2b48SSukumar Swaminathan (void *)log); 229fcf3ce44SJohn Forte } 230fcf3ce44SJohn Forte 231fcf3ce44SJohn Forte if (bp && size) { 232fcf3ce44SJohn Forte kmem_free(bp, size); 233fcf3ce44SJohn Forte } 234291a2b48SSukumar Swaminathan 235fcf3ce44SJohn Forte return (1); 236fcf3ce44SJohn Forte } 237291a2b48SSukumar Swaminathan 238fcf3ce44SJohn Forte mutex_enter(&log->lock); 239fcf3ce44SJohn Forte 240fcf3ce44SJohn Forte /* Get the pointer to the last log entry */ 241fcf3ce44SJohn Forte if (log->next == 0) { 242fcf3ce44SJohn Forte last = log->size - 1; 243fcf3ce44SJohn Forte } else { 244fcf3ce44SJohn Forte last = log->next - 1; 245fcf3ce44SJohn Forte } 246fcf3ce44SJohn Forte entry = &log->entry[last]; 247fcf3ce44SJohn Forte 248fcf3ce44SJohn Forte /* Check if this matches the last message */ 249fcf3ce44SJohn Forte if ((entry->instance == log->instance) && 250fcf3ce44SJohn Forte (entry->vpi == port->vpi) && 251fcf3ce44SJohn Forte (entry->fileno == fileno) && 252fcf3ce44SJohn Forte (entry->line == line) && 253fcf3ce44SJohn Forte (entry->bp == bp) && 254fcf3ce44SJohn Forte (entry->size == size) && 255fcf3ce44SJohn Forte (entry->msg == msg) && 256fcf3ce44SJohn Forte (strcmp(entry->buffer, buffer) == 0)) { 257fcf3ce44SJohn Forte /* If the same message is being logged then increment */ 258fcf3ce44SJohn Forte log->repeat++; 259fcf3ce44SJohn Forte 260fcf3ce44SJohn Forte mutex_exit(&log->lock); 261fcf3ce44SJohn Forte 262fcf3ce44SJohn Forte return (0); 263fcf3ce44SJohn Forte } else if (log->repeat) { 264fcf3ce44SJohn Forte /* Get the pointer to the next log entry */ 265fcf3ce44SJohn Forte entry2 = &log->entry[log->next]; 266fcf3ce44SJohn Forte 267fcf3ce44SJohn Forte /* Increment and check the next entry index */ 268fcf3ce44SJohn Forte if (++(log->next) >= log->size) { 269fcf3ce44SJohn Forte log->next = 0; 270fcf3ce44SJohn Forte } 271291a2b48SSukumar Swaminathan 272fcf3ce44SJohn Forte switch (entry->msg->level) { 273fcf3ce44SJohn Forte case EMLXS_DEBUG: 274fcf3ce44SJohn Forte msg2 = &emlxs_debug_msg; 275fcf3ce44SJohn Forte break; 276fcf3ce44SJohn Forte 277fcf3ce44SJohn Forte case EMLXS_NOTICE: 278fcf3ce44SJohn Forte msg2 = &emlxs_notice_msg; 279fcf3ce44SJohn Forte break; 280fcf3ce44SJohn Forte 281fcf3ce44SJohn Forte case EMLXS_WARNING: 282fcf3ce44SJohn Forte msg2 = &emlxs_warning_msg; 283fcf3ce44SJohn Forte break; 284fcf3ce44SJohn Forte 285fcf3ce44SJohn Forte case EMLXS_ERROR: 286fcf3ce44SJohn Forte msg2 = &emlxs_error_msg; 287fcf3ce44SJohn Forte break; 288fcf3ce44SJohn Forte 289fcf3ce44SJohn Forte case EMLXS_PANIC: 290fcf3ce44SJohn Forte msg2 = &emlxs_panic_msg; 291fcf3ce44SJohn Forte break; 292fcf3ce44SJohn Forte 293fcf3ce44SJohn Forte case EMLXS_EVENT: 294fcf3ce44SJohn Forte msg2 = &emlxs_event_msg; 295fcf3ce44SJohn Forte break; 296fcf3ce44SJohn Forte } 297fcf3ce44SJohn Forte 298fcf3ce44SJohn Forte /* Check if we are about to overwrite an event entry */ 299fcf3ce44SJohn Forte if (entry2->msg && (entry2->msg->level == EMLXS_EVENT)) { 300fcf3ce44SJohn Forte /* Check if this event has not been acquired */ 301fcf3ce44SJohn Forte if (log->count > (hba->hba_event.last_id + log->size)) { 302fcf3ce44SJohn Forte hba->hba_event.missed++; 303728bdc9bSSukumar Swaminathan 304291a2b48SSukumar Swaminathan if ((entry2->msg->mask == EVT_CT) && 305291a2b48SSukumar Swaminathan !(entry2->flag & EMLX_EVENT_DONE)) { 306728bdc9bSSukumar Swaminathan /* Abort exchange */ 307728bdc9bSSukumar Swaminathan rxid = *((uint32_t *)entry2->bp); 308728bdc9bSSukumar Swaminathan } 309fcf3ce44SJohn Forte } 310fcf3ce44SJohn Forte } 311291a2b48SSukumar Swaminathan 312fcf3ce44SJohn Forte /* Free the old context buffer since we are about to erase it */ 313fcf3ce44SJohn Forte if (entry2->bp && entry2->size) { 314fcf3ce44SJohn Forte kmem_free(entry2->bp, entry2->size); 315fcf3ce44SJohn Forte } 316291a2b48SSukumar Swaminathan 317fcf3ce44SJohn Forte /* Initialize */ 318fcf3ce44SJohn Forte entry2->id = log->count++; 319fcf3ce44SJohn Forte entry2->fileno = entry->fileno; 320fcf3ce44SJohn Forte entry2->line = entry->line; 321fcf3ce44SJohn Forte entry2->bp = 0; 322fcf3ce44SJohn Forte entry2->size = 0; 323fcf3ce44SJohn Forte entry2->msg = msg2; 324fcf3ce44SJohn Forte entry2->instance = log->instance; 325fcf3ce44SJohn Forte entry2->vpi = port->vpi; 326291a2b48SSukumar Swaminathan entry2->flag = 0; 327fcf3ce44SJohn Forte 328fcf3ce44SJohn Forte /* Save the additional info buffer */ 329fcf3ce44SJohn Forte (void) sprintf(entry2->buffer, 330fcf3ce44SJohn Forte "Last message repeated %d time(s).", 331fcf3ce44SJohn Forte log->repeat); 332fcf3ce44SJohn Forte 333fcf3ce44SJohn Forte /* Set the entry time stamp */ 334fcf3ce44SJohn Forte (void) drv_getparm(LBOLT, &time); 335fcf3ce44SJohn Forte entry2->time = time - log->start_time; 336fcf3ce44SJohn Forte 337fcf3ce44SJohn Forte log->repeat = 0; 338fcf3ce44SJohn Forte } 339291a2b48SSukumar Swaminathan 340fcf3ce44SJohn Forte /* Get the pointer to the next log entry */ 341fcf3ce44SJohn Forte entry = &log->entry[log->next]; 342fcf3ce44SJohn Forte 343fcf3ce44SJohn Forte /* Increment and check the next entry index */ 344fcf3ce44SJohn Forte if (++(log->next) >= log->size) { 345fcf3ce44SJohn Forte log->next = 0; 346fcf3ce44SJohn Forte } 347291a2b48SSukumar Swaminathan 348fcf3ce44SJohn Forte /* Check if we are about to overwrite an event entry */ 349fcf3ce44SJohn Forte if (entry->msg && (entry->msg->level == EMLXS_EVENT)) { 350fcf3ce44SJohn Forte /* Check if this event has not been acquired */ 351fcf3ce44SJohn Forte if (log->count > (hba->hba_event.last_id + log->size)) { 352fcf3ce44SJohn Forte hba->hba_event.missed++; 353728bdc9bSSukumar Swaminathan 354291a2b48SSukumar Swaminathan if ((entry->msg->mask == EVT_CT) && 355291a2b48SSukumar Swaminathan !(entry->flag & EMLX_EVENT_DONE)) { 356291a2b48SSukumar Swaminathan 357728bdc9bSSukumar Swaminathan /* Abort exchange */ 358728bdc9bSSukumar Swaminathan rxid = *((uint32_t *)entry->bp); 359728bdc9bSSukumar Swaminathan } 360fcf3ce44SJohn Forte } 361fcf3ce44SJohn Forte } 362291a2b48SSukumar Swaminathan 363fcf3ce44SJohn Forte /* Free the old context buffer since we are about to erase it */ 364fcf3ce44SJohn Forte if (entry->bp && entry->size) { 365fcf3ce44SJohn Forte kmem_free(entry->bp, entry->size); 366fcf3ce44SJohn Forte } 367291a2b48SSukumar Swaminathan 368fcf3ce44SJohn Forte /* Initialize */ 369fcf3ce44SJohn Forte entry->id = log->count++; 370fcf3ce44SJohn Forte entry->fileno = fileno; 371fcf3ce44SJohn Forte entry->line = line; 372fcf3ce44SJohn Forte entry->bp = bp; 373fcf3ce44SJohn Forte entry->size = size; 374fcf3ce44SJohn Forte entry->msg = msg; 375fcf3ce44SJohn Forte entry->instance = log->instance; 376fcf3ce44SJohn Forte entry->vpi = port->vpi; 377291a2b48SSukumar Swaminathan entry->flag = 0; 378fcf3ce44SJohn Forte 379fcf3ce44SJohn Forte /* Save the additional info buffer */ 380fcf3ce44SJohn Forte (void) strncpy(entry->buffer, buffer, (MAX_LOG_INFO_LENGTH - 1)); 381fcf3ce44SJohn Forte entry->buffer[MAX_LOG_INFO_LENGTH - 1] = 0; 382fcf3ce44SJohn Forte 383fcf3ce44SJohn Forte /* Set the entry time stamp */ 384fcf3ce44SJohn Forte (void) drv_getparm(LBOLT, &time); 385fcf3ce44SJohn Forte entry->time = time - log->start_time; 386fcf3ce44SJohn Forte 387fcf3ce44SJohn Forte /* Check for a new event */ 388fcf3ce44SJohn Forte if (msg->level == EMLXS_EVENT) { 389fcf3ce44SJohn Forte /* Update the event id */ 390fcf3ce44SJohn Forte mask = msg->mask; 391fcf3ce44SJohn Forte for (i = 0; i < 32; i++) { 392fcf3ce44SJohn Forte if (mask & 0x01) { 393fcf3ce44SJohn Forte hba->hba_event.new++; 394fcf3ce44SJohn Forte log->event_id[i] = entry->id; 395fcf3ce44SJohn Forte cv_broadcast(&log->lock_cv); 396fcf3ce44SJohn Forte break; 397fcf3ce44SJohn Forte } 398291a2b48SSukumar Swaminathan 399fcf3ce44SJohn Forte mask >>= 1; 400fcf3ce44SJohn Forte } 401fcf3ce44SJohn Forte } 402291a2b48SSukumar Swaminathan 403fcf3ce44SJohn Forte mutex_exit(&log->lock); 404fcf3ce44SJohn Forte 405291a2b48SSukumar Swaminathan if (rxid) { 406*bb63f56eSSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_abort_ct_exchange, 407*bb63f56eSSukumar Swaminathan (void *)port, (void *)((unsigned long)rxid)); 408291a2b48SSukumar Swaminathan } 409291a2b48SSukumar Swaminathan 410fcf3ce44SJohn Forte return (0); 411fcf3ce44SJohn Forte 412291a2b48SSukumar Swaminathan } /* emlxs_msg_log() */ 413fcf3ce44SJohn Forte 414fcf3ce44SJohn Forte 415fcf3ce44SJohn Forte static uint32_t 416fcf3ce44SJohn Forte emlxs_msg_log_check(emlxs_port_t *port, emlxs_msg_t *msg) 417fcf3ce44SJohn Forte { 418fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 419fcf3ce44SJohn Forte 420fcf3ce44SJohn Forte switch (msg->level) { 421fcf3ce44SJohn Forte case EMLXS_DEBUG: 422fcf3ce44SJohn Forte if (msg->mask & emlxs_log_debugs) { 423fcf3ce44SJohn Forte return (1); 424fcf3ce44SJohn Forte } 425fcf3ce44SJohn Forte break; 426fcf3ce44SJohn Forte 427fcf3ce44SJohn Forte case EMLXS_NOTICE: 428fcf3ce44SJohn Forte if (msg->mask & emlxs_log_notices) { 429fcf3ce44SJohn Forte return (1); 430fcf3ce44SJohn Forte } 431fcf3ce44SJohn Forte break; 432fcf3ce44SJohn Forte 433fcf3ce44SJohn Forte case EMLXS_WARNING: 434fcf3ce44SJohn Forte if (msg->mask & emlxs_log_warnings) { 435fcf3ce44SJohn Forte return (1); 436fcf3ce44SJohn Forte } 437fcf3ce44SJohn Forte break; 438fcf3ce44SJohn Forte 439fcf3ce44SJohn Forte case EMLXS_ERROR: 440fcf3ce44SJohn Forte if (msg->mask & emlxs_log_errors) { 441fcf3ce44SJohn Forte return (1); 442fcf3ce44SJohn Forte } 443fcf3ce44SJohn Forte break; 444fcf3ce44SJohn Forte 445fcf3ce44SJohn Forte case EMLXS_EVENT: 446fcf3ce44SJohn Forte if (msg->mask & hba->log_events) { 447fcf3ce44SJohn Forte return (1); 448fcf3ce44SJohn Forte } 449291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 450291a2b48SSukumar Swaminathan if (msg->mask & port->sd_reg_events) { 451291a2b48SSukumar Swaminathan return (1); 452291a2b48SSukumar Swaminathan } 453291a2b48SSukumar Swaminathan #endif /* SAN_DIAG_SUPPORT */ 454fcf3ce44SJohn Forte break; 455fcf3ce44SJohn Forte 456fcf3ce44SJohn Forte case EMLXS_PANIC: 457fcf3ce44SJohn Forte return (1); 458fcf3ce44SJohn Forte } 459fcf3ce44SJohn Forte 460fcf3ce44SJohn Forte return (0); 461fcf3ce44SJohn Forte 462291a2b48SSukumar Swaminathan } /* emlxs_msg_log_check() */ 463fcf3ce44SJohn Forte 464fcf3ce44SJohn Forte 465fcf3ce44SJohn Forte static uint32_t 466fcf3ce44SJohn Forte emlxs_msg_print_check(emlxs_port_t *port, emlxs_msg_t *msg) 467fcf3ce44SJohn Forte { 468fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 469fcf3ce44SJohn Forte emlxs_config_t *cfg; 470fcf3ce44SJohn Forte uint32_t rval = 0; 471fcf3ce44SJohn Forte 472fcf3ce44SJohn Forte cfg = &CFG; 473fcf3ce44SJohn Forte 474fcf3ce44SJohn Forte switch (msg->level) { 475fcf3ce44SJohn Forte case EMLXS_DEBUG: 476fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_CONSOLE_DEBUGS].current) { 477fcf3ce44SJohn Forte rval |= 2; 478fcf3ce44SJohn Forte } 479291a2b48SSukumar Swaminathan 480fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_LOG_DEBUGS].current) { 481fcf3ce44SJohn Forte rval |= 1; 482fcf3ce44SJohn Forte } 483291a2b48SSukumar Swaminathan 484fcf3ce44SJohn Forte break; 485fcf3ce44SJohn Forte 486fcf3ce44SJohn Forte case EMLXS_NOTICE: 487fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_CONSOLE_NOTICES].current) { 488fcf3ce44SJohn Forte rval |= 2; 489fcf3ce44SJohn Forte } 490291a2b48SSukumar Swaminathan 491fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_LOG_NOTICES].current) { 492fcf3ce44SJohn Forte rval |= 1; 493fcf3ce44SJohn Forte } 494291a2b48SSukumar Swaminathan 495fcf3ce44SJohn Forte break; 496fcf3ce44SJohn Forte 497fcf3ce44SJohn Forte case EMLXS_WARNING: 498fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_CONSOLE_WARNINGS].current) { 499fcf3ce44SJohn Forte rval |= 2; 500fcf3ce44SJohn Forte } 501291a2b48SSukumar Swaminathan 502fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_LOG_WARNINGS].current) { 503fcf3ce44SJohn Forte rval |= 1; 504fcf3ce44SJohn Forte } 505291a2b48SSukumar Swaminathan 506fcf3ce44SJohn Forte break; 507fcf3ce44SJohn Forte 508fcf3ce44SJohn Forte case EMLXS_ERROR: 509fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_CONSOLE_ERRORS].current) { 510fcf3ce44SJohn Forte rval |= 2; 511fcf3ce44SJohn Forte } 512291a2b48SSukumar Swaminathan 513fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_LOG_ERRORS].current) { 514fcf3ce44SJohn Forte rval |= 1; 515fcf3ce44SJohn Forte } 516fcf3ce44SJohn Forte break; 517fcf3ce44SJohn Forte 518fcf3ce44SJohn Forte case EMLXS_EVENT: 519fcf3ce44SJohn Forte /* Only print an event if it is being logged internally */ 520fcf3ce44SJohn Forte if (msg->mask & hba->log_events) { 521fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_CONSOLE_EVENTS].current) { 522fcf3ce44SJohn Forte rval |= 2; 523fcf3ce44SJohn Forte } 524291a2b48SSukumar Swaminathan 525fcf3ce44SJohn Forte if (msg->mask & cfg[CFG_LOG_EVENTS].current) { 526fcf3ce44SJohn Forte rval |= 1; 527fcf3ce44SJohn Forte } 528fcf3ce44SJohn Forte } 529fcf3ce44SJohn Forte break; 530fcf3ce44SJohn Forte 531fcf3ce44SJohn Forte case EMLXS_PANIC: 532fcf3ce44SJohn Forte default: 533fcf3ce44SJohn Forte rval |= 1; 534fcf3ce44SJohn Forte 535fcf3ce44SJohn Forte } 536fcf3ce44SJohn Forte 537fcf3ce44SJohn Forte return (rval); 538fcf3ce44SJohn Forte 539291a2b48SSukumar Swaminathan } /* emlxs_msg_print_check() */ 540fcf3ce44SJohn Forte 541fcf3ce44SJohn Forte 542fcf3ce44SJohn Forte void 543291a2b48SSukumar Swaminathan emlxs_msg_printf(emlxs_port_t *port, const uint32_t fileno, 544291a2b48SSukumar Swaminathan const uint32_t line, void *bp, uint32_t size, emlxs_msg_t *msg, 545291a2b48SSukumar Swaminathan const char *fmt, ...) 546fcf3ce44SJohn Forte { 547fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 548fcf3ce44SJohn Forte va_list valist; 549fcf3ce44SJohn Forte char va_str[256]; 550fcf3ce44SJohn Forte char msg_str[512]; 551fcf3ce44SJohn Forte char *level; 552fcf3ce44SJohn Forte int32_t cmn_level; 553fcf3ce44SJohn Forte uint32_t rval; 554fcf3ce44SJohn Forte uint32_t logged; 555fcf3ce44SJohn Forte char driver[32]; 556fcf3ce44SJohn Forte 557fcf3ce44SJohn Forte va_str[0] = 0; 558fcf3ce44SJohn Forte 559fcf3ce44SJohn Forte if (fmt) { 560fcf3ce44SJohn Forte va_start(valist, fmt); 561fcf3ce44SJohn Forte (void) vsprintf(va_str, fmt, valist); 562fcf3ce44SJohn Forte va_end(valist); 563fcf3ce44SJohn Forte } 564291a2b48SSukumar Swaminathan 565291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT 566291a2b48SSukumar Swaminathan /* 567291a2b48SSukumar Swaminathan * Don't post fault event or/and error event to fmd 568291a2b48SSukumar Swaminathan * if physical port was not bounded yet. 569291a2b48SSukumar Swaminathan */ 570*bb63f56eSSukumar Swaminathan if (msg->fm_ereport_code) { 571*bb63f56eSSukumar Swaminathan emlxs_fm_ereport(hba, msg->fm_ereport_code); 572*bb63f56eSSukumar Swaminathan } 573291a2b48SSukumar Swaminathan 574*bb63f56eSSukumar Swaminathan if (msg->fm_impact_code) { 575*bb63f56eSSukumar Swaminathan emlxs_fm_service_impact(hba, msg->fm_impact_code); 576291a2b48SSukumar Swaminathan } 577291a2b48SSukumar Swaminathan #endif /* FMA_SUPPORT */ 578291a2b48SSukumar Swaminathan 579fcf3ce44SJohn Forte /* Check if msg should be logged */ 580fcf3ce44SJohn Forte if ((logged = emlxs_msg_log_check(port, msg))) { 581fcf3ce44SJohn Forte /* Log the message */ 582fcf3ce44SJohn Forte if (emlxs_msg_log(port, fileno, line, bp, size, msg, va_str)) { 583fcf3ce44SJohn Forte return; 584fcf3ce44SJohn Forte } 585fcf3ce44SJohn Forte } 586291a2b48SSukumar Swaminathan 587fcf3ce44SJohn Forte /* Check if msg should be printed */ 588fcf3ce44SJohn Forte if (rval = emlxs_msg_print_check(port, msg)) { 589fcf3ce44SJohn Forte cmn_level = CE_CONT; 590fcf3ce44SJohn Forte 591fcf3ce44SJohn Forte switch (msg->level) { 592fcf3ce44SJohn Forte case EMLXS_DEBUG: 593fcf3ce44SJohn Forte level = " DEBUG"; 594fcf3ce44SJohn Forte break; 595fcf3ce44SJohn Forte 596fcf3ce44SJohn Forte case EMLXS_NOTICE: 597fcf3ce44SJohn Forte level = " NOTICE"; 598fcf3ce44SJohn Forte break; 599fcf3ce44SJohn Forte 600fcf3ce44SJohn Forte case EMLXS_WARNING: 601fcf3ce44SJohn Forte level = "WARNING"; 602fcf3ce44SJohn Forte break; 603fcf3ce44SJohn Forte 604fcf3ce44SJohn Forte case EMLXS_ERROR: 605fcf3ce44SJohn Forte level = " ERROR"; 606fcf3ce44SJohn Forte break; 607fcf3ce44SJohn Forte 608fcf3ce44SJohn Forte case EMLXS_PANIC: 609fcf3ce44SJohn Forte cmn_level = CE_PANIC; 610fcf3ce44SJohn Forte level = " PANIC"; 611fcf3ce44SJohn Forte break; 612fcf3ce44SJohn Forte 613fcf3ce44SJohn Forte case EMLXS_EVENT: 614fcf3ce44SJohn Forte level = " EVENT"; 615fcf3ce44SJohn Forte break; 616fcf3ce44SJohn Forte 617fcf3ce44SJohn Forte default: 618fcf3ce44SJohn Forte level = "UNKNOWN"; 619fcf3ce44SJohn Forte break; 620fcf3ce44SJohn Forte } 621fcf3ce44SJohn Forte 622fcf3ce44SJohn Forte if (port->vpi == 0) { 623fcf3ce44SJohn Forte (void) sprintf(driver, "%s%d", DRIVER_NAME, 624fcf3ce44SJohn Forte hba->ddiinst); 625fcf3ce44SJohn Forte } else { 626fcf3ce44SJohn Forte (void) sprintf(driver, "%s%d.%d", DRIVER_NAME, 627fcf3ce44SJohn Forte hba->ddiinst, port->vpi); 628fcf3ce44SJohn Forte } 629fcf3ce44SJohn Forte 630fcf3ce44SJohn Forte /* Generate the message string */ 631fcf3ce44SJohn Forte if (msg->buffer[0] != 0) { 632fcf3ce44SJohn Forte if (va_str[0] != 0) { 633fcf3ce44SJohn Forte (void) sprintf(msg_str, 634291a2b48SSukumar Swaminathan "[%2X.%04X]%s:%7s:%4d: %s (%s)\n", fileno, 635291a2b48SSukumar Swaminathan line, driver, level, msg->id, msg->buffer, 636291a2b48SSukumar Swaminathan va_str); 637fcf3ce44SJohn Forte } else { 638fcf3ce44SJohn Forte (void) sprintf(msg_str, 639fcf3ce44SJohn Forte "[%2X.%04X]%s:%7s:%4d: %s\n", 640fcf3ce44SJohn Forte fileno, line, driver, level, msg->id, 641fcf3ce44SJohn Forte msg->buffer); 642fcf3ce44SJohn Forte } 643fcf3ce44SJohn Forte } else { 644fcf3ce44SJohn Forte if (va_str[0] != 0) { 645fcf3ce44SJohn Forte (void) sprintf(msg_str, 646291a2b48SSukumar Swaminathan "[%2X.%04X]%s:%7s:%4d: (%s)\n", fileno, 647291a2b48SSukumar Swaminathan line, driver, level, msg->id, va_str); 648fcf3ce44SJohn Forte } else { 649fcf3ce44SJohn Forte (void) sprintf(msg_str, 650fcf3ce44SJohn Forte "[%2X.%04X]%s:%7s:%4d\n", 651fcf3ce44SJohn Forte fileno, line, driver, level, msg->id); 652fcf3ce44SJohn Forte } 653fcf3ce44SJohn Forte } 654fcf3ce44SJohn Forte 655fcf3ce44SJohn Forte switch (rval) { 656fcf3ce44SJohn Forte case 1: /* MESSAGE LOG ONLY */ 657291a2b48SSukumar Swaminathan /* Message log & console, if system booted in */ 658291a2b48SSukumar Swaminathan /* verbose mode (CE_CONT only) */ 659fcf3ce44SJohn Forte cmn_err(cmn_level, "?%s", msg_str); 660fcf3ce44SJohn Forte break; 661fcf3ce44SJohn Forte 662fcf3ce44SJohn Forte case 2: /* CONSOLE ONLY */ 663fcf3ce44SJohn Forte cmn_err(cmn_level, "^%s", msg_str); 664fcf3ce44SJohn Forte break; 665fcf3ce44SJohn Forte 666fcf3ce44SJohn Forte case 3: /* CONSOLE AND MESSAGE LOG */ 667fcf3ce44SJohn Forte cmn_err(cmn_level, "%s", msg_str); 668fcf3ce44SJohn Forte break; 669fcf3ce44SJohn Forte 670fcf3ce44SJohn Forte } 671fcf3ce44SJohn Forte 672fcf3ce44SJohn Forte } 673291a2b48SSukumar Swaminathan 674fcf3ce44SJohn Forte /* If message was not logged, then free any context buffer provided */ 675fcf3ce44SJohn Forte if (!logged && bp && size) { 676fcf3ce44SJohn Forte kmem_free(bp, size); 677fcf3ce44SJohn Forte } 678291a2b48SSukumar Swaminathan 679fcf3ce44SJohn Forte return; 680fcf3ce44SJohn Forte 681291a2b48SSukumar Swaminathan } /* emlxs_msg_printf() */ 682fcf3ce44SJohn Forte 683fcf3ce44SJohn Forte 684fcf3ce44SJohn Forte uint32_t 685fcf3ce44SJohn Forte emlxs_msg_log_get(emlxs_hba_t *hba, emlxs_log_req_t *req, 686fcf3ce44SJohn Forte emlxs_log_resp_t *resp) 687fcf3ce44SJohn Forte { 688fcf3ce44SJohn Forte emlxs_msg_log_t *log; 689fcf3ce44SJohn Forte uint32_t first; 690fcf3ce44SJohn Forte uint32_t last; 691fcf3ce44SJohn Forte uint32_t count; 692fcf3ce44SJohn Forte uint32_t index; 693fcf3ce44SJohn Forte uint32_t i; 694fcf3ce44SJohn Forte char *resp_buf; 695fcf3ce44SJohn Forte 696fcf3ce44SJohn Forte log = &LOG; 697fcf3ce44SJohn Forte 698fcf3ce44SJohn Forte mutex_enter(&log->lock); 699fcf3ce44SJohn Forte 700fcf3ce44SJohn Forte /* Check if buffer is empty */ 701fcf3ce44SJohn Forte if (log->count == 0) { 702fcf3ce44SJohn Forte /* If so, exit now */ 703fcf3ce44SJohn Forte resp->first = 0; 704fcf3ce44SJohn Forte resp->last = 0; 705fcf3ce44SJohn Forte resp->count = 0; 706fcf3ce44SJohn Forte mutex_exit(&log->lock); 707fcf3ce44SJohn Forte 708fcf3ce44SJohn Forte return (1); 709fcf3ce44SJohn Forte } 710291a2b48SSukumar Swaminathan 711fcf3ce44SJohn Forte /* Get current log entry ranges */ 712fcf3ce44SJohn Forte 713fcf3ce44SJohn Forte /* Get last entry id saved */ 714fcf3ce44SJohn Forte last = log->count - 1; 715fcf3ce44SJohn Forte 716fcf3ce44SJohn Forte /* Check if request is out of current range */ 717fcf3ce44SJohn Forte if (req->first > last) { 718fcf3ce44SJohn Forte /* if so, exit now */ 719fcf3ce44SJohn Forte resp->first = last; 720fcf3ce44SJohn Forte resp->last = last; 721fcf3ce44SJohn Forte resp->count = 0; 722fcf3ce44SJohn Forte mutex_exit(&log->lock); 723fcf3ce44SJohn Forte 724fcf3ce44SJohn Forte return (0); 725fcf3ce44SJohn Forte } 726291a2b48SSukumar Swaminathan 727fcf3ce44SJohn Forte /* Get oldest entry id and its index */ 728fcf3ce44SJohn Forte 729fcf3ce44SJohn Forte /* Check if buffer has already been filled once */ 730fcf3ce44SJohn Forte if (log->count >= log->size) { 731fcf3ce44SJohn Forte first = log->count - log->size; 732fcf3ce44SJohn Forte index = log->next; 733fcf3ce44SJohn Forte } else { /* Buffer not yet filled */ 734291a2b48SSukumar Swaminathan 735fcf3ce44SJohn Forte first = 0; 736fcf3ce44SJohn Forte index = 0; 737fcf3ce44SJohn Forte } 738fcf3ce44SJohn Forte 739291a2b48SSukumar Swaminathan /* Check if requested first message is greater than actual. */ 740291a2b48SSukumar Swaminathan /* If so, adjust for it. */ 741fcf3ce44SJohn Forte if (req->first > first) { 742fcf3ce44SJohn Forte /* Adjust entry index to first requested message */ 743fcf3ce44SJohn Forte index += (req->first - first); 744fcf3ce44SJohn Forte if (index >= log->size) { 745fcf3ce44SJohn Forte index -= log->size; 746fcf3ce44SJohn Forte } 747291a2b48SSukumar Swaminathan 748fcf3ce44SJohn Forte first = req->first; 749fcf3ce44SJohn Forte } 750291a2b48SSukumar Swaminathan 751fcf3ce44SJohn Forte /* Get the total number of messages available for return */ 752fcf3ce44SJohn Forte count = last - first + 1; 753fcf3ce44SJohn Forte 754fcf3ce44SJohn Forte /* Check if requested count is less than actual. If so, adjust it. */ 755fcf3ce44SJohn Forte if (req->count < count) { 756fcf3ce44SJohn Forte count = req->count; 757fcf3ce44SJohn Forte } 758291a2b48SSukumar Swaminathan 759fcf3ce44SJohn Forte /* Fill in the response header */ 760fcf3ce44SJohn Forte resp->count = count; 761fcf3ce44SJohn Forte resp->first = first; 762fcf3ce44SJohn Forte resp->last = last; 763fcf3ce44SJohn Forte 764fcf3ce44SJohn Forte /* Fill the response buffer */ 765fcf3ce44SJohn Forte resp_buf = (char *)resp + sizeof (emlxs_log_resp_t); 766fcf3ce44SJohn Forte for (i = 0; i < count; i++) { 767fcf3ce44SJohn Forte emlxs_msg_sprintf(resp_buf, &log->entry[index]); 768fcf3ce44SJohn Forte 769fcf3ce44SJohn Forte /* Increment the response buffer */ 770fcf3ce44SJohn Forte resp_buf += MAX_LOG_MSG_LENGTH; 771fcf3ce44SJohn Forte 772fcf3ce44SJohn Forte /* Increment index */ 773fcf3ce44SJohn Forte if (++index >= log->size) { 774fcf3ce44SJohn Forte index = 0; 775fcf3ce44SJohn Forte } 776fcf3ce44SJohn Forte } 777fcf3ce44SJohn Forte 778fcf3ce44SJohn Forte mutex_exit(&log->lock); 779fcf3ce44SJohn Forte 780fcf3ce44SJohn Forte return (1); 781fcf3ce44SJohn Forte 782291a2b48SSukumar Swaminathan } /* emlxs_msg_log_get() */ 783fcf3ce44SJohn Forte 784fcf3ce44SJohn Forte 785fcf3ce44SJohn Forte 786fcf3ce44SJohn Forte static void 787fcf3ce44SJohn Forte emlxs_msg_sprintf(char *buffer, emlxs_msg_entry_t *entry) 788fcf3ce44SJohn Forte { 789fcf3ce44SJohn Forte char *level; 790fcf3ce44SJohn Forte emlxs_msg_t *msg; 791fcf3ce44SJohn Forte uint32_t secs; 792fcf3ce44SJohn Forte uint32_t hsecs; 793fcf3ce44SJohn Forte char buf[256]; 794fcf3ce44SJohn Forte uint32_t buflen; 795fcf3ce44SJohn Forte char driver[32]; 796fcf3ce44SJohn Forte 797fcf3ce44SJohn Forte msg = entry->msg; 798fcf3ce44SJohn Forte hsecs = (entry->time % 100); 799fcf3ce44SJohn Forte secs = entry->time / 100; 800fcf3ce44SJohn Forte 801fcf3ce44SJohn Forte switch (msg->level) { 802fcf3ce44SJohn Forte case EMLXS_DEBUG: 803fcf3ce44SJohn Forte level = " DEBUG"; 804fcf3ce44SJohn Forte break; 805fcf3ce44SJohn Forte 806fcf3ce44SJohn Forte case EMLXS_NOTICE: 807fcf3ce44SJohn Forte level = " NOTICE"; 808fcf3ce44SJohn Forte break; 809fcf3ce44SJohn Forte 810fcf3ce44SJohn Forte case EMLXS_WARNING: 811fcf3ce44SJohn Forte level = "WARNING"; 812fcf3ce44SJohn Forte break; 813fcf3ce44SJohn Forte 814fcf3ce44SJohn Forte case EMLXS_ERROR: 815fcf3ce44SJohn Forte level = " ERROR"; 816fcf3ce44SJohn Forte break; 817fcf3ce44SJohn Forte 818fcf3ce44SJohn Forte case EMLXS_PANIC: 819fcf3ce44SJohn Forte level = " PANIC"; 820fcf3ce44SJohn Forte break; 821fcf3ce44SJohn Forte 822fcf3ce44SJohn Forte case EMLXS_EVENT: 823fcf3ce44SJohn Forte level = " EVENT"; 824fcf3ce44SJohn Forte break; 825fcf3ce44SJohn Forte 826fcf3ce44SJohn Forte default: 827fcf3ce44SJohn Forte level = "UNKNOWN"; 828fcf3ce44SJohn Forte break; 829fcf3ce44SJohn Forte } 830fcf3ce44SJohn Forte 831fcf3ce44SJohn Forte if (entry->vpi == 0) { 832fcf3ce44SJohn Forte (void) sprintf(driver, "%s%d", DRIVER_NAME, entry->instance); 833fcf3ce44SJohn Forte } else { 834fcf3ce44SJohn Forte (void) sprintf(driver, "%s%d.%d", DRIVER_NAME, entry->instance, 835fcf3ce44SJohn Forte entry->vpi); 836fcf3ce44SJohn Forte } 837fcf3ce44SJohn Forte 838fcf3ce44SJohn Forte /* Generate the message string */ 839fcf3ce44SJohn Forte if (msg->buffer[0] != 0) { 840fcf3ce44SJohn Forte if (entry->buffer[0] != 0) { 841fcf3ce44SJohn Forte (void) sprintf(buf, 842fcf3ce44SJohn Forte "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: %s (%s)\n", 843291a2b48SSukumar Swaminathan secs, hsecs, entry->id, entry->fileno, 844291a2b48SSukumar Swaminathan entry->line, driver, level, msg->id, msg->buffer, 845291a2b48SSukumar Swaminathan entry->buffer); 846fcf3ce44SJohn Forte 847fcf3ce44SJohn Forte } else { 848fcf3ce44SJohn Forte (void) sprintf(buf, 849291a2b48SSukumar Swaminathan "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: %s\n", secs, 850291a2b48SSukumar Swaminathan hsecs, entry->id, entry->fileno, entry->line, 851fcf3ce44SJohn Forte driver, level, msg->id, msg->buffer); 852fcf3ce44SJohn Forte } 853fcf3ce44SJohn Forte } else { 854fcf3ce44SJohn Forte if (entry->buffer[0] != 0) { 855fcf3ce44SJohn Forte (void) sprintf(buf, 856fcf3ce44SJohn Forte "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: (%s)\n", 857291a2b48SSukumar Swaminathan secs, hsecs, entry->id, entry->fileno, 858291a2b48SSukumar Swaminathan entry->line, driver, level, msg->id, 859291a2b48SSukumar Swaminathan entry->buffer); 860fcf3ce44SJohn Forte } else { 861fcf3ce44SJohn Forte (void) sprintf(buf, 862fcf3ce44SJohn Forte "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d\n", 863291a2b48SSukumar Swaminathan secs, hsecs, entry->id, entry->fileno, 864291a2b48SSukumar Swaminathan entry->line, driver, level, msg->id); 865fcf3ce44SJohn Forte } 866fcf3ce44SJohn Forte } 867fcf3ce44SJohn Forte 868fcf3ce44SJohn Forte bzero(buffer, MAX_LOG_MSG_LENGTH); 869fcf3ce44SJohn Forte buflen = strlen(buf); 870fcf3ce44SJohn Forte 871fcf3ce44SJohn Forte if (buflen > (MAX_LOG_MSG_LENGTH - 1)) { 872fcf3ce44SJohn Forte (void) strncpy(buffer, buf, (MAX_LOG_MSG_LENGTH - 2)); 873fcf3ce44SJohn Forte buffer[MAX_LOG_MSG_LENGTH - 2] = '\n'; 874fcf3ce44SJohn Forte } else { 875fcf3ce44SJohn Forte (void) strncpy(buffer, buf, buflen); 876fcf3ce44SJohn Forte } 877fcf3ce44SJohn Forte 878fcf3ce44SJohn Forte return; 879fcf3ce44SJohn Forte 880291a2b48SSukumar Swaminathan } /* emlxs_msg_sprintf() */ 881fcf3ce44SJohn Forte 882fcf3ce44SJohn Forte 883fcf3ce44SJohn Forte 884fcf3ce44SJohn Forte 885fcf3ce44SJohn Forte void 886fcf3ce44SJohn Forte emlxs_log_rscn_event(emlxs_port_t *port, uint8_t *payload, uint32_t size) 887fcf3ce44SJohn Forte { 888fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 889291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA; 890fcf3ce44SJohn Forte uint8_t *bp; 891fcf3ce44SJohn Forte uint32_t *ptr; 892fcf3ce44SJohn Forte 893fcf3ce44SJohn Forte /* Check if the event is being requested */ 894291a2b48SSukumar Swaminathan if (!(hba->log_events & EVT_RSCN)) { 895291a2b48SSukumar Swaminathan return; 896291a2b48SSukumar Swaminathan } 897fcf3ce44SJohn Forte 898fcf3ce44SJohn Forte if (size > MAX_RSCN_PAYLOAD) { 899fcf3ce44SJohn Forte size = MAX_RSCN_PAYLOAD; 900fcf3ce44SJohn Forte } 901291a2b48SSukumar Swaminathan 902fcf3ce44SJohn Forte size += sizeof (uint32_t); 903fcf3ce44SJohn Forte 904fcf3ce44SJohn Forte /* Save a copy of the payload for the event log */ 905fcf3ce44SJohn Forte if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 906fcf3ce44SJohn Forte return; 907fcf3ce44SJohn Forte } 908291a2b48SSukumar Swaminathan 909291a2b48SSukumar Swaminathan 910fcf3ce44SJohn Forte /* 911291a2b48SSukumar Swaminathan * Buffer Format: 912291a2b48SSukumar Swaminathan * word[0] = DID of the RSCN 913291a2b48SSukumar Swaminathan * word[1] = RSCN Payload 914fcf3ce44SJohn Forte */ 915fcf3ce44SJohn Forte ptr = (uint32_t *)bp; 916fcf3ce44SJohn Forte *ptr++ = port->did; 917fcf3ce44SJohn Forte bcopy(payload, (char *)ptr, (size - sizeof (uint32_t))); 918fcf3ce44SJohn Forte 919fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_rscn_event, 920fcf3ce44SJohn Forte "bp=%p size=%d", bp, size); 921fcf3ce44SJohn Forte 922291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 923fcf3ce44SJohn Forte return; 924fcf3ce44SJohn Forte 925291a2b48SSukumar Swaminathan } /* emlxs_log_rscn_event() */ 926291a2b48SSukumar Swaminathan 927291a2b48SSukumar Swaminathan 928291a2b48SSukumar Swaminathan void 929291a2b48SSukumar Swaminathan emlxs_log_vportrscn_event(emlxs_port_t *port, uint8_t *payload, uint32_t size) 930291a2b48SSukumar Swaminathan { 931291a2b48SSukumar Swaminathan #ifdef DFC_SUPPORT 932291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA; 933291a2b48SSukumar Swaminathan uint8_t *bp; 934291a2b48SSukumar Swaminathan uint8_t *ptr; 935291a2b48SSukumar Swaminathan 936291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 937291a2b48SSukumar Swaminathan if (!(hba->log_events & EVT_VPORTRSCN)) { 938291a2b48SSukumar Swaminathan return; 939291a2b48SSukumar Swaminathan } 940291a2b48SSukumar Swaminathan 941291a2b48SSukumar Swaminathan if (size > MAX_RSCN_PAYLOAD) { 942291a2b48SSukumar Swaminathan size = MAX_RSCN_PAYLOAD; 943291a2b48SSukumar Swaminathan } 944291a2b48SSukumar Swaminathan 945291a2b48SSukumar Swaminathan /* Save a copy of the payload for the event log */ 946291a2b48SSukumar Swaminathan if (!(bp = 947291a2b48SSukumar Swaminathan (uint8_t *)kmem_alloc(size + sizeof (NAME_TYPE), KM_NOSLEEP))) { 948291a2b48SSukumar Swaminathan return; 949291a2b48SSukumar Swaminathan } 950291a2b48SSukumar Swaminathan 951291a2b48SSukumar Swaminathan 952291a2b48SSukumar Swaminathan /* 953291a2b48SSukumar Swaminathan * Buffer Format: 954291a2b48SSukumar Swaminathan * word[0 - 4] = WWPN of the RSCN 955291a2b48SSukumar Swaminathan * word[5] = RSCN Payload 956291a2b48SSukumar Swaminathan */ 957291a2b48SSukumar Swaminathan ptr = bp; 958291a2b48SSukumar Swaminathan bcopy(&port->wwpn, ptr, sizeof (NAME_TYPE)); 959291a2b48SSukumar Swaminathan ptr += sizeof (NAME_TYPE); 960291a2b48SSukumar Swaminathan bcopy(payload, ptr, size); 961291a2b48SSukumar Swaminathan 962291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size + sizeof (NAME_TYPE), 963291a2b48SSukumar Swaminathan &emlxs_vportrscn_event, "bp=%p size=%d", bp, size); 964291a2b48SSukumar Swaminathan 965291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 966291a2b48SSukumar Swaminathan return; 967291a2b48SSukumar Swaminathan 968291a2b48SSukumar Swaminathan } /* emlxs_log_vportrscn_event() */ 969fcf3ce44SJohn Forte 970fcf3ce44SJohn Forte 971728bdc9bSSukumar Swaminathan uint32_t 972fcf3ce44SJohn Forte emlxs_log_ct_event(emlxs_port_t *port, uint8_t *payload, uint32_t size, 973fcf3ce44SJohn Forte uint32_t rxid) 974fcf3ce44SJohn Forte { 975fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 976fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 977fcf3ce44SJohn Forte uint8_t *bp; 978fcf3ce44SJohn Forte uint32_t *ptr; 979fcf3ce44SJohn Forte 980fcf3ce44SJohn Forte /* Check if the event is being requested */ 981fcf3ce44SJohn Forte if (!(hba->log_events & EVT_CT)) { 982728bdc9bSSukumar Swaminathan return (1); 983fcf3ce44SJohn Forte } 984291a2b48SSukumar Swaminathan 985fcf3ce44SJohn Forte if (size > MAX_CT_PAYLOAD) { 986fcf3ce44SJohn Forte size = MAX_CT_PAYLOAD; 987fcf3ce44SJohn Forte } 988291a2b48SSukumar Swaminathan 989fcf3ce44SJohn Forte size += sizeof (uint32_t); 990fcf3ce44SJohn Forte 991fcf3ce44SJohn Forte /* Save a copy of the payload for the event log */ 992fcf3ce44SJohn Forte if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 993728bdc9bSSukumar Swaminathan return (1); 994fcf3ce44SJohn Forte } 995291a2b48SSukumar Swaminathan 996fcf3ce44SJohn Forte /* 997291a2b48SSukumar Swaminathan * Buffer Format: 998291a2b48SSukumar Swaminathan * word[0] = RXID tag for outgoing reply to this CT request 999291a2b48SSukumar Swaminathan * word[1] = CT Payload 1000fcf3ce44SJohn Forte */ 1001fcf3ce44SJohn Forte ptr = (uint32_t *)bp; 1002fcf3ce44SJohn Forte *ptr++ = rxid; 1003fcf3ce44SJohn Forte 1004fcf3ce44SJohn Forte bcopy(payload, (char *)ptr, (size - sizeof (uint32_t))); 1005fcf3ce44SJohn Forte 1006fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_ct_event, 1007fcf3ce44SJohn Forte "bp=%p size=%d rxid=%x", bp, size, rxid); 1008fcf3ce44SJohn Forte 1009728bdc9bSSukumar Swaminathan 1010291a2b48SSukumar Swaminathan return (0); 1011728bdc9bSSukumar Swaminathan #else 1012728bdc9bSSukumar Swaminathan 1013291a2b48SSukumar Swaminathan return (1); 1014fcf3ce44SJohn Forte 1015291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1016fcf3ce44SJohn Forte 1017291a2b48SSukumar Swaminathan } /* emlxs_log_ct_event() */ 1018fcf3ce44SJohn Forte 1019fcf3ce44SJohn Forte 1020fcf3ce44SJohn Forte void 1021fcf3ce44SJohn Forte emlxs_log_link_event(emlxs_port_t *port) 1022fcf3ce44SJohn Forte { 1023fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 1024fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1025fcf3ce44SJohn Forte uint8_t *bp; 1026fcf3ce44SJohn Forte dfc_linkinfo_t *linkinfo; 1027fcf3ce44SJohn Forte uint8_t *byte; 1028fcf3ce44SJohn Forte uint8_t *linkspeed; 1029fcf3ce44SJohn Forte uint8_t *liptype; 1030fcf3ce44SJohn Forte uint8_t *resv1; 1031fcf3ce44SJohn Forte uint8_t *resv2; 1032fcf3ce44SJohn Forte uint32_t size; 1033fcf3ce44SJohn Forte 1034fcf3ce44SJohn Forte /* Check if the event is being requested */ 1035fcf3ce44SJohn Forte /* 1036fcf3ce44SJohn Forte * if(!(hba->log_events & EVT_LINK)) { return; } 1037fcf3ce44SJohn Forte */ 1038fcf3ce44SJohn Forte size = sizeof (dfc_linkinfo_t) + sizeof (uint32_t); 1039fcf3ce44SJohn Forte 1040fcf3ce44SJohn Forte /* Save a copy of the buffer for the event log */ 1041fcf3ce44SJohn Forte if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 1042fcf3ce44SJohn Forte return; 1043fcf3ce44SJohn Forte } 1044291a2b48SSukumar Swaminathan 1045fcf3ce44SJohn Forte /* 1046291a2b48SSukumar Swaminathan * Buffer Format: 1047291a2b48SSukumar Swaminathan * word[0] = Linkspeed:8 1048291a2b48SSukumar Swaminathan * word[0] = LIP_type:8 1049291a2b48SSukumar Swaminathan * word[0] = resv1:8 1050291a2b48SSukumar Swaminathan * word[0] = resv2:8 1051291a2b48SSukumar Swaminathan * word[1] = dfc_linkinfo_t data 1052fcf3ce44SJohn Forte */ 1053fcf3ce44SJohn Forte byte = (uint8_t *)bp; 1054fcf3ce44SJohn Forte linkspeed = &byte[0]; 1055fcf3ce44SJohn Forte liptype = &byte[1]; 1056fcf3ce44SJohn Forte resv1 = &byte[2]; 1057fcf3ce44SJohn Forte resv2 = &byte[3]; 1058291a2b48SSukumar Swaminathan linkinfo = (dfc_linkinfo_t *)&byte[4]; 1059fcf3ce44SJohn Forte 1060fcf3ce44SJohn Forte *resv1 = 0; 1061fcf3ce44SJohn Forte *resv2 = 0; 1062fcf3ce44SJohn Forte 1063fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1064fcf3ce44SJohn Forte *linkspeed = 0; 1065fcf3ce44SJohn Forte *liptype = 0; 1066fcf3ce44SJohn Forte } else { 1067fcf3ce44SJohn Forte /* Set linkspeed */ 1068fcf3ce44SJohn Forte if (hba->linkspeed == LA_2GHZ_LINK) { 1069fcf3ce44SJohn Forte *linkspeed = HBA_PORTSPEED_2GBIT; 1070fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_4GHZ_LINK) { 1071fcf3ce44SJohn Forte *linkspeed = HBA_PORTSPEED_4GBIT; 1072fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_8GHZ_LINK) { 1073fcf3ce44SJohn Forte *linkspeed = HBA_PORTSPEED_8GBIT; 1074fcf3ce44SJohn Forte } else if (hba->linkspeed == LA_10GHZ_LINK) { 1075fcf3ce44SJohn Forte *linkspeed = HBA_PORTSPEED_10GBIT; 1076fcf3ce44SJohn Forte } else { 1077fcf3ce44SJohn Forte *linkspeed = HBA_PORTSPEED_1GBIT; 1078fcf3ce44SJohn Forte } 1079fcf3ce44SJohn Forte 1080fcf3ce44SJohn Forte /* Set LIP type */ 1081fcf3ce44SJohn Forte *liptype = port->lip_type; 1082fcf3ce44SJohn Forte } 1083fcf3ce44SJohn Forte 1084fcf3ce44SJohn Forte bzero(linkinfo, sizeof (dfc_linkinfo_t)); 1085fcf3ce44SJohn Forte 1086fcf3ce44SJohn Forte linkinfo->a_linkEventTag = hba->link_event_tag; 1087fcf3ce44SJohn Forte linkinfo->a_linkUp = HBASTATS.LinkUp; 1088fcf3ce44SJohn Forte linkinfo->a_linkDown = HBASTATS.LinkDown; 1089fcf3ce44SJohn Forte linkinfo->a_linkMulti = HBASTATS.LinkMultiEvent; 1090fcf3ce44SJohn Forte 1091fcf3ce44SJohn Forte if (hba->state <= FC_LINK_DOWN) { 1092fcf3ce44SJohn Forte linkinfo->a_linkState = LNK_DOWN; 1093fcf3ce44SJohn Forte linkinfo->a_DID = port->prev_did; 1094fcf3ce44SJohn Forte } else if (hba->state < FC_READY) { 1095fcf3ce44SJohn Forte linkinfo->a_linkState = LNK_DISCOVERY; 1096fcf3ce44SJohn Forte } else { 1097fcf3ce44SJohn Forte linkinfo->a_linkState = LNK_READY; 1098fcf3ce44SJohn Forte } 1099fcf3ce44SJohn Forte 1100fcf3ce44SJohn Forte if (linkinfo->a_linkState != LNK_DOWN) { 1101fcf3ce44SJohn Forte if (hba->topology == TOPOLOGY_LOOP) { 1102fcf3ce44SJohn Forte if (hba->flag & FC_FABRIC_ATTACHED) { 1103fcf3ce44SJohn Forte linkinfo->a_topology = LNK_PUBLIC_LOOP; 1104fcf3ce44SJohn Forte } else { 1105fcf3ce44SJohn Forte linkinfo->a_topology = LNK_LOOP; 1106fcf3ce44SJohn Forte } 1107fcf3ce44SJohn Forte 1108fcf3ce44SJohn Forte linkinfo->a_alpa = port->did & 0xff; 1109fcf3ce44SJohn Forte linkinfo->a_DID = linkinfo->a_alpa; 1110fcf3ce44SJohn Forte linkinfo->a_alpaCnt = port->alpa_map[0]; 1111fcf3ce44SJohn Forte 1112fcf3ce44SJohn Forte if (linkinfo->a_alpaCnt > 127) { 1113fcf3ce44SJohn Forte linkinfo->a_alpaCnt = 127; 1114fcf3ce44SJohn Forte } 1115291a2b48SSukumar Swaminathan 1116291a2b48SSukumar Swaminathan bcopy((void *)&port->alpa_map[1], linkinfo->a_alpaMap, 1117fcf3ce44SJohn Forte linkinfo->a_alpaCnt); 1118fcf3ce44SJohn Forte } else { 1119fcf3ce44SJohn Forte if (port->node_count == 1) { 1120fcf3ce44SJohn Forte linkinfo->a_topology = LNK_PT2PT; 1121fcf3ce44SJohn Forte } else { 1122fcf3ce44SJohn Forte linkinfo->a_topology = LNK_FABRIC; 1123fcf3ce44SJohn Forte } 1124fcf3ce44SJohn Forte 1125fcf3ce44SJohn Forte linkinfo->a_DID = port->did; 1126fcf3ce44SJohn Forte } 1127fcf3ce44SJohn Forte } 1128291a2b48SSukumar Swaminathan 1129fcf3ce44SJohn Forte bcopy(&hba->wwpn, linkinfo->a_wwpName, 8); 1130fcf3ce44SJohn Forte bcopy(&hba->wwnn, linkinfo->a_wwnName, 8); 1131fcf3ce44SJohn Forte 1132fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_link_event, 1133fcf3ce44SJohn Forte "bp=%p size=%d tag=%x", bp, size, hba->link_event_tag); 1134fcf3ce44SJohn Forte 1135291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1136fcf3ce44SJohn Forte 1137fcf3ce44SJohn Forte return; 1138fcf3ce44SJohn Forte 1139291a2b48SSukumar Swaminathan } /* emlxs_log_link_event() */ 1140fcf3ce44SJohn Forte 1141fcf3ce44SJohn Forte 1142fcf3ce44SJohn Forte void 1143fcf3ce44SJohn Forte emlxs_log_dump_event(emlxs_port_t *port, uint8_t *buffer, uint32_t size) 1144fcf3ce44SJohn Forte { 1145fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 1146fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1147fcf3ce44SJohn Forte uint8_t *bp; 1148fcf3ce44SJohn Forte 1149fcf3ce44SJohn Forte /* Check if the event is being requested */ 1150fcf3ce44SJohn Forte if (!(hba->log_events & EVT_DUMP)) { 1151291a2b48SSukumar Swaminathan #ifdef DUMP_SUPPORT 1152291a2b48SSukumar Swaminathan /* Schedule a dump thread */ 1153291a2b48SSukumar Swaminathan emlxs_dump(hba, EMLXS_DRV_DUMP, 0, 0); 1154291a2b48SSukumar Swaminathan #endif /* DUMP_SUPPORT */ 1155fcf3ce44SJohn Forte return; 1156fcf3ce44SJohn Forte } 1157291a2b48SSukumar Swaminathan 1158fcf3ce44SJohn Forte if (buffer && size) { 1159fcf3ce44SJohn Forte /* Save a copy of the buffer for the event log */ 1160fcf3ce44SJohn Forte if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 1161fcf3ce44SJohn Forte return; 1162fcf3ce44SJohn Forte } 1163291a2b48SSukumar Swaminathan 1164fcf3ce44SJohn Forte bcopy(buffer, bp, size); 1165fcf3ce44SJohn Forte } else { 1166fcf3ce44SJohn Forte bp = NULL; 1167fcf3ce44SJohn Forte size = 0; 1168fcf3ce44SJohn Forte } 1169fcf3ce44SJohn Forte 1170fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_dump_event, 1171fcf3ce44SJohn Forte "bp=%p size=%d", bp, size); 1172291a2b48SSukumar Swaminathan #else 1173291a2b48SSukumar Swaminathan 1174291a2b48SSukumar Swaminathan #ifdef DUMP_SUPPORT 1175291a2b48SSukumar Swaminathan /* Schedule a dump thread */ 1176291a2b48SSukumar Swaminathan emlxs_dump(hba, EMLXS_DRV_DUMP, 0, 0); 1177291a2b48SSukumar Swaminathan #endif /* DUMP_SUPPORT */ 1178fcf3ce44SJohn Forte 1179291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1180fcf3ce44SJohn Forte 1181fcf3ce44SJohn Forte return; 1182fcf3ce44SJohn Forte 1183291a2b48SSukumar Swaminathan } /* emlxs_log_dump_event() */ 1184fcf3ce44SJohn Forte 1185fcf3ce44SJohn Forte 1186fcf3ce44SJohn Forte extern void 1187fcf3ce44SJohn Forte emlxs_log_temp_event(emlxs_port_t *port, uint32_t type, uint32_t temp) 1188fcf3ce44SJohn Forte { 1189fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1190291a2b48SSukumar Swaminathan 1191291a2b48SSukumar Swaminathan #ifdef DFC_SUPPORT 1192fcf3ce44SJohn Forte uint32_t *bp; 1193fcf3ce44SJohn Forte uint32_t size; 1194fcf3ce44SJohn Forte 1195fcf3ce44SJohn Forte /* Check if the event is being requested */ 1196fcf3ce44SJohn Forte if (!(hba->log_events & EVT_TEMP)) { 1197291a2b48SSukumar Swaminathan #ifdef DUMP_SUPPORT 1198291a2b48SSukumar Swaminathan /* Schedule a dump thread */ 1199291a2b48SSukumar Swaminathan emlxs_dump(hba, EMLXS_TEMP_DUMP, type, temp); 1200291a2b48SSukumar Swaminathan #endif /* DUMP_SUPPORT */ 1201fcf3ce44SJohn Forte return; 1202fcf3ce44SJohn Forte } 1203291a2b48SSukumar Swaminathan 1204fcf3ce44SJohn Forte size = 2 * sizeof (uint32_t); 1205fcf3ce44SJohn Forte 1206fcf3ce44SJohn Forte if (!(bp = (uint32_t *)kmem_alloc(size, KM_NOSLEEP))) { 1207fcf3ce44SJohn Forte return; 1208fcf3ce44SJohn Forte } 1209291a2b48SSukumar Swaminathan 1210fcf3ce44SJohn Forte bp[0] = type; 1211fcf3ce44SJohn Forte bp[1] = temp; 1212fcf3ce44SJohn Forte 1213fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_temp_event, 1214fcf3ce44SJohn Forte "type=%x temp=%d bp=%p size=%d", type, temp, bp, size); 1215fcf3ce44SJohn Forte 1216291a2b48SSukumar Swaminathan #else /* !DFC_SUPPORT */ 1217291a2b48SSukumar Swaminathan 1218291a2b48SSukumar Swaminathan #ifdef DUMP_SUPPORT 1219291a2b48SSukumar Swaminathan /* Schedule a dump thread */ 1220291a2b48SSukumar Swaminathan emlxs_dump(hba, EMLXS_TEMP_DUMP, type, temp); 1221291a2b48SSukumar Swaminathan #endif /* DUMP_SUPPORT */ 1222291a2b48SSukumar Swaminathan 1223291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1224fcf3ce44SJohn Forte 1225fcf3ce44SJohn Forte return; 1226fcf3ce44SJohn Forte 1227291a2b48SSukumar Swaminathan } /* emlxs_log_temp_event() */ 1228fcf3ce44SJohn Forte 1229fcf3ce44SJohn Forte 1230fcf3ce44SJohn Forte 1231fcf3ce44SJohn Forte extern void 1232fcf3ce44SJohn Forte emlxs_log_fcoe_event(emlxs_port_t *port, menlo_init_rsp_t *init_rsp) 1233fcf3ce44SJohn Forte { 1234fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 1235fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1236fcf3ce44SJohn Forte uint8_t *bp; 1237fcf3ce44SJohn Forte uint32_t size; 1238fcf3ce44SJohn Forte 1239fcf3ce44SJohn Forte /* Check if the event is being requested */ 1240fcf3ce44SJohn Forte if (!(hba->log_events & EVT_FCOE)) { 1241fcf3ce44SJohn Forte return; 1242fcf3ce44SJohn Forte } 1243291a2b48SSukumar Swaminathan 1244fcf3ce44SJohn Forte /* Check if this is a FCOE adapter */ 1245fcf3ce44SJohn Forte if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) { 1246fcf3ce44SJohn Forte return; 1247fcf3ce44SJohn Forte } 1248291a2b48SSukumar Swaminathan 1249fcf3ce44SJohn Forte size = sizeof (menlo_init_rsp_t); 1250fcf3ce44SJohn Forte 1251fcf3ce44SJohn Forte if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 1252fcf3ce44SJohn Forte return; 1253fcf3ce44SJohn Forte } 1254291a2b48SSukumar Swaminathan 1255fcf3ce44SJohn Forte bcopy((uint8_t *)init_rsp, bp, size); 1256fcf3ce44SJohn Forte 1257fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_fcoe_event, 1258fcf3ce44SJohn Forte "bp=%p size=%d", bp, size); 1259291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 1260291a2b48SSukumar Swaminathan 1261291a2b48SSukumar Swaminathan return; 1262291a2b48SSukumar Swaminathan 1263291a2b48SSukumar Swaminathan } /* emlxs_log_fcoe_event() */ 1264291a2b48SSukumar Swaminathan 1265291a2b48SSukumar Swaminathan 1266291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1267291a2b48SSukumar Swaminathan extern void 1268291a2b48SSukumar Swaminathan emlxs_log_sd_basic_els_event(emlxs_port_t *port, uint32_t subcat, 1269291a2b48SSukumar Swaminathan HBA_WWN *portname, HBA_WWN *nodename) 1270291a2b48SSukumar Swaminathan { 1271291a2b48SSukumar Swaminathan struct sd_plogi_rcv_v0 *bp; 1272291a2b48SSukumar Swaminathan uint32_t size; 1273291a2b48SSukumar Swaminathan 1274291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1275291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_ELS)) 1276291a2b48SSukumar Swaminathan return; 1277291a2b48SSukumar Swaminathan 1278291a2b48SSukumar Swaminathan size = sizeof (struct sd_plogi_rcv_v0); 1279291a2b48SSukumar Swaminathan 1280291a2b48SSukumar Swaminathan if (!(bp = (struct sd_plogi_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1281291a2b48SSukumar Swaminathan return; 1282291a2b48SSukumar Swaminathan 1283291a2b48SSukumar Swaminathan /* 1284291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1285291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1286291a2b48SSukumar Swaminathan */ 1287291a2b48SSukumar Swaminathan bp->sd_plogir_version = subcat; 1288291a2b48SSukumar Swaminathan bcopy((uint8_t *)portname, (uint8_t *)&bp->sd_plogir_portname, 1289291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1290291a2b48SSukumar Swaminathan bcopy((uint8_t *)nodename, (uint8_t *)&bp->sd_plogir_nodename, 1291291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1292291a2b48SSukumar Swaminathan 1293291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_els_event, 1294291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1295291a2b48SSukumar Swaminathan 1296291a2b48SSukumar Swaminathan return; 1297291a2b48SSukumar Swaminathan 1298291a2b48SSukumar Swaminathan } /* emlxs_log_sd_basic_els_event() */ 1299291a2b48SSukumar Swaminathan 1300291a2b48SSukumar Swaminathan 1301291a2b48SSukumar Swaminathan extern void 1302291a2b48SSukumar Swaminathan emlxs_log_sd_prlo_event(emlxs_port_t *port, HBA_WWN *remoteport) 1303291a2b48SSukumar Swaminathan { 1304291a2b48SSukumar Swaminathan struct sd_prlo_rcv_v0 *bp; 1305291a2b48SSukumar Swaminathan uint32_t size; 1306291a2b48SSukumar Swaminathan 1307291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1308291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_ELS)) 1309291a2b48SSukumar Swaminathan return; 1310291a2b48SSukumar Swaminathan 1311291a2b48SSukumar Swaminathan size = sizeof (struct sd_prlo_rcv_v0); 1312291a2b48SSukumar Swaminathan 1313291a2b48SSukumar Swaminathan if (!(bp = (struct sd_prlo_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1314291a2b48SSukumar Swaminathan return; 1315291a2b48SSukumar Swaminathan 1316291a2b48SSukumar Swaminathan /* 1317291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1318291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1319291a2b48SSukumar Swaminathan */ 1320291a2b48SSukumar Swaminathan bp->sd_prlor_version = SD_ELS_SUBCATEGORY_PRLO_RCV; 1321291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_prlor_remoteport, 1322291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1323291a2b48SSukumar Swaminathan 1324291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_els_event, 1325291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1326291a2b48SSukumar Swaminathan 1327291a2b48SSukumar Swaminathan return; 1328291a2b48SSukumar Swaminathan 1329291a2b48SSukumar Swaminathan } /* emlxs_log_sd_prlo_event() */ 1330291a2b48SSukumar Swaminathan 1331291a2b48SSukumar Swaminathan 1332291a2b48SSukumar Swaminathan extern void 1333291a2b48SSukumar Swaminathan emlxs_log_sd_lsrjt_event(emlxs_port_t *port, HBA_WWN *remoteport, 1334291a2b48SSukumar Swaminathan uint32_t orig_cmd, uint32_t reason, uint32_t reason_expl) 1335291a2b48SSukumar Swaminathan { 1336291a2b48SSukumar Swaminathan struct sd_lsrjt_rcv_v0 *bp; 1337291a2b48SSukumar Swaminathan uint32_t size; 1338291a2b48SSukumar Swaminathan 1339291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1340291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_ELS)) 1341291a2b48SSukumar Swaminathan return; 1342291a2b48SSukumar Swaminathan 1343291a2b48SSukumar Swaminathan size = sizeof (struct sd_lsrjt_rcv_v0); 1344291a2b48SSukumar Swaminathan 1345291a2b48SSukumar Swaminathan if (!(bp = (struct sd_lsrjt_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1346291a2b48SSukumar Swaminathan return; 1347291a2b48SSukumar Swaminathan 1348291a2b48SSukumar Swaminathan /* 1349291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1350291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1351291a2b48SSukumar Swaminathan */ 1352291a2b48SSukumar Swaminathan bp->sd_lsrjtr_version = SD_ELS_SUBCATEGORY_LSRJT_RCV; 1353291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_lsrjtr_remoteport, 1354291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1355291a2b48SSukumar Swaminathan bp->sd_lsrjtr_original_cmd = orig_cmd; 1356291a2b48SSukumar Swaminathan bp->sd_lsrjtr_reasoncode = reason; 1357291a2b48SSukumar Swaminathan bp->sd_lsrjtr_reasoncodeexpl = reason_expl; 1358291a2b48SSukumar Swaminathan 1359291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_els_event, 1360291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1361291a2b48SSukumar Swaminathan 1362291a2b48SSukumar Swaminathan return; 1363291a2b48SSukumar Swaminathan 1364291a2b48SSukumar Swaminathan } /* emlxs_log_sd_lsrjt_event() */ 1365291a2b48SSukumar Swaminathan 1366291a2b48SSukumar Swaminathan 1367291a2b48SSukumar Swaminathan 1368291a2b48SSukumar Swaminathan extern void 1369291a2b48SSukumar Swaminathan emlxs_log_sd_fc_bsy_event(emlxs_port_t *port, HBA_WWN *remoteport) 1370291a2b48SSukumar Swaminathan { 1371291a2b48SSukumar Swaminathan struct sd_pbsy_rcv_v0 *bp; 1372291a2b48SSukumar Swaminathan uint32_t size; 1373291a2b48SSukumar Swaminathan 1374291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1375291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_FABRIC)) 1376291a2b48SSukumar Swaminathan return; 1377291a2b48SSukumar Swaminathan 1378291a2b48SSukumar Swaminathan size = sizeof (struct sd_pbsy_rcv_v0); 1379291a2b48SSukumar Swaminathan 1380291a2b48SSukumar Swaminathan if (!(bp = (struct sd_pbsy_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1381291a2b48SSukumar Swaminathan return; 1382291a2b48SSukumar Swaminathan 1383291a2b48SSukumar Swaminathan /* 1384291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1385291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1386291a2b48SSukumar Swaminathan */ 1387291a2b48SSukumar Swaminathan if (remoteport == NULL) 1388291a2b48SSukumar Swaminathan bp->sd_pbsyr_evt_version = SD_FABRIC_SUBCATEGORY_FABRIC_BUSY; 1389291a2b48SSukumar Swaminathan else 1390291a2b48SSukumar Swaminathan { 1391291a2b48SSukumar Swaminathan bp->sd_pbsyr_evt_version = SD_FABRIC_SUBCATEGORY_PORT_BUSY; 1392291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_pbsyr_rport, 1393291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1394291a2b48SSukumar Swaminathan } 1395291a2b48SSukumar Swaminathan 1396291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_fabric_event, 1397291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1398291a2b48SSukumar Swaminathan 1399291a2b48SSukumar Swaminathan return; 1400291a2b48SSukumar Swaminathan 1401291a2b48SSukumar Swaminathan } /* emlxs_log_sd_fc_bsy_event() */ 1402291a2b48SSukumar Swaminathan 1403291a2b48SSukumar Swaminathan 1404291a2b48SSukumar Swaminathan extern void 1405291a2b48SSukumar Swaminathan emlxs_log_sd_fc_rdchk_event(emlxs_port_t *port, HBA_WWN *remoteport, 1406291a2b48SSukumar Swaminathan uint32_t lun, uint32_t opcode, uint32_t fcp_param) 1407291a2b48SSukumar Swaminathan { 1408291a2b48SSukumar Swaminathan struct sd_fcprdchkerr_v0 *bp; 1409291a2b48SSukumar Swaminathan uint32_t size; 1410291a2b48SSukumar Swaminathan 1411291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1412291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_FABRIC)) 1413291a2b48SSukumar Swaminathan return; 1414291a2b48SSukumar Swaminathan 1415291a2b48SSukumar Swaminathan size = sizeof (struct sd_fcprdchkerr_v0); 1416291a2b48SSukumar Swaminathan 1417291a2b48SSukumar Swaminathan if (!(bp = (struct sd_fcprdchkerr_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1418291a2b48SSukumar Swaminathan return; 1419291a2b48SSukumar Swaminathan 1420291a2b48SSukumar Swaminathan /* 1421291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1422291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1423291a2b48SSukumar Swaminathan */ 1424291a2b48SSukumar Swaminathan bp->sd_fcprdchkerr_version = SD_FABRIC_SUBCATEGORY_FCPRDCHKERR; 1425291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_fcprdchkerr_rport, 1426291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1427291a2b48SSukumar Swaminathan bp->sd_fcprdchkerr_lun = lun; 1428291a2b48SSukumar Swaminathan bp->sd_fcprdchkerr_opcode = opcode; 1429291a2b48SSukumar Swaminathan bp->sd_fcprdchkerr_fcpiparam = fcp_param; 1430291a2b48SSukumar Swaminathan 1431291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_fabric_event, 1432291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1433291a2b48SSukumar Swaminathan 1434291a2b48SSukumar Swaminathan return; 1435291a2b48SSukumar Swaminathan 1436291a2b48SSukumar Swaminathan } /* emlxs_log_sd_rdchk_event() */ 1437291a2b48SSukumar Swaminathan 1438291a2b48SSukumar Swaminathan 1439291a2b48SSukumar Swaminathan extern void 1440291a2b48SSukumar Swaminathan emlxs_log_sd_scsi_event(emlxs_port_t *port, uint32_t type, 1441291a2b48SSukumar Swaminathan HBA_WWN *remoteport, int32_t lun) 1442291a2b48SSukumar Swaminathan { 1443291a2b48SSukumar Swaminathan struct sd_scsi_generic_v0 *bp; 1444291a2b48SSukumar Swaminathan uint32_t size; 1445291a2b48SSukumar Swaminathan 1446291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1447291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_SCSI)) 1448291a2b48SSukumar Swaminathan return; 1449291a2b48SSukumar Swaminathan 1450291a2b48SSukumar Swaminathan size = sizeof (struct sd_scsi_generic_v0); 1451291a2b48SSukumar Swaminathan 1452291a2b48SSukumar Swaminathan if (!(bp = (struct sd_scsi_generic_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1453291a2b48SSukumar Swaminathan return; 1454fcf3ce44SJohn Forte 1455291a2b48SSukumar Swaminathan /* 1456291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1457291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1458291a2b48SSukumar Swaminathan */ 1459291a2b48SSukumar Swaminathan bp->sd_scsi_generic_version = type; 1460291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_scsi_generic_rport, 1461291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1462291a2b48SSukumar Swaminathan bp->sd_scsi_generic_lun = lun; 1463291a2b48SSukumar Swaminathan 1464291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_scsi_event, 1465291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1466fcf3ce44SJohn Forte 1467fcf3ce44SJohn Forte return; 1468fcf3ce44SJohn Forte 1469291a2b48SSukumar Swaminathan } /* emlxs_log_sd_scsi_event() */ 1470291a2b48SSukumar Swaminathan 1471291a2b48SSukumar Swaminathan 1472291a2b48SSukumar Swaminathan extern void 1473291a2b48SSukumar Swaminathan emlxs_log_sd_scsi_check_event(emlxs_port_t *port, HBA_WWN *remoteport, 1474291a2b48SSukumar Swaminathan uint32_t lun, uint32_t cmdcode, uint32_t sensekey, 1475291a2b48SSukumar Swaminathan uint32_t asc, uint32_t ascq) 1476291a2b48SSukumar Swaminathan { 1477291a2b48SSukumar Swaminathan struct sd_scsi_checkcond_v0 *bp; 1478291a2b48SSukumar Swaminathan uint32_t size; 1479291a2b48SSukumar Swaminathan 1480291a2b48SSukumar Swaminathan /* Check if the event is being requested */ 1481291a2b48SSukumar Swaminathan if (!(port->sd_reg_events & EVT_SD_SCSI)) 1482291a2b48SSukumar Swaminathan return; 1483291a2b48SSukumar Swaminathan 1484291a2b48SSukumar Swaminathan size = sizeof (struct sd_scsi_checkcond_v0); 1485291a2b48SSukumar Swaminathan 1486291a2b48SSukumar Swaminathan if (!(bp = (struct sd_scsi_checkcond_v0 *)kmem_alloc(size, KM_NOSLEEP))) 1487291a2b48SSukumar Swaminathan return; 1488291a2b48SSukumar Swaminathan 1489291a2b48SSukumar Swaminathan /* 1490291a2b48SSukumar Swaminathan * we are using version field to store subtype, libdfc 1491291a2b48SSukumar Swaminathan * will fix this up before returning data to app. 1492291a2b48SSukumar Swaminathan */ 1493291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_version = SD_SCSI_SUBCATEGORY_CHECKCONDITION; 1494291a2b48SSukumar Swaminathan bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_scsi_checkcond_rport, 1495291a2b48SSukumar Swaminathan sizeof (HBA_WWN)); 1496291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_lun = lun; 1497291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_cmdcode = cmdcode; 1498291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_sensekey = sensekey; 1499291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_asc = asc; 1500291a2b48SSukumar Swaminathan bp->sd_scsi_checkcond_ascq = ascq; 1501291a2b48SSukumar Swaminathan 1502291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_scsi_event, 1503291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1504291a2b48SSukumar Swaminathan 1505291a2b48SSukumar Swaminathan } 1506291a2b48SSukumar Swaminathan #endif /* SAN_DIAG_SUPPORT */ 1507291a2b48SSukumar Swaminathan 1508291a2b48SSukumar Swaminathan 1509291a2b48SSukumar Swaminathan extern void 1510291a2b48SSukumar Swaminathan emlxs_log_async_event(emlxs_port_t *port, IOCB *iocb) 1511291a2b48SSukumar Swaminathan { 1512291a2b48SSukumar Swaminathan uint8_t *bp; 1513291a2b48SSukumar Swaminathan uint32_t size; 1514291a2b48SSukumar Swaminathan 1515291a2b48SSukumar Swaminathan /* ASYNC_STATUS_CN response size */ 1516291a2b48SSukumar Swaminathan size = 64; 1517291a2b48SSukumar Swaminathan 1518291a2b48SSukumar Swaminathan if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) { 1519291a2b48SSukumar Swaminathan return; 1520291a2b48SSukumar Swaminathan } 1521fcf3ce44SJohn Forte 1522291a2b48SSukumar Swaminathan bcopy((uint8_t *)iocb, bp, size); 1523fcf3ce44SJohn Forte 1524291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_async_event, 1525291a2b48SSukumar Swaminathan "bp=%p size=%d", bp, size); 1526291a2b48SSukumar Swaminathan 1527291a2b48SSukumar Swaminathan } /* emlxs_log_async_event() */ 1528fcf3ce44SJohn Forte 1529fcf3ce44SJohn Forte #ifdef DFC_SUPPORT 1530fcf3ce44SJohn Forte 1531fcf3ce44SJohn Forte extern uint32_t 1532fcf3ce44SJohn Forte emlxs_get_dfc_eventinfo(emlxs_port_t *port, HBA_EVENTINFO *eventinfo, 1533fcf3ce44SJohn Forte uint32_t *eventcount, uint32_t *missed) 1534fcf3ce44SJohn Forte { 1535fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1536fcf3ce44SJohn Forte emlxs_msg_log_t *log; 1537fcf3ce44SJohn Forte uint32_t first; 1538fcf3ce44SJohn Forte uint32_t last; 1539fcf3ce44SJohn Forte uint32_t count; 1540fcf3ce44SJohn Forte uint32_t index; 1541fcf3ce44SJohn Forte emlxs_msg_entry_t *entry; 1542fcf3ce44SJohn Forte dfc_linkinfo_t *linkinfo; 1543fcf3ce44SJohn Forte uint32_t *word; 1544fcf3ce44SJohn Forte uint8_t *byte; 1545fcf3ce44SJohn Forte uint8_t linkspeed; 1546fcf3ce44SJohn Forte uint8_t liptype; 1547fcf3ce44SJohn Forte fc_affected_id_t *aid; 1548fcf3ce44SJohn Forte uint32_t max_events; 1549fcf3ce44SJohn Forte uint32_t events; 1550fcf3ce44SJohn Forte emlxs_hba_event_t *hba_event; 1551fcf3ce44SJohn Forte 1552fcf3ce44SJohn Forte if (!eventinfo || !eventcount || !missed) { 1553fcf3ce44SJohn Forte return (DFC_ARG_NULL); 1554fcf3ce44SJohn Forte } 1555291a2b48SSukumar Swaminathan 1556fcf3ce44SJohn Forte hba_event = &hba->hba_event; 1557fcf3ce44SJohn Forte max_events = *eventcount; 1558fcf3ce44SJohn Forte *eventcount = 0; 1559fcf3ce44SJohn Forte 1560fcf3ce44SJohn Forte log = &LOG; 1561fcf3ce44SJohn Forte 1562fcf3ce44SJohn Forte mutex_enter(&log->lock); 1563fcf3ce44SJohn Forte 1564fcf3ce44SJohn Forte /* Check if log is empty */ 1565fcf3ce44SJohn Forte if (log->count == 0) { 1566fcf3ce44SJohn Forte /* Make sure everything is initialized */ 1567fcf3ce44SJohn Forte hba_event->new = 0; 1568fcf3ce44SJohn Forte hba_event->missed = 0; 1569fcf3ce44SJohn Forte hba_event->last_id = 0; 1570fcf3ce44SJohn Forte 1571fcf3ce44SJohn Forte mutex_exit(&log->lock); 1572fcf3ce44SJohn Forte return (0); 1573fcf3ce44SJohn Forte } 1574291a2b48SSukumar Swaminathan 1575fcf3ce44SJohn Forte /* Safety check */ 1576fcf3ce44SJohn Forte if (hba_event->last_id > (log->count - 1)) { 1577fcf3ce44SJohn Forte hba_event->last_id = log->count - 1; 1578fcf3ce44SJohn Forte } 1579291a2b48SSukumar Swaminathan 1580fcf3ce44SJohn Forte /* Account for missed events */ 1581fcf3ce44SJohn Forte if (hba_event->new > hba_event->missed) { 1582fcf3ce44SJohn Forte hba_event->new -= hba_event->missed; 1583fcf3ce44SJohn Forte } else { 1584fcf3ce44SJohn Forte hba_event->new = 0; 1585fcf3ce44SJohn Forte } 1586fcf3ce44SJohn Forte 1587fcf3ce44SJohn Forte *missed = hba_event->missed; 1588fcf3ce44SJohn Forte hba_event->missed = 0; 1589fcf3ce44SJohn Forte 1590fcf3ce44SJohn Forte if (!hba_event->new) { 1591fcf3ce44SJohn Forte hba_event->last_id = log->count; 1592fcf3ce44SJohn Forte mutex_exit(&log->lock); 1593fcf3ce44SJohn Forte return (0); 1594fcf3ce44SJohn Forte } 1595291a2b48SSukumar Swaminathan 1596fcf3ce44SJohn Forte /* A new event has occurred since last acquisition */ 1597fcf3ce44SJohn Forte /* Calculate the current buffer boundaries */ 1598fcf3ce44SJohn Forte 1599fcf3ce44SJohn Forte /* Get last entry id saved */ 1600fcf3ce44SJohn Forte last = log->count - 1; 1601fcf3ce44SJohn Forte 1602fcf3ce44SJohn Forte /* Get oldest entry id and its index */ 1603fcf3ce44SJohn Forte /* Check if buffer has already been filled once */ 1604fcf3ce44SJohn Forte if (log->count >= log->size) { 1605fcf3ce44SJohn Forte first = log->count - log->size; 1606fcf3ce44SJohn Forte index = log->next; 1607fcf3ce44SJohn Forte } else { /* Buffer not yet filled */ 1608291a2b48SSukumar Swaminathan 1609fcf3ce44SJohn Forte first = 0; 1610fcf3ce44SJohn Forte index = 0; 1611fcf3ce44SJohn Forte } 1612fcf3ce44SJohn Forte 1613291a2b48SSukumar Swaminathan /* Check if requested first event is greater than actual. */ 1614291a2b48SSukumar Swaminathan /* If so, adjust for it. */ 1615fcf3ce44SJohn Forte if (hba_event->last_id > first) { 1616fcf3ce44SJohn Forte /* Adjust entry index to first requested message */ 1617fcf3ce44SJohn Forte index += (hba_event->last_id - first); 1618fcf3ce44SJohn Forte if (index >= log->size) { 1619fcf3ce44SJohn Forte index -= log->size; 1620fcf3ce44SJohn Forte } 1621291a2b48SSukumar Swaminathan 1622fcf3ce44SJohn Forte first = hba_event->last_id; 1623fcf3ce44SJohn Forte } 1624291a2b48SSukumar Swaminathan 1625fcf3ce44SJohn Forte /* Get the total number of new messages */ 1626fcf3ce44SJohn Forte count = last - first; 1627fcf3ce44SJohn Forte 1628fcf3ce44SJohn Forte /* Scan log for next event */ 1629fcf3ce44SJohn Forte events = 0; 1630fcf3ce44SJohn Forte while (count-- && (events < max_events)) { 1631fcf3ce44SJohn Forte if (++index >= log->size) { 1632fcf3ce44SJohn Forte index = 0; 1633fcf3ce44SJohn Forte } 1634291a2b48SSukumar Swaminathan 1635fcf3ce44SJohn Forte entry = &log->entry[index]; 1636fcf3ce44SJohn Forte 1637fcf3ce44SJohn Forte if (!entry->msg) { 1638fcf3ce44SJohn Forte break; 1639fcf3ce44SJohn Forte } 1640291a2b48SSukumar Swaminathan 1641fcf3ce44SJohn Forte if ((entry->msg->level == EMLXS_EVENT) && 1642fcf3ce44SJohn Forte (entry->msg->mask & (EVT_LINK | EVT_RSCN))) { 1643fcf3ce44SJohn Forte /* Process this event */ 1644fcf3ce44SJohn Forte switch (entry->msg->mask) { 1645fcf3ce44SJohn Forte case EVT_LINK: 1646fcf3ce44SJohn Forte byte = (uint8_t *)entry->bp; 1647fcf3ce44SJohn Forte linkspeed = byte[0]; 1648fcf3ce44SJohn Forte liptype = byte[1]; 1649291a2b48SSukumar Swaminathan linkinfo = (dfc_linkinfo_t *)&byte[4]; 1650fcf3ce44SJohn Forte 1651fcf3ce44SJohn Forte if (linkinfo->a_linkState == LNK_DOWN) { 1652fcf3ce44SJohn Forte eventinfo->EventCode = 1653fcf3ce44SJohn Forte HBA_EVENT_LINK_DOWN; 1654fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1655fcf3ce44SJohn Forte PortFcId = linkinfo->a_DID; 1656fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1657fcf3ce44SJohn Forte Reserved[0] = 0; 1658fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1659fcf3ce44SJohn Forte Reserved[1] = 0; 1660fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1661fcf3ce44SJohn Forte Reserved[2] = 0; 1662fcf3ce44SJohn Forte } else { 1663fcf3ce44SJohn Forte eventinfo->EventCode = 1664fcf3ce44SJohn Forte HBA_EVENT_LINK_UP; 1665fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1666fcf3ce44SJohn Forte PortFcId = linkinfo->a_DID; 1667fcf3ce44SJohn Forte 1668fcf3ce44SJohn Forte if ((linkinfo->a_topology == 1669fcf3ce44SJohn Forte LNK_PUBLIC_LOOP) || 1670fcf3ce44SJohn Forte (linkinfo->a_topology == 1671fcf3ce44SJohn Forte LNK_LOOP)) { 1672291a2b48SSukumar Swaminathan eventinfo->Event. 1673291a2b48SSukumar Swaminathan Link_EventInfo. 1674fcf3ce44SJohn Forte Reserved[0] = 2; 1675fcf3ce44SJohn Forte } else { 1676291a2b48SSukumar Swaminathan eventinfo->Event. 1677291a2b48SSukumar Swaminathan Link_EventInfo. 1678fcf3ce44SJohn Forte Reserved[0] = 1; 1679fcf3ce44SJohn Forte } 1680fcf3ce44SJohn Forte 1681fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1682fcf3ce44SJohn Forte Reserved[1] = liptype; 1683fcf3ce44SJohn Forte eventinfo->Event.Link_EventInfo. 1684fcf3ce44SJohn Forte Reserved[2] = linkspeed; 1685fcf3ce44SJohn Forte } 1686fcf3ce44SJohn Forte 1687fcf3ce44SJohn Forte break; 1688fcf3ce44SJohn Forte 1689fcf3ce44SJohn Forte case EVT_RSCN: 1690fcf3ce44SJohn Forte word = (uint32_t *)entry->bp; 1691fcf3ce44SJohn Forte eventinfo->EventCode = HBA_EVENT_RSCN; 1692fcf3ce44SJohn Forte eventinfo->Event.RSCN_EventInfo.PortFcId = 1693fcf3ce44SJohn Forte word[0] & 0xFFFFFF; 1694fcf3ce44SJohn Forte /* word[1] is the RSCN payload command */ 1695fcf3ce44SJohn Forte 1696291a2b48SSukumar Swaminathan aid = (fc_affected_id_t *)&word[2]; 1697fcf3ce44SJohn Forte 1698fcf3ce44SJohn Forte switch (aid->aff_format) { 1699fcf3ce44SJohn Forte case 0: /* Port */ 1700fcf3ce44SJohn Forte eventinfo->Event.RSCN_EventInfo. 1701fcf3ce44SJohn Forte NPortPage = 1702fcf3ce44SJohn Forte aid->aff_d_id & 0x00ffffff; 1703fcf3ce44SJohn Forte break; 1704fcf3ce44SJohn Forte 1705fcf3ce44SJohn Forte case 1: /* Area */ 1706fcf3ce44SJohn Forte eventinfo->Event.RSCN_EventInfo. 1707fcf3ce44SJohn Forte NPortPage = 1708fcf3ce44SJohn Forte aid->aff_d_id & 0x00ffff00; 1709fcf3ce44SJohn Forte break; 1710fcf3ce44SJohn Forte 1711fcf3ce44SJohn Forte case 2: /* Domain */ 1712fcf3ce44SJohn Forte eventinfo->Event.RSCN_EventInfo. 1713fcf3ce44SJohn Forte NPortPage = 1714fcf3ce44SJohn Forte aid->aff_d_id & 0x00ff0000; 1715fcf3ce44SJohn Forte break; 1716fcf3ce44SJohn Forte 1717fcf3ce44SJohn Forte case 3: /* Network */ 1718fcf3ce44SJohn Forte eventinfo->Event.RSCN_EventInfo. 1719fcf3ce44SJohn Forte NPortPage = 0; 1720fcf3ce44SJohn Forte break; 1721fcf3ce44SJohn Forte } 1722fcf3ce44SJohn Forte 1723291a2b48SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo.Reserved[0] = 1724291a2b48SSukumar Swaminathan 0; 1725291a2b48SSukumar Swaminathan eventinfo->Event.RSCN_EventInfo.Reserved[1] = 1726291a2b48SSukumar Swaminathan 0; 1727fcf3ce44SJohn Forte 1728fcf3ce44SJohn Forte break; 1729fcf3ce44SJohn Forte } 1730fcf3ce44SJohn Forte 1731fcf3ce44SJohn Forte eventinfo++; 1732fcf3ce44SJohn Forte events++; 1733fcf3ce44SJohn Forte } 1734291a2b48SSukumar Swaminathan 1735fcf3ce44SJohn Forte hba_event->last_id = entry->id; 1736fcf3ce44SJohn Forte } 1737fcf3ce44SJohn Forte 1738fcf3ce44SJohn Forte /* Adjust new count */ 1739fcf3ce44SJohn Forte if (!count || (events >= hba_event->new)) { 1740fcf3ce44SJohn Forte hba_event->new = 0; 1741fcf3ce44SJohn Forte } else { 1742fcf3ce44SJohn Forte hba_event->new -= events; 1743fcf3ce44SJohn Forte } 1744fcf3ce44SJohn Forte 1745fcf3ce44SJohn Forte /* Return number of events acquired */ 1746fcf3ce44SJohn Forte *eventcount = events; 1747fcf3ce44SJohn Forte 1748fcf3ce44SJohn Forte mutex_exit(&log->lock); 1749fcf3ce44SJohn Forte 1750fcf3ce44SJohn Forte return (0); 1751fcf3ce44SJohn Forte 1752291a2b48SSukumar Swaminathan } /* emlxs_get_dfc_eventinfo() */ 1753fcf3ce44SJohn Forte 1754fcf3ce44SJohn Forte 1755fcf3ce44SJohn Forte uint32_t 1756fcf3ce44SJohn Forte emlxs_get_dfc_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event, 1757fcf3ce44SJohn Forte uint32_t sleep) 1758fcf3ce44SJohn Forte { 1759fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1760fcf3ce44SJohn Forte emlxs_msg_log_t *log; 1761fcf3ce44SJohn Forte uint32_t first; 1762fcf3ce44SJohn Forte uint32_t last; 1763fcf3ce44SJohn Forte uint32_t count; 1764fcf3ce44SJohn Forte uint32_t index; 1765fcf3ce44SJohn Forte uint32_t mask; 1766fcf3ce44SJohn Forte uint32_t i; 1767fcf3ce44SJohn Forte emlxs_msg_entry_t *entry; 1768fcf3ce44SJohn Forte uint32_t size; 1769fcf3ce44SJohn Forte uint32_t rc; 1770fcf3ce44SJohn Forte 1771fcf3ce44SJohn Forte size = 0; 1772fcf3ce44SJohn Forte 1773fcf3ce44SJohn Forte if (dfc_event->dataout && dfc_event->size) { 1774fcf3ce44SJohn Forte size = dfc_event->size; 1775fcf3ce44SJohn Forte } 1776fcf3ce44SJohn Forte dfc_event->size = 0; 1777fcf3ce44SJohn Forte 1778fcf3ce44SJohn Forte /* Get the log file pointer */ 1779fcf3ce44SJohn Forte log = &LOG; 1780fcf3ce44SJohn Forte 1781fcf3ce44SJohn Forte /* Calculate the event index */ 1782fcf3ce44SJohn Forte mask = dfc_event->event; 1783fcf3ce44SJohn Forte for (i = 0; i < 32; i++) { 1784fcf3ce44SJohn Forte if (mask & 0x01) { 1785fcf3ce44SJohn Forte break; 1786fcf3ce44SJohn Forte } 1787291a2b48SSukumar Swaminathan 1788fcf3ce44SJohn Forte mask >>= 1; 1789fcf3ce44SJohn Forte } 1790fcf3ce44SJohn Forte if (i == 32) { 1791fcf3ce44SJohn Forte return (DFC_ARG_INVALID); 1792fcf3ce44SJohn Forte } 1793291a2b48SSukumar Swaminathan 1794fcf3ce44SJohn Forte mutex_enter(&log->lock); 1795fcf3ce44SJohn Forte 1796fcf3ce44SJohn Forte /* Check if log is empty */ 1797fcf3ce44SJohn Forte if (log->count == 0) { 1798fcf3ce44SJohn Forte /* Make sure everything is initialized */ 1799fcf3ce44SJohn Forte log->event_id[i] = 0; 1800fcf3ce44SJohn Forte dfc_event->last_id = 0; 1801fcf3ce44SJohn Forte } else { 1802fcf3ce44SJohn Forte /* Check ranges for safety */ 1803fcf3ce44SJohn Forte if (log->event_id[i] > (log->count - 1)) { 1804fcf3ce44SJohn Forte log->event_id[i] = log->count - 1; 1805fcf3ce44SJohn Forte } 1806291a2b48SSukumar Swaminathan 1807fcf3ce44SJohn Forte if (dfc_event->last_id > log->event_id[i]) { 1808fcf3ce44SJohn Forte dfc_event->last_id = log->event_id[i]; 1809fcf3ce44SJohn Forte } 1810fcf3ce44SJohn Forte } 1811fcf3ce44SJohn Forte 1812fcf3ce44SJohn Forte wait_for_event: 1813fcf3ce44SJohn Forte 1814fcf3ce44SJohn Forte /* Check if no new event has ocurred */ 1815fcf3ce44SJohn Forte if (dfc_event->last_id == log->event_id[i]) { 1816fcf3ce44SJohn Forte if (!sleep) { 1817fcf3ce44SJohn Forte mutex_exit(&log->lock); 1818fcf3ce44SJohn Forte return (0); 1819fcf3ce44SJohn Forte } 1820291a2b48SSukumar Swaminathan 1821291a2b48SSukumar Swaminathan /* While event is still active and */ 1822291a2b48SSukumar Swaminathan /* no new event has been logged */ 1823fcf3ce44SJohn Forte while ((dfc_event->event & hba->log_events) && 1824fcf3ce44SJohn Forte (dfc_event->last_id == log->event_id[i])) { 1825fcf3ce44SJohn Forte rc = cv_wait_sig(&log->lock_cv, &log->lock); 1826fcf3ce44SJohn Forte 1827fcf3ce44SJohn Forte /* Check if thread was killed by kernel */ 1828fcf3ce44SJohn Forte if (rc == 0) { 1829fcf3ce44SJohn Forte dfc_event->pid = 0; 1830fcf3ce44SJohn Forte dfc_event->event = 0; 1831fcf3ce44SJohn Forte mutex_exit(&log->lock); 1832fcf3ce44SJohn Forte return (0); 1833fcf3ce44SJohn Forte } 1834fcf3ce44SJohn Forte } 1835fcf3ce44SJohn Forte 1836291a2b48SSukumar Swaminathan /* If the event is no longer registered then */ 1837291a2b48SSukumar Swaminathan /* return immediately */ 1838fcf3ce44SJohn Forte if (!(dfc_event->event & hba->log_events)) { 1839fcf3ce44SJohn Forte mutex_exit(&log->lock); 1840fcf3ce44SJohn Forte return (0); 1841fcf3ce44SJohn Forte } 1842fcf3ce44SJohn Forte } 1843291a2b48SSukumar Swaminathan 1844fcf3ce44SJohn Forte /* !!! An event has occurred since last_id !!! */ 1845fcf3ce44SJohn Forte 1846fcf3ce44SJohn Forte /* Check if event data is not being requested */ 1847fcf3ce44SJohn Forte if (!size) { 1848fcf3ce44SJohn Forte /* If so, then just return the last event id */ 1849fcf3ce44SJohn Forte dfc_event->last_id = log->event_id[i]; 1850fcf3ce44SJohn Forte 1851fcf3ce44SJohn Forte mutex_exit(&log->lock); 1852fcf3ce44SJohn Forte return (0); 1853fcf3ce44SJohn Forte } 1854291a2b48SSukumar Swaminathan 1855fcf3ce44SJohn Forte /* !!! The requester wants the next event buffer !!! */ 1856fcf3ce44SJohn Forte 1857fcf3ce44SJohn Forte /* Calculate the current buffer boundaries */ 1858fcf3ce44SJohn Forte 1859fcf3ce44SJohn Forte /* Get last entry id saved */ 1860fcf3ce44SJohn Forte last = log->count - 1; 1861fcf3ce44SJohn Forte 1862fcf3ce44SJohn Forte /* Get oldest entry id and its index */ 1863fcf3ce44SJohn Forte /* Check if buffer has already been filled once */ 1864fcf3ce44SJohn Forte if (log->count >= log->size) { 1865fcf3ce44SJohn Forte first = log->count - log->size; 1866fcf3ce44SJohn Forte index = log->next; 1867fcf3ce44SJohn Forte } else { /* Buffer not yet filled */ 1868291a2b48SSukumar Swaminathan 1869fcf3ce44SJohn Forte first = 0; 1870fcf3ce44SJohn Forte index = 0; 1871fcf3ce44SJohn Forte } 1872fcf3ce44SJohn Forte 1873fcf3ce44SJohn Forte /* Check to see if the buffer has wrapped since the last event */ 1874fcf3ce44SJohn Forte if (first > log->event_id[i]) { 1875fcf3ce44SJohn Forte /* Update last_id to the last known event */ 1876fcf3ce44SJohn Forte dfc_event->last_id = log->event_id[i]; 1877fcf3ce44SJohn Forte 1878fcf3ce44SJohn Forte /* Try waiting again if we can */ 1879fcf3ce44SJohn Forte goto wait_for_event; 1880fcf3ce44SJohn Forte } 1881291a2b48SSukumar Swaminathan 1882291a2b48SSukumar Swaminathan /* Check if requested first event is greater than actual. */ 1883291a2b48SSukumar Swaminathan /* If so, adjust for it. */ 1884fcf3ce44SJohn Forte if (dfc_event->last_id > first) { 1885fcf3ce44SJohn Forte /* Adjust entry index to first requested message */ 1886fcf3ce44SJohn Forte index += (dfc_event->last_id - first); 1887fcf3ce44SJohn Forte if (index >= log->size) { 1888fcf3ce44SJohn Forte index -= log->size; 1889fcf3ce44SJohn Forte } 1890291a2b48SSukumar Swaminathan 1891fcf3ce44SJohn Forte first = dfc_event->last_id; 1892fcf3ce44SJohn Forte } 1893291a2b48SSukumar Swaminathan 1894fcf3ce44SJohn Forte /* Get the total number of new messages */ 1895fcf3ce44SJohn Forte count = last - first + 1; 1896fcf3ce44SJohn Forte 1897fcf3ce44SJohn Forte /* Scan log for next event */ 1898fcf3ce44SJohn Forte while (count--) { 1899fcf3ce44SJohn Forte if (++index >= log->size) { 1900fcf3ce44SJohn Forte index = 0; 1901fcf3ce44SJohn Forte } 1902291a2b48SSukumar Swaminathan 1903fcf3ce44SJohn Forte entry = &log->entry[index]; 1904fcf3ce44SJohn Forte 1905fcf3ce44SJohn Forte if ((entry->msg->level == EMLXS_EVENT) && 1906fcf3ce44SJohn Forte (entry->msg->mask == dfc_event->event)) { 1907fcf3ce44SJohn Forte break; 1908fcf3ce44SJohn Forte } 1909fcf3ce44SJohn Forte } 1910fcf3ce44SJohn Forte 1911291a2b48SSukumar Swaminathan /* Check if no new event was found in the current log buffer */ 1912291a2b48SSukumar Swaminathan /* This would indicate that the buffer wrapped since that last event */ 1913fcf3ce44SJohn Forte if (!count) { 1914fcf3ce44SJohn Forte /* Update last_id to the last known event */ 1915fcf3ce44SJohn Forte dfc_event->last_id = log->event_id[i]; 1916fcf3ce44SJohn Forte 1917fcf3ce44SJohn Forte /* Try waiting again if we can */ 1918fcf3ce44SJohn Forte goto wait_for_event; 1919fcf3ce44SJohn Forte } 1920291a2b48SSukumar Swaminathan 1921fcf3ce44SJohn Forte /* !!! Next event found !!! */ 1922fcf3ce44SJohn Forte 1923fcf3ce44SJohn Forte /* Copy the context buffer to the buffer provided */ 1924fcf3ce44SJohn Forte if (entry->bp && entry->size) { 1925fcf3ce44SJohn Forte if (entry->size < size) { 1926fcf3ce44SJohn Forte size = entry->size; 1927fcf3ce44SJohn Forte } 1928291a2b48SSukumar Swaminathan 1929291a2b48SSukumar Swaminathan if (ddi_copyout((void *)entry->bp, dfc_event->dataout, size, 1930fcf3ce44SJohn Forte dfc_event->mode) != 0) { 1931fcf3ce44SJohn Forte mutex_exit(&log->lock); 1932fcf3ce44SJohn Forte 1933fcf3ce44SJohn Forte return (DFC_COPYOUT_ERROR); 1934fcf3ce44SJohn Forte } 1935291a2b48SSukumar Swaminathan 1936291a2b48SSukumar Swaminathan /* Data has been retrieved by the apps */ 1937291a2b48SSukumar Swaminathan entry->flag |= EMLX_EVENT_DONE; 1938291a2b48SSukumar Swaminathan 1939fcf3ce44SJohn Forte dfc_event->size = size; 1940fcf3ce44SJohn Forte } 1941291a2b48SSukumar Swaminathan 1942fcf3ce44SJohn Forte dfc_event->last_id = entry->id; 1943fcf3ce44SJohn Forte 1944fcf3ce44SJohn Forte mutex_exit(&log->lock); 1945fcf3ce44SJohn Forte return (0); 1946fcf3ce44SJohn Forte 1947291a2b48SSukumar Swaminathan } /* emlxs_get_dfc_event() */ 1948fcf3ce44SJohn Forte 1949fcf3ce44SJohn Forte 1950fcf3ce44SJohn Forte uint32_t 1951fcf3ce44SJohn Forte emlxs_kill_dfc_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event) 1952fcf3ce44SJohn Forte { 1953fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA; 1954fcf3ce44SJohn Forte emlxs_msg_log_t *log; 1955fcf3ce44SJohn Forte 1956fcf3ce44SJohn Forte /* Get the log file pointer */ 1957fcf3ce44SJohn Forte log = &LOG; 1958fcf3ce44SJohn Forte 1959fcf3ce44SJohn Forte mutex_enter(&log->lock); 1960fcf3ce44SJohn Forte dfc_event->pid = 0; 1961fcf3ce44SJohn Forte dfc_event->event = 0; 1962fcf3ce44SJohn Forte cv_broadcast(&log->lock_cv); 1963fcf3ce44SJohn Forte mutex_exit(&log->lock); 1964fcf3ce44SJohn Forte 1965fcf3ce44SJohn Forte return (0); 1966fcf3ce44SJohn Forte 1967291a2b48SSukumar Swaminathan } /* emlxs_kill_dfc_event() */ 1968291a2b48SSukumar Swaminathan 1969291a2b48SSukumar Swaminathan 1970291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT 1971291a2b48SSukumar Swaminathan uint32_t 1972291a2b48SSukumar Swaminathan emlxs_get_sd_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event, 1973291a2b48SSukumar Swaminathan uint32_t sleep) 1974291a2b48SSukumar Swaminathan { 1975291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA; 1976291a2b48SSukumar Swaminathan emlxs_msg_log_t *log; 1977291a2b48SSukumar Swaminathan emlxs_msg_entry_t *entry; 1978291a2b48SSukumar Swaminathan uint32_t size; 1979291a2b48SSukumar Swaminathan uint32_t rc; 1980291a2b48SSukumar Swaminathan uint32_t first; 1981291a2b48SSukumar Swaminathan uint32_t last; 1982291a2b48SSukumar Swaminathan uint32_t count; 1983291a2b48SSukumar Swaminathan uint32_t index; 1984291a2b48SSukumar Swaminathan uint32_t mask; 1985291a2b48SSukumar Swaminathan uint32_t i; 1986291a2b48SSukumar Swaminathan 1987291a2b48SSukumar Swaminathan size = 0; 1988291a2b48SSukumar Swaminathan 1989291a2b48SSukumar Swaminathan if (dfc_event->dataout && dfc_event->size) { 1990291a2b48SSukumar Swaminathan size = dfc_event->size; 1991291a2b48SSukumar Swaminathan } 1992291a2b48SSukumar Swaminathan dfc_event->size = 0; 1993291a2b48SSukumar Swaminathan 1994291a2b48SSukumar Swaminathan /* Get the log file pointer */ 1995291a2b48SSukumar Swaminathan log = &LOG; 1996291a2b48SSukumar Swaminathan 1997291a2b48SSukumar Swaminathan /* Calculate the event index */ 1998291a2b48SSukumar Swaminathan mask = dfc_event->event; 1999291a2b48SSukumar Swaminathan for (i = 0; i < 32; i++) { 2000291a2b48SSukumar Swaminathan if (mask & 0x01) 2001291a2b48SSukumar Swaminathan break; 2002291a2b48SSukumar Swaminathan 2003291a2b48SSukumar Swaminathan mask >>= 1; 2004291a2b48SSukumar Swaminathan } 2005291a2b48SSukumar Swaminathan if (i == 32) 2006291a2b48SSukumar Swaminathan return (DFC_ARG_INVALID); 2007291a2b48SSukumar Swaminathan 2008291a2b48SSukumar Swaminathan mutex_enter(&log->lock); 2009fcf3ce44SJohn Forte 2010291a2b48SSukumar Swaminathan /* Check if log is empty */ 2011291a2b48SSukumar Swaminathan if (log->count == 0) { 2012291a2b48SSukumar Swaminathan /* Make sure everything is initialized */ 2013291a2b48SSukumar Swaminathan log->event_id[i] = 0; 2014291a2b48SSukumar Swaminathan dfc_event->last_id = 0; 2015291a2b48SSukumar Swaminathan } else { 2016291a2b48SSukumar Swaminathan /* Check ranges for safety */ 2017291a2b48SSukumar Swaminathan if (log->event_id[i] > (log->count - 1)) 2018291a2b48SSukumar Swaminathan log->event_id[i] = log->count - 1; 2019291a2b48SSukumar Swaminathan 2020291a2b48SSukumar Swaminathan if (dfc_event->last_id > log->event_id[i]) 2021291a2b48SSukumar Swaminathan dfc_event->last_id = log->event_id[i]; 2022291a2b48SSukumar Swaminathan } 2023291a2b48SSukumar Swaminathan 2024291a2b48SSukumar Swaminathan wait_for_sd_event: 2025291a2b48SSukumar Swaminathan /* Check if no new event has ocurred */ 2026291a2b48SSukumar Swaminathan if (dfc_event->last_id == log->event_id[i]) { 2027291a2b48SSukumar Swaminathan if (!sleep) { 2028291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2029291a2b48SSukumar Swaminathan return (0); 2030291a2b48SSukumar Swaminathan } 2031291a2b48SSukumar Swaminathan 2032291a2b48SSukumar Swaminathan /* While event is active and no new event has been logged */ 2033291a2b48SSukumar Swaminathan while ((dfc_event->event & port->sd_reg_events) && 2034291a2b48SSukumar Swaminathan (dfc_event->last_id == log->event_id[i])) { 2035291a2b48SSukumar Swaminathan rc = cv_wait_sig(&log->lock_cv, &log->lock); 2036291a2b48SSukumar Swaminathan 2037291a2b48SSukumar Swaminathan /* Check if thread was killed by kernel */ 2038291a2b48SSukumar Swaminathan if (rc == 0) { 2039291a2b48SSukumar Swaminathan dfc_event->pid = 0; 2040291a2b48SSukumar Swaminathan dfc_event->event = 0; 2041291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2042291a2b48SSukumar Swaminathan return (0); 2043291a2b48SSukumar Swaminathan } 2044291a2b48SSukumar Swaminathan } 2045291a2b48SSukumar Swaminathan 2046291a2b48SSukumar Swaminathan /* If the event is no longer registered then return */ 2047291a2b48SSukumar Swaminathan if (!(dfc_event->event & port->sd_reg_events)) { 2048291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2049291a2b48SSukumar Swaminathan return (0); 2050291a2b48SSukumar Swaminathan } 2051291a2b48SSukumar Swaminathan } 2052291a2b48SSukumar Swaminathan 2053291a2b48SSukumar Swaminathan /* !!! An event has occurred since last_id !!! */ 2054291a2b48SSukumar Swaminathan 2055291a2b48SSukumar Swaminathan /* Check if event data is not being requested */ 2056291a2b48SSukumar Swaminathan if (!size) { 2057291a2b48SSukumar Swaminathan /* If so, then just return the last event id */ 2058291a2b48SSukumar Swaminathan dfc_event->last_id = log->event_id[i]; 2059291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2060291a2b48SSukumar Swaminathan return (0); 2061291a2b48SSukumar Swaminathan } 2062291a2b48SSukumar Swaminathan 2063291a2b48SSukumar Swaminathan /* !!! The requester wants the next event buffer !!! */ 2064291a2b48SSukumar Swaminathan 2065291a2b48SSukumar Swaminathan /* Calculate the current buffer boundaries */ 2066291a2b48SSukumar Swaminathan 2067291a2b48SSukumar Swaminathan /* Get last entry id saved */ 2068291a2b48SSukumar Swaminathan last = log->count - 1; 2069291a2b48SSukumar Swaminathan 2070291a2b48SSukumar Swaminathan /* Get oldest entry id and its index */ 2071291a2b48SSukumar Swaminathan /* Check if buffer has already been filled once */ 2072291a2b48SSukumar Swaminathan if (log->count >= log->size) { 2073291a2b48SSukumar Swaminathan first = log->count - log->size; 2074291a2b48SSukumar Swaminathan index = log->next; 2075291a2b48SSukumar Swaminathan } else { /* Buffer not yet filled */ 2076291a2b48SSukumar Swaminathan first = 0; 2077291a2b48SSukumar Swaminathan index = 0; 2078291a2b48SSukumar Swaminathan } 2079291a2b48SSukumar Swaminathan 2080291a2b48SSukumar Swaminathan /* Check to see if the buffer has wrapped since the last event */ 2081291a2b48SSukumar Swaminathan if (first > log->event_id[i]) { 2082291a2b48SSukumar Swaminathan /* Update last_id to the last known event */ 2083291a2b48SSukumar Swaminathan dfc_event->last_id = log->event_id[i]; 2084291a2b48SSukumar Swaminathan 2085291a2b48SSukumar Swaminathan /* Try waiting again if we can */ 2086291a2b48SSukumar Swaminathan goto wait_for_sd_event; 2087291a2b48SSukumar Swaminathan } 2088291a2b48SSukumar Swaminathan 2089291a2b48SSukumar Swaminathan /* if requested first event is greater than actual, adjust for it. */ 2090291a2b48SSukumar Swaminathan if (dfc_event->last_id > first) { 2091291a2b48SSukumar Swaminathan /* Adjust entry index to first requested message */ 2092291a2b48SSukumar Swaminathan index += (dfc_event->last_id - first); 2093291a2b48SSukumar Swaminathan if (index >= log->size) { 2094291a2b48SSukumar Swaminathan index -= log->size; 2095291a2b48SSukumar Swaminathan } 2096291a2b48SSukumar Swaminathan 2097291a2b48SSukumar Swaminathan first = dfc_event->last_id; 2098291a2b48SSukumar Swaminathan } 2099291a2b48SSukumar Swaminathan 2100291a2b48SSukumar Swaminathan /* Get the total number of new messages */ 2101291a2b48SSukumar Swaminathan count = last - first + 1; 2102291a2b48SSukumar Swaminathan 2103291a2b48SSukumar Swaminathan /* Scan log for next event */ 2104291a2b48SSukumar Swaminathan while (count--) { 2105291a2b48SSukumar Swaminathan if (++index >= log->size) 2106291a2b48SSukumar Swaminathan index = 0; 2107291a2b48SSukumar Swaminathan 2108291a2b48SSukumar Swaminathan entry = &log->entry[index]; 2109291a2b48SSukumar Swaminathan 2110291a2b48SSukumar Swaminathan if ((entry->msg->level == EMLXS_EVENT) && 2111291a2b48SSukumar Swaminathan (entry->vpi == port->vpi) && 2112291a2b48SSukumar Swaminathan (entry->msg->mask == dfc_event->event)) 2113291a2b48SSukumar Swaminathan break; 2114291a2b48SSukumar Swaminathan } 2115291a2b48SSukumar Swaminathan 2116291a2b48SSukumar Swaminathan /* Check if no new event was found in the current log buffer */ 2117291a2b48SSukumar Swaminathan /* This would indicate that the buffer wrapped since that last event */ 2118291a2b48SSukumar Swaminathan if (!count) { 2119291a2b48SSukumar Swaminathan /* Update last_id to the last known event */ 2120291a2b48SSukumar Swaminathan dfc_event->last_id = log->event_id[i]; 2121291a2b48SSukumar Swaminathan 2122291a2b48SSukumar Swaminathan /* Try waiting again if we can */ 2123291a2b48SSukumar Swaminathan goto wait_for_sd_event; 2124291a2b48SSukumar Swaminathan } 2125291a2b48SSukumar Swaminathan 2126291a2b48SSukumar Swaminathan /* !!! Next event found !!! */ 2127291a2b48SSukumar Swaminathan 2128291a2b48SSukumar Swaminathan /* Copy the context buffer to the buffer provided */ 2129291a2b48SSukumar Swaminathan if (entry->bp && entry->size) { 2130291a2b48SSukumar Swaminathan if (entry->size < size) 2131291a2b48SSukumar Swaminathan size = entry->size; 2132291a2b48SSukumar Swaminathan 2133291a2b48SSukumar Swaminathan if (ddi_copyout((void *) entry->bp, dfc_event->dataout, 2134291a2b48SSukumar Swaminathan size, dfc_event->mode) != 0) { 2135291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2136291a2b48SSukumar Swaminathan 2137291a2b48SSukumar Swaminathan return (DFC_COPYOUT_ERROR); 2138291a2b48SSukumar Swaminathan } 2139291a2b48SSukumar Swaminathan 2140291a2b48SSukumar Swaminathan dfc_event->size = size; 2141291a2b48SSukumar Swaminathan } 2142291a2b48SSukumar Swaminathan 2143291a2b48SSukumar Swaminathan dfc_event->last_id = entry->id; 2144291a2b48SSukumar Swaminathan mutex_exit(&log->lock); 2145291a2b48SSukumar Swaminathan 2146291a2b48SSukumar Swaminathan return (0); 2147291a2b48SSukumar Swaminathan } /* emlxs_get_sd_event */ 2148291a2b48SSukumar Swaminathan #endif /* SAN_DIAG_SUPPORT */ 2149fcf3ce44SJohn Forte 2150fcf3ce44SJohn Forte 2151291a2b48SSukumar Swaminathan #endif /* DFC_SUPPORT */ 2152