xref: /freebsd/sys/dev/aacraid/aacraid_debug.c (revision e453e498cbb88570a3ff7b3679de65c88707da95)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2006-2010 Adaptec, Inc.
5  * Copyright (c) 2010-2012 PMC-Sierra, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  */
30 
31 #include <sys/cdefs.h>
32 /*
33  * Debugging support.
34  */
35 #include "opt_aacraid.h"
36 
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/conf.h>
41 
42 #include <sys/bus.h>
43 
44 #include <machine/resource.h>
45 #include <machine/bus.h>
46 
47 #include <dev/aacraid/aacraid_reg.h>
48 #include <sys/aac_ioctl.h>
49 #include <dev/aacraid/aacraid_var.h>
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/kernel.h>
53 #include <sys/conf.h>
54 #include <sys/bus.h>
55 #include <sys/rman.h>
56 #include <sys/stdarg.h>
57 
58 #include <machine/resource.h>
59 #include <machine/bus.h>
60 
61 #include <dev/aacraid/aacraid_debug.h>
62 
63 #ifdef AACRAID_DEBUG
64 /*
65  * Dump the command queue indices
66  */
67 void
aacraid_print_queues(struct aac_softc * sc)68 aacraid_print_queues(struct aac_softc *sc)
69 {
70 	device_printf(sc->aac_dev, "AACQ_FREE      %d/%d\n",
71 	    sc->aac_qstat[AACQ_FREE].q_length, sc->aac_qstat[AACQ_FREE].q_max);
72 	device_printf(sc->aac_dev, "AACQ_READY     %d/%d\n",
73 	    sc->aac_qstat[AACQ_READY].q_length,
74 	    sc->aac_qstat[AACQ_READY].q_max);
75 	device_printf(sc->aac_dev, "AACQ_BUSY      %d/%d\n",
76 	    sc->aac_qstat[AACQ_BUSY].q_length, sc->aac_qstat[AACQ_BUSY].q_max);
77 }
78 
79 /*
80  * Print a FIB
81  */
82 void
aacraid_print_fib(struct aac_softc * sc,struct aac_fib * fib,const char * caller)83 aacraid_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
84 {
85 	if (fib == NULL) {
86 		device_printf(sc->aac_dev,
87 			      "aac_print_fib called with NULL fib\n");
88 		return;
89 	}
90 	device_printf(sc->aac_dev, "%s: FIB @ %p\n", caller, fib);
91 	device_printf(sc->aac_dev, "  XferState %b\n", fib->Header.XferState,
92 		      "\20"
93 		      "\1HOSTOWNED"
94 		      "\2ADAPTEROWNED"
95 		      "\3INITIALISED"
96 		      "\4EMPTY"
97 		      "\5FROMPOOL"
98 		      "\6FROMHOST"
99 		      "\7FROMADAP"
100 		      "\10REXPECTED"
101 		      "\11RNOTEXPECTED"
102 		      "\12DONEADAP"
103 		      "\13DONEHOST"
104 		      "\14HIGH"
105 		      "\15NORM"
106 		      "\16ASYNC"
107 		      "\17PAGEFILEIO"
108 		      "\20SHUTDOWN"
109 		      "\21LAZYWRITE"
110 		      "\22ADAPMICROFIB"
111 		      "\23BIOSFIB"
112 		      "\24FAST_RESPONSE"
113 		      "\25APIFIB\n");
114 	device_printf(sc->aac_dev, "  Command       %d\n", fib->Header.Command);
115 	device_printf(sc->aac_dev, "  StructType    %d\n",
116 		      fib->Header.StructType);
117 	device_printf(sc->aac_dev, "  Size          %d\n", fib->Header.Size);
118 	device_printf(sc->aac_dev, "  SenderSize    %d\n",
119 		      fib->Header.SenderSize);
120 	device_printf(sc->aac_dev, "  SenderAddress 0x%x\n",
121 		      fib->Header.SenderFibAddress);
122 	device_printf(sc->aac_dev, "  RcvrAddress   0x%x\n",
123 		      fib->Header.u.ReceiverFibAddress);
124 	device_printf(sc->aac_dev, "  Handle    0x%x\n",
125 		      fib->Header.Handle);
126 	switch(fib->Header.Command) {
127 	case ContainerCommand:
128 	{
129 		struct aac_blockread *br;
130 		struct aac_blockwrite *bw;
131 		struct aac_sg_table *sg;
132 		int i;
133 
134 		br = (struct aac_blockread*)fib->data;
135 		bw = (struct aac_blockwrite*)fib->data;
136 		sg = NULL;
137 
138 		if (br->Command == VM_CtBlockRead) {
139 			device_printf(sc->aac_dev,
140 				      "  BlockRead: container %d  0x%x/%d\n",
141 				      br->ContainerId, br->BlockNumber,
142 				      br->ByteCount);
143 			sg = &br->SgMap;
144 		}
145 		if (bw->Command == VM_CtBlockWrite) {
146 			device_printf(sc->aac_dev,
147 				      "  BlockWrite: container %d  0x%x/%d "
148 				      "(%s)\n", bw->ContainerId,
149 				      bw->BlockNumber, bw->ByteCount,
150 				      bw->Stable == CSTABLE ? "stable" :
151 				      "unstable");
152 			sg = &bw->SgMap;
153 		}
154 		if (sg != NULL) {
155 			device_printf(sc->aac_dev,
156 				      "  %d s/g entries\n", sg->SgCount);
157 			for (i = 0; i < sg->SgCount; i++)
158 				device_printf(sc->aac_dev, "  0x%08x/%d\n",
159 					      sg->SgEntry[i].SgAddress,
160 					      sg->SgEntry[i].SgByteCount);
161 		}
162 		break;
163 	}
164 	default:
165 		device_printf(sc->aac_dev, "   %16D\n", fib->data, " ");
166 		device_printf(sc->aac_dev, "   %16D\n", fib->data + 16, " ");
167 		break;
168 	}
169 }
170 
171 /*
172  * Describe an AIF we have received.
173  */
174 void
aacraid_print_aif(struct aac_softc * sc,struct aac_aif_command * aif)175 aacraid_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
176 {
177 	switch(aif->command) {
178 	case AifCmdEventNotify:
179 		device_printf(sc->aac_dev, "EventNotify(%d)\n", aif->seqNumber);
180 		switch(aif->data.EN.type) {
181 		case AifEnGeneric:		/* Generic notification */
182 			device_printf(sc->aac_dev, "(Generic) %.*s\n",
183 				  (int)sizeof(aif->data.EN.data.EG),
184 				  aif->data.EN.data.EG.text);
185 			break;
186 		case AifEnTaskComplete:		/* Task has completed */
187 			device_printf(sc->aac_dev, "(TaskComplete)\n");
188 			break;
189 		case AifEnConfigChange:		/* Adapter configuration change
190 						 * occurred */
191 			device_printf(sc->aac_dev, "(ConfigChange)\n");
192 			break;
193 		case AifEnContainerChange:	/* Adapter specific container
194 						 * configuration change */
195 			device_printf(sc->aac_dev, "(ContainerChange) "
196 				      "container %d,%d\n",
197 				      aif->data.EN.data.ECC.container[0],
198 				      aif->data.EN.data.ECC.container[1]);
199 			break;
200 		case AifEnDeviceFailure:	/* SCSI device failed */
201 			device_printf(sc->aac_dev, "(DeviceFailure) "
202 				      "handle %d\n",
203 				      aif->data.EN.data.EDF.deviceHandle);
204 			break;
205 		case AifEnMirrorFailover:	/* Mirror failover started */
206 			device_printf(sc->aac_dev, "(MirrorFailover) "
207 				      "container %d failed, "
208 				      "migrating from slice %d to %d\n",
209 				      aif->data.EN.data.EMF.container,
210 				      aif->data.EN.data.EMF.failedSlice,
211 				      aif->data.EN.data.EMF.creatingSlice);
212 			break;
213 		case AifEnContainerEvent:	/* Significant container
214 						 * event */
215 			device_printf(sc->aac_dev, "(ContainerEvent) "
216 				      "container %d event "
217 				      "%d\n", aif->data.EN.data.ECE.container,
218 				      aif->data.EN.data.ECE.eventType);
219 			break;
220 		case AifEnFileSystemChange:	/* File system changed */
221 			device_printf(sc->aac_dev, "(FileSystemChange)\n");
222 			break;
223 		case AifEnConfigPause:		/* Container pause event */
224 			device_printf(sc->aac_dev, "(ConfigPause)\n");
225 			break;
226 		case AifEnConfigResume:		/* Container resume event */
227 			device_printf(sc->aac_dev, "(ConfigResume)\n");
228 			break;
229 		case AifEnFailoverChange:	/* Failover space assignment
230 						 * changed */
231 			device_printf(sc->aac_dev, "(FailoverChange)\n");
232 			break;
233 		case AifEnRAID5RebuildDone:	/* RAID5 rebuild finished */
234 			device_printf(sc->aac_dev, "(RAID5RebuildDone)\n");
235 			break;
236 		case AifEnEnclosureManagement:	/* Enclosure management event */
237 			device_printf(sc->aac_dev, "(EnclosureManagement) "
238 				      "EMPID %d unit %d "
239 				      "event %d\n", aif->data.EN.data.EEE.empID,
240 				      aif->data.EN.data.EEE.unitID,
241 				      aif->data.EN.data.EEE.eventType);
242 			break;
243 		case AifEnBatteryEvent:		/* Significant NV battery
244 						 * event */
245 			device_printf(sc->aac_dev, "(BatteryEvent) %d "
246 				      "(state was %d, is %d\n",
247 				      aif->data.EN.data.EBE.transition_type,
248 				      aif->data.EN.data.EBE.current_state,
249 				      aif->data.EN.data.EBE.prior_state);
250 			break;
251 		case AifEnAddContainer:		/* A new container was
252 						 * created. */
253 			device_printf(sc->aac_dev, "(AddContainer)\n");
254 			break;
255 		case AifEnDeleteContainer:	/* A container was deleted. */
256 			device_printf(sc->aac_dev, "(DeleteContainer)\n");
257 			break;
258 		case AifEnBatteryNeedsRecond:	/* The battery needs
259 						 * reconditioning */
260 			device_printf(sc->aac_dev, "(BatteryNeedsRecond)\n");
261 			break;
262 		case AifEnClusterEvent:		/* Some cluster event */
263 			device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
264 				      aif->data.EN.data.ECLE.eventType);
265 			break;
266 		case AifEnDiskSetEvent:		/* A disk set event occurred. */
267 			device_printf(sc->aac_dev, "(DiskSetEvent) event %d "
268 				      "diskset %jd creator %jd\n",
269 				      aif->data.EN.data.EDS.eventType,
270 				      (intmax_t)aif->data.EN.data.EDS.DsNum,
271 				      (intmax_t)aif->data.EN.data.EDS.CreatorId);
272 			break;
273 		case AifDenMorphComplete: 	/* A morph operation
274 						 * completed */
275 			device_printf(sc->aac_dev, "(MorphComplete)\n");
276 			break;
277 		case AifDenVolumeExtendComplete: /* A volume expand operation
278 						  * completed */
279 			device_printf(sc->aac_dev, "(VolumeExtendComplete)\n");
280 			break;
281 		default:
282 			device_printf(sc->aac_dev, "(%d)\n", aif->data.EN.type);
283 			break;
284 		}
285 		break;
286 	case AifCmdJobProgress:
287 	{
288 		char	*status;
289 		switch(aif->data.PR[0].status) {
290 		case AifJobStsSuccess:
291 			status = "success"; break;
292 		case AifJobStsFinished:
293 			status = "finished"; break;
294 		case AifJobStsAborted:
295 			status = "aborted"; break;
296 		case AifJobStsFailed:
297 			status = "failed"; break;
298 		case AifJobStsSuspended:
299 			status = "suspended"; break;
300 		case AifJobStsRunning:
301 			status = "running"; break;
302 		default:
303 			status = "unknown status"; break;
304 		}
305 
306 		device_printf(sc->aac_dev, "JobProgress (%d) - %s (%d, %d)\n",
307 			      aif->seqNumber, status,
308 			      aif->data.PR[0].currentTick,
309 			      aif->data.PR[0].finalTick);
310 		switch(aif->data.PR[0].jd.type) {
311 		case AifJobScsiZero:		/* SCSI dev clear operation */
312 			device_printf(sc->aac_dev, "(ScsiZero) handle %d\n",
313 				      aif->data.PR[0].jd.client.scsi_dh);
314 			break;
315 		case AifJobScsiVerify:		/* SCSI device Verify operation
316 						 * NO REPAIR */
317 			device_printf(sc->aac_dev, "(ScsiVerify) handle %d\n",
318 				      aif->data.PR[0].jd.client.scsi_dh);
319 			break;
320 		case AifJobScsiExercise:	/* SCSI device Exercise
321 						 * operation */
322 			device_printf(sc->aac_dev, "(ScsiExercise) handle %d\n",
323 				      aif->data.PR[0].jd.client.scsi_dh);
324 			break;
325 		case AifJobScsiVerifyRepair:	/* SCSI device Verify operation
326 						 * WITH repair */
327 			device_printf(sc->aac_dev,
328 				      "(ScsiVerifyRepair) handle %d\n",
329 				      aif->data.PR[0].jd.client.scsi_dh);
330 			break;
331 		case AifJobCtrZero:		/* Container clear operation */
332 			device_printf(sc->aac_dev,
333 				      "(ContainerZero) container %d\n",
334 				      aif->data.PR[0].jd.client.container.src);
335 			break;
336 		case AifJobCtrCopy:		/* Container copy operation */
337 			device_printf(sc->aac_dev,
338 				      "(ContainerCopy) container %d to %d\n",
339 				      aif->data.PR[0].jd.client.container.src,
340 				      aif->data.PR[0].jd.client.container.dst);
341 			break;
342 		case AifJobCtrCreateMirror:	/* Container Create Mirror
343 						 * operation */
344 			device_printf(sc->aac_dev,
345 				      "(ContainerCreateMirror) container %d\n",
346 				      aif->data.PR[0].jd.client.container.src);
347 				      /* XXX two containers? */
348 			break;
349 		case AifJobCtrMergeMirror:	/* Container Merge Mirror
350 						 * operation */
351 			device_printf(sc->aac_dev,
352 				      "(ContainerMergeMirror) container %d\n",
353 				      aif->data.PR[0].jd.client.container.src);
354 				      /* XXX two containers? */
355 			break;
356 		case AifJobCtrScrubMirror:	/* Container Scrub Mirror
357 						 * operation */
358 			device_printf(sc->aac_dev,
359 				      "(ContainerScrubMirror) container %d\n",
360 				      aif->data.PR[0].jd.client.container.src);
361 			break;
362 		case AifJobCtrRebuildRaid5:	/* Container Rebuild Raid5
363 						 * operation */
364 			device_printf(sc->aac_dev,
365 				      "(ContainerRebuildRaid5) container %d\n",
366 				      aif->data.PR[0].jd.client.container.src);
367 			break;
368 		case AifJobCtrScrubRaid5:	/* Container Scrub Raid5
369 						 * operation */
370 			device_printf(sc->aac_dev,
371 				      "(ContainerScrubRaid5) container %d\n",
372 				      aif->data.PR[0].jd.client.container.src);
373 			break;
374 		case AifJobCtrMorph:		/* Container morph operation */
375 			device_printf(sc->aac_dev,
376 				      "(ContainerMorph) container %d\n",
377 				      aif->data.PR[0].jd.client.container.src);
378 				      /* XXX two containers? */
379 			break;
380 		case AifJobCtrPartCopy:		/* Container Partition copy
381 						 * operation */
382 			device_printf(sc->aac_dev,
383 				      "(ContainerPartCopy) container %d to "
384 				      "%d\n",
385 				      aif->data.PR[0].jd.client.container.src,
386 				      aif->data.PR[0].jd.client.container.dst);
387 			break;
388 		case AifJobCtrRebuildMirror:	/* Container Rebuild Mirror
389 						 * operation */
390 			device_printf(sc->aac_dev,
391 				      "(ContainerRebuildMirror) container "
392 				      "%d\n",
393 				      aif->data.PR[0].jd.client.container.src);
394 			break;
395 		case AifJobCtrCrazyCache:	/* crazy cache */
396 			device_printf(sc->aac_dev,
397 				      "(ContainerCrazyCache) container %d\n",
398 				      aif->data.PR[0].jd.client.container.src);
399 				      /* XXX two containers? */
400 			break;
401 		case AifJobFsCreate:		/* File System Create
402 						 * operation */
403 			device_printf(sc->aac_dev, "(FsCreate)\n");
404 			break;
405 		case AifJobFsVerify:		/* File System Verify
406 						 * operation */
407 			device_printf(sc->aac_dev, "(FsVerivy)\n");
408 			break;
409 		case AifJobFsExtend:		/* File System Extend
410 						 * operation */
411 			device_printf(sc->aac_dev, "(FsExtend)\n");
412 			break;
413 		case AifJobApiFormatNTFS:	/* Format a drive to NTFS */
414 			device_printf(sc->aac_dev, "(FormatNTFS)\n");
415 			break;
416 		case AifJobApiFormatFAT:	/* Format a drive to FAT */
417 			device_printf(sc->aac_dev, "(FormatFAT)\n");
418 			break;
419 		case AifJobApiUpdateSnapshot:	/* update the read/write half
420 						 * of a snapshot */
421 			device_printf(sc->aac_dev, "(UpdateSnapshot)\n");
422 			break;
423 		case AifJobApiFormatFAT32:	/* Format a drive to FAT32 */
424 			device_printf(sc->aac_dev, "(FormatFAT32)\n");
425 			break;
426 		case AifJobCtlContinuousCtrVerify: /* Adapter operation */
427 			device_printf(sc->aac_dev, "(ContinuousCtrVerify)\n");
428 			break;
429 		default:
430 			device_printf(sc->aac_dev, "(%d)\n",
431 				      aif->data.PR[0].jd.type);
432 			break;
433 		}
434 		break;
435 	}
436 	case AifCmdAPIReport:
437 		device_printf(sc->aac_dev, "APIReport (%d)\n", aif->seqNumber);
438 		break;
439 	case AifCmdDriverNotify:
440 		device_printf(sc->aac_dev, "DriverNotify (%d)\n",
441 			      aif->seqNumber);
442 		break;
443 	default:
444 		device_printf(sc->aac_dev, "AIF %d (%d)\n", aif->command,
445 			      aif->seqNumber);
446 		break;
447 	}
448 }
449 #endif /* AACRAID_DEBUG */
450 
451 /*
452  * Debug flags to be put into the HBA flags field when initialized
453  */
454 const unsigned long aacraid_debug_flags = /* Variable to setup with above flags. */
455 /*			HBA_FLAGS_DBG_KERNEL_PRINT_B |		*/
456 			HBA_FLAGS_DBG_FW_PRINT_B |
457 /*			HBA_FLAGS_DBG_FUNCTION_ENTRY_B |	*/
458 			HBA_FLAGS_DBG_FUNCTION_EXIT_B |
459 			HBA_FLAGS_DBG_ERROR_B |
460 			HBA_FLAGS_DBG_INIT_B |
461 /*			HBA_FLAGS_DBG_OS_COMMANDS_B |		*/
462 /*			HBA_FLAGS_DBG_SCAN_B |			*/
463 /*			HBA_FLAGS_DBG_COALESCE_B |		*/
464 /*			HBA_FLAGS_DBG_IOCTL_COMMANDS_B |	*/
465 /*			HBA_FLAGS_DBG_SYNC_COMMANDS_B |		*/
466 			HBA_FLAGS_DBG_COMM_B |
467 /*			HBA_FLAGS_DBG_AIF_B |			*/
468 /*			HBA_FLAGS_DBG_CSMI_COMMANDS_B | 	*/
469 			HBA_FLAGS_DBG_DEBUG_B |
470 /*			HBA_FLAGS_DBG_FLAGS_MASK | 		*/
471 0;
472 
aacraid_get_fw_debug_buffer(struct aac_softc * sc)473 int aacraid_get_fw_debug_buffer(struct aac_softc *sc)
474 {
475 	u_int32_t MonDriverBufferPhysAddrLow = 0;
476 	u_int32_t MonDriverBufferPhysAddrHigh = 0;
477 	u_int32_t MonDriverBufferSize = 0;
478 	u_int32_t MonDriverHeaderSize = 0;
479 
480 	/*
481 	 * Get the firmware print buffer parameters from the firmware
482 	 * If the command was successful map in the address.
483 	 */
484 	if (!aacraid_sync_command(sc, AAC_MONKER_GETDRVPROP, 0, 0, 0, 0, NULL, NULL)) {
485 		MonDriverBufferPhysAddrLow = AAC_GET_MAILBOX(sc, 1);
486 		MonDriverBufferPhysAddrHigh = AAC_GET_MAILBOX(sc, 2);
487 		MonDriverBufferSize = AAC_GET_MAILBOX(sc, 3);
488 		MonDriverHeaderSize = AAC_GET_MAILBOX(sc, 4);
489 		if (MonDriverBufferSize) {
490 			unsigned long Offset = MonDriverBufferPhysAddrLow
491 				- rman_get_start(sc->aac_regs_res1);
492 
493 			/*
494 			 * See if the address is already mapped in and if so set it up
495 			 * from the base address
496 			 */
497 			if ((MonDriverBufferPhysAddrHigh == 0) &&
498 				(Offset + MonDriverBufferSize <
499 				rman_get_size(sc->aac_regs_res1))) {
500 				sc->DebugOffset = Offset;
501 				sc->DebugHeaderSize = MonDriverHeaderSize;
502 				sc->FwDebugBufferSize = MonDriverBufferSize;
503 				sc->FwDebugFlags = 0;
504 				sc->DebugFlags = aacraid_debug_flags;
505 				return 1;
506 			}
507 		}
508 	}
509 
510 	/*
511 	 * The GET_DRIVER_BUFFER_PROPERTIES command failed
512 	 */
513 	return 0;
514 }
515 
516 #define PRINT_TIMEOUT 250000 /* 1/4 second */
517 
aacraid_fw_printf(struct aac_softc * sc,unsigned long PrintFlags,const char * fmt,...)518 void aacraid_fw_printf(struct aac_softc *sc, unsigned long PrintFlags, const char * fmt, ...)
519 {
520 	va_list args;
521 	u_int32_t Count, i;
522 	char PrintBuffer_P[PRINT_BUFFER_SIZE];
523 	unsigned long PrintType;
524 
525 	PrintType = PrintFlags &
526 		~(HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B);
527 	if (((PrintType!=0) && (sc!=NULL) && ((sc->DebugFlags & PrintType)==0))
528 		|| ((sc!=NULL) && (sc->DebugFlags
529 		& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B)) == 0))
530 		return;
531 
532 	/*
533 	 * Set up parameters and call sprintf function to format the data
534 	 */
535 	va_start(args, fmt);
536 	vsprintf(PrintBuffer_P, fmt, args);
537 	va_end(args);
538 
539 	/*
540 	 * Make sure the HBA structure has been passed in for this section
541 	 */
542 	if ((sc != NULL) && (sc->FwDebugBufferSize)) {
543 		/*
544 		 * If we are set up for a Firmware print
545 		 */
546 		if ((sc->DebugFlags & HBA_FLAGS_DBG_FW_PRINT_B)
547 			&& ((PrintFlags
548 			& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B))
549 			!= HBA_FLAGS_DBG_KERNEL_PRINT_B)) {
550 			/*
551 			 * Make sure the string size is within boundaries
552 			 */
553 			Count = strlen(PrintBuffer_P);
554 			if (Count > sc->FwDebugBufferSize)
555 				Count = (u_int16_t)sc->FwDebugBufferSize;
556 
557 			/*
558 			 * Wait for no more than PRINT_TIMEOUT for the previous
559 			 * message length to clear (the handshake).
560 			 */
561 			for (i = 0; i < PRINT_TIMEOUT; ++i) {
562 				if (!AAC_MEM1_GETREG4(sc,
563 					sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET)) {
564 					break;
565 				}
566 				DELAY(1);
567             }
568 
569 			/*
570 			 * If the Length is clear, copy over the message, the
571 			 * flags, and the length. Make sure the length is the
572 			 * last because that is the signal for the Firmware to
573 			 * pick it up.
574 			 */
575 			if (!AAC_MEM1_GETREG4(sc,
576 				sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET)) {
577 				for (i = 0; i < Count; ++i) {
578 					AAC_MEM1_SETREG1(sc, sc->DebugOffset + sc->DebugHeaderSize + i,
579 								PrintBuffer_P[i]);
580 				}
581 				AAC_MEM1_SETREG4(sc, sc->DebugOffset + FW_DEBUG_FLAGS_OFFSET,
582 							sc->FwDebugFlags);
583 				AAC_MEM1_SETREG4(sc, sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET,
584                             Count);
585 			} else
586 				sc->DebugFlags &= ~HBA_FLAGS_DBG_FW_PRINT_B;
587 		}
588 
589 		/*
590 		 * If the Kernel Debug Print flag is set, send it off to the
591 		 * Kernel debugger
592 		 */
593 		if ((sc->DebugFlags & HBA_FLAGS_DBG_KERNEL_PRINT_B)
594 			&& ((PrintFlags
595 			& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B))
596 			!= HBA_FLAGS_DBG_FW_PRINT_B)) {
597 			if (sc->FwDebugFlags & FW_DEBUG_FLAGS_NO_HEADERS_B)
598 				printf ("%s\n", PrintBuffer_P);
599 			else
600 				device_printf (sc->aac_dev, "%s\n", PrintBuffer_P);
601 		}
602 
603 	} else {
604 		/*
605 		 * No HBA structure passed in so it has to be for the Kernel Debugger
606 		 */
607 		if ((sc != NULL) && (sc->FwDebugFlags & FW_DEBUG_FLAGS_NO_HEADERS_B))
608 			printf ("%s\n", PrintBuffer_P);
609 		else if (sc != NULL)
610 			device_printf (sc->aac_dev, "%s\n", PrintBuffer_P);
611 		else
612 			printf("%s\n", PrintBuffer_P);
613 	}
614 }
615 
aacraid_fw_print_mem(struct aac_softc * sc,unsigned long PrintFlags,u_int8_t * Addr,int Count)616 void aacraid_fw_print_mem(struct aac_softc *sc, unsigned long PrintFlags, u_int8_t *Addr, int Count)
617 {
618 	int Offset, i;
619 	u_int32_t DebugFlags = 0;
620 	char Buffer[100];
621 	char *LineBuffer_P;
622 
623 	/*
624 	 * If we have an HBA structure, save off the flags and set the no
625 	 * headers flag so we don't have garbage between our lines of data
626 	 */
627 	if (sc != NULL) {
628 		DebugFlags = sc->FwDebugFlags;
629 		sc->FwDebugFlags |= FW_DEBUG_FLAGS_NO_HEADERS_B;
630 	}
631 
632 	Offset = 0;
633 
634 	/*
635 	 * Loop through all the data
636 	 */
637 	while (Offset < Count) {
638 		/*
639 		 * We will format each line into a buffer and then print out
640 		 * the entire line so set the pointer to the beginning of the
641 		 * buffer
642 		 */
643 		LineBuffer_P = Buffer;
644 
645 		/*
646 		 * Set up the address in HEX
647 		 */
648 		sprintf(LineBuffer_P, "\n%04x  ", Offset);
649 		LineBuffer_P += 6;
650 
651 		/*
652 		 * Set up 16 bytes in HEX format
653 		 */
654 		for (i = 0; i < 16; ++i) {
655 			/*
656 			 * If we are past the count of data bytes to output,
657 			 * pad with blanks
658 			 */
659 			if ((Offset + i) >= Count)
660 				sprintf (LineBuffer_P, "   ");
661 			else
662 			  	sprintf (LineBuffer_P, "%02x ", Addr[Offset+i]);
663 			LineBuffer_P += 3;
664 
665 			/*
666 			 * At the mid point we will put in a divider
667 			 */
668 			if (i == 7) {
669 				sprintf (LineBuffer_P, "- ");
670 				LineBuffer_P += 2;
671 			}
672 		}
673 		/*
674 		 * Now do the same 16 bytes at the end of the line in ASCII
675 		 * format
676 		 */
677 		sprintf (LineBuffer_P, "  ");
678 		LineBuffer_P += 2;
679 		for (i = 0; i < 16; ++i) {
680 			/*
681 			 * If all data processed, OUT-O-HERE
682 			 */
683 			if ((Offset + i) >= Count)
684 				break;
685 
686 			/*
687 			 * If this is a printable ASCII character, convert it
688 			 */
689 			if ((Addr[Offset+i] > 0x1F) && (Addr[Offset+i] < 0x7F))
690 				sprintf (LineBuffer_P, "%c", Addr[Offset+i]);
691 			else
692 				sprintf (LineBuffer_P, ".");
693 			++LineBuffer_P;
694 		}
695 		/*
696 		 * The line is now formatted, so print it out
697 		 */
698 		aacraid_fw_printf(sc, PrintFlags, "%s", Buffer);
699 
700 		/*
701 		 * Bump the offset by 16 for the next line
702 		 */
703 		Offset += 16;
704 	}
705 
706 	/*
707 	 * Restore the saved off flags
708 	 */
709 	if (sc != NULL)
710 		sc->FwDebugFlags = DebugFlags;
711 }
712