]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/aacraid/aacraid_debug.c
Ensure a minimum packet length before creating a mbuf in if_ure.
[FreeBSD/FreeBSD.git] / sys / dev / aacraid / aacraid_debug.c
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                       "\20"
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 }