emlxs_msg.c (3be114ed) emlxs_msg.c (82527734)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 7 unchanged lines hidden (view full) ---

16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2009 Emulex. All rights reserved.
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 7 unchanged lines hidden (view full) ---

16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2009 Emulex. All rights reserved.
24 * Use is subject to License terms.
24 * Use is subject to license terms.
25 */
26
25 */
26
27
27#define DEF_MSG_STRUCT /* Needed for emlxs_messages.h in emlxs_msg.h */
28#include <emlxs.h>
29
30
31/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
32EMLXS_MSG_DEF(EMLXS_MSG_C);
33
34uint32_t emlxs_log_size = 2048;

--- 27 unchanged lines hidden (view full) ---

62 DRIVER_NAME, hba->ddiinst, (void *)log);
63 return (0);
64 }
65
66 /* Clear the log */
67 bzero(log, sizeof (emlxs_msg_log_t));
68
69 /* Allocate the memory needed for the log file */
28#define DEF_MSG_STRUCT /* Needed for emlxs_messages.h in emlxs_msg.h */
29#include <emlxs.h>
30
31
32/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
33EMLXS_MSG_DEF(EMLXS_MSG_C);
34
35uint32_t emlxs_log_size = 2048;

--- 27 unchanged lines hidden (view full) ---

63 DRIVER_NAME, hba->ddiinst, (void *)log);
64 return (0);
65 }
66
67 /* Clear the log */
68 bzero(log, sizeof (emlxs_msg_log_t));
69
70 /* Allocate the memory needed for the log file */
70 if (!(log->entry = (emlxs_msg_entry_t *)kmem_zalloc(size, KM_SLEEP))) {
71 cmn_err(CE_WARN,
72 "?%s%d: Unable to allocate log memory. log=%p",
73 DRIVER_NAME, hba->ddiinst, (void *)log);
74 return (0);
75 }
71 log->entry = (emlxs_msg_entry_t *)kmem_zalloc(size, KM_SLEEP);
76
77 /* Initialize */
78 log->size = emlxs_log_size;
79 log->instance = hba->ddiinst;
80 log->start_time = emlxs_device.log_timestamp;
81
72
73 /* Initialize */
74 log->size = emlxs_log_size;
75 log->instance = hba->ddiinst;
76 log->start_time = emlxs_device.log_timestamp;
77
82 (void) sprintf(buf, "?%s%d_log_lock control variable", DRIVER_NAME,
83 hba->ddiinst);
84 cv_init(&log->lock_cv, buf, CV_DRIVER, NULL);
85
86 (void) sprintf(buf, "?%s%d_log_lock mutex", DRIVER_NAME, hba->ddiinst);
87
88 if (!(hba->intr_flags & EMLXS_MSI_ENABLED)) {
89 /* Get the current interrupt block cookie */
90 (void) ddi_get_iblock_cookie(hba->dip, (uint_t)EMLXS_INUMBER,
91 &iblock);
92
93 /* Create the log mutex lock */

--- 41 unchanged lines hidden (view full) ---

135
136 /* Free the temporary handle */
137 (void) ddi_intr_free(handle);
138 }
139#endif
140
141 return (1);
142
78 (void) sprintf(buf, "?%s%d_log_lock mutex", DRIVER_NAME, hba->ddiinst);
79
80 if (!(hba->intr_flags & EMLXS_MSI_ENABLED)) {
81 /* Get the current interrupt block cookie */
82 (void) ddi_get_iblock_cookie(hba->dip, (uint_t)EMLXS_INUMBER,
83 &iblock);
84
85 /* Create the log mutex lock */

--- 41 unchanged lines hidden (view full) ---

127
128 /* Free the temporary handle */
129 (void) ddi_intr_free(handle);
130 }
131#endif
132
133 return (1);
134
143} /* emlxs_msg_log_create() */
135} /* emlxs_msg_log_create() */
144
145
146uint32_t
147emlxs_msg_log_destroy(emlxs_hba_t *hba)
148{
149 emlxs_msg_log_t *log = &LOG;
150 uint32_t size;
136
137
138uint32_t
139emlxs_msg_log_destroy(emlxs_hba_t *hba)
140{
141 emlxs_msg_log_t *log = &LOG;
142 uint32_t size;
151 emlxs_msg_entry_t *entry;
152 uint32_t i;
153
154 /* Check if log is already destroyed */
155 if (!log->entry) {
156 cmn_err(CE_WARN,
157 "?%s%d: message log already destroyed. log=%p",
158 DRIVER_NAME, hba->ddiinst, (void *)log);
159
160 return (1);
161 }
162
143
144 /* Check if log is already destroyed */
145 if (!log->entry) {
146 cmn_err(CE_WARN,
147 "?%s%d: message log already destroyed. log=%p",
148 DRIVER_NAME, hba->ddiinst, (void *)log);
149
150 return (1);
151 }
152
163 /* If events are being logged there might be */
164 /* threads waiting so release them */
165 if (hba->log_events) {
166 mutex_enter(&log->lock);
167 hba->log_events = 0;
168 cv_broadcast(&log->lock_cv);
169 mutex_exit(&log->lock);
170
171 DELAYMS(1);
172 }
173
174 /* Destroy the lock */
175 mutex_destroy(&log->lock);
153 /* Destroy the lock */
154 mutex_destroy(&log->lock);
176 cv_destroy(&log->lock_cv);
177
155
178 /* Free the context buffers */
179 for (i = 0; i < log->size; i++) {
180 entry = &log->entry[i];
181
182 if (entry->bp && entry->size) {
183 kmem_free(entry->bp, entry->size);
184 }
185 }
186
187 /* Free the log buffer */
188 size = sizeof (emlxs_msg_entry_t) * log->size;
189 kmem_free(log->entry, size);
190
191 /* Clear the log */
192 bzero(log, sizeof (emlxs_msg_log_t));
193
194 return (1);
195
156 /* Free the log buffer */
157 size = sizeof (emlxs_msg_entry_t) * log->size;
158 kmem_free(log->entry, size);
159
160 /* Clear the log */
161 bzero(log, sizeof (emlxs_msg_log_t));
162
163 return (1);
164
196} /* emlxs_msg_log_destroy() */
165} /* emlxs_msg_log_destroy() */
197
198
199uint32_t
200emlxs_msg_log(emlxs_port_t *port, const uint32_t fileno, const uint32_t line,
166
167
168uint32_t
169emlxs_msg_log(emlxs_port_t *port, const uint32_t fileno, const uint32_t line,
201 void *bp, uint32_t size, emlxs_msg_t *msg, char *buffer)
170 emlxs_msg_t *msg, char *buffer)
202{
203 emlxs_hba_t *hba = HBA;
204 emlxs_msg_entry_t *entry;
205 emlxs_msg_entry_t *entry2;
206 clock_t time;
207 emlxs_msg_log_t *log;
208 uint32_t last;
171{
172 emlxs_hba_t *hba = HBA;
173 emlxs_msg_entry_t *entry;
174 emlxs_msg_entry_t *entry2;
175 clock_t time;
176 emlxs_msg_log_t *log;
177 uint32_t last;
209 uint32_t mask;
210 emlxs_msg_t *msg2;
178 emlxs_msg_t *msg2;
211 uint32_t rxid = 0;
212 uint32_t i;
213
214 /* Get the log file for this instance */
215 log = &LOG;
216
217 /* Check if log is initialized */
218 if (log->entry == NULL) {
219
220 if (port->vpi == 0) {
221 cmn_err(CE_WARN,
222 "?%s%d: message log not created. log=%p",
223 DRIVER_NAME, hba->ddiinst, (void *)log);
224 } else {
225 cmn_err(CE_WARN,
226 "?%s%d.%d: message log not created. log=%p",
227 DRIVER_NAME, hba->ddiinst, port->vpi,
228 (void *)log);
229 }
230
179
180 /* Get the log file for this instance */
181 log = &LOG;
182
183 /* Check if log is initialized */
184 if (log->entry == NULL) {
185
186 if (port->vpi == 0) {
187 cmn_err(CE_WARN,
188 "?%s%d: message log not created. log=%p",
189 DRIVER_NAME, hba->ddiinst, (void *)log);
190 } else {
191 cmn_err(CE_WARN,
192 "?%s%d.%d: message log not created. log=%p",
193 DRIVER_NAME, hba->ddiinst, port->vpi,
194 (void *)log);
195 }
196
231 if (bp && size) {
232 kmem_free(bp, size);
233 }
234
235 return (1);
236 }
237
238 mutex_enter(&log->lock);
239
240 /* Get the pointer to the last log entry */
241 if (log->next == 0) {
242 last = log->size - 1;
243 } else {
244 last = log->next - 1;
245 }
246 entry = &log->entry[last];
247
248 /* Check if this matches the last message */
249 if ((entry->instance == log->instance) &&
250 (entry->vpi == port->vpi) &&
251 (entry->fileno == fileno) &&
252 (entry->line == line) &&
197 return (1);
198 }
199
200 mutex_enter(&log->lock);
201
202 /* Get the pointer to the last log entry */
203 if (log->next == 0) {
204 last = log->size - 1;
205 } else {
206 last = log->next - 1;
207 }
208 entry = &log->entry[last];
209
210 /* Check if this matches the last message */
211 if ((entry->instance == log->instance) &&
212 (entry->vpi == port->vpi) &&
213 (entry->fileno == fileno) &&
214 (entry->line == line) &&
253 (entry->bp == bp) &&
254 (entry->size == size) &&
255 (entry->msg == msg) &&
256 (strcmp(entry->buffer, buffer) == 0)) {
257 /* If the same message is being logged then increment */
258 log->repeat++;
259
260 mutex_exit(&log->lock);
261
262 return (0);

--- 21 unchanged lines hidden (view full) ---

284
285 case EMLXS_ERROR:
286 msg2 = &emlxs_error_msg;
287 break;
288
289 case EMLXS_PANIC:
290 msg2 = &emlxs_panic_msg;
291 break;
215 (entry->msg == msg) &&
216 (strcmp(entry->buffer, buffer) == 0)) {
217 /* If the same message is being logged then increment */
218 log->repeat++;
219
220 mutex_exit(&log->lock);
221
222 return (0);

--- 21 unchanged lines hidden (view full) ---

244
245 case EMLXS_ERROR:
246 msg2 = &emlxs_error_msg;
247 break;
248
249 case EMLXS_PANIC:
250 msg2 = &emlxs_panic_msg;
251 break;
292
293 case EMLXS_EVENT:
294 msg2 = &emlxs_event_msg;
295 break;
296 }
297
252 }
253
298 /* Check if we are about to overwrite an event entry */
299 if (entry2->msg && (entry2->msg->level == EMLXS_EVENT)) {
300 /* Check if this event has not been acquired */
301 if (log->count > (hba->hba_event.last_id + log->size)) {
302 hba->hba_event.missed++;
303
304 if ((entry2->msg->mask == EVT_CT) &&
305 !(entry2->flag & EMLX_EVENT_DONE)) {
306 /* Abort exchange */
307 rxid = *((uint32_t *)entry2->bp);
308 }
309 }
310 }
311
312 /* Free the old context buffer since we are about to erase it */
313 if (entry2->bp && entry2->size) {
314 kmem_free(entry2->bp, entry2->size);
315 }
316
317 /* Initialize */
318 entry2->id = log->count++;
319 entry2->fileno = entry->fileno;
320 entry2->line = entry->line;
254 /* Initialize */
255 entry2->id = log->count++;
256 entry2->fileno = entry->fileno;
257 entry2->line = entry->line;
321 entry2->bp = 0;
322 entry2->size = 0;
323 entry2->msg = msg2;
324 entry2->instance = log->instance;
325 entry2->vpi = port->vpi;
258 entry2->msg = msg2;
259 entry2->instance = log->instance;
260 entry2->vpi = port->vpi;
326 entry2->flag = 0;
327
328 /* Save the additional info buffer */
329 (void) sprintf(entry2->buffer,
330 "Last message repeated %d time(s).",
331 log->repeat);
332
333 /* Set the entry time stamp */
334 (void) drv_getparm(LBOLT, &time);
335 entry2->time = time - log->start_time;
336
261
262 /* Save the additional info buffer */
263 (void) sprintf(entry2->buffer,
264 "Last message repeated %d time(s).",
265 log->repeat);
266
267 /* Set the entry time stamp */
268 (void) drv_getparm(LBOLT, &time);
269 entry2->time = time - log->start_time;
270
271 gethrestime(&entry2->id_time);
272
337 log->repeat = 0;
338 }
339
340 /* Get the pointer to the next log entry */
341 entry = &log->entry[log->next];
342
343 /* Increment and check the next entry index */
344 if (++(log->next) >= log->size) {
345 log->next = 0;
346 }
347
273 log->repeat = 0;
274 }
275
276 /* Get the pointer to the next log entry */
277 entry = &log->entry[log->next];
278
279 /* Increment and check the next entry index */
280 if (++(log->next) >= log->size) {
281 log->next = 0;
282 }
283
348 /* Check if we are about to overwrite an event entry */
349 if (entry->msg && (entry->msg->level == EMLXS_EVENT)) {
350 /* Check if this event has not been acquired */
351 if (log->count > (hba->hba_event.last_id + log->size)) {
352 hba->hba_event.missed++;
353
354 if ((entry->msg->mask == EVT_CT) &&
355 !(entry->flag & EMLX_EVENT_DONE)) {
356
357 /* Abort exchange */
358 rxid = *((uint32_t *)entry->bp);
359 }
360 }
361 }
362
363 /* Free the old context buffer since we are about to erase it */
364 if (entry->bp && entry->size) {
365 kmem_free(entry->bp, entry->size);
366 }
367
368 /* Initialize */
369 entry->id = log->count++;
370 entry->fileno = fileno;
371 entry->line = line;
284 /* Initialize */
285 entry->id = log->count++;
286 entry->fileno = fileno;
287 entry->line = line;
372 entry->bp = bp;
373 entry->size = size;
374 entry->msg = msg;
375 entry->instance = log->instance;
376 entry->vpi = port->vpi;
288 entry->msg = msg;
289 entry->instance = log->instance;
290 entry->vpi = port->vpi;
377 entry->flag = 0;
378
379 /* Save the additional info buffer */
380 (void) strncpy(entry->buffer, buffer, (MAX_LOG_INFO_LENGTH - 1));
381 entry->buffer[MAX_LOG_INFO_LENGTH - 1] = 0;
382
383 /* Set the entry time stamp */
384 (void) drv_getparm(LBOLT, &time);
385 entry->time = time - log->start_time;
386
291
292 /* Save the additional info buffer */
293 (void) strncpy(entry->buffer, buffer, (MAX_LOG_INFO_LENGTH - 1));
294 entry->buffer[MAX_LOG_INFO_LENGTH - 1] = 0;
295
296 /* Set the entry time stamp */
297 (void) drv_getparm(LBOLT, &time);
298 entry->time = time - log->start_time;
299
387 /* Check for a new event */
388 if (msg->level == EMLXS_EVENT) {
389 /* Update the event id */
390 mask = msg->mask;
391 for (i = 0; i < 32; i++) {
392 if (mask & 0x01) {
393 hba->hba_event.new++;
394 log->event_id[i] = entry->id;
395 cv_broadcast(&log->lock_cv);
396 break;
397 }
300 gethrestime(&entry->id_time);
398
301
399 mask >>= 1;
400 }
401 }
402
403 mutex_exit(&log->lock);
404
302 mutex_exit(&log->lock);
303
405 if (rxid) {
406 emlxs_thread_spawn(hba, emlxs_abort_ct_exchange,
407 (void *)port, (void *)((unsigned long)rxid));
408 }
409
410 return (0);
411
304 return (0);
305
412} /* emlxs_msg_log() */
306} /* emlxs_msg_log() */
413
414
307
308
309/*ARGSUSED*/
415static uint32_t
416emlxs_msg_log_check(emlxs_port_t *port, emlxs_msg_t *msg)
417{
310static uint32_t
311emlxs_msg_log_check(emlxs_port_t *port, emlxs_msg_t *msg)
312{
418 emlxs_hba_t *hba = HBA;
419
420 switch (msg->level) {
421 case EMLXS_DEBUG:
422 if (msg->mask & emlxs_log_debugs) {
423 return (1);
424 }
425 break;
426

--- 10 unchanged lines hidden (view full) ---

437 break;
438
439 case EMLXS_ERROR:
440 if (msg->mask & emlxs_log_errors) {
441 return (1);
442 }
443 break;
444
313
314 switch (msg->level) {
315 case EMLXS_DEBUG:
316 if (msg->mask & emlxs_log_debugs) {
317 return (1);
318 }
319 break;
320

--- 10 unchanged lines hidden (view full) ---

331 break;
332
333 case EMLXS_ERROR:
334 if (msg->mask & emlxs_log_errors) {
335 return (1);
336 }
337 break;
338
445 case EMLXS_EVENT:
446 if (msg->mask & hba->log_events) {
447 return (1);
448 }
449#ifdef SAN_DIAG_SUPPORT
450 if (msg->mask & port->sd_reg_events) {
451 return (1);
452 }
453#endif /* SAN_DIAG_SUPPORT */
454 break;
455
456 case EMLXS_PANIC:
457 return (1);
458 }
459
460 return (0);
461
339 case EMLXS_PANIC:
340 return (1);
341 }
342
343 return (0);
344
462} /* emlxs_msg_log_check() */
345} /* emlxs_msg_log_check() */
463
464
465static uint32_t
466emlxs_msg_print_check(emlxs_port_t *port, emlxs_msg_t *msg)
467{
468 emlxs_hba_t *hba = HBA;
469 emlxs_config_t *cfg;
470 uint32_t rval = 0;

--- 39 unchanged lines hidden (view full) ---

510 rval |= 2;
511 }
512
513 if (msg->mask & cfg[CFG_LOG_ERRORS].current) {
514 rval |= 1;
515 }
516 break;
517
346
347
348static uint32_t
349emlxs_msg_print_check(emlxs_port_t *port, emlxs_msg_t *msg)
350{
351 emlxs_hba_t *hba = HBA;
352 emlxs_config_t *cfg;
353 uint32_t rval = 0;

--- 39 unchanged lines hidden (view full) ---

393 rval |= 2;
394 }
395
396 if (msg->mask & cfg[CFG_LOG_ERRORS].current) {
397 rval |= 1;
398 }
399 break;
400
518 case EMLXS_EVENT:
519 /* Only print an event if it is being logged internally */
520 if (msg->mask & hba->log_events) {
521 if (msg->mask & cfg[CFG_CONSOLE_EVENTS].current) {
522 rval |= 2;
523 }
524
525 if (msg->mask & cfg[CFG_LOG_EVENTS].current) {
526 rval |= 1;
527 }
528 }
529 break;
530
531 case EMLXS_PANIC:
532 default:
533 rval |= 1;
534
535 }
536
537 return (rval);
538
401 case EMLXS_PANIC:
402 default:
403 rval |= 1;
404
405 }
406
407 return (rval);
408
539} /* emlxs_msg_print_check() */
409} /* emlxs_msg_print_check() */
540
541
542void
543emlxs_msg_printf(emlxs_port_t *port, const uint32_t fileno,
410
411
412void
413emlxs_msg_printf(emlxs_port_t *port, const uint32_t fileno,
544 const uint32_t line, void *bp, uint32_t size, emlxs_msg_t *msg,
414 const uint32_t line, emlxs_msg_t *msg,
545 const char *fmt, ...)
546{
547 emlxs_hba_t *hba = HBA;
548 va_list valist;
549 char va_str[256];
550 char msg_str[512];
551 char *level;
552 int32_t cmn_level;
553 uint32_t rval;
415 const char *fmt, ...)
416{
417 emlxs_hba_t *hba = HBA;
418 va_list valist;
419 char va_str[256];
420 char msg_str[512];
421 char *level;
422 int32_t cmn_level;
423 uint32_t rval;
554 uint32_t logged;
555 char driver[32];
556
557 va_str[0] = 0;
558
559 if (fmt) {
560 va_start(valist, fmt);
561 (void) vsprintf(va_str, fmt, valist);
562 va_end(valist);
563 }
564
565#ifdef FMA_SUPPORT
424 char driver[32];
425
426 va_str[0] = 0;
427
428 if (fmt) {
429 va_start(valist, fmt);
430 (void) vsprintf(va_str, fmt, valist);
431 va_end(valist);
432 }
433
434#ifdef FMA_SUPPORT
566 /*
567 * Don't post fault event or/and error event to fmd
568 * if physical port was not bounded yet.
569 */
570 if (msg->fm_ereport_code) {
571 emlxs_fm_ereport(hba, msg->fm_ereport_code);
572 }
573
574 if (msg->fm_impact_code) {
575 emlxs_fm_service_impact(hba, msg->fm_impact_code);
576 }
577#endif /* FMA_SUPPORT */
578
579 /* Check if msg should be logged */
435 if (msg->fm_ereport_code) {
436 emlxs_fm_ereport(hba, msg->fm_ereport_code);
437 }
438
439 if (msg->fm_impact_code) {
440 emlxs_fm_service_impact(hba, msg->fm_impact_code);
441 }
442#endif /* FMA_SUPPORT */
443
444 /* Check if msg should be logged */
580 if ((logged = emlxs_msg_log_check(port, msg))) {
445 if (emlxs_msg_log_check(port, msg)) {
581 /* Log the message */
446 /* Log the message */
582 if (emlxs_msg_log(port, fileno, line, bp, size, msg, va_str)) {
447 if (emlxs_msg_log(port, fileno, line, msg, va_str)) {
583 return;
584 }
585 }
586
587 /* Check if msg should be printed */
588 if (rval = emlxs_msg_print_check(port, msg)) {
589 cmn_level = CE_CONT;
590

--- 14 unchanged lines hidden (view full) ---

605 level = " ERROR";
606 break;
607
608 case EMLXS_PANIC:
609 cmn_level = CE_PANIC;
610 level = " PANIC";
611 break;
612
448 return;
449 }
450 }
451
452 /* Check if msg should be printed */
453 if (rval = emlxs_msg_print_check(port, msg)) {
454 cmn_level = CE_CONT;
455

--- 14 unchanged lines hidden (view full) ---

470 level = " ERROR";
471 break;
472
473 case EMLXS_PANIC:
474 cmn_level = CE_PANIC;
475 level = " PANIC";
476 break;
477
613 case EMLXS_EVENT:
614 level = " EVENT";
615 break;
616
617 default:
618 level = "UNKNOWN";
619 break;
620 }
621
622 if (port->vpi == 0) {
623 (void) sprintf(driver, "%s%d", DRIVER_NAME,
624 hba->ddiinst);

--- 41 unchanged lines hidden (view full) ---

666 case 3: /* CONSOLE AND MESSAGE LOG */
667 cmn_err(cmn_level, "%s", msg_str);
668 break;
669
670 }
671
672 }
673
478 default:
479 level = "UNKNOWN";
480 break;
481 }
482
483 if (port->vpi == 0) {
484 (void) sprintf(driver, "%s%d", DRIVER_NAME,
485 hba->ddiinst);

--- 41 unchanged lines hidden (view full) ---

527 case 3: /* CONSOLE AND MESSAGE LOG */
528 cmn_err(cmn_level, "%s", msg_str);
529 break;
530
531 }
532
533 }
534
674 /* If message was not logged, then free any context buffer provided */
675 if (!logged && bp && size) {
676 kmem_free(bp, size);
677 }
678
679 return;
680
535 return;
536
681} /* emlxs_msg_printf() */
537} /* emlxs_msg_printf() */
682
683
684uint32_t
685emlxs_msg_log_get(emlxs_hba_t *hba, emlxs_log_req_t *req,
686 emlxs_log_resp_t *resp)
687{
688 emlxs_msg_log_t *log;
689 uint32_t first;

--- 84 unchanged lines hidden (view full) ---

774 index = 0;
775 }
776 }
777
778 mutex_exit(&log->lock);
779
780 return (1);
781
538
539
540uint32_t
541emlxs_msg_log_get(emlxs_hba_t *hba, emlxs_log_req_t *req,
542 emlxs_log_resp_t *resp)
543{
544 emlxs_msg_log_t *log;
545 uint32_t first;

--- 84 unchanged lines hidden (view full) ---

630 index = 0;
631 }
632 }
633
634 mutex_exit(&log->lock);
635
636 return (1);
637
782} /* emlxs_msg_log_get() */
638} /* emlxs_msg_log_get() */
783
784
785
786static void
787emlxs_msg_sprintf(char *buffer, emlxs_msg_entry_t *entry)
788{
789 char *level;
790 emlxs_msg_t *msg;
791 uint32_t secs;
792 uint32_t hsecs;
793 char buf[256];
794 uint32_t buflen;
795 char driver[32];
796
797 msg = entry->msg;
639
640
641
642static void
643emlxs_msg_sprintf(char *buffer, emlxs_msg_entry_t *entry)
644{
645 char *level;
646 emlxs_msg_t *msg;
647 uint32_t secs;
648 uint32_t hsecs;
649 char buf[256];
650 uint32_t buflen;
651 char driver[32];
652
653 msg = entry->msg;
654
798 hsecs = (entry->time % 100);
799 secs = entry->time / 100;
800
801 switch (msg->level) {
802 case EMLXS_DEBUG:
803 level = " DEBUG";
804 break;
805

--- 8 unchanged lines hidden (view full) ---

814 case EMLXS_ERROR:
815 level = " ERROR";
816 break;
817
818 case EMLXS_PANIC:
819 level = " PANIC";
820 break;
821
655 hsecs = (entry->time % 100);
656 secs = entry->time / 100;
657
658 switch (msg->level) {
659 case EMLXS_DEBUG:
660 level = " DEBUG";
661 break;
662

--- 8 unchanged lines hidden (view full) ---

671 case EMLXS_ERROR:
672 level = " ERROR";
673 break;
674
675 case EMLXS_PANIC:
676 level = " PANIC";
677 break;
678
822 case EMLXS_EVENT:
823 level = " EVENT";
824 break;
825
826 default:
827 level = "UNKNOWN";
828 break;
829 }
830
831 if (entry->vpi == 0) {
832 (void) sprintf(driver, "%s%d", DRIVER_NAME, entry->instance);
833 } else {

--- 38 unchanged lines hidden (view full) ---

872 (void) strncpy(buffer, buf, (MAX_LOG_MSG_LENGTH - 2));
873 buffer[MAX_LOG_MSG_LENGTH - 2] = '\n';
874 } else {
875 (void) strncpy(buffer, buf, buflen);
876 }
877
878 return;
879
679 default:
680 level = "UNKNOWN";
681 break;
682 }
683
684 if (entry->vpi == 0) {
685 (void) sprintf(driver, "%s%d", DRIVER_NAME, entry->instance);
686 } else {

--- 38 unchanged lines hidden (view full) ---

725 (void) strncpy(buffer, buf, (MAX_LOG_MSG_LENGTH - 2));
726 buffer[MAX_LOG_MSG_LENGTH - 2] = '\n';
727 } else {
728 (void) strncpy(buffer, buf, buflen);
729 }
730
731 return;
732
880} /* emlxs_msg_sprintf() */
881
882
883
884
885void
886emlxs_log_rscn_event(emlxs_port_t *port, uint8_t *payload, uint32_t size)
887{
888#ifdef DFC_SUPPORT
889 emlxs_hba_t *hba = HBA;
890 uint8_t *bp;
891 uint32_t *ptr;
892
893 /* Check if the event is being requested */
894 if (!(hba->log_events & EVT_RSCN)) {
895 return;
896 }
897
898 if (size > MAX_RSCN_PAYLOAD) {
899 size = MAX_RSCN_PAYLOAD;
900 }
901
902 size += sizeof (uint32_t);
903
904 /* Save a copy of the payload for the event log */
905 if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) {
906 return;
907 }
908
909
910 /*
911 * Buffer Format:
912 * word[0] = DID of the RSCN
913 * word[1] = RSCN Payload
914 */
915 ptr = (uint32_t *)bp;
916 *ptr++ = port->did;
917 bcopy(payload, (char *)ptr, (size - sizeof (uint32_t)));
918
919 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_rscn_event,
920 "bp=%p size=%d", bp, size);
921
922#endif /* DFC_SUPPORT */
923 return;
924
925} /* emlxs_log_rscn_event() */
926
927
928void
929emlxs_log_vportrscn_event(emlxs_port_t *port, uint8_t *payload, uint32_t size)
930{
931#ifdef DFC_SUPPORT
932 emlxs_hba_t *hba = HBA;
933 uint8_t *bp;
934 uint8_t *ptr;
935
936 /* Check if the event is being requested */
937 if (!(hba->log_events & EVT_VPORTRSCN)) {
938 return;
939 }
940
941 if (size > MAX_RSCN_PAYLOAD) {
942 size = MAX_RSCN_PAYLOAD;
943 }
944
945 /* Save a copy of the payload for the event log */
946 if (!(bp =
947 (uint8_t *)kmem_alloc(size + sizeof (NAME_TYPE), KM_NOSLEEP))) {
948 return;
949 }
950
951
952 /*
953 * Buffer Format:
954 * word[0 - 4] = WWPN of the RSCN
955 * word[5] = RSCN Payload
956 */
957 ptr = bp;
958 bcopy(&port->wwpn, ptr, sizeof (NAME_TYPE));
959 ptr += sizeof (NAME_TYPE);
960 bcopy(payload, ptr, size);
961
962 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size + sizeof (NAME_TYPE),
963 &emlxs_vportrscn_event, "bp=%p size=%d", bp, size);
964
965#endif /* DFC_SUPPORT */
966 return;
967
968} /* emlxs_log_vportrscn_event() */
969
970
971uint32_t
972emlxs_log_ct_event(emlxs_port_t *port, uint8_t *payload, uint32_t size,
973 uint32_t rxid)
974{
975#ifdef DFC_SUPPORT
976 emlxs_hba_t *hba = HBA;
977 uint8_t *bp;
978 uint32_t *ptr;
979
980 /* Check if the event is being requested */
981 if (!(hba->log_events & EVT_CT)) {
982 return (1);
983 }
984
985 if (size > MAX_CT_PAYLOAD) {
986 size = MAX_CT_PAYLOAD;
987 }
988
989 size += sizeof (uint32_t);
990
991 /* Save a copy of the payload for the event log */
992 if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) {
993 return (1);
994 }
995
996 /*
997 * Buffer Format:
998 * word[0] = RXID tag for outgoing reply to this CT request
999 * word[1] = CT Payload
1000 */
1001 ptr = (uint32_t *)bp;
1002 *ptr++ = rxid;
1003
1004 bcopy(payload, (char *)ptr, (size - sizeof (uint32_t)));
1005
1006 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_ct_event,
1007 "bp=%p size=%d rxid=%x", bp, size, rxid);
1008
1009
1010 return (0);
1011#else
1012
1013 return (1);
1014
1015#endif /* DFC_SUPPORT */
1016
1017} /* emlxs_log_ct_event() */
1018
1019
1020void
1021emlxs_log_link_event(emlxs_port_t *port)
1022{
1023#ifdef DFC_SUPPORT
1024 emlxs_hba_t *hba = HBA;
1025 uint8_t *bp;
1026 dfc_linkinfo_t *linkinfo;
1027 uint8_t *byte;
1028 uint8_t *linkspeed;
1029 uint8_t *liptype;
1030 uint8_t *resv1;
1031 uint8_t *resv2;
1032 uint32_t size;
1033
1034 /* Check if the event is being requested */
1035 /*
1036 * if(!(hba->log_events & EVT_LINK)) { return; }
1037 */
1038 size = sizeof (dfc_linkinfo_t) + sizeof (uint32_t);
1039
1040 /* Save a copy of the buffer for the event log */
1041 if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) {
1042 return;
1043 }
1044
1045 /*
1046 * Buffer Format:
1047 * word[0] = Linkspeed:8
1048 * word[0] = LIP_type:8
1049 * word[0] = resv1:8
1050 * word[0] = resv2:8
1051 * word[1] = dfc_linkinfo_t data
1052 */
1053 byte = (uint8_t *)bp;
1054 linkspeed = &byte[0];
1055 liptype = &byte[1];
1056 resv1 = &byte[2];
1057 resv2 = &byte[3];
1058 linkinfo = (dfc_linkinfo_t *)&byte[4];
1059
1060 *resv1 = 0;
1061 *resv2 = 0;
1062
1063 if (hba->state <= FC_LINK_DOWN) {
1064 *linkspeed = 0;
1065 *liptype = 0;
1066 } else {
1067 /* Set linkspeed */
1068 if (hba->linkspeed == LA_2GHZ_LINK) {
1069 *linkspeed = HBA_PORTSPEED_2GBIT;
1070 } else if (hba->linkspeed == LA_4GHZ_LINK) {
1071 *linkspeed = HBA_PORTSPEED_4GBIT;
1072 } else if (hba->linkspeed == LA_8GHZ_LINK) {
1073 *linkspeed = HBA_PORTSPEED_8GBIT;
1074 } else if (hba->linkspeed == LA_10GHZ_LINK) {
1075 *linkspeed = HBA_PORTSPEED_10GBIT;
1076 } else {
1077 *linkspeed = HBA_PORTSPEED_1GBIT;
1078 }
1079
1080 /* Set LIP type */
1081 *liptype = port->lip_type;
1082 }
1083
1084 bzero(linkinfo, sizeof (dfc_linkinfo_t));
1085
1086 linkinfo->a_linkEventTag = hba->link_event_tag;
1087 linkinfo->a_linkUp = HBASTATS.LinkUp;
1088 linkinfo->a_linkDown = HBASTATS.LinkDown;
1089 linkinfo->a_linkMulti = HBASTATS.LinkMultiEvent;
1090
1091 if (hba->state <= FC_LINK_DOWN) {
1092 linkinfo->a_linkState = LNK_DOWN;
1093 linkinfo->a_DID = port->prev_did;
1094 } else if (hba->state < FC_READY) {
1095 linkinfo->a_linkState = LNK_DISCOVERY;
1096 } else {
1097 linkinfo->a_linkState = LNK_READY;
1098 }
1099
1100 if (linkinfo->a_linkState != LNK_DOWN) {
1101 if (hba->topology == TOPOLOGY_LOOP) {
1102 if (hba->flag & FC_FABRIC_ATTACHED) {
1103 linkinfo->a_topology = LNK_PUBLIC_LOOP;
1104 } else {
1105 linkinfo->a_topology = LNK_LOOP;
1106 }
1107
1108 linkinfo->a_alpa = port->did & 0xff;
1109 linkinfo->a_DID = linkinfo->a_alpa;
1110 linkinfo->a_alpaCnt = port->alpa_map[0];
1111
1112 if (linkinfo->a_alpaCnt > 127) {
1113 linkinfo->a_alpaCnt = 127;
1114 }
1115
1116 bcopy((void *)&port->alpa_map[1], linkinfo->a_alpaMap,
1117 linkinfo->a_alpaCnt);
1118 } else {
1119 if (port->node_count == 1) {
1120 linkinfo->a_topology = LNK_PT2PT;
1121 } else {
1122 linkinfo->a_topology = LNK_FABRIC;
1123 }
1124
1125 linkinfo->a_DID = port->did;
1126 }
1127 }
1128
1129 bcopy(&hba->wwpn, linkinfo->a_wwpName, 8);
1130 bcopy(&hba->wwnn, linkinfo->a_wwnName, 8);
1131
1132 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_link_event,
1133 "bp=%p size=%d tag=%x", bp, size, hba->link_event_tag);
1134
1135#endif /* DFC_SUPPORT */
1136
1137 return;
1138
1139} /* emlxs_log_link_event() */
1140
1141
1142void
1143emlxs_log_dump_event(emlxs_port_t *port, uint8_t *buffer, uint32_t size)
1144{
1145#ifdef DFC_SUPPORT
1146 emlxs_hba_t *hba = HBA;
1147 uint8_t *bp;
1148
1149 /* Check if the event is being requested */
1150 if (!(hba->log_events & EVT_DUMP)) {
1151#ifdef DUMP_SUPPORT
1152 /* Schedule a dump thread */
1153 emlxs_dump(hba, EMLXS_DRV_DUMP, 0, 0);
1154#endif /* DUMP_SUPPORT */
1155 return;
1156 }
1157
1158 if (buffer && size) {
1159 /* Save a copy of the buffer for the event log */
1160 if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) {
1161 return;
1162 }
1163
1164 bcopy(buffer, bp, size);
1165 } else {
1166 bp = NULL;
1167 size = 0;
1168 }
1169
1170 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_dump_event,
1171 "bp=%p size=%d", bp, size);
1172#else
1173
1174#ifdef DUMP_SUPPORT
1175 /* Schedule a dump thread */
1176 emlxs_dump(hba, EMLXS_DRV_DUMP, 0, 0);
1177#endif /* DUMP_SUPPORT */
1178
1179#endif /* DFC_SUPPORT */
1180
1181 return;
1182
1183} /* emlxs_log_dump_event() */
1184
1185
1186extern void
1187emlxs_log_temp_event(emlxs_port_t *port, uint32_t type, uint32_t temp)
1188{
1189 emlxs_hba_t *hba = HBA;
1190
1191#ifdef DFC_SUPPORT
1192 uint32_t *bp;
1193 uint32_t size;
1194
1195 /* Check if the event is being requested */
1196 if (!(hba->log_events & EVT_TEMP)) {
1197#ifdef DUMP_SUPPORT
1198 /* Schedule a dump thread */
1199 emlxs_dump(hba, EMLXS_TEMP_DUMP, type, temp);
1200#endif /* DUMP_SUPPORT */
1201 return;
1202 }
1203
1204 size = 2 * sizeof (uint32_t);
1205
1206 if (!(bp = (uint32_t *)kmem_alloc(size, KM_NOSLEEP))) {
1207 return;
1208 }
1209
1210 bp[0] = type;
1211 bp[1] = temp;
1212
1213 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_temp_event,
1214 "type=%x temp=%d bp=%p size=%d", type, temp, bp, size);
1215
1216#else /* !DFC_SUPPORT */
1217
1218#ifdef DUMP_SUPPORT
1219 /* Schedule a dump thread */
1220 emlxs_dump(hba, EMLXS_TEMP_DUMP, type, temp);
1221#endif /* DUMP_SUPPORT */
1222
1223#endif /* DFC_SUPPORT */
1224
1225 return;
1226
1227} /* emlxs_log_temp_event() */
1228
1229
1230
1231extern void
1232emlxs_log_fcoe_event(emlxs_port_t *port, menlo_init_rsp_t *init_rsp)
1233{
1234#ifdef DFC_SUPPORT
1235 emlxs_hba_t *hba = HBA;
1236 uint8_t *bp;
1237 uint32_t size;
1238
1239 /* Check if the event is being requested */
1240 if (!(hba->log_events & EVT_FCOE)) {
1241 return;
1242 }
1243
1244 /* Check if this is a FCOE adapter */
1245 if (hba->model_info.device_id != PCI_DEVICE_ID_LP21000_M) {
1246 return;
1247 }
1248
1249 size = sizeof (menlo_init_rsp_t);
1250
1251 if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) {
1252 return;
1253 }
1254
1255 bcopy((uint8_t *)init_rsp, bp, size);
1256
1257 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_fcoe_event,
1258 "bp=%p size=%d", bp, size);
1259#endif /* DFC_SUPPORT */
1260
1261 return;
1262
1263} /* emlxs_log_fcoe_event() */
1264
1265
1266#ifdef SAN_DIAG_SUPPORT
1267extern void
1268emlxs_log_sd_basic_els_event(emlxs_port_t *port, uint32_t subcat,
1269 HBA_WWN *portname, HBA_WWN *nodename)
1270{
1271 struct sd_plogi_rcv_v0 *bp;
1272 uint32_t size;
1273
1274 /* Check if the event is being requested */
1275 if (!(port->sd_reg_events & EVT_SD_ELS))
1276 return;
1277
1278 size = sizeof (struct sd_plogi_rcv_v0);
1279
1280 if (!(bp = (struct sd_plogi_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP)))
1281 return;
1282
1283 /*
1284 * we are using version field to store subtype, libdfc
1285 * will fix this up before returning data to app.
1286 */
1287 bp->sd_plogir_version = subcat;
1288 bcopy((uint8_t *)portname, (uint8_t *)&bp->sd_plogir_portname,
1289 sizeof (HBA_WWN));
1290 bcopy((uint8_t *)nodename, (uint8_t *)&bp->sd_plogir_nodename,
1291 sizeof (HBA_WWN));
1292
1293 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_els_event,
1294 "bp=%p size=%d", bp, size);
1295
1296 return;
1297
1298} /* emlxs_log_sd_basic_els_event() */
1299
1300
1301extern void
1302emlxs_log_sd_prlo_event(emlxs_port_t *port, HBA_WWN *remoteport)
1303{
1304 struct sd_prlo_rcv_v0 *bp;
1305 uint32_t size;
1306
1307 /* Check if the event is being requested */
1308 if (!(port->sd_reg_events & EVT_SD_ELS))
1309 return;
1310
1311 size = sizeof (struct sd_prlo_rcv_v0);
1312
1313 if (!(bp = (struct sd_prlo_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP)))
1314 return;
1315
1316 /*
1317 * we are using version field to store subtype, libdfc
1318 * will fix this up before returning data to app.
1319 */
1320 bp->sd_prlor_version = SD_ELS_SUBCATEGORY_PRLO_RCV;
1321 bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_prlor_remoteport,
1322 sizeof (HBA_WWN));
1323
1324 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_els_event,
1325 "bp=%p size=%d", bp, size);
1326
1327 return;
1328
1329} /* emlxs_log_sd_prlo_event() */
1330
1331
1332extern void
1333emlxs_log_sd_lsrjt_event(emlxs_port_t *port, HBA_WWN *remoteport,
1334 uint32_t orig_cmd, uint32_t reason, uint32_t reason_expl)
1335{
1336 struct sd_lsrjt_rcv_v0 *bp;
1337 uint32_t size;
1338
1339 /* Check if the event is being requested */
1340 if (!(port->sd_reg_events & EVT_SD_ELS))
1341 return;
1342
1343 size = sizeof (struct sd_lsrjt_rcv_v0);
1344
1345 if (!(bp = (struct sd_lsrjt_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP)))
1346 return;
1347
1348 /*
1349 * we are using version field to store subtype, libdfc
1350 * will fix this up before returning data to app.
1351 */
1352 bp->sd_lsrjtr_version = SD_ELS_SUBCATEGORY_LSRJT_RCV;
1353 bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_lsrjtr_remoteport,
1354 sizeof (HBA_WWN));
1355 bp->sd_lsrjtr_original_cmd = orig_cmd;
1356 bp->sd_lsrjtr_reasoncode = reason;
1357 bp->sd_lsrjtr_reasoncodeexpl = reason_expl;
1358
1359 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_els_event,
1360 "bp=%p size=%d", bp, size);
1361
1362 return;
1363
1364} /* emlxs_log_sd_lsrjt_event() */
1365
1366
1367
1368extern void
1369emlxs_log_sd_fc_bsy_event(emlxs_port_t *port, HBA_WWN *remoteport)
1370{
1371 struct sd_pbsy_rcv_v0 *bp;
1372 uint32_t size;
1373
1374 /* Check if the event is being requested */
1375 if (!(port->sd_reg_events & EVT_SD_FABRIC))
1376 return;
1377
1378 size = sizeof (struct sd_pbsy_rcv_v0);
1379
1380 if (!(bp = (struct sd_pbsy_rcv_v0 *)kmem_alloc(size, KM_NOSLEEP)))
1381 return;
1382
1383 /*
1384 * we are using version field to store subtype, libdfc
1385 * will fix this up before returning data to app.
1386 */
1387 if (remoteport == NULL)
1388 bp->sd_pbsyr_evt_version = SD_FABRIC_SUBCATEGORY_FABRIC_BUSY;
1389 else
1390 {
1391 bp->sd_pbsyr_evt_version = SD_FABRIC_SUBCATEGORY_PORT_BUSY;
1392 bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_pbsyr_rport,
1393 sizeof (HBA_WWN));
1394 }
1395
1396 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_fabric_event,
1397 "bp=%p size=%d", bp, size);
1398
1399 return;
1400
1401} /* emlxs_log_sd_fc_bsy_event() */
1402
1403
1404extern void
1405emlxs_log_sd_fc_rdchk_event(emlxs_port_t *port, HBA_WWN *remoteport,
1406 uint32_t lun, uint32_t opcode, uint32_t fcp_param)
1407{
1408 struct sd_fcprdchkerr_v0 *bp;
1409 uint32_t size;
1410
1411 /* Check if the event is being requested */
1412 if (!(port->sd_reg_events & EVT_SD_FABRIC))
1413 return;
1414
1415 size = sizeof (struct sd_fcprdchkerr_v0);
1416
1417 if (!(bp = (struct sd_fcprdchkerr_v0 *)kmem_alloc(size, KM_NOSLEEP)))
1418 return;
1419
1420 /*
1421 * we are using version field to store subtype, libdfc
1422 * will fix this up before returning data to app.
1423 */
1424 bp->sd_fcprdchkerr_version = SD_FABRIC_SUBCATEGORY_FCPRDCHKERR;
1425 bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_fcprdchkerr_rport,
1426 sizeof (HBA_WWN));
1427 bp->sd_fcprdchkerr_lun = lun;
1428 bp->sd_fcprdchkerr_opcode = opcode;
1429 bp->sd_fcprdchkerr_fcpiparam = fcp_param;
1430
1431 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_fabric_event,
1432 "bp=%p size=%d", bp, size);
1433
1434 return;
1435
1436} /* emlxs_log_sd_rdchk_event() */
1437
1438
1439extern void
1440emlxs_log_sd_scsi_event(emlxs_port_t *port, uint32_t type,
1441 HBA_WWN *remoteport, int32_t lun)
1442{
1443 struct sd_scsi_generic_v0 *bp;
1444 uint32_t size;
1445
1446 /* Check if the event is being requested */
1447 if (!(port->sd_reg_events & EVT_SD_SCSI))
1448 return;
1449
1450 size = sizeof (struct sd_scsi_generic_v0);
1451
1452 if (!(bp = (struct sd_scsi_generic_v0 *)kmem_alloc(size, KM_NOSLEEP)))
1453 return;
1454
1455 /*
1456 * we are using version field to store subtype, libdfc
1457 * will fix this up before returning data to app.
1458 */
1459 bp->sd_scsi_generic_version = type;
1460 bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_scsi_generic_rport,
1461 sizeof (HBA_WWN));
1462 bp->sd_scsi_generic_lun = lun;
1463
1464 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_scsi_event,
1465 "bp=%p size=%d", bp, size);
1466
1467 return;
1468
1469} /* emlxs_log_sd_scsi_event() */
1470
1471
1472extern void
1473emlxs_log_sd_scsi_check_event(emlxs_port_t *port, HBA_WWN *remoteport,
1474 uint32_t lun, uint32_t cmdcode, uint32_t sensekey,
1475 uint32_t asc, uint32_t ascq)
1476{
1477 struct sd_scsi_checkcond_v0 *bp;
1478 uint32_t size;
1479
1480 /* Check if the event is being requested */
1481 if (!(port->sd_reg_events & EVT_SD_SCSI))
1482 return;
1483
1484 size = sizeof (struct sd_scsi_checkcond_v0);
1485
1486 if (!(bp = (struct sd_scsi_checkcond_v0 *)kmem_alloc(size, KM_NOSLEEP)))
1487 return;
1488
1489 /*
1490 * we are using version field to store subtype, libdfc
1491 * will fix this up before returning data to app.
1492 */
1493 bp->sd_scsi_checkcond_version = SD_SCSI_SUBCATEGORY_CHECKCONDITION;
1494 bcopy((uint8_t *)remoteport, (uint8_t *)&bp->sd_scsi_checkcond_rport,
1495 sizeof (HBA_WWN));
1496 bp->sd_scsi_checkcond_lun = lun;
1497 bp->sd_scsi_checkcond_cmdcode = cmdcode;
1498 bp->sd_scsi_checkcond_sensekey = sensekey;
1499 bp->sd_scsi_checkcond_asc = asc;
1500 bp->sd_scsi_checkcond_ascq = ascq;
1501
1502 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_sd_scsi_event,
1503 "bp=%p size=%d", bp, size);
1504
1505}
1506#endif /* SAN_DIAG_SUPPORT */
1507
1508
1509extern void
1510emlxs_log_async_event(emlxs_port_t *port, IOCB *iocb)
1511{
1512 uint8_t *bp;
1513 uint32_t size;
1514
1515 /* ASYNC_STATUS_CN response size */
1516 size = 64;
1517
1518 if (!(bp = (uint8_t *)kmem_alloc(size, KM_NOSLEEP))) {
1519 return;
1520 }
1521
1522 bcopy((uint8_t *)iocb, bp, size);
1523
1524 EMLXS_MSGF(EMLXS_CONTEXT_BP, bp, size, &emlxs_async_event,
1525 "bp=%p size=%d", bp, size);
1526
1527} /* emlxs_log_async_event() */
1528
1529#ifdef DFC_SUPPORT
1530
1531extern uint32_t
1532emlxs_get_dfc_eventinfo(emlxs_port_t *port, HBA_EVENTINFO *eventinfo,
1533 uint32_t *eventcount, uint32_t *missed)
1534{
1535 emlxs_hba_t *hba = HBA;
1536 emlxs_msg_log_t *log;
1537 uint32_t first;
1538 uint32_t last;
1539 uint32_t count;
1540 uint32_t index;
1541 emlxs_msg_entry_t *entry;
1542 dfc_linkinfo_t *linkinfo;
1543 uint32_t *word;
1544 uint8_t *byte;
1545 uint8_t linkspeed;
1546 uint8_t liptype;
1547 fc_affected_id_t *aid;
1548 uint32_t max_events;
1549 uint32_t events;
1550 uint8_t format;
1551 emlxs_hba_event_t *hba_event;
1552
1553 if (!eventinfo || !eventcount || !missed) {
1554 return (DFC_ARG_NULL);
1555 }
1556
1557 hba_event = &hba->hba_event;
1558 max_events = *eventcount;
1559 *eventcount = 0;
1560
1561 log = &LOG;
1562
1563 mutex_enter(&log->lock);
1564
1565 /* Check if log is empty */
1566 if (log->count == 0) {
1567 /* Make sure everything is initialized */
1568 hba_event->new = 0;
1569 hba_event->missed = 0;
1570 hba_event->last_id = 0;
1571
1572 mutex_exit(&log->lock);
1573 return (0);
1574 }
1575
1576 /* Safety check */
1577 if (hba_event->last_id > (log->count - 1)) {
1578 hba_event->last_id = log->count - 1;
1579 }
1580
1581 /* Account for missed events */
1582 if (hba_event->new > hba_event->missed) {
1583 hba_event->new -= hba_event->missed;
1584 } else {
1585 hba_event->new = 0;
1586 }
1587
1588 *missed = hba_event->missed;
1589 hba_event->missed = 0;
1590
1591 if (!hba_event->new) {
1592 hba_event->last_id = log->count;
1593 mutex_exit(&log->lock);
1594 return (0);
1595 }
1596
1597 /* A new event has occurred since last acquisition */
1598 /* Calculate the current buffer boundaries */
1599
1600 /* Get last entry id saved */
1601 last = log->count - 1;
1602
1603 /* Get oldest entry id and its index */
1604 /* Check if buffer has already been filled once */
1605 if (log->count >= log->size) {
1606 first = log->count - log->size;
1607 index = log->next;
1608 } else { /* Buffer not yet filled */
1609
1610 first = 0;
1611 index = 0;
1612 }
1613
1614 /* Check if requested first event is greater than actual. */
1615 /* If so, adjust for it. */
1616 if (hba_event->last_id > first) {
1617 /* Adjust entry index to first requested message */
1618 index += (hba_event->last_id - first);
1619 if (index >= log->size) {
1620 index -= log->size;
1621 }
1622
1623 first = hba_event->last_id;
1624 }
1625
1626 /* Get the total number of new messages */
1627 count = last - first;
1628
1629 /* Scan log for next event */
1630 events = 0;
1631 while (count-- && (events < max_events)) {
1632 if (++index >= log->size) {
1633 index = 0;
1634 }
1635
1636 entry = &log->entry[index];
1637
1638 if (!entry->msg) {
1639 break;
1640 }
1641
1642 if ((entry->msg->level == EMLXS_EVENT) &&
1643 (entry->msg->mask & (EVT_LINK | EVT_RSCN))) {
1644 /* Process this event */
1645 switch (entry->msg->mask) {
1646 case EVT_LINK:
1647 byte = (uint8_t *)entry->bp;
1648 linkspeed = byte[0];
1649 liptype = byte[1];
1650 linkinfo = (dfc_linkinfo_t *)&byte[4];
1651
1652 if (linkinfo->a_linkState == LNK_DOWN) {
1653 eventinfo->EventCode =
1654 HBA_EVENT_LINK_DOWN;
1655 eventinfo->Event.Link_EventInfo.
1656 PortFcId = linkinfo->a_DID;
1657 eventinfo->Event.Link_EventInfo.
1658 Reserved[0] = 0;
1659 eventinfo->Event.Link_EventInfo.
1660 Reserved[1] = 0;
1661 eventinfo->Event.Link_EventInfo.
1662 Reserved[2] = 0;
1663 } else {
1664 eventinfo->EventCode =
1665 HBA_EVENT_LINK_UP;
1666 eventinfo->Event.Link_EventInfo.
1667 PortFcId = linkinfo->a_DID;
1668
1669 if ((linkinfo->a_topology ==
1670 LNK_PUBLIC_LOOP) ||
1671 (linkinfo->a_topology ==
1672 LNK_LOOP)) {
1673 eventinfo->Event.
1674 Link_EventInfo.
1675 Reserved[0] = 2;
1676 } else {
1677 eventinfo->Event.
1678 Link_EventInfo.
1679 Reserved[0] = 1;
1680 }
1681
1682 eventinfo->Event.Link_EventInfo.
1683 Reserved[1] = liptype;
1684 eventinfo->Event.Link_EventInfo.
1685 Reserved[2] = linkspeed;
1686 }
1687
1688 break;
1689
1690 case EVT_RSCN:
1691 word = (uint32_t *)entry->bp;
1692 eventinfo->EventCode = HBA_EVENT_RSCN;
1693 eventinfo->Event.RSCN_EventInfo.PortFcId =
1694 word[0] & 0xFFFFFF;
1695 /* word[1] is the RSCN payload command */
1696
1697 aid = (fc_affected_id_t *)&word[2];
1698 format = aid->aff_format;
1699
1700 switch (format) {
1701 case 0: /* Port */
1702 eventinfo->Event.RSCN_EventInfo.
1703 NPortPage =
1704 aid->aff_d_id & 0x00ffffff;
1705 break;
1706
1707 case 1: /* Area */
1708 eventinfo->Event.RSCN_EventInfo.
1709 NPortPage =
1710 aid->aff_d_id & 0x00ffff00;
1711 break;
1712
1713 case 2: /* Domain */
1714 eventinfo->Event.RSCN_EventInfo.
1715 NPortPage =
1716 aid->aff_d_id & 0x00ff0000;
1717 break;
1718
1719 case 3: /* Network */
1720 eventinfo->Event.RSCN_EventInfo.
1721 NPortPage = 0;
1722 break;
1723 }
1724
1725 eventinfo->Event.RSCN_EventInfo.Reserved[0] =
1726 0;
1727 eventinfo->Event.RSCN_EventInfo.Reserved[1] =
1728 0;
1729
1730 break;
1731 }
1732
1733 eventinfo++;
1734 events++;
1735 }
1736
1737 hba_event->last_id = entry->id;
1738 }
1739
1740 /* Adjust new count */
1741 if (!count || (events >= hba_event->new)) {
1742 hba_event->new = 0;
1743 } else {
1744 hba_event->new -= events;
1745 }
1746
1747 /* Return number of events acquired */
1748 *eventcount = events;
1749
1750 mutex_exit(&log->lock);
1751
1752 return (0);
1753
1754} /* emlxs_get_dfc_eventinfo() */
1755
1756
1757uint32_t
1758emlxs_get_dfc_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event,
1759 uint32_t sleep)
1760{
1761 emlxs_hba_t *hba = HBA;
1762 emlxs_msg_log_t *log;
1763 uint32_t first;
1764 uint32_t last;
1765 uint32_t count;
1766 uint32_t index;
1767 uint32_t mask;
1768 uint32_t i;
1769 emlxs_msg_entry_t *entry;
1770 uint32_t size;
1771 uint32_t rc;
1772
1773 size = 0;
1774
1775 if (dfc_event->dataout && dfc_event->size) {
1776 size = dfc_event->size;
1777 }
1778 dfc_event->size = 0;
1779
1780 /* Get the log file pointer */
1781 log = &LOG;
1782
1783 /* Calculate the event index */
1784 mask = dfc_event->event;
1785 for (i = 0; i < 32; i++) {
1786 if (mask & 0x01) {
1787 break;
1788 }
1789
1790 mask >>= 1;
1791 }
1792 if (i == 32) {
1793 return (DFC_ARG_INVALID);
1794 }
1795
1796 mutex_enter(&log->lock);
1797
1798 /* Check if log is empty */
1799 if (log->count == 0) {
1800 /* Make sure everything is initialized */
1801 log->event_id[i] = 0;
1802 dfc_event->last_id = 0;
1803 } else {
1804 /* Check ranges for safety */
1805 if (log->event_id[i] > (log->count - 1)) {
1806 log->event_id[i] = log->count - 1;
1807 }
1808
1809 if (dfc_event->last_id > log->event_id[i]) {
1810 dfc_event->last_id = log->event_id[i];
1811 }
1812 }
1813
1814wait_for_event:
1815
1816 /* Check if no new event has ocurred */
1817 if (dfc_event->last_id == log->event_id[i]) {
1818 if (!sleep) {
1819 mutex_exit(&log->lock);
1820 return (0);
1821 }
1822
1823 /* While event is still active and */
1824 /* no new event has been logged */
1825 while ((dfc_event->event & hba->log_events) &&
1826 (dfc_event->last_id == log->event_id[i])) {
1827 rc = cv_wait_sig(&log->lock_cv, &log->lock);
1828
1829 /* Check if thread was killed by kernel */
1830 if (rc == 0) {
1831 dfc_event->pid = 0;
1832 dfc_event->event = 0;
1833 mutex_exit(&log->lock);
1834 return (0);
1835 }
1836 }
1837
1838 /* If the event is no longer registered then */
1839 /* return immediately */
1840 if (!(dfc_event->event & hba->log_events)) {
1841 mutex_exit(&log->lock);
1842 return (0);
1843 }
1844 }
1845
1846 /* !!! An event has occurred since last_id !!! */
1847
1848 /* Check if event data is not being requested */
1849 if (!size) {
1850 /* If so, then just return the last event id */
1851 dfc_event->last_id = log->event_id[i];
1852
1853 mutex_exit(&log->lock);
1854 return (0);
1855 }
1856
1857 /* !!! The requester wants the next event buffer !!! */
1858
1859 /* Calculate the current buffer boundaries */
1860
1861 /* Get last entry id saved */
1862 last = log->count - 1;
1863
1864 /* Get oldest entry id and its index */
1865 /* Check if buffer has already been filled once */
1866 if (log->count >= log->size) {
1867 first = log->count - log->size;
1868 index = log->next;
1869 } else { /* Buffer not yet filled */
1870
1871 first = 0;
1872 index = 0;
1873 }
1874
1875 /* Check to see if the buffer has wrapped since the last event */
1876 if (first > log->event_id[i]) {
1877 /* Update last_id to the last known event */
1878 dfc_event->last_id = log->event_id[i];
1879
1880 /* Try waiting again if we can */
1881 goto wait_for_event;
1882 }
1883
1884 /* Check if requested first event is greater than actual. */
1885 /* If so, adjust for it. */
1886 if (dfc_event->last_id > first) {
1887 /* Adjust entry index to first requested message */
1888 index += (dfc_event->last_id - first);
1889 if (index >= log->size) {
1890 index -= log->size;
1891 }
1892
1893 first = dfc_event->last_id;
1894 }
1895
1896 /* Get the total number of new messages */
1897 count = last - first + 1;
1898
1899 /* Scan log for next event */
1900 while (count--) {
1901 if (++index >= log->size) {
1902 index = 0;
1903 }
1904
1905 entry = &log->entry[index];
1906
1907 if ((entry->msg->level == EMLXS_EVENT) &&
1908 (entry->msg->mask == dfc_event->event)) {
1909 break;
1910 }
1911 }
1912
1913 /* Check if no new event was found in the current log buffer */
1914 /* This would indicate that the buffer wrapped since that last event */
1915 if (!count) {
1916 /* Update last_id to the last known event */
1917 dfc_event->last_id = log->event_id[i];
1918
1919 /* Try waiting again if we can */
1920 goto wait_for_event;
1921 }
1922
1923 /* !!! Next event found !!! */
1924
1925 /* Copy the context buffer to the buffer provided */
1926 if (entry->bp && entry->size) {
1927 if (entry->size < size) {
1928 size = entry->size;
1929 }
1930
1931 if (ddi_copyout((void *)entry->bp, dfc_event->dataout, size,
1932 dfc_event->mode) != 0) {
1933 mutex_exit(&log->lock);
1934
1935 return (DFC_COPYOUT_ERROR);
1936 }
1937
1938 /* Data has been retrieved by the apps */
1939 entry->flag |= EMLX_EVENT_DONE;
1940
1941 dfc_event->size = size;
1942 }
1943
1944 dfc_event->last_id = entry->id;
1945
1946 mutex_exit(&log->lock);
1947 return (0);
1948
1949} /* emlxs_get_dfc_event() */
1950
1951
1952uint32_t
1953emlxs_kill_dfc_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event)
1954{
1955 emlxs_hba_t *hba = HBA;
1956 emlxs_msg_log_t *log;
1957
1958 /* Get the log file pointer */
1959 log = &LOG;
1960
1961 mutex_enter(&log->lock);
1962 dfc_event->pid = 0;
1963 dfc_event->event = 0;
1964 cv_broadcast(&log->lock_cv);
1965 mutex_exit(&log->lock);
1966
1967 return (0);
1968
1969} /* emlxs_kill_dfc_event() */
1970
1971
1972#ifdef SAN_DIAG_SUPPORT
1973uint32_t
1974emlxs_get_sd_event(emlxs_port_t *port, emlxs_dfc_event_t *dfc_event,
1975 uint32_t sleep)
1976{
1977 emlxs_hba_t *hba = HBA;
1978 emlxs_msg_log_t *log;
1979 emlxs_msg_entry_t *entry;
1980 uint32_t size;
1981 uint32_t rc;
1982 uint32_t first;
1983 uint32_t last;
1984 uint32_t count;
1985 uint32_t index;
1986 uint32_t mask;
1987 uint32_t i;
1988
1989 size = 0;
1990
1991 if (dfc_event->dataout && dfc_event->size) {
1992 size = dfc_event->size;
1993 }
1994 dfc_event->size = 0;
1995
1996 /* Get the log file pointer */
1997 log = &LOG;
1998
1999 /* Calculate the event index */
2000 mask = dfc_event->event;
2001 for (i = 0; i < 32; i++) {
2002 if (mask & 0x01)
2003 break;
2004
2005 mask >>= 1;
2006 }
2007 if (i == 32)
2008 return (DFC_ARG_INVALID);
2009
2010 mutex_enter(&log->lock);
2011
2012 /* Check if log is empty */
2013 if (log->count == 0) {
2014 /* Make sure everything is initialized */
2015 log->event_id[i] = 0;
2016 dfc_event->last_id = 0;
2017 } else {
2018 /* Check ranges for safety */
2019 if (log->event_id[i] > (log->count - 1))
2020 log->event_id[i] = log->count - 1;
2021
2022 if (dfc_event->last_id > log->event_id[i])
2023 dfc_event->last_id = log->event_id[i];
2024 }
2025
2026wait_for_sd_event:
2027 /* Check if no new event has ocurred */
2028 if (dfc_event->last_id == log->event_id[i]) {
2029 if (!sleep) {
2030 mutex_exit(&log->lock);
2031 return (0);
2032 }
2033
2034 /* While event is active and no new event has been logged */
2035 while ((dfc_event->event & port->sd_reg_events) &&
2036 (dfc_event->last_id == log->event_id[i])) {
2037 rc = cv_wait_sig(&log->lock_cv, &log->lock);
2038
2039 /* Check if thread was killed by kernel */
2040 if (rc == 0) {
2041 dfc_event->pid = 0;
2042 dfc_event->event = 0;
2043 mutex_exit(&log->lock);
2044 return (0);
2045 }
2046 }
2047
2048 /* If the event is no longer registered then return */
2049 if (!(dfc_event->event & port->sd_reg_events)) {
2050 mutex_exit(&log->lock);
2051 return (0);
2052 }
2053 }
2054
2055 /* !!! An event has occurred since last_id !!! */
2056
2057 /* Check if event data is not being requested */
2058 if (!size) {
2059 /* If so, then just return the last event id */
2060 dfc_event->last_id = log->event_id[i];
2061 mutex_exit(&log->lock);
2062 return (0);
2063 }
2064
2065 /* !!! The requester wants the next event buffer !!! */
2066
2067 /* Calculate the current buffer boundaries */
2068
2069 /* Get last entry id saved */
2070 last = log->count - 1;
2071
2072 /* Get oldest entry id and its index */
2073 /* Check if buffer has already been filled once */
2074 if (log->count >= log->size) {
2075 first = log->count - log->size;
2076 index = log->next;
2077 } else { /* Buffer not yet filled */
2078 first = 0;
2079 index = 0;
2080 }
2081
2082 /* Check to see if the buffer has wrapped since the last event */
2083 if (first > log->event_id[i]) {
2084 /* Update last_id to the last known event */
2085 dfc_event->last_id = log->event_id[i];
2086
2087 /* Try waiting again if we can */
2088 goto wait_for_sd_event;
2089 }
2090
2091 /* if requested first event is greater than actual, adjust for it. */
2092 if (dfc_event->last_id > first) {
2093 /* Adjust entry index to first requested message */
2094 index += (dfc_event->last_id - first);
2095 if (index >= log->size) {
2096 index -= log->size;
2097 }
2098
2099 first = dfc_event->last_id;
2100 }
2101
2102 /* Get the total number of new messages */
2103 count = last - first + 1;
2104
2105 /* Scan log for next event */
2106 while (count--) {
2107 if (++index >= log->size)
2108 index = 0;
2109
2110 entry = &log->entry[index];
2111
2112 if ((entry->msg->level == EMLXS_EVENT) &&
2113 (entry->vpi == port->vpi) &&
2114 (entry->msg->mask == dfc_event->event))
2115 break;
2116 }
2117
2118 /* Check if no new event was found in the current log buffer */
2119 /* This would indicate that the buffer wrapped since that last event */
2120 if (!count) {
2121 /* Update last_id to the last known event */
2122 dfc_event->last_id = log->event_id[i];
2123
2124 /* Try waiting again if we can */
2125 goto wait_for_sd_event;
2126 }
2127
2128 /* !!! Next event found !!! */
2129
2130 /* Copy the context buffer to the buffer provided */
2131 if (entry->bp && entry->size) {
2132 if (entry->size < size)
2133 size = entry->size;
2134
2135 if (ddi_copyout((void *) entry->bp, dfc_event->dataout,
2136 size, dfc_event->mode) != 0) {
2137 mutex_exit(&log->lock);
2138
2139 return (DFC_COPYOUT_ERROR);
2140 }
2141
2142 dfc_event->size = size;
2143 }
2144
2145 dfc_event->last_id = entry->id;
2146 mutex_exit(&log->lock);
2147
2148 return (0);
2149} /* emlxs_get_sd_event */
2150#endif /* SAN_DIAG_SUPPORT */
2151
2152
2153#endif /* DFC_SUPPORT */
733} /* emlxs_msg_sprintf() */