xref: /freebsd/sys/dev/aac/aacreg.h (revision b6de9e91bd2c47efaeec72a08642f8fd99cc7b20)
1 /*-
2  * Copyright (c) 2000 Michael Smith
3  * Copyright (c) 2000-2001 Scott Long
4  * Copyright (c) 2000 BSDi
5  * Copyright (c) 2001 Adaptec, 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  *	$FreeBSD$
30  */
31 
32 /*
33  * Data structures defining the interface between the driver and the Adaptec
34  * 'FSA' adapters.  Note that many field names and comments here are taken
35  * verbatim from the Adaptec driver source in order to make comparing the
36  * two slightly easier.
37  */
38 
39 /*
40  * Misc. magic numbers.
41  */
42 #define AAC_MAX_CONTAINERS	64
43 #define AAC_BLOCK_SIZE		512
44 
45 /*
46  * Communications interface.
47  *
48  * Where datastructure layouts are closely parallel to the Adaptec sample code,
49  * retain their naming conventions (for now) to aid in cross-referencing.
50  */
51 
52 /*
53  * We establish 4 command queues and matching response queues.  Queues must
54  * be 16-byte aligned, and are sized as follows:
55  */
56 #define AAC_HOST_NORM_CMD_ENTRIES	8	/* command adapter->host,
57 						 * normal priority */
58 #define AAC_HOST_HIGH_CMD_ENTRIES	4	/* command adapter->host,
59 						 * high priority */
60 #define AAC_ADAP_NORM_CMD_ENTRIES	512	/* command host->adapter,
61 						 * normal priority */
62 #define AAC_ADAP_HIGH_CMD_ENTRIES	4	/* command host->adapter,
63 						 * high priority */
64 #define AAC_HOST_NORM_RESP_ENTRIES	512	/* response, adapter->host,
65 						 * normal priority */
66 #define AAC_HOST_HIGH_RESP_ENTRIES	4	/* response, adapter->host,
67 						 * high priority */
68 #define AAC_ADAP_NORM_RESP_ENTRIES	8	/* response, host->adapter,
69 						 * normal priority */
70 #define AAC_ADAP_HIGH_RESP_ENTRIES	4	/* response, host->adapter,
71 						 * high priority */
72 
73 #define AAC_TOTALQ_LENGTH	(AAC_HOST_HIGH_CMD_ENTRIES +	\
74 				 AAC_HOST_NORM_CMD_ENTRIES +	\
75 				 AAC_ADAP_HIGH_CMD_ENTRIES +	\
76 				 AAC_ADAP_NORM_CMD_ENTRIES +	\
77 				 AAC_HOST_HIGH_RESP_ENTRIES +	\
78 				 AAC_HOST_NORM_RESP_ENTRIES +	\
79 				 AAC_ADAP_HIGH_RESP_ENTRIES +	\
80 				 AAC_ADAP_NORM_RESP_ENTRIES)
81 #define AAC_QUEUE_COUNT		8
82 #define AAC_QUEUE_ALIGN		16
83 
84 struct aac_queue_entry {
85 	u_int32_t	aq_fib_size;	/* FIB size in bytes */
86 	u_int32_t	aq_fib_addr;	/* receiver-space address of the FIB */
87 } __packed;
88 
89 #define AAC_PRODUCER_INDEX	0
90 #define AAC_CONSUMER_INDEX	1
91 
92 /*
93  * Table of queue indices and queues used to communicate with the
94  * controller.  This structure must be aligned to AAC_QUEUE_ALIGN
95  */
96 struct aac_queue_table {
97 	/* queue consumer/producer indexes (layout mandated by adapter) */
98 	u_int32_t			qt_qindex[AAC_QUEUE_COUNT][2];
99 
100 	/* queue entry structures (layout mandated by adapter) */
101 	struct aac_queue_entry qt_HostNormCmdQueue [AAC_HOST_NORM_CMD_ENTRIES];
102 	struct aac_queue_entry qt_HostHighCmdQueue [AAC_HOST_HIGH_CMD_ENTRIES];
103 	struct aac_queue_entry qt_AdapNormCmdQueue [AAC_ADAP_NORM_CMD_ENTRIES];
104 	struct aac_queue_entry qt_AdapHighCmdQueue [AAC_ADAP_HIGH_CMD_ENTRIES];
105 	struct aac_queue_entry qt_HostNormRespQueue[AAC_HOST_NORM_RESP_ENTRIES];
106 	struct aac_queue_entry qt_HostHighRespQueue[AAC_HOST_HIGH_RESP_ENTRIES];
107 	struct aac_queue_entry qt_AdapNormRespQueue[AAC_ADAP_NORM_RESP_ENTRIES];
108 	struct aac_queue_entry qt_AdapHighRespQueue[AAC_ADAP_HIGH_RESP_ENTRIES];
109 } __packed;
110 
111 /*
112  * Queue names
113  *
114  * Note that we base these at 0 in order to use them as array indices.  Adaptec
115  * used base 1 for some unknown reason, and sorted them in a different order.
116  */
117 #define AAC_HOST_NORM_CMD_QUEUE		0
118 #define AAC_HOST_HIGH_CMD_QUEUE		1
119 #define AAC_ADAP_NORM_CMD_QUEUE		2
120 #define AAC_ADAP_HIGH_CMD_QUEUE		3
121 #define AAC_HOST_NORM_RESP_QUEUE	4
122 #define AAC_HOST_HIGH_RESP_QUEUE	5
123 #define AAC_ADAP_NORM_RESP_QUEUE	6
124 #define AAC_ADAP_HIGH_RESP_QUEUE	7
125 
126 /*
127  * List structure used to chain FIBs (used by the adapter - we hang FIBs off
128  * our private command structure and don't touch these)
129  */
130 struct aac_fib_list_entry {
131 	u_int32_t	Flink;
132 	u_int32_t	Blink;
133 } __packed;
134 
135 /*
136  * FIB (FSA Interface Block?); this is the datastructure passed between the host
137  * and adapter.
138  */
139 struct aac_fib_header {
140 	u_int32_t		XferState;
141 	u_int16_t		Command;
142 	u_int8_t		StructType;
143 	u_int8_t		Flags;
144 	u_int16_t		Size;
145 	u_int16_t		SenderSize;
146 	u_int32_t		SenderFibAddress;
147 	u_int32_t		ReceiverFibAddress;
148 	u_int32_t		SenderData;
149 	union {
150 		struct {
151 			u_int32_t	ReceiverTimeStart;
152 			u_int32_t	ReceiverTimeDone;
153 		} _s;
154 		struct aac_fib_list_entry FibLinks;
155 	} _u;
156 } __packed;
157 
158 #define AAC_FIB_DATASIZE	(512 - sizeof(struct aac_fib_header))
159 
160 struct aac_fib {
161 	struct aac_fib_header	Header;
162 	u_int8_t			data[AAC_FIB_DATASIZE];
163 } __packed;
164 
165 /*
166  * FIB commands
167  */
168 typedef enum {
169 	TestCommandResponse =		1,
170 	TestAdapterCommand =		2,
171 
172 	/* lowlevel and comm commands */
173 	LastTestCommand =		100,
174 	ReinitHostNormCommandQueue =	101,
175 	ReinitHostHighCommandQueue =	102,
176 	ReinitHostHighRespQueue =	103,
177 	ReinitHostNormRespQueue =	104,
178 	ReinitAdapNormCommandQueue =	105,
179 	ReinitAdapHighCommandQueue =	107,
180 	ReinitAdapHighRespQueue =	108,
181 	ReinitAdapNormRespQueue =	109,
182 	InterfaceShutdown =		110,
183 	DmaCommandFib =			120,
184 	StartProfile =			121,
185 	TermProfile =			122,
186 	SpeedTest =			123,
187 	TakeABreakPt =			124,
188 	RequestPerfData =		125,
189 	SetInterruptDefTimer=		126,
190 	SetInterruptDefCount=		127,
191 	GetInterruptDefStatus=		128,
192 	LastCommCommand =		129,
193 
194 	/* filesystem commands */
195 	NuFileSystem =			300,
196 	UFS =				301,
197 	HostFileSystem =		302,
198 	LastFileSystemCommand =		303,
199 
200 	/* Container Commands */
201 	ContainerCommand =		500,
202 	ContainerCommand64 =		501,
203 
204 	/* Cluster Commands */
205 	ClusterCommand =		550,
206 
207 	/* Scsi Port commands (scsi passthrough) */
208 	ScsiPortCommand =		600,
209 
210 	/* misc house keeping and generic adapter initiated commands */
211 	AifRequest =			700,
212 	CheckRevision =			701,
213 	FsaHostShutdown =		702,
214 	RequestAdapterInfo =		703,
215 	IsAdapterPaused =		704,
216 	SendHostTime =			705,
217 	LastMiscCommand =		706
218 } AAC_FibCommands;
219 
220 /*
221  * FIB types
222  */
223 #define AAC_FIBTYPE_TFIB	1
224 #define AAC_FIBTYPE_TQE		2
225 #define AAC_FIBTYPE_TCTPERF	3
226 
227 /*
228  * FIB transfer state
229  */
230 #define AAC_FIBSTATE_HOSTOWNED		(1<<0)	/* owned by the host */
231 #define AAC_FIBSTATE_ADAPTEROWNED	(1<<1)	/* owned by the adapter */
232 #define AAC_FIBSTATE_INITIALISED	(1<<2)	/* initialised */
233 #define AAC_FIBSTATE_EMPTY		(1<<3)	/* empty */
234 #define AAC_FIBSTATE_FROMPOOL		(1<<4)	/* allocated from pool */
235 #define AAC_FIBSTATE_FROMHOST		(1<<5)	/* sent from the host */
236 #define AAC_FIBSTATE_FROMADAP		(1<<6)	/* sent from the adapter */
237 #define AAC_FIBSTATE_REXPECTED		(1<<7)	/* response is expected */
238 #define AAC_FIBSTATE_RNOTEXPECTED	(1<<8)	/* response is not expected */
239 #define AAC_FIBSTATE_DONEADAP		(1<<9)	/* processed by the adapter */
240 #define AAC_FIBSTATE_DONEHOST		(1<<10)	/* processed by the host */
241 #define AAC_FIBSTATE_HIGH		(1<<11)	/* high priority */
242 #define AAC_FIBSTATE_NORM		(1<<12)	/* normal priority */
243 #define AAC_FIBSTATE_ASYNC		(1<<13)
244 #define AAC_FIBSTATE_ASYNCIO		(1<<13)	/* to be removed */
245 #define AAC_FIBSTATE_PAGEFILEIO		(1<<14)	/* to be removed */
246 #define AAC_FIBSTATE_SHUTDOWN		(1<<15)
247 #define AAC_FIBSTATE_LAZYWRITE		(1<<16)	/* to be removed */
248 #define AAC_FIBSTATE_ADAPMICROFIB	(1<<17)
249 #define AAC_FIBSTATE_BIOSFIB		(1<<18)
250 #define AAC_FIBSTATE_FAST_RESPONSE	(1<<19)	/* fast response capable */
251 #define AAC_FIBSTATE_APIFIB		(1<<20)
252 
253 /*
254  * FIB error values
255  */
256 #define AAC_ERROR_NORMAL			0x00
257 #define AAC_ERROR_PENDING			0x01
258 #define AAC_ERROR_FATAL				0x02
259 #define AAC_ERROR_INVALID_QUEUE			0x03
260 #define AAC_ERROR_NOENTRIES			0x04
261 #define AAC_ERROR_SENDFAILED			0x05
262 #define AAC_ERROR_INVALID_QUEUE_PRIORITY	0x06
263 #define AAC_ERROR_FIB_ALLOCATION_FAILED		0x07
264 #define AAC_ERROR_FIB_DEALLOCATION_FAILED	0x08
265 
266 /*
267  * Adapter Init Structure: this is passed to the adapter with the
268  * AAC_MONKER_INITSTRUCT command to point it at our control structures.
269  */
270 struct aac_adapter_init {
271 	u_int32_t	InitStructRevision;
272 #define AAC_INIT_STRUCT_REVISION		3
273 	u_int32_t	MiniPortRevision;
274 #define AAC_INIT_STRUCT_MINIPORT_REVISION	1
275 	u_int32_t	FilesystemRevision;
276 	u_int32_t	CommHeaderAddress;
277 	u_int32_t	FastIoCommAreaAddress;
278 	u_int32_t	AdapterFibsPhysicalAddress;
279 	u_int32_t 	AdapterFibsVirtualAddress;
280 	u_int32_t	AdapterFibsSize;
281 	u_int32_t	AdapterFibAlign;
282 	u_int32_t	PrintfBufferAddress;
283 	u_int32_t	PrintfBufferSize;
284 #define	AAC_PAGE_SIZE				4096
285 	u_int32_t	HostPhysMemPages;
286 	u_int32_t	HostElapsedSeconds;
287 } __packed;
288 
289 /*
290  * Shared data types
291  */
292 /*
293  * Container types
294  */
295 typedef enum {
296 	CT_NONE = 0,
297 	CT_VOLUME,
298 	CT_MIRROR,
299 	CT_STRIPE,
300 	CT_RAID5,
301 	CT_SSRW,
302 	CT_SSRO,
303 	CT_MORPH,
304 	CT_PASSTHRU,
305 	CT_RAID4,
306 	CT_RAID10,                  /* stripe of mirror */
307 	CT_RAID00,                  /* stripe of stripe */
308 	CT_VOLUME_OF_MIRRORS,       /* volume of mirror */
309 	CT_PSEUDO_RAID3,            /* really raid4 */
310 	CT_RAID50,		    /* stripe of raid5 */
311 } AAC_FSAVolType;
312 
313 /*
314  * Host-addressable object types
315  */
316 typedef enum {
317 	FT_REG = 1,     /* regular file */
318 	FT_DIR,         /* directory */
319 	FT_BLK,         /* "block" device - reserved */
320 	FT_CHR,         /* "character special" device - reserved */
321 	FT_LNK,         /* symbolic link */
322 	FT_SOCK,        /* socket */
323 	FT_FIFO,        /* fifo */
324 	FT_FILESYS,     /* ADAPTEC's "FSA"(tm) filesystem */
325 	FT_DRIVE,       /* physical disk - addressable in scsi by b/t/l */
326 	FT_SLICE,       /* virtual disk - raw volume - slice */
327 	FT_PARTITION,   /* FSA partition - carved out of a slice - building
328 			 * block for containers */
329 	FT_VOLUME,      /* Container - Volume Set */
330 	FT_STRIPE,      /* Container - Stripe Set */
331 	FT_MIRROR,      /* Container - Mirror Set */
332 	FT_RAID5,       /* Container - Raid 5 Set */
333 	FT_DATABASE     /* Storage object with "foreign" content manager */
334 } AAC_FType;
335 
336 /*
337  * Host-side scatter/gather list for 32-bit commands.
338  */
339 struct aac_sg_entry {
340 	u_int32_t	SgAddress;
341 	u_int32_t	SgByteCount;
342 } __packed;
343 
344 struct aac_sg_entry64 {
345 	u_int64_t	SgAddress;
346 	u_int32_t	SgByteCount;
347 } __packed;
348 
349 struct aac_sg_table {
350 	u_int32_t		SgCount;
351 	struct aac_sg_entry	SgEntry[0];
352 } __packed;
353 
354 /*
355  * Host-side scatter/gather list for 64-bit commands.
356  */
357 struct aac_sg_table64 {
358 	u_int32_t	SgCount;
359 	struct aac_sg_entry64	SgEntry64[0];
360 } __packed;
361 
362 /*
363  * Container creation data
364  */
365 struct aac_container_creation {
366 	u_int8_t	ViaBuildNumber;
367 	u_int8_t	MicroSecond;
368 	u_int8_t	Via;		/* 1 = FSU, 2 = API, etc. */
369 	u_int8_t	YearsSince1900;
370 	u_int32_t	Month:4;	/* 1-12 */
371 	u_int32_t	Day:6;		/* 1-32 */
372 	u_int32_t	Hour:6;		/* 0-23 */
373 	u_int32_t	Minute:6;	/* 0-59 */
374 	u_int32_t	Second:6;	/* 0-59 */
375 	u_int64_t	ViaAdapterSerialNumber;
376 } __packed;
377 
378 /*
379  * Revision number handling
380  */
381 
382 typedef enum {
383 	RevApplication = 1,
384 	RevDkiCli,
385 	RevNetService,
386 	RevApi,
387 	RevFileSysDriver,
388 	RevMiniportDriver,
389 	RevAdapterSW,
390 	RevMonitor,
391 	RevRemoteApi
392 } RevComponent;
393 
394 struct FsaRevision {
395 	union {
396 		struct {
397 			u_int8_t	dash;
398 			u_int8_t	type;
399 			u_int8_t	minor;
400 			u_int8_t	major;
401 		} comp;
402 		u_int32_t	ul;
403 	} external;
404 	u_int32_t	buildNumber;
405 }  __packed;
406 
407 /*
408  * Adapter Information
409  */
410 
411 typedef enum {
412 	CPU_NTSIM = 1,
413 	CPU_I960,
414 	CPU_ARM,
415 	CPU_SPARC,
416 	CPU_POWERPC,
417 	CPU_ALPHA,
418 	CPU_P7,
419 	CPU_I960_RX,
420 	CPU__last
421 } AAC_CpuType;
422 
423 typedef enum {
424 	CPUI960_JX = 1,
425 	CPUI960_CX,
426 	CPUI960_HX,
427 	CPUI960_RX,
428 	CPUARM_SA110,
429 	CPUARM_xxx,
430 	CPUMPC_824x,
431 	CPUPPC_xxx,
432 	CPUI960_30X,
433 	CPUSUBTYPE__last
434 } AAC_CpuSubType;
435 
436 typedef enum {
437 	PLAT_NTSIM = 1,
438 	PLAT_V3ADU,
439 	PLAT_CYCLONE,
440 	PLAT_CYCLONE_HD,
441 	PLAT_BATBOARD,
442 	PLAT_BATBOARD_HD,
443 	PLAT_YOLO,
444 	PLAT_COBRA,
445 	PLAT_ANAHEIM,
446 	PLAT_JALAPENO,
447 	PLAT_QUEENS,
448 	PLAT_JALAPENO_DELL,
449 	PLAT_POBLANO,
450 	PLAT_POBLANO_OPAL,
451 	PLAT_POBLANO_SL0,
452 	PLAT_POBLANO_SL1,
453 	PLAT_POBLANO_SL2,
454 	PLAT_POBLANO_XXX,
455 	PLAT_JALAPENO_P2,
456 	PLAT_HABANERO,
457 	PLAT__last
458 } AAC_Platform;
459 
460 typedef enum {
461 	OEM_FLAVOR_ADAPTEC = 1,
462 	OEM_FLAVOR_DELL,
463 	OEM_FLAVOR_HP,
464 	OEM_FLAVOR_IBM,
465 	OEM_FLAVOR_CPQ,
466 	OEM_FLAVOR_BRAND_X,
467 	OEM_FLAVOR_BRAND_Y,
468 	OEM_FLAVOR_BRAND_Z,
469 	OEM_FLAVOR__last
470 } AAC_OemFlavor;
471 
472 /*
473  * XXX the aac-2622 with no battery present reports PLATFORM_BAT_OPT_PRESENT
474  */
475 typedef enum
476 {
477 	PLATFORM_BAT_REQ_PRESENT = 1,	/* BATTERY REQUIRED AND PRESENT */
478 	PLATFORM_BAT_REQ_NOTPRESENT,	/* BATTERY REQUIRED AND NOT PRESENT */
479 	PLATFORM_BAT_OPT_PRESENT,	/* BATTERY OPTIONAL AND PRESENT */
480 	PLATFORM_BAT_OPT_NOTPRESENT,	/* BATTERY OPTIONAL AND NOT PRESENT */
481 	PLATFORM_BAT_NOT_SUPPORTED	/* BATTERY NOT SUPPORTED */
482 } AAC_BatteryPlatform;
483 
484 /*
485  * options supported by this board
486  * there has to be a one to one mapping of these defines and the ones in
487  * fsaapi.h, search for FSA_SUPPORT_SNAPSHOT
488  */
489 #define AAC_SUPPORTED_SNAPSHOT		0x01
490 #define AAC_SUPPORTED_CLUSTERS		0x02
491 #define AAC_SUPPORTED_WRITE_CACHE	0x04
492 #define AAC_SUPPORTED_64BIT_DATA	0x08
493 #define AAC_SUPPORTED_HOST_TIME_FIB	0x10
494 #define AAC_SUPPORTED_RAID50		0x20
495 #define AAC_SUPPORTED_4GB_WINDOW	0x40
496 #define AAC_SUPPORTED_SCSI_UPGRADEABLE	0x80
497 #define AAC_SUPPORTED_SOFT_ERR_REPORT	0x100
498 #define AAC_SUPPORTED_NOT_RECONDITION	0x200
499 #define AAC_SUPPORTED_SGMAP_HOST64	0x400
500 #define AAC_SUPPORTED_ALARM		0x800
501 #define AAC_SUPPORTED_NONDASD		0x1000
502 
503 /*
504  * Structure used to respond to a RequestAdapterInfo fib.
505  */
506 struct aac_adapter_info {
507 	AAC_Platform		PlatformBase;    /* adapter type */
508 	AAC_CpuType		CpuArchitecture; /* adapter CPU type */
509 	AAC_CpuSubType		CpuVariant;      /* adapter CPU subtype */
510 	u_int32_t		ClockSpeed;      /* adapter CPU clockspeed */
511 	u_int32_t		ExecutionMem;    /* adapter Execution Memory
512 						  * size */
513 	u_int32_t		BufferMem;       /* adapter Data Memory */
514 	u_int32_t		TotalMem;        /* adapter Total Memory */
515 	struct FsaRevision	KernelRevision;  /* adapter Kernel Software
516 						  * Revision */
517 	struct FsaRevision	MonitorRevision; /* adapter Monitor/Diagnostic
518 						  * Software Revision */
519 	struct FsaRevision	HardwareRevision;/* TBD */
520 	struct FsaRevision	BIOSRevision;    /* adapter BIOS Revision */
521 	u_int32_t		ClusteringEnabled;
522 	u_int32_t		ClusterChannelMask;
523 	u_int64_t		SerialNumber;
524 	AAC_BatteryPlatform	batteryPlatform;
525 	u_int32_t		SupportedOptions; /* supported features of this
526 						   * controller */
527 	AAC_OemFlavor	OemVariant;
528 } __packed;
529 
530 /*
531  * Monitor/Kernel interface.
532  */
533 
534 /*
535  * Synchronous commands to the monitor/kernel.
536  */
537 #define AAC_MONKER_INITSTRUCT	0x05
538 #define AAC_MONKER_SYNCFIB	0x0c
539 #define AAC_MONKER_GETKERNVER	0x11
540 #define AAC_MONKER_GETINFO	0x19
541 
542 /*
543  *  Adapter Status Register
544  *
545  *  Phase Staus mailbox is 32bits:
546  *  <31:16> = Phase Status
547  *  <15:0>  = Phase
548  *
549  *  The adapter reports its present state through the phase.  Only
550  *  a single phase should be ever be set.  Each phase can have multiple
551  *  phase status bits to provide more detailed information about the
552  *  state of the adapter.
553  */
554 #define AAC_SELF_TEST_FAILED	0x00000004
555 #define AAC_MONITOR_PANIC	0x00000020
556 #define AAC_UP_AND_RUNNING	0x00000080
557 #define AAC_KERNEL_PANIC	0x00000100
558 
559 /*
560  * Data types relating to control and monitoring of the NVRAM/WriteCache
561  * subsystem.
562  */
563 
564 #define AAC_NFILESYS	24	/* maximum number of filesystems */
565 
566 /*
567  * NVRAM/Write Cache subsystem states
568  */
569 typedef enum {
570 	NVSTATUS_DISABLED = 0,	/* present, clean, not being used */
571 	NVSTATUS_ENABLED,	/* present, possibly dirty, ready for use */
572 	NVSTATUS_ERROR,		/* present, dirty, contains dirty data */
573 	NVSTATUS_BATTERY,	/* present, bad or low battery, may contain
574 				 * dirty data */
575 	NVSTATUS_UNKNOWN	/* for bad/missing device */
576 } AAC_NVSTATUS;
577 
578 /*
579  * NVRAM/Write Cache subsystem battery component states
580  *
581  */
582 typedef enum {
583 	NVBATTSTATUS_NONE = 0,	/* battery has no power or is not present */
584 	NVBATTSTATUS_LOW,	/* battery is low on power */
585 	NVBATTSTATUS_OK,	/* battery is okay - normal operation possible
586 				 * only in this state */
587 	NVBATTSTATUS_RECONDITIONING	/* no battery present - reconditioning
588 					 * in process */
589 } AAC_NVBATTSTATUS;
590 
591 /*
592  * Battery transition type
593  */
594 typedef enum {
595 	NVBATT_TRANSITION_NONE = 0,	/* battery now has no power or is not
596 					 * present */
597 	NVBATT_TRANSITION_LOW,		/* battery is now low on power */
598 	NVBATT_TRANSITION_OK		/* battery is now okay - normal
599 					 * operation possible only in this
600 					 * state */
601 } AAC_NVBATT_TRANSITION;
602 
603 /*
604  * NVRAM Info structure returned for NVRAM_GetInfo call
605  */
606 struct aac_nvramdevinfo {
607 	u_int32_t	NV_Enabled;	/* write caching enabled */
608 	u_int32_t	NV_Error;	/* device in error state */
609 	u_int32_t	NV_NDirty;	/* count of dirty NVRAM buffers */
610 	u_int32_t	NV_NActive;	/* count of NVRAM buffers being
611 					 * written */
612 } __packed;
613 
614 struct aac_nvraminfo {
615 	AAC_NVSTATUS		NV_Status;	/* nvram subsystem status */
616 	AAC_NVBATTSTATUS	NV_BattStatus;	/* battery status */
617 	u_int32_t		NV_Size;	/* size of WriteCache NVRAM in
618 						 * bytes */
619 	u_int32_t		NV_BufSize;	/* size of NVRAM buffers in
620 						 * bytes */
621 	u_int32_t		NV_NBufs;	/* number of NVRAM buffers */
622 	u_int32_t		NV_NDirty;	/* Num dirty NVRAM buffers */
623 	u_int32_t		NV_NClean;	/* Num clean NVRAM buffers */
624 	u_int32_t		NV_NActive;	/* Num NVRAM buffers being
625 						 * written */
626 	u_int32_t		NV_NBrokered;	/* Num brokered NVRAM buffers */
627 	struct aac_nvramdevinfo	NV_DevInfo[AAC_NFILESYS];	/* per device
628 								 * info */
629 	u_int32_t		NV_BattNeedsReconditioning;	/* boolean */
630 	u_int32_t		NV_TotalSize;	/* size of all non-volatile
631 						 * memories in bytes */
632 } __packed;
633 
634 /*
635  * Data types relating to adapter-initiated FIBs
636  *
637  * Based on types and structures in <aifstruc.h>
638  */
639 
640 /*
641  * Progress Reports
642  */
643 typedef enum {
644 	AifJobStsSuccess = 1,
645 	AifJobStsFinished,
646 	AifJobStsAborted,
647 	AifJobStsFailed,
648 	AifJobStsLastReportMarker = 100,	/* All prior mean last report */
649 	AifJobStsSuspended,
650 	AifJobStsRunning
651 } AAC_AifJobStatus;
652 
653 typedef enum {
654 	AifJobScsiMin = 1,		/* Minimum value for Scsi operation */
655 	AifJobScsiZero,			/* SCSI device clear operation */
656 	AifJobScsiVerify,		/* SCSI device Verify operation NO
657 					 * REPAIR */
658 	AifJobScsiExercise,		/* SCSI device Exercise operation */
659 	AifJobScsiVerifyRepair,		/* SCSI device Verify operation WITH
660 					 * repair */
661 	AifJobScsiMax = 99,		/* Max Scsi value */
662 	AifJobCtrMin,			/* Min Ctr op value */
663 	AifJobCtrZero,			/* Container clear operation */
664 	AifJobCtrCopy,			/* Container copy operation */
665 	AifJobCtrCreateMirror,		/* Container Create Mirror operation */
666 	AifJobCtrMergeMirror,		/* Container Merge Mirror operation */
667 	AifJobCtrScrubMirror,		/* Container Scrub Mirror operation */
668 	AifJobCtrRebuildRaid5,		/* Container Rebuild Raid5 operation */
669 	AifJobCtrScrubRaid5,		/* Container Scrub Raid5 operation */
670 	AifJobCtrMorph,			/* Container morph operation */
671 	AifJobCtrPartCopy,		/* Container Partition copy operation */
672 	AifJobCtrRebuildMirror,		/* Container Rebuild Mirror operation */
673 	AifJobCtrCrazyCache,		/* crazy cache */
674 	AifJobCtrMax = 199,		/* Max Ctr type operation */
675 	AifJobFsMin,			/* Min Fs type operation */
676 	AifJobFsCreate,			/* File System Create operation */
677 	AifJobFsVerify,			/* File System Verify operation */
678 	AifJobFsExtend,			/* File System Extend operation */
679 	AifJobFsMax = 299,		/* Max Fs type operation */
680 	AifJobApiFormatNTFS,		/* Format a drive to NTFS */
681 	AifJobApiFormatFAT,		/* Format a drive to FAT */
682 	AifJobApiUpdateSnapshot,	/* update the read/write half of a
683 					 * snapshot */
684 	AifJobApiFormatFAT32,		/* Format a drive to FAT32 */
685 	AifJobApiMax = 399,		/* Max API type operation */
686 	AifJobCtlContinuousCtrVerify,	/* Adapter operation */
687 	AifJobCtlMax = 499		/* Max Adapter type operation */
688 } AAC_AifJobType;
689 
690 struct aac_AifContainers {
691 	u_int32_t	src;		/* from/master */
692 	u_int32_t	dst;		/* to/slave */
693 } __packed;
694 
695 union aac_AifJobClient {
696 	struct aac_AifContainers	container;	/* For Container and
697 							 * filesystem progress
698 							 * ops; */
699 	int32_t				scsi_dh;	/* For SCSI progress
700 							 * ops */
701 };
702 
703 struct aac_AifJobDesc {
704 	u_int32_t		jobID;		/* DO NOT FILL IN! Will be
705 						 * filled in by AIF */
706 	AAC_AifJobType		type;		/* Operation that is being
707 						 * performed */
708 	union aac_AifJobClient	client;		/* Details */
709 } __packed;
710 
711 struct aac_AifJobProgressReport {
712 	struct aac_AifJobDesc	jd;
713 	AAC_AifJobStatus	status;
714 	u_int32_t		finalTick;
715 	u_int32_t		currentTick;
716 	u_int32_t		jobSpecificData1;
717 	u_int32_t		jobSpecificData2;
718 } __packed;
719 
720 /*
721  * Event Notification
722  */
723 typedef enum {
724 	/* General application notifies start here */
725 	AifEnGeneric = 1,		/* Generic notification */
726 	AifEnTaskComplete,		/* Task has completed */
727 	AifEnConfigChange,		/* Adapter config change occurred */
728 	AifEnContainerChange,		/* Adapter specific container
729 					 * configuration change */
730 	AifEnDeviceFailure,		/* SCSI device failed */
731 	AifEnMirrorFailover,		/* Mirror failover started */
732 	AifEnContainerEvent,		/* Significant container event */
733 	AifEnFileSystemChange,		/* File system changed */
734 	AifEnConfigPause,		/* Container pause event */
735 	AifEnConfigResume,		/* Container resume event */
736 	AifEnFailoverChange,		/* Failover space assignment changed */
737 	AifEnRAID5RebuildDone,		/* RAID5 rebuild finished */
738 	AifEnEnclosureManagement,	/* Enclosure management event */
739 	AifEnBatteryEvent,		/* Significant NV battery event */
740 	AifEnAddContainer,		/* A new container was created. */
741 	AifEnDeleteContainer,		/* A container was deleted. */
742 	AifEnSMARTEvent, 	       	/* SMART Event */
743 	AifEnBatteryNeedsRecond,	/* The battery needs reconditioning */
744 	AifEnClusterEvent,		/* Some cluster event */
745 	AifEnDiskSetEvent,		/* A disk set event occured. */
746 	AifDriverNotifyStart=199,	/* Notifies for host driver go here */
747 	/* Host driver notifications start here */
748 	AifDenMorphComplete, 		/* A morph operation completed */
749 	AifDenVolumeExtendComplete 	/* Volume expand operation completed */
750 } AAC_AifEventNotifyType;
751 
752 struct aac_AifEnsGeneric {
753 	char	text[132];		/* Generic text */
754 } __packed;
755 
756 struct aac_AifEnsDeviceFailure {
757 	u_int32_t	deviceHandle;	/* SCSI device handle */
758 } __packed;
759 
760 struct aac_AifEnsMirrorFailover {
761 	u_int32_t	container;	/* Container with failed element */
762 	u_int32_t	failedSlice;	/* Old slice which failed */
763 	u_int32_t	creatingSlice;	/* New slice used for auto-create */
764 } __packed;
765 
766 struct aac_AifEnsContainerChange {
767 	u_int32_t	container[2];	/* container that changed, -1 if no
768 					 * container */
769 } __packed;
770 
771 struct aac_AifEnsContainerEvent {
772 	u_int32_t	container;	/* container number  */
773 	u_int32_t	eventType;	/* event type */
774 } __packed;
775 
776 struct aac_AifEnsEnclosureEvent {
777 	u_int32_t	empID;		/* enclosure management proc number  */
778 	u_int32_t	unitID;		/* unitId, fan id, power supply id,
779 					 * slot id, tempsensor id.  */
780 	u_int32_t	eventType;	/* event type */
781 } __packed;
782 
783 struct aac_AifEnsBatteryEvent {
784 	AAC_NVBATT_TRANSITION	transition_type;	/* eg from low to ok */
785 	AAC_NVBATTSTATUS	current_state;		/* current batt state */
786 	AAC_NVBATTSTATUS	prior_state;		/* prev batt state */
787 } __packed;
788 
789 struct aac_AifEnsDiskSetEvent {
790 	u_int32_t	eventType;
791 	u_int64_t	DsNum;
792 	u_int64_t	CreatorId;
793 } __packed;
794 
795 typedef enum {
796 	CLUSTER_NULL_EVENT = 0,
797 	CLUSTER_PARTNER_NAME_EVENT,	/* change in partner hostname or
798 					 * adaptername from NULL to non-NULL */
799 	/* (partner's agent may be up) */
800 	CLUSTER_PARTNER_NULL_NAME_EVENT	/* change in partner hostname or
801 					 * adaptername from non-null to NULL */
802 	/* (partner has rebooted) */
803 } AAC_ClusterAifEvent;
804 
805 struct aac_AifEnsClusterEvent {
806 	AAC_ClusterAifEvent	eventType;
807 } __packed;
808 
809 struct aac_AifEventNotify {
810 	AAC_AifEventNotifyType	type;
811 	union {
812 		struct aac_AifEnsGeneric		EG;
813 		struct aac_AifEnsDeviceFailure		EDF;
814 		struct aac_AifEnsMirrorFailover		EMF;
815 		struct aac_AifEnsContainerChange	ECC;
816 		struct aac_AifEnsContainerEvent		ECE;
817 		struct aac_AifEnsEnclosureEvent		EEE;
818 		struct aac_AifEnsBatteryEvent		EBE;
819 		struct aac_AifEnsDiskSetEvent		EDS;
820 /*		struct aac_AifEnsSMARTEvent		ES;*/
821 		struct aac_AifEnsClusterEvent		ECLE;
822 	} data;
823 } __packed;
824 
825 /*
826  * Adapter Initiated FIB command structures. Start with the adapter
827  * initiated FIBs that really come from the adapter, and get responded
828  * to by the host.
829  */
830 #define AAC_AIF_REPORT_MAX_SIZE 64
831 
832 typedef enum {
833 	AifCmdEventNotify = 1,	/* Notify of event */
834 	AifCmdJobProgress,	/* Progress report */
835 	AifCmdAPIReport,	/* Report from other user of API */
836 	AifCmdDriverNotify,	/* Notify host driver of event */
837 	AifReqJobList = 100,	/* Gets back complete job list */
838 	AifReqJobsForCtr,	/* Gets back jobs for specific container */
839 	AifReqJobsForScsi,	/* Gets back jobs for specific SCSI device */
840 	AifReqJobReport,	/* Gets back a specific job report or list */
841 	AifReqTerminateJob,	/* Terminates job */
842 	AifReqSuspendJob,	/* Suspends a job */
843 	AifReqResumeJob,	/* Resumes a job */
844 	AifReqSendAPIReport,	/* API generic report requests */
845 	AifReqAPIJobStart,	/* Start a job from the API */
846 	AifReqAPIJobUpdate,	/* Update a job report from the API */
847 	AifReqAPIJobFinish	/* Finish a job from the API */
848 } AAC_AifCommand;
849 
850 struct aac_aif_command {
851 	AAC_AifCommand	command;	/* Tell host what type of
852 					 * notify this is */
853 	u_int32_t	seqNumber;	/* To allow ordering of
854 					 * reports (if necessary) */
855 	union {
856 		struct aac_AifEventNotify	EN;	/* Event notify */
857 		struct aac_AifJobProgressReport	PR[1];	/* Progress report */
858 		u_int8_t			AR[AAC_AIF_REPORT_MAX_SIZE];
859 		u_int8_t			data[AAC_FIB_DATASIZE - 8];
860 	} data;
861 } __packed;
862 
863 /*
864  * Filesystem commands/data
865  *
866  * The adapter has a very complex filesystem interface, most of which we ignore.
867  * (And which seems not to be implemented, anyway.)
868  */
869 
870 /*
871  * FSA commands
872  * (not used?)
873  */
874 typedef enum {
875 	Null = 0,
876 	GetAttributes,
877 	SetAttributes,
878 	Lookup,
879 	ReadLink,
880 	Read,
881 	Write,
882 	Create,
883 	MakeDirectory,
884 	SymbolicLink,
885 	MakeNode,
886 	Removex,
887 	RemoveDirectory,
888 	Rename,
889 	Link,
890 	ReadDirectory,
891 	ReadDirectoryPlus,
892 	FileSystemStatus,
893 	FileSystemInfo,
894 	PathConfigure,
895 	Commit,
896 	Mount,
897 	UnMount,
898 	Newfs,
899 	FsCheck,
900 	FsSync,
901 	SimReadWrite,
902 	SetFileSystemStatus,
903 	BlockRead,
904 	BlockWrite,
905 	NvramIoctl,
906 	FsSyncWait,
907 	ClearArchiveBit,
908 	SetAcl,
909 	GetAcl,
910 	AssignAcl,
911 	FaultInsertion,
912 	CrazyCache
913 } AAC_FSACommand;
914 
915 /*
916  * Command status values
917  */
918 typedef enum {
919 	ST_OK = 0,
920 	ST_PERM = 1,
921 	ST_NOENT = 2,
922 	ST_IO = 5,
923 	ST_NXIO = 6,
924 	ST_E2BIG = 7,
925 	ST_ACCES = 13,
926 	ST_EXIST = 17,
927 	ST_XDEV = 18,
928 	ST_NODEV = 19,
929 	ST_NOTDIR = 20,
930 	ST_ISDIR = 21,
931 	ST_INVAL = 22,
932 	ST_FBIG = 27,
933 	ST_NOSPC = 28,
934 	ST_ROFS = 30,
935 	ST_MLINK = 31,
936 	ST_WOULDBLOCK = 35,
937 	ST_NAMETOOLONG = 63,
938 	ST_NOTEMPTY = 66,
939 	ST_DQUOT = 69,
940 	ST_STALE = 70,
941 	ST_REMOTE = 71,
942 	ST_BADHANDLE = 10001,
943 	ST_NOT_SYNC = 10002,
944 	ST_BAD_COOKIE = 10003,
945 	ST_NOTSUPP = 10004,
946 	ST_TOOSMALL = 10005,
947 	ST_SERVERFAULT = 10006,
948 	ST_BADTYPE = 10007,
949 	ST_JUKEBOX = 10008,
950 	ST_NOTMOUNTED = 10009,
951 	ST_MAINTMODE = 10010,
952 	ST_STALEACL = 10011
953 } AAC_FSAStatus;
954 
955 /*
956  * Volume manager commands
957  */
958 typedef enum _VM_COMMANDS {
959 	VM_Null = 0,
960 	VM_NameServe,
961 	VM_ContainerConfig,
962 	VM_Ioctl,
963 	VM_FilesystemIoctl,
964 	VM_CloseAll,
965 	VM_CtBlockRead,
966 	VM_CtBlockWrite,
967 	VM_SliceBlockRead,	 /* raw access to configured storage objects */
968 	VM_SliceBlockWrite,
969 	VM_DriveBlockRead,	 /* raw access to physical devices */
970 	VM_DriveBlockWrite,
971 	VM_EnclosureMgt,	 /* enclosure management */
972 	VM_Unused,		 /* used to be diskset management */
973 	VM_CtBlockVerify,
974 	VM_CtPerf,		 /* performance test */
975 	VM_CtBlockRead64,
976 	VM_CtBlockWrite64,
977 	VM_CtBlockVerify64,
978 	VM_CtHostRead64,
979 	VM_CtHostWrite64,
980 } AAC_VMCommand;
981 
982 /*
983  * "mountable object"
984  */
985 struct aac_mntobj {
986 	u_int32_t			ObjectId;
987 	char				FileSystemName[16];
988 	struct aac_container_creation	CreateInfo;
989 	u_int32_t			Capacity;
990 	u_int32_t			VolType;
991 	u_int32_t			ObjType;
992 	u_int32_t			ContentState;
993 #define FSCS_READONLY		0x0002		/* XXX need more information
994 						 * than this */
995 	union {
996 		u_int32_t	pad[8];
997 	} ObjExtension;
998 	u_int32_t			AlterEgoId;
999 } __packed;
1000 
1001 struct aac_mntinfo {
1002 	u_int32_t		Command;
1003 	u_int32_t		MntType;
1004 	u_int32_t		MntCount;
1005 } __packed;
1006 
1007 struct aac_mntinforesp {
1008 	u_int32_t		Status;
1009 	u_int32_t		MntType;
1010 	u_int32_t		MntRespCount;
1011 	struct aac_mntobj	MntTable[1];
1012 } __packed;
1013 
1014 /*
1015  * Container shutdown command.
1016  */
1017 struct aac_closecommand {
1018 	u_int32_t	Command;
1019 	u_int32_t	ContainerId;
1020 } __packed;
1021 
1022 /*
1023  * Container Config Command
1024  */
1025 #define CT_GET_SCSI_METHOD	64
1026 struct aac_ctcfg {
1027 	u_int32_t		Command;
1028 	u_int32_t		cmd;
1029 	u_int32_t		param;
1030 } __packed;
1031 
1032 struct aac_ctcfg_resp {
1033 	u_int32_t		Status;
1034 	u_int32_t		resp;
1035 	u_int32_t		param;
1036 } __packed;
1037 
1038 /*
1039  * 'Ioctl' commads
1040  */
1041 #define AAC_SCSI_MAX_PORTS	10
1042 #define AAC_BUS_NO_EXIST	0
1043 #define AAC_BUS_VALID		1
1044 #define AAC_BUS_FAULTED		2
1045 #define AAC_BUS_DISABLED	3
1046 #define GetBusInfo		0x9
1047 
1048 struct aac_getbusinf {
1049 	u_int32_t		ProbeComplete;
1050 	u_int32_t		BusCount;
1051 	u_int32_t		TargetsPerBus;
1052 	u_int8_t		InitiatorBusId[AAC_SCSI_MAX_PORTS];
1053 	u_int8_t		BusValid[AAC_SCSI_MAX_PORTS];
1054 } __packed;
1055 
1056 struct aac_vmioctl {
1057 	u_int32_t		Command;
1058 	u_int32_t		ObjType;
1059 	u_int32_t		MethId;
1060 	u_int32_t		ObjId;
1061 	u_int32_t		IoctlCmd;
1062 	u_int32_t		IoctlBuf[1];	/* Placeholder? */
1063 } __packed;
1064 
1065 struct aac_vmi_businf_resp {
1066 	u_int32_t		Status;
1067 	u_int32_t		ObjType;
1068 	u_int32_t		MethId;
1069 	u_int32_t		ObjId;
1070 	u_int32_t		IoctlCmd;
1071 	struct aac_getbusinf	BusInf;
1072 } __packed;
1073 
1074 #define AAC_BTL_TO_HANDLE(b, t, l) \
1075     (((b & 0x3f) << 7) | ((l & 0x7) << 4) | (t & 0xf))
1076 #define GetDeviceProbeInfo 0x5
1077 
1078 struct aac_vmi_devinfo_resp {
1079 	u_int32_t		Status;
1080 	u_int32_t		ObjType;
1081 	u_int32_t		MethId;
1082 	u_int32_t		ObjId;
1083 	u_int32_t		IoctlCmd;
1084 	u_int8_t		VendorId[8];
1085 	u_int8_t		ProductId[16];
1086 	u_int8_t		ProductRev[4];
1087 	u_int32_t		Inquiry7;
1088 	u_int32_t		align1;
1089 	u_int32_t		Inquiry0;
1090 	u_int32_t		align2;
1091 	u_int32_t		Inquiry1;
1092 	u_int32_t		align3;
1093 	u_int32_t		reserved[2];
1094 	u_int8_t		VendorSpecific[20];
1095 	u_int32_t		Smart:1;
1096 	u_int32_t		AAC_Managed:1;
1097 	u_int32_t		align4;
1098 	u_int32_t		reserved2:6;
1099 	u_int32_t		Bus;
1100 	u_int32_t		Target;
1101 	u_int32_t		Lun;
1102 	u_int32_t		ultraEnable:1,
1103 				disconnectEnable:1,
1104 				fast20EnabledW:1,
1105 				scamDevice:1,
1106 				scamTolerant:1,
1107 				setForSync:1,
1108 				setForWide:1,
1109 				syncDevice:1,
1110 				wideDevice:1,
1111 				reserved1:7,
1112 				ScsiRate:8,
1113 				ScsiOffset:8;
1114 }; /* Do not pack */
1115 
1116 #define ResetBus 0x16
1117 struct aac_resetbus {
1118 	u_int32_t		BusNumber;
1119 };
1120 
1121 /*
1122  * Write 'stability' options.
1123  */
1124 typedef enum {
1125 	CSTABLE = 1,
1126 	CUNSTABLE
1127 } AAC_CacheLevel;
1128 
1129 /*
1130  * Commit level response for a write request.
1131  */
1132 typedef enum {
1133 	CMFILE_SYNC_NVRAM = 1,
1134 	CMDATA_SYNC_NVRAM,
1135 	CMFILE_SYNC,
1136 	CMDATA_SYNC,
1137 	CMUNSTABLE
1138 } AAC_CommitLevel;
1139 
1140 /*
1141  * Block read/write operations.
1142  * These structures are packed into the 'data' area in the FIB.
1143  */
1144 
1145 struct aac_blockread {
1146 	u_int32_t		Command;	/* not FSACommand! */
1147 	u_int32_t		ContainerId;
1148 	u_int32_t		BlockNumber;
1149 	u_int32_t		ByteCount;
1150 	struct aac_sg_table	SgMap;		/* variable size */
1151 } __packed;
1152 
1153 struct aac_blockread64 {
1154 	u_int32_t		Command;
1155 	u_int16_t		ContainerId;
1156 	u_int16_t		SectorCount;
1157 	u_int32_t		BlockNumber;
1158 	u_int16_t		Pad;
1159 	u_int16_t		Flags;
1160 	struct aac_sg_table64	SgMap64;
1161 } __packed;
1162 
1163 struct aac_blockread_response {
1164 	u_int32_t		Status;
1165 	u_int32_t		ByteCount;
1166 } __packed;
1167 
1168 struct aac_blockwrite {
1169 	u_int32_t		Command;	/* not FSACommand! */
1170 	u_int32_t		ContainerId;
1171 	u_int32_t		BlockNumber;
1172 	u_int32_t		ByteCount;
1173 	u_int32_t		Stable;
1174 	struct aac_sg_table	SgMap;		/* variable size */
1175 } __packed;
1176 
1177 struct aac_blockwrite64 {
1178 	u_int32_t		Command;	/* not FSACommand! */
1179 	u_int16_t		ContainerId;
1180 	u_int16_t		SectorCount;
1181 	u_int32_t		BlockNumber;
1182 	u_int16_t		Pad;
1183 	u_int16_t		Flags;
1184 	struct aac_sg_table64	SgMap64;	/* variable size */
1185 } __packed;
1186 
1187 struct aac_blockwrite_response {
1188 	u_int32_t		Status;
1189 	u_int32_t		ByteCount;
1190 	u_int32_t		Committed;
1191 } __packed;
1192 
1193 /*
1194  * Container shutdown command.
1195  */
1196 struct aac_close_command {
1197 	u_int32_t		Command;
1198 	u_int32_t		ContainerId;
1199 };
1200 
1201 /*
1202  * SCSI Passthrough structures
1203  */
1204 struct aac_srb32 {
1205 	u_int32_t		function;
1206 	u_int32_t		bus;
1207 	u_int32_t		target;
1208 	u_int32_t		lun;
1209 	u_int32_t		timeout;
1210 	u_int32_t		flags;
1211 	u_int32_t		data_len;
1212 	u_int32_t		retry_limit;
1213 	u_int32_t		cdb_len;
1214 	u_int8_t		cdb[16];
1215 	struct aac_sg_table	sg_map32;
1216 };
1217 
1218 enum {
1219 	AAC_SRB_FUNC_EXECUTE_SCSI	= 0x00,
1220 	AAC_SRB_FUNC_CLAIM_DEVICE,
1221 	AAC_SRB_FUNC_IO_CONTROL,
1222 	AAC_SRB_FUNC_RECEIVE_EVENT,
1223 	AAC_SRB_FUNC_RELEASE_QUEUE,
1224 	AAC_SRB_FUNC_ATTACH_DEVICE,
1225 	AAC_SRB_FUNC_RELEASE_DEVICE,
1226 	AAC_SRB_FUNC_SHUTDOWN,
1227 	AAC_SRB_FUNC_FLUSH,
1228 	AAC_SRB_FUNC_ABORT_COMMAND	= 0x10,
1229 	AAC_SRB_FUNC_RELEASE_RECOVERY,
1230 	AAC_SRB_FUNC_RESET_BUS,
1231 	AAC_SRB_FUNC_RESET_DEVICE,
1232 	AAC_SRB_FUNC_TERMINATE_IO,
1233 	AAC_SRB_FUNC_FLUSH_QUEUE,
1234 	AAC_SRB_FUNC_REMOVE_DEVICE,
1235 	AAC_SRB_FUNC_DOMAIN_VALIDATION
1236 };
1237 
1238 #define AAC_SRB_FLAGS_NO_DATA_XFER		0x0000
1239 #define	AAC_SRB_FLAGS_DISABLE_DISCONNECT	0x0004
1240 #define	AAC_SRB_FLAGS_DISABLE_SYNC_TRANSFER	0x0008
1241 #define AAC_SRB_FLAGS_BYPASS_FROZEN_QUEUE	0x0010
1242 #define	AAC_SRB_FLAGS_DISABLE_AUTOSENSE		0x0020
1243 #define	AAC_SRB_FLAGS_DATA_IN			0x0040
1244 #define AAC_SRB_FLAGS_DATA_OUT			0x0080
1245 #define	AAC_SRB_FLAGS_UNSPECIFIED_DIRECTION \
1246 			(AAC_SRB_FLAGS_DATA_IN | AAC_SRB_FLAGS_DATA_OUT)
1247 
1248 #define AAC_HOST_SENSE_DATA_MAX			30
1249 
1250 struct aac_srb_response {
1251 	u_int32_t	fib_status;
1252 	u_int32_t	srb_status;
1253 	u_int32_t	scsi_status;
1254 	u_int32_t	data_len;
1255 	u_int32_t	sense_len;
1256 	u_int8_t	sense[AAC_HOST_SENSE_DATA_MAX];
1257 };
1258 
1259 enum {
1260 	AAC_SRB_STS_PENDING			= 0x00,
1261 	AAC_SRB_STS_SUCCESS,
1262 	AAC_SRB_STS_ABORTED,
1263 	AAC_SRB_STS_ABORT_FAILED,
1264 	AAC_SRB_STS_ERROR,
1265 	AAC_SRB_STS_BUSY,
1266 	AAC_SRB_STS_INVALID_REQUEST,
1267 	AAC_SRB_STS_INVALID_PATH_ID,
1268 	AAC_SRB_STS_NO_DEVICE,
1269 	AAC_SRB_STS_TIMEOUT,
1270 	AAC_SRB_STS_SELECTION_TIMEOUT,
1271 	AAC_SRB_STS_COMMAND_TIMEOUT,
1272 	AAC_SRB_STS_MESSAGE_REJECTED		= 0x0D,
1273 	AAC_SRB_STS_BUS_RESET,
1274 	AAC_SRB_STS_PARITY_ERROR,
1275 	AAC_SRB_STS_REQUEST_SENSE_FAILED,
1276 	AAC_SRB_STS_NO_HBA,
1277 	AAC_SRB_STS_DATA_OVERRUN,
1278 	AAC_SRB_STS_UNEXPECTED_BUS_FREE,
1279 	AAC_SRB_STS_PHASE_SEQUENCE_FAILURE,
1280 	AAC_SRB_STS_BAD_SRB_BLOCK_LENGTH,
1281 	AAC_SRB_STS_REQUEST_FLUSHED,
1282 	AAC_SRB_STS_INVALID_LUN			= 0x20,
1283 	AAC_SRB_STS_INVALID_TARGET_ID,
1284 	AAC_SRB_STS_BAD_FUNCTION,
1285 	AAC_SRB_STS_ERROR_RECOVERY
1286 };
1287 
1288 /*
1289  * Register set for adapters based on the Falcon bridge and PPC core
1290  */
1291 
1292 #define AAC_FA_DOORBELL0_CLEAR		0x00
1293 #define AAC_FA_DOORBELL1_CLEAR		0x02
1294 #define AAC_FA_DOORBELL0		0x04
1295 #define AAC_FA_DOORBELL1		0x06
1296 #define AAC_FA_MASK0_CLEAR		0x08
1297 #define AAC_FA_MASK1_CLEAR		0x0a
1298 #define	AAC_FA_MASK0			0x0c
1299 #define AAC_FA_MASK1			0x0e
1300 #define AAC_FA_MAILBOX			0x10
1301 #define	AAC_FA_FWSTATUS			0x2c	/* Mailbox 7 */
1302 #define	AAC_FA_INTSRC			0x900
1303 
1304 #define AAC_FA_HACK(sc)	(void)AAC_GETREG4(sc, AAC_FA_INTSRC)
1305 
1306 /*
1307  * Register definitions for the Adaptec AAC-364 'Jalapeno I/II' adapters, based
1308  * on the SA110 'StrongArm'.
1309  */
1310 
1311 #define AAC_SA_DOORBELL0_CLEAR		0x98	/* doorbell 0 (adapter->host) */
1312 #define AAC_SA_DOORBELL0_SET		0x9c
1313 #define AAC_SA_DOORBELL0		0x9c
1314 #define AAC_SA_MASK0_CLEAR		0xa0
1315 #define AAC_SA_MASK0_SET		0xa4
1316 
1317 #define AAC_SA_DOORBELL1_CLEAR		0x9a	/* doorbell 1 (host->adapter) */
1318 #define AAC_SA_DOORBELL1_SET		0x9e
1319 #define AAC_SA_DOORBELL1		0x9e
1320 #define AAC_SA_MASK1_CLEAR		0xa2
1321 #define AAC_SA_MASK1_SET		0xa6
1322 
1323 #define AAC_SA_MAILBOX			0xa8	/* mailbox (20 bytes) */
1324 #define AAC_SA_FWSTATUS			0xc4
1325 
1326 /*
1327  * Register definitions for the Adaptec 'Pablano' adapters, based on the i960Rx,
1328  * and other related adapters.
1329  */
1330 
1331 #define AAC_RX_IDBR		0x20	/* inbound doorbell register */
1332 #define AAC_RX_IISR		0x24	/* inbound interrupt status register */
1333 #define AAC_RX_IIMR		0x28	/* inbound interrupt mask register */
1334 #define AAC_RX_ODBR		0x2c	/* outbound doorbell register */
1335 #define AAC_RX_OISR		0x30	/* outbound interrupt status register */
1336 #define AAC_RX_OIMR		0x34	/* outbound interrupt mask register */
1337 
1338 #define AAC_RX_MAILBOX		0x50	/* mailbox (20 bytes) */
1339 #define AAC_RX_FWSTATUS		0x6c
1340 
1341 /*
1342  * Register definitions for the Adaptec 'Rocket' RAID-On-Chip adapters.
1343  * Unsurprisingly, it's quite similar to the i960!
1344  */
1345 
1346 #define AAC_RKT_IDBR		0x20	/* inbound doorbell register */
1347 #define AAC_RKT_IISR		0x24	/* inbound interrupt status register */
1348 #define AAC_RKT_IIMR		0x28	/* inbound interrupt mask register */
1349 #define AAC_RKT_ODBR		0x2c	/* outbound doorbell register */
1350 #define AAC_RKT_OISR		0x30	/* outbound interrupt status register */
1351 #define AAC_RKT_OIMR		0x34	/* outbound interrupt mask register */
1352 
1353 #define AAC_RKT_MAILBOX		0x1000	/* mailbox */
1354 #define AAC_RKT_FWSTATUS	0x101c	/* Firmware Status (mailbox 7) */
1355 
1356 /*
1357  * Common bit definitions for the doorbell registers.
1358  */
1359 
1360 /*
1361  * Status bits in the doorbell registers.
1362  */
1363 #define AAC_DB_SYNC_COMMAND	(1<<0)	/* send/completed synchronous FIB */
1364 #define AAC_DB_COMMAND_READY	(1<<1)	/* posted one or more commands */
1365 #define AAC_DB_RESPONSE_READY	(1<<2)	/* one or more commands complete */
1366 #define AAC_DB_COMMAND_NOT_FULL	(1<<3)	/* command queue not full */
1367 #define AAC_DB_RESPONSE_NOT_FULL (1<<4)	/* response queue not full */
1368 
1369 /*
1370  * The adapter can request the host print a message by setting the
1371  * DB_PRINTF flag in DOORBELL0.  The driver responds by collecting the
1372  * message from the printf buffer, clearing the DB_PRINTF flag in
1373  * DOORBELL0 and setting it in DOORBELL1.
1374  * (ODBR and IDBR respectively for the i960Rx adapters)
1375  */
1376 #define AAC_DB_PRINTF		(1<<5)	/* adapter requests host printf */
1377 #define AAC_PRINTF_DONE		(1<<5)	/* Host completed printf processing */
1378 
1379 /*
1380  * Mask containing the interrupt bits we care about.  We don't anticipate (or
1381  * want) interrupts not in this mask.
1382  */
1383 #define AAC_DB_INTERRUPTS	(AAC_DB_COMMAND_READY  |	\
1384 				 AAC_DB_RESPONSE_READY |	\
1385 				 AAC_DB_PRINTF)
1386