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