Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/aacraid/aacraid_debug.c
39534 views
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
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
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
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
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
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
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
713