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