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  *
8*8f23e9faSHans Rosenfeld  * You can obtain a copy of the license at
9*8f23e9faSHans Rosenfeld  * http://www.opensource.org/licenses/cddl1.txt.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22fcf3ce44SJohn Forte /*
23*8f23e9faSHans Rosenfeld  * Copyright (c) 2004-2012 Emulex. All rights reserved.
2482527734SSukumar Swaminathan  * 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 
30291a2b48SSukumar Swaminathan uint32_t emlxs_log_size		= 2048;
31291a2b48SSukumar Swaminathan uint32_t emlxs_log_debugs	= 0x7FFFFFFF;
32291a2b48SSukumar Swaminathan uint32_t emlxs_log_notices	= 0xFFFFFFFF;
33291a2b48SSukumar Swaminathan uint32_t emlxs_log_warnings	= 0xFFFFFFFF;
34291a2b48SSukumar Swaminathan uint32_t emlxs_log_errors	= 0xFFFFFFFF;
35fcf3ce44SJohn Forte 
36291a2b48SSukumar Swaminathan static uint32_t	emlxs_msg_log_check(emlxs_port_t *port, emlxs_msg_t *msg);
37291a2b48SSukumar Swaminathan static uint32_t	emlxs_msg_print_check(emlxs_port_t *port, emlxs_msg_t *msg);
38291a2b48SSukumar Swaminathan static void	emlxs_msg_sprintf(char *buffer, emlxs_msg_entry_t *entry);
39fcf3ce44SJohn Forte 
40fcf3ce44SJohn Forte 
41fcf3ce44SJohn Forte uint32_t
emlxs_msg_log_create(emlxs_hba_t * hba)42fcf3ce44SJohn Forte emlxs_msg_log_create(emlxs_hba_t *hba)
43fcf3ce44SJohn Forte {
44fcf3ce44SJohn Forte 	emlxs_msg_log_t *log = &LOG;
45fcf3ce44SJohn Forte 	uint32_t size = sizeof (emlxs_msg_entry_t) * emlxs_log_size;
46fcf3ce44SJohn Forte 	ddi_iblock_cookie_t iblock;
47fcf3ce44SJohn Forte 
48fcf3ce44SJohn Forte 	/* Check if log is already created */
49fcf3ce44SJohn Forte 	if (log->entry) {
50fcf3ce44SJohn Forte 		cmn_err(CE_WARN, "?%s%d: message log already created. log=%p",
51291a2b48SSukumar Swaminathan 		    DRIVER_NAME, hba->ddiinst, (void *)log);
52fcf3ce44SJohn Forte 		return (0);
53fcf3ce44SJohn Forte 	}
54291a2b48SSukumar Swaminathan 
55fcf3ce44SJohn Forte 	/* Clear the log */
56fcf3ce44SJohn Forte 	bzero(log, sizeof (emlxs_msg_log_t));
57fcf3ce44SJohn Forte 
58fcf3ce44SJohn Forte 	/* Allocate the memory needed for the log file */
5982527734SSukumar Swaminathan 	log->entry = (emlxs_msg_entry_t *)kmem_zalloc(size, KM_SLEEP);
60291a2b48SSukumar Swaminathan 
61fcf3ce44SJohn Forte 	/* Initialize */
62fcf3ce44SJohn Forte 	log->size = emlxs_log_size;
63fcf3ce44SJohn Forte 	log->instance = hba->ddiinst;
64fcf3ce44SJohn Forte 	log->start_time = emlxs_device.log_timestamp;
65fcf3ce44SJohn Forte 
66fcf3ce44SJohn Forte 	if (!(hba->intr_flags & EMLXS_MSI_ENABLED)) {
67fcf3ce44SJohn Forte 		/* Get the current interrupt block cookie */
68fcf3ce44SJohn Forte 		(void) ddi_get_iblock_cookie(hba->dip, (uint_t)EMLXS_INUMBER,
69fcf3ce44SJohn Forte 		    &iblock);
70fcf3ce44SJohn Forte 
71fcf3ce44SJohn Forte 		/* Create the log mutex lock */
72*8f23e9faSHans Rosenfeld 		mutex_init(&log->lock, NULL, MUTEX_DRIVER, (void *)iblock);
73fcf3ce44SJohn Forte 	}
74fcf3ce44SJohn Forte #ifdef  MSI_SUPPORT
75fcf3ce44SJohn Forte 	else {
76a9800bebSGarrett D'Amore 		/* Create the temporary log mutex lock */
77*8f23e9faSHans Rosenfeld 		mutex_init(&log->lock, NULL, MUTEX_DRIVER, NULL);
78a9800bebSGarrett D'Amore 	}
79a9800bebSGarrett D'Amore #endif
80291a2b48SSukumar Swaminathan 
81a9800bebSGarrett D'Amore 	return (1);
82fcf3ce44SJohn Forte 
83a9800bebSGarrett D'Amore } /* emlxs_msg_log_create() */
84fcf3ce44SJohn Forte 
85fcf3ce44SJohn Forte 
86a9800bebSGarrett D'Amore void
emlxs_msg_lock_reinit(emlxs_hba_t * hba)87a9800bebSGarrett D'Amore emlxs_msg_lock_reinit(emlxs_hba_t *hba)
88a9800bebSGarrett D'Amore {
89a9800bebSGarrett D'Amore 	emlxs_msg_log_t *log = &LOG;
90291a2b48SSukumar Swaminathan 
91a9800bebSGarrett D'Amore 	/* Check if log is already destroyed */
92a9800bebSGarrett D'Amore 	if (!log->entry) {
93a9800bebSGarrett D'Amore 		cmn_err(CE_WARN,
94a9800bebSGarrett D'Amore 		    "?%s%d: message log already destroyed. log=%p",
95a9800bebSGarrett D'Amore 		    DRIVER_NAME, hba->ddiinst, (void *)log);
96fcf3ce44SJohn Forte 
97a9800bebSGarrett D'Amore 		return;
98fcf3ce44SJohn Forte 	}
99fcf3ce44SJohn Forte 
100a9800bebSGarrett D'Amore 	/* Destroy the temporary lock */
101a9800bebSGarrett D'Amore 	mutex_destroy(&log->lock);
102fcf3ce44SJohn Forte 
103a9800bebSGarrett D'Amore 	/* Re-create the log mutex lock */
104*8f23e9faSHans Rosenfeld 	mutex_init(&log->lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(hba->intr_arg));
105fcf3ce44SJohn Forte 
106a9800bebSGarrett D'Amore 	return;
107fcf3ce44SJohn Forte 
108a9800bebSGarrett D'Amore } /* emlxs_msg_lock_reinit() */
109a9800bebSGarrett D'Amore 
110a9800bebSGarrett D'Amore void
emlxs_msg_log_destroy(emlxs_hba_t * hba)111fcf3ce44SJohn Forte emlxs_msg_log_destroy(emlxs_hba_t *hba)
112fcf3ce44SJohn Forte {
113fcf3ce44SJohn Forte 	emlxs_msg_log_t *log = &LOG;
114fcf3ce44SJohn Forte 	uint32_t size;
115fcf3ce44SJohn Forte 
116fcf3ce44SJohn Forte 	/* Check if log is already destroyed */
117fcf3ce44SJohn Forte 	if (!log->entry) {
118291a2b48SSukumar Swaminathan 		cmn_err(CE_WARN,
119291a2b48SSukumar Swaminathan 		    "?%s%d: message log already destroyed. log=%p",
120291a2b48SSukumar Swaminathan 		    DRIVER_NAME, hba->ddiinst, (void *)log);
121fcf3ce44SJohn Forte 
122a9800bebSGarrett D'Amore 		return;
123fcf3ce44SJohn Forte 	}
124291a2b48SSukumar Swaminathan 
125fcf3ce44SJohn Forte 	/* Destroy the lock */
126fcf3ce44SJohn Forte 	mutex_destroy(&log->lock);
127fcf3ce44SJohn Forte 
128fcf3ce44SJohn Forte 	/* Free the log buffer */
129fcf3ce44SJohn Forte 	size = sizeof (emlxs_msg_entry_t) * log->size;
130fcf3ce44SJohn Forte 	kmem_free(log->entry, size);
131fcf3ce44SJohn Forte 
132fcf3ce44SJohn Forte 	/* Clear the log */
133fcf3ce44SJohn Forte 	bzero(log, sizeof (emlxs_msg_log_t));
134fcf3ce44SJohn Forte 
135a9800bebSGarrett D'Amore 	return;
136fcf3ce44SJohn Forte 
13782527734SSukumar Swaminathan } /* emlxs_msg_log_destroy() */
138291a2b48SSukumar Swaminathan 
139fcf3ce44SJohn Forte 
140fcf3ce44SJohn Forte uint32_t
emlxs_msg_log(emlxs_port_t * port,const uint32_t fileno,const uint32_t line,emlxs_msg_t * msg,char * buffer)141fcf3ce44SJohn Forte emlxs_msg_log(emlxs_port_t *port, const uint32_t fileno, const uint32_t line,
14282527734SSukumar Swaminathan     emlxs_msg_t *msg, char *buffer)
143fcf3ce44SJohn Forte {
144fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
145fcf3ce44SJohn Forte 	emlxs_msg_entry_t *entry;
146fcf3ce44SJohn Forte 	emlxs_msg_entry_t *entry2;
147fcf3ce44SJohn Forte 	clock_t time;
148fcf3ce44SJohn Forte 	emlxs_msg_log_t *log;
149fcf3ce44SJohn Forte 	uint32_t last;
150fcf3ce44SJohn Forte 	emlxs_msg_t *msg2;
151fcf3ce44SJohn Forte 
152fcf3ce44SJohn Forte 	/* Get the log file for this instance */
153fcf3ce44SJohn Forte 	log = &LOG;
154fcf3ce44SJohn Forte 
155fcf3ce44SJohn Forte 	/* Check if log is initialized */
156fcf3ce44SJohn Forte 	if (log->entry == NULL) {
157*8f23e9faSHans Rosenfeld 		return (0);
158fcf3ce44SJohn Forte 	}
159291a2b48SSukumar Swaminathan 
160fcf3ce44SJohn Forte 	mutex_enter(&log->lock);
161fcf3ce44SJohn Forte 
162fcf3ce44SJohn Forte 	/* Get the pointer to the last log entry */
163fcf3ce44SJohn Forte 	if (log->next == 0) {
164fcf3ce44SJohn Forte 		last = log->size - 1;
165fcf3ce44SJohn Forte 	} else {
166fcf3ce44SJohn Forte 		last = log->next - 1;
167fcf3ce44SJohn Forte 	}
168fcf3ce44SJohn Forte 	entry = &log->entry[last];
169fcf3ce44SJohn Forte 
170fcf3ce44SJohn Forte 	/* Check if this matches the last message */
171fcf3ce44SJohn Forte 	if ((entry->instance == log->instance) &&
172fcf3ce44SJohn Forte 	    (entry->vpi == port->vpi) &&
173fcf3ce44SJohn Forte 	    (entry->fileno == fileno) &&
174fcf3ce44SJohn Forte 	    (entry->line == line) &&
175fcf3ce44SJohn Forte 	    (entry->msg == msg) &&
176fcf3ce44SJohn Forte 	    (strcmp(entry->buffer, buffer) == 0)) {
177fcf3ce44SJohn Forte 		/* If the same message is being logged then increment */
178fcf3ce44SJohn Forte 		log->repeat++;
179fcf3ce44SJohn Forte 
180fcf3ce44SJohn Forte 		mutex_exit(&log->lock);
181fcf3ce44SJohn Forte 
182fcf3ce44SJohn Forte 		return (0);
183fcf3ce44SJohn Forte 	} else if (log->repeat) {
184fcf3ce44SJohn Forte 		/* Get the pointer to the next log entry */
185fcf3ce44SJohn Forte 		entry2 = &log->entry[log->next];
186fcf3ce44SJohn Forte 
187fcf3ce44SJohn Forte 		/* Increment and check the next entry index */
188fcf3ce44SJohn Forte 		if (++(log->next) >= log->size) {
189fcf3ce44SJohn Forte 			log->next = 0;
190fcf3ce44SJohn Forte 		}
191291a2b48SSukumar Swaminathan 
192fcf3ce44SJohn Forte 		switch (entry->msg->level) {
193fcf3ce44SJohn Forte 		case EMLXS_NOTICE:
194fcf3ce44SJohn Forte 			msg2 = &emlxs_notice_msg;
195fcf3ce44SJohn Forte 			break;
196fcf3ce44SJohn Forte 
197fcf3ce44SJohn Forte 		case EMLXS_WARNING:
198fcf3ce44SJohn Forte 			msg2 = &emlxs_warning_msg;
199fcf3ce44SJohn Forte 			break;
200fcf3ce44SJohn Forte 
201fcf3ce44SJohn Forte 		case EMLXS_ERROR:
202fcf3ce44SJohn Forte 			msg2 = &emlxs_error_msg;
203fcf3ce44SJohn Forte 			break;
204fcf3ce44SJohn Forte 
205fcf3ce44SJohn Forte 		case EMLXS_PANIC:
206fcf3ce44SJohn Forte 			msg2 = &emlxs_panic_msg;
207fcf3ce44SJohn Forte 			break;
208*8f23e9faSHans Rosenfeld 
209*8f23e9faSHans Rosenfeld 		case EMLXS_DEBUG:
210*8f23e9faSHans Rosenfeld 		default:
211*8f23e9faSHans Rosenfeld 			msg2 = &emlxs_debug_msg;
212*8f23e9faSHans Rosenfeld 			break;
213fcf3ce44SJohn Forte 		}
214291a2b48SSukumar Swaminathan 
215fcf3ce44SJohn Forte 		/* Initialize */
216fcf3ce44SJohn Forte 		entry2->id = log->count++;
217fcf3ce44SJohn Forte 		entry2->fileno = entry->fileno;
218fcf3ce44SJohn Forte 		entry2->line = entry->line;
219fcf3ce44SJohn Forte 		entry2->msg = msg2;
220fcf3ce44SJohn Forte 		entry2->instance = log->instance;
221fcf3ce44SJohn Forte 		entry2->vpi = port->vpi;
222fcf3ce44SJohn Forte 
223fcf3ce44SJohn Forte 		/* Save the additional info buffer */
224*8f23e9faSHans Rosenfeld 		(void) snprintf(entry2->buffer, MAX_LOG_INFO_LENGTH,
225fcf3ce44SJohn Forte 		    "Last message repeated %d time(s).",
226fcf3ce44SJohn Forte 		    log->repeat);
227fcf3ce44SJohn Forte 
228fcf3ce44SJohn Forte 		/* Set the entry time stamp */
229fcf3ce44SJohn Forte 		(void) drv_getparm(LBOLT, &time);
230fcf3ce44SJohn Forte 		entry2->time = time - log->start_time;
231fcf3ce44SJohn Forte 
23282527734SSukumar Swaminathan 		gethrestime(&entry2->id_time);
23382527734SSukumar Swaminathan 
234fcf3ce44SJohn Forte 		log->repeat = 0;
235fcf3ce44SJohn Forte 	}
236291a2b48SSukumar Swaminathan 
237fcf3ce44SJohn Forte 	/* Get the pointer to the next log entry */
238fcf3ce44SJohn Forte 	entry = &log->entry[log->next];
239fcf3ce44SJohn Forte 
240fcf3ce44SJohn Forte 	/* Increment and check the next entry index */
241fcf3ce44SJohn Forte 	if (++(log->next) >= log->size) {
242fcf3ce44SJohn Forte 		log->next = 0;
243fcf3ce44SJohn Forte 	}
244291a2b48SSukumar Swaminathan 
245fcf3ce44SJohn Forte 	/* Initialize */
246fcf3ce44SJohn Forte 	entry->id = log->count++;
247fcf3ce44SJohn Forte 	entry->fileno = fileno;
248fcf3ce44SJohn Forte 	entry->line = line;
249fcf3ce44SJohn Forte 	entry->msg = msg;
250fcf3ce44SJohn Forte 	entry->instance = log->instance;
251fcf3ce44SJohn Forte 	entry->vpi = port->vpi;
252fcf3ce44SJohn Forte 
253fcf3ce44SJohn Forte 	/* Save the additional info buffer */
254fcf3ce44SJohn Forte 	(void) strncpy(entry->buffer, buffer, (MAX_LOG_INFO_LENGTH - 1));
255fcf3ce44SJohn Forte 	entry->buffer[MAX_LOG_INFO_LENGTH - 1] = 0;
256fcf3ce44SJohn Forte 
257fcf3ce44SJohn Forte 	/* Set the entry time stamp */
258fcf3ce44SJohn Forte 	(void) drv_getparm(LBOLT, &time);
259fcf3ce44SJohn Forte 	entry->time = time - log->start_time;
260fcf3ce44SJohn Forte 
26182527734SSukumar Swaminathan 	gethrestime(&entry->id_time);
262291a2b48SSukumar Swaminathan 
263fcf3ce44SJohn Forte 	mutex_exit(&log->lock);
264fcf3ce44SJohn Forte 
265fcf3ce44SJohn Forte 	return (0);
266fcf3ce44SJohn Forte 
26782527734SSukumar Swaminathan } /* emlxs_msg_log() */
268fcf3ce44SJohn Forte 
269fcf3ce44SJohn Forte 
27082527734SSukumar Swaminathan /*ARGSUSED*/
271fcf3ce44SJohn Forte static uint32_t
emlxs_msg_log_check(emlxs_port_t * port,emlxs_msg_t * msg)272fcf3ce44SJohn Forte emlxs_msg_log_check(emlxs_port_t *port, emlxs_msg_t *msg)
273fcf3ce44SJohn Forte {
274fcf3ce44SJohn Forte 
275fcf3ce44SJohn Forte 	switch (msg->level) {
276fcf3ce44SJohn Forte 	case EMLXS_DEBUG:
277fcf3ce44SJohn Forte 		if (msg->mask & emlxs_log_debugs) {
278fcf3ce44SJohn Forte 			return (1);
279fcf3ce44SJohn Forte 		}
280fcf3ce44SJohn Forte 		break;
281fcf3ce44SJohn Forte 
282fcf3ce44SJohn Forte 	case EMLXS_NOTICE:
283fcf3ce44SJohn Forte 		if (msg->mask & emlxs_log_notices) {
284fcf3ce44SJohn Forte 			return (1);
285fcf3ce44SJohn Forte 		}
286fcf3ce44SJohn Forte 		break;
287fcf3ce44SJohn Forte 
288fcf3ce44SJohn Forte 	case EMLXS_WARNING:
289fcf3ce44SJohn Forte 		if (msg->mask & emlxs_log_warnings) {
290fcf3ce44SJohn Forte 			return (1);
291fcf3ce44SJohn Forte 		}
292fcf3ce44SJohn Forte 		break;
293fcf3ce44SJohn Forte 
294fcf3ce44SJohn Forte 	case EMLXS_ERROR:
295fcf3ce44SJohn Forte 		if (msg->mask & emlxs_log_errors) {
296fcf3ce44SJohn Forte 			return (1);
297fcf3ce44SJohn Forte 		}
298fcf3ce44SJohn Forte 		break;
299fcf3ce44SJohn Forte 
300fcf3ce44SJohn Forte 	case EMLXS_PANIC:
301fcf3ce44SJohn Forte 		return (1);
302fcf3ce44SJohn Forte 	}
303fcf3ce44SJohn Forte 
304fcf3ce44SJohn Forte 	return (0);
305fcf3ce44SJohn Forte 
30682527734SSukumar Swaminathan } /* emlxs_msg_log_check() */
307fcf3ce44SJohn Forte 
308fcf3ce44SJohn Forte 
309fcf3ce44SJohn Forte static uint32_t
emlxs_msg_print_check(emlxs_port_t * port,emlxs_msg_t * msg)310fcf3ce44SJohn Forte emlxs_msg_print_check(emlxs_port_t *port, emlxs_msg_t *msg)
311fcf3ce44SJohn Forte {
312fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
313fcf3ce44SJohn Forte 	emlxs_config_t *cfg;
314fcf3ce44SJohn Forte 	uint32_t rval = 0;
315fcf3ce44SJohn Forte 
316fcf3ce44SJohn Forte 	cfg = &CFG;
317fcf3ce44SJohn Forte 
318fcf3ce44SJohn Forte 	switch (msg->level) {
319fcf3ce44SJohn Forte 	case EMLXS_DEBUG:
320fcf3ce44SJohn Forte 		if (msg->mask & cfg[CFG_CONSOLE_DEBUGS].current) {
321fcf3ce44SJohn Forte 			rval |= 2;
322fcf3ce44SJohn Forte 		}
323291a2b48SSukumar Swaminathan 
324fcf3ce44SJohn Forte 		if (msg->mask & cfg[CFG_LOG_DEBUGS].current) {
325fcf3ce44SJohn Forte 			rval |= 1;
326fcf3ce44SJohn Forte 		}
327291a2b48SSukumar Swaminathan 
328fcf3ce44SJohn Forte 		break;
329fcf3ce44SJohn Forte 
330fcf3ce44SJohn Forte 	case EMLXS_NOTICE:
331fcf3ce44SJohn Forte 		if (msg->mask & cfg[CFG_CONSOLE_NOTICES].current) {
332fcf3ce44SJohn Forte 			rval |= 2;
333fcf3ce44SJohn Forte 		}
334291a2b48SSukumar Swaminathan 
335fcf3ce44SJohn Forte 		if (msg->mask & cfg[CFG_LOG_NOTICES].current) {
336fcf3ce44SJohn Forte 			rval |= 1;
337fcf3ce44SJohn Forte 		}
338291a2b48SSukumar Swaminathan 
339fcf3ce44SJohn Forte 		break;
340fcf3ce44SJohn Forte 
341fcf3ce44SJohn Forte 	case EMLXS_WARNING:
342fcf3ce44SJohn Forte 		if (msg->mask & cfg[CFG_CONSOLE_WARNINGS].current) {
343fcf3ce44SJohn Forte 			rval |= 2;
344fcf3ce44SJohn Forte 		}
345291a2b48SSukumar Swaminathan 
346fcf3ce44SJohn Forte 		if (msg->mask & cfg[CFG_LOG_WARNINGS].current) {
347fcf3ce44SJohn Forte 			rval |= 1;
348fcf3ce44SJohn Forte 		}
349291a2b48SSukumar Swaminathan 
350fcf3ce44SJohn Forte 		break;
351fcf3ce44SJohn Forte 
352fcf3ce44SJohn Forte 	case EMLXS_ERROR:
353fcf3ce44SJohn Forte 		if (msg->mask & cfg[CFG_CONSOLE_ERRORS].current) {
354fcf3ce44SJohn Forte 			rval |= 2;
355fcf3ce44SJohn Forte 		}
356291a2b48SSukumar Swaminathan 
357fcf3ce44SJohn Forte 		if (msg->mask & cfg[CFG_LOG_ERRORS].current) {
358fcf3ce44SJohn Forte 			rval |= 1;
359fcf3ce44SJohn Forte 		}
360fcf3ce44SJohn Forte 		break;
361fcf3ce44SJohn Forte 
362fcf3ce44SJohn Forte 	case EMLXS_PANIC:
363fcf3ce44SJohn Forte 	default:
364fcf3ce44SJohn Forte 		rval |= 1;
365fcf3ce44SJohn Forte 
366fcf3ce44SJohn Forte 	}
367fcf3ce44SJohn Forte 
368fcf3ce44SJohn Forte 	return (rval);
369fcf3ce44SJohn Forte 
37082527734SSukumar Swaminathan } /* emlxs_msg_print_check() */
371fcf3ce44SJohn Forte 
372fcf3ce44SJohn Forte 
373fcf3ce44SJohn Forte void
emlxs_msg_printf(emlxs_port_t * port,const uint32_t fileno,const uint32_t line,emlxs_msg_t * msg,const char * fmt,...)374291a2b48SSukumar Swaminathan emlxs_msg_printf(emlxs_port_t *port, const uint32_t fileno,
37582527734SSukumar Swaminathan     const uint32_t line, emlxs_msg_t *msg,
376291a2b48SSukumar Swaminathan     const char *fmt, ...)
377fcf3ce44SJohn Forte {
378fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
379fcf3ce44SJohn Forte 	va_list valist;
380fcf3ce44SJohn Forte 	char va_str[256];
381fcf3ce44SJohn Forte 	char msg_str[512];
382fcf3ce44SJohn Forte 	char *level;
383fcf3ce44SJohn Forte 	int32_t cmn_level;
384fcf3ce44SJohn Forte 	uint32_t rval;
385fcf3ce44SJohn Forte 	char driver[32];
386fcf3ce44SJohn Forte 
387fcf3ce44SJohn Forte 	va_str[0] = 0;
388fcf3ce44SJohn Forte 
389fcf3ce44SJohn Forte 	if (fmt) {
390fcf3ce44SJohn Forte 		va_start(valist, fmt);
391*8f23e9faSHans Rosenfeld 		(void) vsnprintf(va_str, sizeof (va_str), fmt, valist);
392fcf3ce44SJohn Forte 		va_end(valist);
393fcf3ce44SJohn Forte 	}
394291a2b48SSukumar Swaminathan 
395291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT
396bb63f56eSSukumar Swaminathan 	if (msg->fm_ereport_code) {
397bb63f56eSSukumar Swaminathan 		emlxs_fm_ereport(hba, msg->fm_ereport_code);
398bb63f56eSSukumar Swaminathan 	}
399291a2b48SSukumar Swaminathan 
400bb63f56eSSukumar Swaminathan 	if (msg->fm_impact_code) {
401bb63f56eSSukumar Swaminathan 		emlxs_fm_service_impact(hba, msg->fm_impact_code);
402291a2b48SSukumar Swaminathan 	}
403291a2b48SSukumar Swaminathan #endif	/* FMA_SUPPORT */
404291a2b48SSukumar Swaminathan 
405fcf3ce44SJohn Forte 	/* Check if msg should be logged */
40682527734SSukumar Swaminathan 	if (emlxs_msg_log_check(port, msg)) {
407fcf3ce44SJohn Forte 		/* Log the message */
40882527734SSukumar Swaminathan 		if (emlxs_msg_log(port, fileno, line, msg, va_str)) {
409fcf3ce44SJohn Forte 			return;
410fcf3ce44SJohn Forte 		}
411fcf3ce44SJohn Forte 	}
412291a2b48SSukumar Swaminathan 
413fcf3ce44SJohn Forte 	/* Check if msg should be printed */
414fcf3ce44SJohn Forte 	if (rval = emlxs_msg_print_check(port, msg)) {
415fcf3ce44SJohn Forte 		cmn_level = CE_CONT;
416fcf3ce44SJohn Forte 
417fcf3ce44SJohn Forte 		switch (msg->level) {
418fcf3ce44SJohn Forte 		case EMLXS_DEBUG:
419fcf3ce44SJohn Forte 			level = "  DEBUG";
420fcf3ce44SJohn Forte 			break;
421fcf3ce44SJohn Forte 
422fcf3ce44SJohn Forte 		case EMLXS_NOTICE:
423fcf3ce44SJohn Forte 			level = " NOTICE";
424fcf3ce44SJohn Forte 			break;
425fcf3ce44SJohn Forte 
426fcf3ce44SJohn Forte 		case EMLXS_WARNING:
427fcf3ce44SJohn Forte 			level = "WARNING";
428fcf3ce44SJohn Forte 			break;
429fcf3ce44SJohn Forte 
430fcf3ce44SJohn Forte 		case EMLXS_ERROR:
431fcf3ce44SJohn Forte 			level = "  ERROR";
432fcf3ce44SJohn Forte 			break;
433fcf3ce44SJohn Forte 
434fcf3ce44SJohn Forte 		case EMLXS_PANIC:
435fcf3ce44SJohn Forte 			cmn_level = CE_PANIC;
436fcf3ce44SJohn Forte 			level = "  PANIC";
437fcf3ce44SJohn Forte 			break;
438fcf3ce44SJohn Forte 
439fcf3ce44SJohn Forte 		default:
440fcf3ce44SJohn Forte 			level = "UNKNOWN";
441fcf3ce44SJohn Forte 			break;
442fcf3ce44SJohn Forte 		}
443fcf3ce44SJohn Forte 
444fcf3ce44SJohn Forte 		if (port->vpi == 0) {
445*8f23e9faSHans Rosenfeld 			(void) snprintf(driver, sizeof (driver), "%s%d",
446*8f23e9faSHans Rosenfeld 			    DRIVER_NAME, hba->ddiinst);
447fcf3ce44SJohn Forte 		} else {
448*8f23e9faSHans Rosenfeld 			(void) snprintf(driver, sizeof (driver), "%s%d.%d",
449*8f23e9faSHans Rosenfeld 			    DRIVER_NAME, hba->ddiinst, port->vpi);
450fcf3ce44SJohn Forte 		}
451fcf3ce44SJohn Forte 
452fcf3ce44SJohn Forte 		/* Generate the message string */
453fcf3ce44SJohn Forte 		if (msg->buffer[0] != 0) {
454fcf3ce44SJohn Forte 			if (va_str[0] != 0) {
455*8f23e9faSHans Rosenfeld 				(void) snprintf(msg_str, sizeof (msg_str),
456291a2b48SSukumar Swaminathan 				    "[%2X.%04X]%s:%7s:%4d: %s (%s)\n", fileno,
457291a2b48SSukumar Swaminathan 				    line, driver, level, msg->id, msg->buffer,
458291a2b48SSukumar Swaminathan 				    va_str);
459fcf3ce44SJohn Forte 			} else {
460*8f23e9faSHans Rosenfeld 				(void) snprintf(msg_str, sizeof (msg_str),
461fcf3ce44SJohn Forte 				    "[%2X.%04X]%s:%7s:%4d: %s\n",
462fcf3ce44SJohn Forte 				    fileno, line, driver, level, msg->id,
463fcf3ce44SJohn Forte 				    msg->buffer);
464fcf3ce44SJohn Forte 			}
465fcf3ce44SJohn Forte 		} else {
466fcf3ce44SJohn Forte 			if (va_str[0] != 0) {
467*8f23e9faSHans Rosenfeld 				(void) snprintf(msg_str, sizeof (msg_str),
468291a2b48SSukumar Swaminathan 				    "[%2X.%04X]%s:%7s:%4d: (%s)\n", fileno,
469291a2b48SSukumar Swaminathan 				    line, driver, level, msg->id, va_str);
470fcf3ce44SJohn Forte 			} else {
471*8f23e9faSHans Rosenfeld 				(void) snprintf(msg_str, sizeof (msg_str),
472fcf3ce44SJohn Forte 				    "[%2X.%04X]%s:%7s:%4d\n",
473fcf3ce44SJohn Forte 				    fileno, line, driver, level, msg->id);
474fcf3ce44SJohn Forte 			}
475fcf3ce44SJohn Forte 		}
476fcf3ce44SJohn Forte 
477fcf3ce44SJohn Forte 		switch (rval) {
478fcf3ce44SJohn Forte 		case 1:	/* MESSAGE LOG ONLY */
479291a2b48SSukumar Swaminathan 			/* Message log & console, if system booted in */
480291a2b48SSukumar Swaminathan 			/* verbose mode (CE_CONT only) */
481fcf3ce44SJohn Forte 			cmn_err(cmn_level, "?%s", msg_str);
482fcf3ce44SJohn Forte 			break;
483fcf3ce44SJohn Forte 
484fcf3ce44SJohn Forte 		case 2:	/* CONSOLE ONLY */
485fcf3ce44SJohn Forte 			cmn_err(cmn_level, "^%s", msg_str);
486fcf3ce44SJohn Forte 			break;
487fcf3ce44SJohn Forte 
488fcf3ce44SJohn Forte 		case 3:	/* CONSOLE AND MESSAGE LOG */
489fcf3ce44SJohn Forte 			cmn_err(cmn_level, "%s", msg_str);
490fcf3ce44SJohn Forte 			break;
491fcf3ce44SJohn Forte 
492fcf3ce44SJohn Forte 		}
493fcf3ce44SJohn Forte 
494fcf3ce44SJohn Forte 	}
495291a2b48SSukumar Swaminathan 
496fcf3ce44SJohn Forte 	return;
497fcf3ce44SJohn Forte 
49882527734SSukumar Swaminathan } /* emlxs_msg_printf() */
499fcf3ce44SJohn Forte 
500fcf3ce44SJohn Forte 
501fcf3ce44SJohn Forte uint32_t
emlxs_msg_log_get(emlxs_hba_t * hba,emlxs_log_req_t * req,emlxs_log_resp_t * resp)502fcf3ce44SJohn Forte emlxs_msg_log_get(emlxs_hba_t *hba, emlxs_log_req_t *req,
503fcf3ce44SJohn Forte     emlxs_log_resp_t *resp)
504fcf3ce44SJohn Forte {
505fcf3ce44SJohn Forte 	emlxs_msg_log_t *log;
506fcf3ce44SJohn Forte 	uint32_t first;
507fcf3ce44SJohn Forte 	uint32_t last;
508fcf3ce44SJohn Forte 	uint32_t count;
509fcf3ce44SJohn Forte 	uint32_t index;
510fcf3ce44SJohn Forte 	uint32_t i;
511fcf3ce44SJohn Forte 	char *resp_buf;
512fcf3ce44SJohn Forte 
513fcf3ce44SJohn Forte 	log = &LOG;
514fcf3ce44SJohn Forte 
515fcf3ce44SJohn Forte 	mutex_enter(&log->lock);
516fcf3ce44SJohn Forte 
517fcf3ce44SJohn Forte 	/* Check if buffer is empty */
518fcf3ce44SJohn Forte 	if (log->count == 0) {
519fcf3ce44SJohn Forte 		/* If so, exit now */
520fcf3ce44SJohn Forte 		resp->first = 0;
521fcf3ce44SJohn Forte 		resp->last = 0;
522fcf3ce44SJohn Forte 		resp->count = 0;
523fcf3ce44SJohn Forte 		mutex_exit(&log->lock);
524fcf3ce44SJohn Forte 
525fcf3ce44SJohn Forte 		return (1);
526fcf3ce44SJohn Forte 	}
527291a2b48SSukumar Swaminathan 
528fcf3ce44SJohn Forte 	/* Get current log entry ranges */
529fcf3ce44SJohn Forte 
530fcf3ce44SJohn Forte 	/* Get last entry id saved */
531fcf3ce44SJohn Forte 	last = log->count - 1;
532fcf3ce44SJohn Forte 
533fcf3ce44SJohn Forte 	/* Check if request is out of current range */
534fcf3ce44SJohn Forte 	if (req->first > last) {
535fcf3ce44SJohn Forte 		/* if so, exit now */
536fcf3ce44SJohn Forte 		resp->first = last;
537fcf3ce44SJohn Forte 		resp->last = last;
538fcf3ce44SJohn Forte 		resp->count = 0;
539fcf3ce44SJohn Forte 		mutex_exit(&log->lock);
540fcf3ce44SJohn Forte 
541fcf3ce44SJohn Forte 		return (0);
542fcf3ce44SJohn Forte 	}
543291a2b48SSukumar Swaminathan 
544fcf3ce44SJohn Forte 	/* Get oldest entry id and its index */
545fcf3ce44SJohn Forte 
546fcf3ce44SJohn Forte 	/* Check if buffer has already been filled once */
547fcf3ce44SJohn Forte 	if (log->count >= log->size) {
548fcf3ce44SJohn Forte 		first = log->count - log->size;
549fcf3ce44SJohn Forte 		index = log->next;
550fcf3ce44SJohn Forte 	} else {	/* Buffer not yet filled */
551291a2b48SSukumar Swaminathan 
552fcf3ce44SJohn Forte 		first = 0;
553fcf3ce44SJohn Forte 		index = 0;
554fcf3ce44SJohn Forte 	}
555fcf3ce44SJohn Forte 
556291a2b48SSukumar Swaminathan 	/* Check if requested first message is greater than actual. */
557291a2b48SSukumar Swaminathan 	/* If so, adjust for it.  */
558fcf3ce44SJohn Forte 	if (req->first > first) {
559fcf3ce44SJohn Forte 		/* Adjust entry index to first requested message */
560fcf3ce44SJohn Forte 		index += (req->first - first);
561fcf3ce44SJohn Forte 		if (index >= log->size) {
562fcf3ce44SJohn Forte 			index -= log->size;
563fcf3ce44SJohn Forte 		}
564291a2b48SSukumar Swaminathan 
565fcf3ce44SJohn Forte 		first = req->first;
566fcf3ce44SJohn Forte 	}
567291a2b48SSukumar Swaminathan 
568fcf3ce44SJohn Forte 	/* Get the total number of messages available for return */
569fcf3ce44SJohn Forte 	count = last - first + 1;
570fcf3ce44SJohn Forte 
571fcf3ce44SJohn Forte 	/* Check if requested count is less than actual.  If so, adjust it. */
572fcf3ce44SJohn Forte 	if (req->count < count) {
573fcf3ce44SJohn Forte 		count = req->count;
574fcf3ce44SJohn Forte 	}
575291a2b48SSukumar Swaminathan 
576fcf3ce44SJohn Forte 	/* Fill in the response header */
577fcf3ce44SJohn Forte 	resp->count = count;
578fcf3ce44SJohn Forte 	resp->first = first;
579fcf3ce44SJohn Forte 	resp->last = last;
580fcf3ce44SJohn Forte 
581fcf3ce44SJohn Forte 	/* Fill the response buffer */
582fcf3ce44SJohn Forte 	resp_buf = (char *)resp + sizeof (emlxs_log_resp_t);
583fcf3ce44SJohn Forte 	for (i = 0; i < count; i++) {
584fcf3ce44SJohn Forte 		emlxs_msg_sprintf(resp_buf, &log->entry[index]);
585fcf3ce44SJohn Forte 
586fcf3ce44SJohn Forte 		/* Increment the response buffer */
587fcf3ce44SJohn Forte 		resp_buf += MAX_LOG_MSG_LENGTH;
588fcf3ce44SJohn Forte 
589fcf3ce44SJohn Forte 		/* Increment index */
590fcf3ce44SJohn Forte 		if (++index >= log->size) {
591fcf3ce44SJohn Forte 			index = 0;
592fcf3ce44SJohn Forte 		}
593fcf3ce44SJohn Forte 	}
594fcf3ce44SJohn Forte 
595fcf3ce44SJohn Forte 	mutex_exit(&log->lock);
596fcf3ce44SJohn Forte 
597fcf3ce44SJohn Forte 	return (1);
598fcf3ce44SJohn Forte 
59982527734SSukumar Swaminathan } /* emlxs_msg_log_get() */
600fcf3ce44SJohn Forte 
601fcf3ce44SJohn Forte 
602fcf3ce44SJohn Forte 
603fcf3ce44SJohn Forte static void
emlxs_msg_sprintf(char * buffer,emlxs_msg_entry_t * entry)604fcf3ce44SJohn Forte emlxs_msg_sprintf(char *buffer, emlxs_msg_entry_t *entry)
605fcf3ce44SJohn Forte {
606fcf3ce44SJohn Forte 	char *level;
607fcf3ce44SJohn Forte 	emlxs_msg_t *msg;
608fcf3ce44SJohn Forte 	uint32_t secs;
609fcf3ce44SJohn Forte 	uint32_t hsecs;
610fcf3ce44SJohn Forte 	char buf[256];
611fcf3ce44SJohn Forte 	uint32_t buflen;
612fcf3ce44SJohn Forte 	char driver[32];
613fcf3ce44SJohn Forte 
614fcf3ce44SJohn Forte 	msg = entry->msg;
61582527734SSukumar Swaminathan 
616fcf3ce44SJohn Forte 	hsecs = (entry->time % 100);
617fcf3ce44SJohn Forte 	secs = entry->time / 100;
618fcf3ce44SJohn Forte 
619fcf3ce44SJohn Forte 	switch (msg->level) {
620fcf3ce44SJohn Forte 	case EMLXS_DEBUG:
621fcf3ce44SJohn Forte 		level = "  DEBUG";
622fcf3ce44SJohn Forte 		break;
623fcf3ce44SJohn Forte 
624fcf3ce44SJohn Forte 	case EMLXS_NOTICE:
625fcf3ce44SJohn Forte 		level = " NOTICE";
626fcf3ce44SJohn Forte 		break;
627fcf3ce44SJohn Forte 
628fcf3ce44SJohn Forte 	case EMLXS_WARNING:
629fcf3ce44SJohn Forte 		level = "WARNING";
630fcf3ce44SJohn Forte 		break;
631fcf3ce44SJohn Forte 
632fcf3ce44SJohn Forte 	case EMLXS_ERROR:
633fcf3ce44SJohn Forte 		level = "  ERROR";
634fcf3ce44SJohn Forte 		break;
635fcf3ce44SJohn Forte 
636fcf3ce44SJohn Forte 	case EMLXS_PANIC:
637fcf3ce44SJohn Forte 		level = "  PANIC";
638fcf3ce44SJohn Forte 		break;
639fcf3ce44SJohn Forte 
640fcf3ce44SJohn Forte 	default:
641fcf3ce44SJohn Forte 		level = "UNKNOWN";
642fcf3ce44SJohn Forte 		break;
643fcf3ce44SJohn Forte 	}
644fcf3ce44SJohn Forte 
645fcf3ce44SJohn Forte 	if (entry->vpi == 0) {
646*8f23e9faSHans Rosenfeld 		(void) snprintf(driver, sizeof (driver), "%s%d", DRIVER_NAME,
647*8f23e9faSHans Rosenfeld 		    entry->instance);
648fcf3ce44SJohn Forte 	} else {
649*8f23e9faSHans Rosenfeld 		(void) snprintf(driver, sizeof (driver), "%s%d.%d", DRIVER_NAME,
650*8f23e9faSHans Rosenfeld 		    entry->instance, entry->vpi);
651fcf3ce44SJohn Forte 	}
652fcf3ce44SJohn Forte 
653fcf3ce44SJohn Forte 	/* Generate the message string */
654fcf3ce44SJohn Forte 	if (msg->buffer[0] != 0) {
655fcf3ce44SJohn Forte 		if (entry->buffer[0] != 0) {
656*8f23e9faSHans Rosenfeld 			(void) snprintf(buf, sizeof (buf),
657fcf3ce44SJohn Forte 			    "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: %s (%s)\n",
658291a2b48SSukumar Swaminathan 			    secs, hsecs, entry->id, entry->fileno,
659291a2b48SSukumar Swaminathan 			    entry->line, driver, level, msg->id, msg->buffer,
660291a2b48SSukumar Swaminathan 			    entry->buffer);
661fcf3ce44SJohn Forte 
662fcf3ce44SJohn Forte 		} else {
663*8f23e9faSHans Rosenfeld 			(void) snprintf(buf, sizeof (buf),
664291a2b48SSukumar Swaminathan 			    "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: %s\n", secs,
665291a2b48SSukumar Swaminathan 			    hsecs, entry->id, entry->fileno, entry->line,
666fcf3ce44SJohn Forte 			    driver, level, msg->id, msg->buffer);
667fcf3ce44SJohn Forte 		}
668fcf3ce44SJohn Forte 	} else {
669fcf3ce44SJohn Forte 		if (entry->buffer[0] != 0) {
670*8f23e9faSHans Rosenfeld 			(void) snprintf(buf, sizeof (buf),
671fcf3ce44SJohn Forte 			    "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d: (%s)\n",
672291a2b48SSukumar Swaminathan 			    secs, hsecs, entry->id, entry->fileno,
673291a2b48SSukumar Swaminathan 			    entry->line, driver, level, msg->id,
674291a2b48SSukumar Swaminathan 			    entry->buffer);
675fcf3ce44SJohn Forte 		} else {
676*8f23e9faSHans Rosenfeld 			(void) snprintf(buf, sizeof (buf),
677fcf3ce44SJohn Forte 			    "%8d.%02d: %6d:[%2X.%04X]%s:%7s:%4d\n",
678291a2b48SSukumar Swaminathan 			    secs, hsecs, entry->id, entry->fileno,
679291a2b48SSukumar Swaminathan 			    entry->line, driver, level, msg->id);
680fcf3ce44SJohn Forte 		}
681fcf3ce44SJohn Forte 	}
682fcf3ce44SJohn Forte 
683fcf3ce44SJohn Forte 	bzero(buffer, MAX_LOG_MSG_LENGTH);
684fcf3ce44SJohn Forte 	buflen = strlen(buf);
685fcf3ce44SJohn Forte 
686fcf3ce44SJohn Forte 	if (buflen > (MAX_LOG_MSG_LENGTH - 1)) {
687fcf3ce44SJohn Forte 		(void) strncpy(buffer, buf, (MAX_LOG_MSG_LENGTH - 2));
688fcf3ce44SJohn Forte 		buffer[MAX_LOG_MSG_LENGTH - 2] = '\n';
689fcf3ce44SJohn Forte 	} else {
690fcf3ce44SJohn Forte 		(void) strncpy(buffer, buf, buflen);
691fcf3ce44SJohn Forte 	}
692fcf3ce44SJohn Forte 
693fcf3ce44SJohn Forte 	return;
694fcf3ce44SJohn Forte 
69582527734SSukumar Swaminathan } /* emlxs_msg_sprintf() */