File: /usr/src/linux/drivers/block/DAC960.h

1     /*
2     
3       Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
4     
5       Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com>
6     
7       This program is free software; you may redistribute and/or modify it under
8       the terms of the GNU General Public License Version 2 as published by the
9       Free Software Foundation.
10     
11       This program is distributed in the hope that it will be useful, but
12       WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
13       or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14       for complete details.
15     
16       The author respectfully requests that any modifications to this software be
17       sent directly to him for evaluation and testing.
18     
19     */
20     
21     
22     /*
23       Define the maximum number of DAC960 Controllers supported by this driver.
24     */
25     
26     #define DAC960_MaxControllers			8
27     
28     
29     /*
30       Define the maximum number of Controller Channels supported by DAC960
31       V1 and V2 Firmware Controllers.
32     */
33     
34     #define DAC960_V1_MaxChannels			3
35     #define DAC960_V2_MaxChannels			4
36     
37     
38     /*
39       Define the maximum number of Targets per Channel supported by DAC960
40       V1 and V2 Firmware Controllers.
41     */
42     
43     #define DAC960_V1_MaxTargets			16
44     #define DAC960_V2_MaxTargets			128
45     
46     
47     /*
48       Define the maximum number of Logical Drives supported by DAC960
49       V1 and V2 Firmware Controllers.
50     */
51     
52     #define DAC960_MaxLogicalDrives			32
53     
54     
55     /*
56       Define the maximum number of Physical Devices supported by DAC960
57       V1 and V2 Firmware Controllers.
58     */
59     
60     #define DAC960_V1_MaxPhysicalDevices		45
61     #define DAC960_V2_MaxPhysicalDevices		272
62     
63     
64     /*
65       Define a Boolean data type.
66     */
67     
68     typedef enum { false, true } __attribute__ ((packed)) boolean;
69     
70     
71     /*
72       Define a 32/64 bit I/O Address data type.
73     */
74     
75     typedef unsigned long DAC960_IO_Address_T;
76     
77     
78     /*
79       Define a 32/64 bit PCI Bus Address data type.
80     */
81     
82     typedef unsigned long DAC960_PCI_Address_T;
83     
84     
85     /*
86       Define a 32 bit Bus Address data type.
87     */
88     
89     typedef unsigned int DAC960_BusAddress32_T;
90     
91     
92     /*
93       Define a 64 bit Bus Address data type.
94     */
95     
96     typedef unsigned long long DAC960_BusAddress64_T;
97     
98     
99     /*
100       Define a 32 bit Byte Count data type.
101     */
102     
103     typedef unsigned int DAC960_ByteCount32_T;
104     
105     
106     /*
107       Define a 64 bit Byte Count data type.
108     */
109     
110     typedef unsigned long long DAC960_ByteCount64_T;
111     
112     
113     /*
114       Define the SCSI INQUIRY Standard Data structure.
115     */
116     
117     typedef struct DAC960_SCSI_Inquiry
118     {
119       unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
120       unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
121       unsigned char DeviceTypeModifier:7;			/* Byte 1 Bits 0-6 */
122       boolean RMB:1;					/* Byte 1 Bit 7 */
123       unsigned char ANSI_ApprovedVersion:3;			/* Byte 2 Bits 0-2 */
124       unsigned char ECMA_Version:3;				/* Byte 2 Bits 3-5 */
125       unsigned char ISO_Version:2;				/* Byte 2 Bits 6-7 */
126       unsigned char ResponseDataFormat:4;			/* Byte 3 Bits 0-3 */
127       unsigned char :2;					/* Byte 3 Bits 4-5 */
128       boolean TrmIOP:1;					/* Byte 3 Bit 6 */
129       boolean AENC:1;					/* Byte 3 Bit 7 */
130       unsigned char AdditionalLength;			/* Byte 4 */
131       unsigned char :8;					/* Byte 5 */
132       unsigned char :8;					/* Byte 6 */
133       boolean SftRe:1;					/* Byte 7 Bit 0 */
134       boolean CmdQue:1;					/* Byte 7 Bit 1 */
135       boolean :1;						/* Byte 7 Bit 2 */
136       boolean Linked:1;					/* Byte 7 Bit 3 */
137       boolean Sync:1;					/* Byte 7 Bit 4 */
138       boolean WBus16:1;					/* Byte 7 Bit 5 */
139       boolean WBus32:1;					/* Byte 7 Bit 6 */
140       boolean RelAdr:1;					/* Byte 7 Bit 7 */
141       unsigned char VendorIdentification[8];		/* Bytes 8-15 */
142       unsigned char ProductIdentification[16];		/* Bytes 16-31 */
143       unsigned char ProductRevisionLevel[4];		/* Bytes 32-35 */
144     }
145     DAC960_SCSI_Inquiry_T;
146     
147     
148     /*
149       Define the SCSI INQUIRY Unit Serial Number structure.
150     */
151     
152     typedef struct DAC960_SCSI_Inquiry_UnitSerialNumber
153     {
154       unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
155       unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
156       unsigned char PageCode;				/* Byte 1 */
157       unsigned char :8;					/* Byte 2 */
158       unsigned char PageLength;				/* Byte 3 */
159       unsigned char ProductSerialNumber[28];		/* Bytes 4-31 */
160     }
161     DAC960_SCSI_Inquiry_UnitSerialNumber_T;
162     
163     
164     /*
165       Define the SCSI REQUEST SENSE Sense Key type.
166     */
167     
168     typedef enum
169     {
170       DAC960_SenseKey_NoSense =			0x0,
171       DAC960_SenseKey_RecoveredError =		0x1,
172       DAC960_SenseKey_NotReady =			0x2,
173       DAC960_SenseKey_MediumError =			0x3,
174       DAC960_SenseKey_HardwareError =		0x4,
175       DAC960_SenseKey_IllegalRequest =		0x5,
176       DAC960_SenseKey_UnitAttention =		0x6,
177       DAC960_SenseKey_DataProtect =			0x7,
178       DAC960_SenseKey_BlankCheck =			0x8,
179       DAC960_SenseKey_VendorSpecific =		0x9,
180       DAC960_SenseKey_CopyAborted =			0xA,
181       DAC960_SenseKey_AbortedCommand =		0xB,
182       DAC960_SenseKey_Equal =			0xC,
183       DAC960_SenseKey_VolumeOverflow =		0xD,
184       DAC960_SenseKey_Miscompare =			0xE,
185       DAC960_SenseKey_Reserved =			0xF
186     }
187     __attribute__ ((packed))
188     DAC960_SCSI_RequestSenseKey_T;
189     
190     
191     /*
192       Define the SCSI REQUEST SENSE structure.
193     */
194     
195     typedef struct DAC960_SCSI_RequestSense
196     {
197       unsigned char ErrorCode:7;				/* Byte 0 Bits 0-6 */
198       boolean Valid:1;					/* Byte 0 Bit 7 */
199       unsigned char SegmentNumber;				/* Byte 1 */
200       DAC960_SCSI_RequestSenseKey_T SenseKey:4;		/* Byte 2 Bits 0-3 */
201       unsigned char :1;					/* Byte 2 Bit 4 */
202       boolean ILI:1;					/* Byte 2 Bit 5 */
203       boolean EOM:1;					/* Byte 2 Bit 6 */
204       boolean Filemark:1;					/* Byte 2 Bit 7 */
205       unsigned char Information[4];				/* Bytes 3-6 */
206       unsigned char AdditionalSenseLength;			/* Byte 7 */
207       unsigned char CommandSpecificInformation[4];		/* Bytes 8-11 */
208       unsigned char AdditionalSenseCode;			/* Byte 12 */
209       unsigned char AdditionalSenseCodeQualifier;		/* Byte 13 */
210     }
211     DAC960_SCSI_RequestSense_T;
212     
213     
214     /*
215       Define the DAC960 V1 Firmware Command Opcodes.
216     */
217     
218     typedef enum
219     {
220       /* I/O Commands */
221       DAC960_V1_ReadExtended =			0x33,
222       DAC960_V1_WriteExtended =			0x34,
223       DAC960_V1_ReadAheadExtended =			0x35,
224       DAC960_V1_ReadExtendedWithScatterGather =	0xB3,
225       DAC960_V1_WriteExtendedWithScatterGather =	0xB4,
226       DAC960_V1_Read =				0x36,
227       DAC960_V1_ReadWithOldScatterGather =		0xB6,
228       DAC960_V1_Write =				0x37,
229       DAC960_V1_WriteWithOldScatterGather =		0xB7,
230       DAC960_V1_DCDB =				0x04,
231       DAC960_V1_DCDBWithScatterGather =		0x84,
232       DAC960_V1_Flush =				0x0A,
233       /* Controller Status Related Commands */
234       DAC960_V1_Enquiry =				0x53,
235       DAC960_V1_Enquiry2 =				0x1C,
236       DAC960_V1_GetLogicalDriveElement =		0x55,
237       DAC960_V1_GetLogicalDriveInformation =	0x19,
238       DAC960_V1_IOPortRead =			0x39,
239       DAC960_V1_IOPortWrite =			0x3A,
240       DAC960_V1_GetSDStats =			0x3E,
241       DAC960_V1_GetPDStats =			0x3F,
242       DAC960_V1_PerformEventLogOperation =		0x72,
243       /* Device Related Commands */
244       DAC960_V1_StartDevice =			0x10,
245       DAC960_V1_GetDeviceState =			0x50,
246       DAC960_V1_StopChannel =			0x13,
247       DAC960_V1_StartChannel =			0x12,
248       DAC960_V1_ResetChannel =			0x1A,
249       /* Commands Associated with Data Consistency and Errors */
250       DAC960_V1_Rebuild =				0x09,
251       DAC960_V1_RebuildAsync =			0x16,
252       DAC960_V1_CheckConsistency =			0x0F,
253       DAC960_V1_CheckConsistencyAsync =		0x1E,
254       DAC960_V1_RebuildStat =			0x0C,
255       DAC960_V1_GetRebuildProgress =		0x27,
256       DAC960_V1_RebuildControl =			0x1F,
257       DAC960_V1_ReadBadBlockTable =			0x0B,
258       DAC960_V1_ReadBadDataTable =			0x25,
259       DAC960_V1_ClearBadDataTable =			0x26,
260       DAC960_V1_GetErrorTable =			0x17,
261       DAC960_V1_AddCapacityAsync =			0x2A,
262       DAC960_V1_BackgroundInitializationControl =	0x2B,
263       /* Configuration Related Commands */
264       DAC960_V1_ReadConfig2 =			0x3D,
265       DAC960_V1_WriteConfig2 =			0x3C,
266       DAC960_V1_ReadConfigurationOnDisk =		0x4A,
267       DAC960_V1_WriteConfigurationOnDisk =		0x4B,
268       DAC960_V1_ReadConfiguration =			0x4E,
269       DAC960_V1_ReadBackupConfiguration =		0x4D,
270       DAC960_V1_WriteConfiguration =		0x4F,
271       DAC960_V1_AddConfiguration =			0x4C,
272       DAC960_V1_ReadConfigurationLabel =		0x48,
273       DAC960_V1_WriteConfigurationLabel =		0x49,
274       /* Firmware Upgrade Related Commands */
275       DAC960_V1_LoadImage =				0x20,
276       DAC960_V1_StoreImage =			0x21,
277       DAC960_V1_ProgramImage =			0x22,
278       /* Diagnostic Commands */
279       DAC960_V1_SetDiagnosticMode =			0x31,
280       DAC960_V1_RunDiagnostic =			0x32,
281       /* Subsystem Service Commands */
282       DAC960_V1_GetSubsystemData =			0x70,
283       DAC960_V1_SetSubsystemParameters =		0x71
284     }
285     __attribute__ ((packed))
286     DAC960_V1_CommandOpcode_T;
287     
288     
289     /*
290       Define the DAC960 V1 Firmware Command Identifier type.
291     */
292     
293     typedef unsigned char DAC960_V1_CommandIdentifier_T;
294     
295     
296     /*
297       Define the DAC960 V1 Firmware Command Status Codes.
298     */
299     
300     #define DAC960_V1_NormalCompletion		0x0000	/* Common */
301     #define DAC960_V1_CheckConditionReceived	0x0002	/* Common */
302     #define DAC960_V1_NoDeviceAtAddress		0x0102	/* Common */
303     #define DAC960_V1_InvalidDeviceAddress		0x0105	/* Common */
304     #define DAC960_V1_InvalidParameter		0x0105	/* Common */
305     #define DAC960_V1_IrrecoverableDataError	0x0001	/* I/O */
306     #define DAC960_V1_LogicalDriveNonexistentOrOffline 0x0002 /* I/O */
307     #define DAC960_V1_AccessBeyondEndOfLogicalDrive	0x0105	/* I/O */
308     #define DAC960_V1_BadDataEncountered		0x010C	/* I/O */
309     #define DAC960_V1_DeviceBusy			0x0008	/* DCDB */
310     #define DAC960_V1_DeviceNonresponsive		0x000E	/* DCDB */
311     #define DAC960_V1_CommandTerminatedAbnormally	0x000F	/* DCDB */
312     #define DAC960_V1_UnableToStartDevice		0x0002	/* Device */
313     #define DAC960_V1_InvalidChannelOrTargetOrModifier 0x0105 /* Device */
314     #define DAC960_V1_ChannelBusy			0x0106	/* Device */
315     #define DAC960_V1_ChannelNotStopped		0x0002	/* Device */
316     #define DAC960_V1_AttemptToRebuildOnlineDrive	0x0002	/* Consistency */
317     #define DAC960_V1_RebuildBadBlocksEncountered	0x0003	/* Consistency */
318     #define DAC960_V1_NewDiskFailedDuringRebuild	0x0004	/* Consistency */
319     #define DAC960_V1_RebuildOrCheckAlreadyInProgress 0x0106 /* Consistency */
320     #define DAC960_V1_DependentDiskIsDead		0x0002	/* Consistency */
321     #define DAC960_V1_InconsistentBlocksFound	0x0003	/* Consistency */
322     #define DAC960_V1_InvalidOrNonredundantLogicalDrive 0x0105 /* Consistency */
323     #define DAC960_V1_NoRebuildOrCheckInProgress	0x0105	/* Consistency */
324     #define DAC960_V1_RebuildInProgress_DataValid	0x0000	/* Consistency */
325     #define DAC960_V1_RebuildFailed_LogicalDriveFailure 0x0002 /* Consistency */
326     #define DAC960_V1_RebuildFailed_BadBlocksOnOther 0x0003	/* Consistency */
327     #define DAC960_V1_RebuildFailed_NewDriveFailed	0x0004	/* Consistency */
328     #define DAC960_V1_RebuildSuccessful		0x0100	/* Consistency */
329     #define DAC960_V1_RebuildSuccessfullyTerminated	0x0107	/* Consistency */
330     #define DAC960_V1_AddCapacityInProgress		0x0004	/* Consistency */
331     #define DAC960_V1_AddCapacityFailedOrSuspended	0x00F4	/* Consistency */
332     #define DAC960_V1_Config2ChecksumError		0x0002	/* Configuration */
333     #define DAC960_V1_ConfigurationSuspended	0x0106	/* Configuration */
334     #define DAC960_V1_FailedToConfigureNVRAM	0x0105	/* Configuration */
335     #define DAC960_V1_ConfigurationNotSavedStateChange 0x0106 /* Configuration */
336     #define DAC960_V1_SubsystemNotInstalled		0x0001	/* Subsystem */
337     #define DAC960_V1_SubsystemFailed		0x0002	/* Subsystem */
338     #define DAC960_V1_SubsystemBusy			0x0106	/* Subsystem */
339     
340     typedef unsigned short DAC960_V1_CommandStatus_T;
341     
342     
343     /*
344       Define the DAC960 V1 Firmware Enquiry Command reply structure.
345     */
346     
347     typedef struct DAC960_V1_Enquiry
348     {
349       unsigned char NumberOfLogicalDrives;			/* Byte 0 */
350       unsigned int :24;					/* Bytes 1-3 */
351       unsigned int LogicalDriveSizes[32];			/* Bytes 4-131 */
352       unsigned short FlashAge;				/* Bytes 132-133 */
353       struct {
354         boolean DeferredWriteError:1;			/* Byte 134 Bit 0 */
355         boolean BatteryLow:1;				/* Byte 134 Bit 1 */
356         unsigned char :6;					/* Byte 134 Bits 2-7 */
357       } StatusFlags;
358       unsigned char :8;					/* Byte 135 */
359       unsigned char MinorFirmwareVersion;			/* Byte 136 */
360       unsigned char MajorFirmwareVersion;			/* Byte 137 */
361       enum {
362         DAC960_V1_NoStandbyRebuildOrCheckInProgress =		    0x00,
363         DAC960_V1_StandbyRebuildInProgress =			    0x01,
364         DAC960_V1_BackgroundRebuildInProgress =			    0x02,
365         DAC960_V1_BackgroundCheckInProgress =			    0x03,
366         DAC960_V1_StandbyRebuildCompletedWithError =		    0xFF,
367         DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed =	    0xF0,
368         DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed =   0xF1,
369         DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses =	    0xF2,
370         DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated =	    0xF3
371       } __attribute__ ((packed)) RebuildFlag;		/* Byte 138 */
372       unsigned char MaxCommands;				/* Byte 139 */
373       unsigned char OfflineLogicalDriveCount;		/* Byte 140 */
374       unsigned char :8;					/* Byte 141 */
375       unsigned short EventLogSequenceNumber;		/* Bytes 142-143 */
376       unsigned char CriticalLogicalDriveCount;		/* Byte 144 */
377       unsigned int :24;					/* Bytes 145-147 */
378       unsigned char DeadDriveCount;				/* Byte 148 */
379       unsigned char :8;					/* Byte 149 */
380       unsigned char RebuildCount;				/* Byte 150 */
381       struct {
382         unsigned char :3;					/* Byte 151 Bits 0-2 */
383         boolean BatteryBackupUnitPresent:1;			/* Byte 151 Bit 3 */
384         unsigned char :3;					/* Byte 151 Bits 4-6 */
385         unsigned char :1;					/* Byte 151 Bit 7 */
386       } MiscFlags;
387       struct {
388         unsigned char TargetID;
389         unsigned char Channel;
390       } DeadDrives[21];					/* Bytes 152-194 */
391       unsigned char Reserved[62];				/* Bytes 195-255 */
392     }
393     __attribute__ ((packed))
394     DAC960_V1_Enquiry_T;
395     
396     
397     /*
398       Define the DAC960 V1 Firmware Enquiry2 Command reply structure.
399     */
400     
401     typedef struct DAC960_V1_Enquiry2
402     {
403       struct {
404         enum {
405           DAC960_V1_P_PD_PU =			0x01,
406           DAC960_V1_PL =				0x02,
407           DAC960_V1_PG =				0x10,
408           DAC960_V1_PJ =				0x11,
409           DAC960_V1_PR =				0x12,
410           DAC960_V1_PT =				0x13,
411           DAC960_V1_PTL0 =				0x14,
412           DAC960_V1_PRL =				0x15,
413           DAC960_V1_PTL1 =				0x16,
414           DAC960_V1_1164P =				0x20
415         } __attribute__ ((packed)) SubModel;		/* Byte 0 */
416         unsigned char ActualChannels;			/* Byte 1 */
417         enum {
418           DAC960_V1_FiveChannelBoard =		0x01,
419           DAC960_V1_ThreeChannelBoard =		0x02,
420           DAC960_V1_TwoChannelBoard =		0x03,
421           DAC960_V1_ThreeChannelASIC_DAC =		0x04
422         } __attribute__ ((packed)) Model;			/* Byte 2 */
423         enum {
424           DAC960_V1_EISA_Controller =		0x01,
425           DAC960_V1_MicroChannel_Controller =	0x02,
426           DAC960_V1_PCI_Controller =		0x03,
427           DAC960_V1_SCSItoSCSI_Controller =		0x08
428         } __attribute__ ((packed)) ProductFamily;		/* Byte 3 */
429       } HardwareID;						/* Bytes 0-3 */
430       /* MajorVersion.MinorVersion-FirmwareType-TurnID */
431       struct {
432         unsigned char MajorVersion;				/* Byte 4 */
433         unsigned char MinorVersion;				/* Byte 5 */
434         unsigned char TurnID;				/* Byte 6 */
435         char FirmwareType;					/* Byte 7 */
436       } FirmwareID;						/* Bytes 4-7 */
437       unsigned char :8;					/* Byte 8 */
438       unsigned int :24;					/* Bytes 9-11 */
439       unsigned char ConfiguredChannels;			/* Byte 12 */
440       unsigned char ActualChannels;				/* Byte 13 */
441       unsigned char MaxTargets;				/* Byte 14 */
442       unsigned char MaxTags;				/* Byte 15 */
443       unsigned char MaxLogicalDrives;			/* Byte 16 */
444       unsigned char MaxArms;				/* Byte 17 */
445       unsigned char MaxSpans;				/* Byte 18 */
446       unsigned char :8;					/* Byte 19 */
447       unsigned int :32;					/* Bytes 20-23 */
448       unsigned int MemorySize;				/* Bytes 24-27 */
449       unsigned int CacheSize;				/* Bytes 28-31 */
450       unsigned int FlashMemorySize;				/* Bytes 32-35 */
451       unsigned int NonVolatileMemorySize;			/* Bytes 36-39 */
452       struct {
453         enum {
454           DAC960_V1_RamType_DRAM =			0x0,
455           DAC960_V1_RamType_EDO =			0x1,
456           DAC960_V1_RamType_SDRAM =			0x2,
457           DAC960_V1_RamType_Last =			0x7
458         } __attribute__ ((packed)) RamType:3;		/* Byte 40 Bits 0-2 */
459         enum {
460           DAC960_V1_ErrorCorrection_None =		0x0,
461           DAC960_V1_ErrorCorrection_Parity =	0x1,
462           DAC960_V1_ErrorCorrection_ECC =		0x2,
463           DAC960_V1_ErrorCorrection_Last =		0x7
464         } __attribute__ ((packed)) ErrorCorrection:3;	/* Byte 40 Bits 3-5 */
465         boolean FastPageMode:1;				/* Byte 40 Bit 6 */
466         boolean LowPowerMemory:1;				/* Byte 40 Bit 7 */
467         unsigned char :8;					/* Bytes 41 */
468       } MemoryType;
469       unsigned short ClockSpeed;				/* Bytes 42-43 */
470       unsigned short MemorySpeed;				/* Bytes 44-45 */
471       unsigned short HardwareSpeed;				/* Bytes 46-47 */
472       unsigned int :32;					/* Bytes 48-51 */
473       unsigned int :32;					/* Bytes 52-55 */
474       unsigned char :8;					/* Byte 56 */
475       unsigned char :8;					/* Byte 57 */
476       unsigned short :16;					/* Bytes 58-59 */
477       unsigned short MaxCommands;				/* Bytes 60-61 */
478       unsigned short MaxScatterGatherEntries;		/* Bytes 62-63 */
479       unsigned short MaxDriveCommands;			/* Bytes 64-65 */
480       unsigned short MaxIODescriptors;			/* Bytes 66-67 */
481       unsigned short MaxCombinedSectors;			/* Bytes 68-69 */
482       unsigned char Latency;				/* Byte 70 */
483       unsigned char :8;					/* Byte 71 */
484       unsigned char SCSITimeout;				/* Byte 72 */
485       unsigned char :8;					/* Byte 73 */
486       unsigned short MinFreeLines;				/* Bytes 74-75 */
487       unsigned int :32;					/* Bytes 76-79 */
488       unsigned int :32;					/* Bytes 80-83 */
489       unsigned char RebuildRateConstant;			/* Byte 84 */
490       unsigned char :8;					/* Byte 85 */
491       unsigned char :8;					/* Byte 86 */
492       unsigned char :8;					/* Byte 87 */
493       unsigned int :32;					/* Bytes 88-91 */
494       unsigned int :32;					/* Bytes 92-95 */
495       unsigned short PhysicalDriveBlockSize;		/* Bytes 96-97 */
496       unsigned short LogicalDriveBlockSize;			/* Bytes 98-99 */
497       unsigned short MaxBlocksPerCommand;			/* Bytes 100-101 */
498       unsigned short BlockFactor;				/* Bytes 102-103 */
499       unsigned short CacheLineSize;				/* Bytes 104-105 */
500       struct {
501         enum {
502           DAC960_V1_Narrow_8bit =			0x0,
503           DAC960_V1_Wide_16bit =			0x1,
504           DAC960_V1_Wide_32bit =			0x2
505         } __attribute__ ((packed)) BusWidth:2;		/* Byte 106 Bits 0-1 */
506         enum {
507           DAC960_V1_Fast =				0x0,
508           DAC960_V1_Ultra =				0x1,
509           DAC960_V1_Ultra2 =			0x2
510         } __attribute__ ((packed)) BusSpeed:2;		/* Byte 106 Bits 2-3 */
511         boolean Differential:1;				/* Byte 106 Bit 4 */
512         unsigned char :3;					/* Byte 106 Bits 5-7 */
513       } SCSICapability;
514       unsigned char :8;					/* Byte 107 */
515       unsigned int :32;					/* Bytes 108-111 */
516       unsigned short FirmwareBuildNumber;			/* Bytes 112-113 */
517       enum {
518         DAC960_V1_AEMI =				0x01,
519         DAC960_V1_OEM1 =				0x02,
520         DAC960_V1_OEM2 =				0x04,
521         DAC960_V1_OEM3 =				0x08,
522         DAC960_V1_Conner =				0x10,
523         DAC960_V1_SAFTE =				0x20
524       } __attribute__ ((packed)) FaultManagementType;	/* Byte 114 */
525       unsigned char :8;					/* Byte 115 */
526       struct {
527         boolean Clustering:1;				/* Byte 116 Bit 0 */
528         boolean MylexOnlineRAIDExpansion:1;			/* Byte 116 Bit 1 */
529         boolean ReadAhead:1;				/* Byte 116 Bit 2 */
530         boolean BackgroundInitialization:1;			/* Byte 116 Bit 3 */
531         unsigned int :28;					/* Bytes 116-119 */
532       } FirmwareFeatures;
533       unsigned int :32;					/* Bytes 120-123 */
534       unsigned int :32;					/* Bytes 124-127 */
535     }
536     DAC960_V1_Enquiry2_T;
537     
538     
539     /*
540       Define the DAC960 V1 Firmware Logical Drive State type.
541     */
542     
543     typedef enum
544     {
545       DAC960_V1_LogicalDrive_Online =		0x03,
546       DAC960_V1_LogicalDrive_Critical =		0x04,
547       DAC960_V1_LogicalDrive_Offline =		0xFF
548     }
549     __attribute__ ((packed))
550     DAC960_V1_LogicalDriveState_T;
551     
552     
553     /*
554       Define the DAC960 V1 Firmware Logical Drive Information structure.
555     */
556     
557     typedef struct DAC960_V1_LogicalDriveInformation
558     {
559       unsigned int LogicalDriveSize;			/* Bytes 0-3 */
560       DAC960_V1_LogicalDriveState_T LogicalDriveState;	/* Byte 4 */
561       unsigned char RAIDLevel:7;				/* Byte 5 Bits 0-6 */
562       boolean WriteBack:1;					/* Byte 5 Bit 7 */
563       unsigned short :16;					/* Bytes 6-7 */
564     }
565     DAC960_V1_LogicalDriveInformation_T;
566     
567     
568     /*
569       Define the DAC960 V1 Firmware Get Logical Drive Information Command
570       reply structure.
571     */
572     
573     typedef DAC960_V1_LogicalDriveInformation_T
574     	DAC960_V1_LogicalDriveInformationArray_T[DAC960_MaxLogicalDrives];
575     
576     
577     /*
578       Define the DAC960 V1 Firmware Perform Event Log Operation Types.
579     */
580     
581     typedef enum
582     {
583       DAC960_V1_GetEventLogEntry =			0x00
584     }
585     __attribute__ ((packed))
586     DAC960_V1_PerformEventLogOpType_T;
587     
588     
589     /*
590       Define the DAC960 V1 Firmware Get Event Log Entry Command reply structure.
591     */
592     
593     typedef struct DAC960_V1_EventLogEntry
594     {
595       unsigned char MessageType;				/* Byte 0 */
596       unsigned char MessageLength;				/* Byte 1 */
597       unsigned char TargetID:5;				/* Byte 2 Bits 0-4 */
598       unsigned char Channel:3;				/* Byte 2 Bits 5-7 */
599       unsigned char LogicalUnit:6;				/* Byte 3 Bits 0-5 */
600       unsigned char :2;					/* Byte 3 Bits 6-7 */
601       unsigned short SequenceNumber;			/* Bytes 4-5 */
602       unsigned char ErrorCode:7;				/* Byte 6 Bits 0-6 */
603       boolean Valid:1;					/* Byte 6 Bit 7 */
604       unsigned char SegmentNumber;				/* Byte 7 */
605       DAC960_SCSI_RequestSenseKey_T SenseKey:4;		/* Byte 8 Bits 0-3 */
606       unsigned char :1;					/* Byte 8 Bit 4 */
607       boolean ILI:1;					/* Byte 8 Bit 5 */
608       boolean EOM:1;					/* Byte 8 Bit 6 */
609       boolean Filemark:1;					/* Byte 8 Bit 7 */
610       unsigned char Information[4];				/* Bytes 9-12 */
611       unsigned char AdditionalSenseLength;			/* Byte 13 */
612       unsigned char CommandSpecificInformation[4];		/* Bytes 14-17 */
613       unsigned char AdditionalSenseCode;			/* Byte 18 */
614       unsigned char AdditionalSenseCodeQualifier;		/* Byte 19 */
615       unsigned char Dummy[12];				/* Bytes 20-31 */
616     }
617     DAC960_V1_EventLogEntry_T;
618     
619     
620     /*
621       Define the DAC960 V1 Firmware Physical Device State type.
622     */
623     
624     typedef enum
625     {
626         DAC960_V1_Device_Dead =			0x00,
627         DAC960_V1_Device_WriteOnly =		0x02,
628         DAC960_V1_Device_Online =			0x03,
629         DAC960_V1_Device_Standby =			0x10
630     }
631     __attribute__ ((packed))
632     DAC960_V1_PhysicalDeviceState_T;
633     
634     
635     /*
636       Define the DAC960 V1 Firmware Get Device State Command reply structure.
637     */
638     
639     typedef struct DAC960_V1_DeviceState
640     {
641       boolean Present:1;					/* Byte 0 Bit 0 */
642       unsigned char :7;					/* Byte 0 Bits 1-7 */
643       enum {
644         DAC960_V1_OtherType =			0x0,
645         DAC960_V1_DiskType =			0x1,
646         DAC960_V1_SequentialType =			0x2,
647         DAC960_V1_CDROM_or_WORM_Type =		0x3
648         } __attribute__ ((packed)) DeviceType:2;		/* Byte 1 Bits 0-1 */
649       boolean :1;						/* Byte 1 Bit 2 */
650       boolean Fast20:1;					/* Byte 1 Bit 3 */
651       boolean Sync:1;					/* Byte 1 Bit 4 */
652       boolean Fast:1;					/* Byte 1 Bit 5 */
653       boolean Wide:1;					/* Byte 1 Bit 6 */
654       boolean TaggedQueuingSupported:1;			/* Byte 1 Bit 7 */
655       DAC960_V1_PhysicalDeviceState_T DeviceState;		/* Byte 2 */
656       unsigned char :8;					/* Byte 3 */
657       unsigned char SynchronousMultiplier;			/* Byte 4 */
658       unsigned char SynchronousOffset:5;			/* Byte 5 Bits 0-4 */
659       unsigned char :3;					/* Byte 5 Bits 5-7 */
660       unsigned int DiskSize __attribute__ ((packed));	/* Bytes 6-9 */
661     }
662     DAC960_V1_DeviceState_T;
663     
664     
665     /*
666       Define the DAC960 V1 Firmware Get Rebuild Progress Command reply structure.
667     */
668     
669     typedef struct DAC960_V1_RebuildProgress
670     {
671       unsigned int LogicalDriveNumber;			/* Bytes 0-3 */
672       unsigned int LogicalDriveSize;			/* Bytes 4-7 */
673       unsigned int RemainingBlocks;				/* Bytes 8-11 */
674     }
675     DAC960_V1_RebuildProgress_T;
676     
677     
678     /*
679       Define the DAC960 V1 Firmware Error Table Entry structure.
680     */
681     
682     typedef struct DAC960_V1_ErrorTableEntry
683     {
684       unsigned char ParityErrorCount;			/* Byte 0 */
685       unsigned char SoftErrorCount;				/* Byte 1 */
686       unsigned char HardErrorCount;				/* Byte 2 */
687       unsigned char MiscErrorCount;				/* Byte 3 */
688     }
689     DAC960_V1_ErrorTableEntry_T;
690     
691     
692     /*
693       Define the DAC960 V1 Firmware Get Error Table Command reply structure.
694     */
695     
696     typedef struct DAC960_V1_ErrorTable
697     {
698       DAC960_V1_ErrorTableEntry_T
699         ErrorTableEntries[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
700     }
701     DAC960_V1_ErrorTable_T;
702     
703     
704     /*
705       Define the DAC960 V1 Firmware Read Config2 Command reply structure.
706     */
707     
708     typedef struct DAC960_V1_Config2
709     {
710       unsigned char :1;					/* Byte 0 Bit 0 */
711       boolean ActiveNegationEnabled:1;			/* Byte 0 Bit 1 */
712       unsigned char :5;					/* Byte 0 Bits 2-6 */
713       boolean NoRescanIfResetReceivedDuringScan:1;		/* Byte 0 Bit 7 */
714       boolean StorageWorksSupportEnabled:1;			/* Byte 1 Bit 0 */
715       boolean HewlettPackardSupportEnabled:1;		/* Byte 1 Bit 1 */
716       boolean NoDisconnectOnFirstCommand:1;			/* Byte 1 Bit 2 */
717       unsigned char :2;					/* Byte 1 Bits 3-4 */
718       boolean AEMI_ARM:1;					/* Byte 1 Bit 5 */
719       boolean AEMI_OFM:1;					/* Byte 1 Bit 6 */
720       unsigned char :1;					/* Byte 1 Bit 7 */
721       enum {
722         DAC960_V1_OEMID_Mylex =			0x00,
723         DAC960_V1_OEMID_IBM =			0x08,
724         DAC960_V1_OEMID_HP =			0x0A,
725         DAC960_V1_OEMID_DEC =			0x0C,
726         DAC960_V1_OEMID_Siemens =			0x10,
727         DAC960_V1_OEMID_Intel =			0x12
728       } __attribute__ ((packed)) OEMID;			/* Byte 2 */
729       unsigned char OEMModelNumber;				/* Byte 3 */
730       unsigned char PhysicalSector;				/* Byte 4 */
731       unsigned char LogicalSector;				/* Byte 5 */
732       unsigned char BlockFactor;				/* Byte 6 */
733       boolean ReadAheadEnabled:1;				/* Byte 7 Bit 0 */
734       boolean LowBIOSDelay:1;				/* Byte 7 Bit 1 */
735       unsigned char :2;					/* Byte 7 Bits 2-3 */
736       boolean ReassignRestrictedToOneSector:1;		/* Byte 7 Bit 4 */
737       unsigned char :1;					/* Byte 7 Bit 5 */
738       boolean ForceUnitAccessDuringWriteRecovery:1;		/* Byte 7 Bit 6 */
739       boolean EnableLeftSymmetricRAID5Algorithm:1;		/* Byte 7 Bit 7 */
740       unsigned char DefaultRebuildRate;			/* Byte 8 */
741       unsigned char :8;					/* Byte 9 */
742       unsigned char BlocksPerCacheLine;			/* Byte 10 */
743       unsigned char BlocksPerStripe;			/* Byte 11 */
744       struct {
745         enum {
746           DAC960_V1_Async =				0x0,
747           DAC960_V1_Sync_8MHz =			0x1,
748           DAC960_V1_Sync_5MHz =			0x2,
749           DAC960_V1_Sync_10or20MHz =		0x3	/* Byte 11 Bits 0-1 */
750         } __attribute__ ((packed)) Speed:2;
751         boolean Force8Bit:1;				/* Byte 11 Bit 2 */
752         boolean DisableFast20:1;				/* Byte 11 Bit 3 */
753         unsigned char :3;					/* Byte 11 Bits 4-6 */
754         boolean EnableTaggedQueuing:1;			/* Byte 11 Bit 7 */
755       } __attribute__ ((packed)) ChannelParameters[6];	/* Bytes 12-17 */
756       unsigned char SCSIInitiatorID;			/* Byte 18 */
757       unsigned char :8;					/* Byte 19 */
758       enum {
759         DAC960_V1_StartupMode_ControllerSpinUp =	0x00,
760         DAC960_V1_StartupMode_PowerOnSpinUp =	0x01
761       } __attribute__ ((packed)) StartupMode;		/* Byte 20 */
762       unsigned char SimultaneousDeviceSpinUpCount;		/* Byte 21 */
763       unsigned char SecondsDelayBetweenSpinUps;		/* Byte 22 */
764       unsigned char Reserved1[29];				/* Bytes 23-51 */
765       boolean BIOSDisabled:1;				/* Byte 52 Bit 0 */
766       boolean CDROMBootEnabled:1;				/* Byte 52 Bit 1 */
767       unsigned char :3;					/* Byte 52 Bits 2-4 */
768       enum {
769         DAC960_V1_Geometry_128_32 =			0x0,
770         DAC960_V1_Geometry_255_63 =			0x1,
771         DAC960_V1_Geometry_Reserved1 =		0x2,
772         DAC960_V1_Geometry_Reserved2 =		0x3
773       } __attribute__ ((packed)) DriveGeometry:2;		/* Byte 52 Bits 5-6 */
774       unsigned char :1;					/* Byte 52 Bit 7 */
775       unsigned char Reserved2[9];				/* Bytes 53-61 */
776       unsigned short Checksum;				/* Bytes 62-63 */
777     }
778     DAC960_V1_Config2_T;
779     
780     
781     /*
782       Define the DAC960 V1 Firmware DCDB request structure.
783     */
784     
785     typedef struct DAC960_V1_DCDB
786     {
787       unsigned char TargetID:4;				 /* Byte 0 Bits 0-3 */
788       unsigned char Channel:4;				 /* Byte 0 Bits 4-7 */
789       enum {
790         DAC960_V1_DCDB_NoDataTransfer =		0,
791         DAC960_V1_DCDB_DataTransferDeviceToSystem = 1,
792         DAC960_V1_DCDB_DataTransferSystemToDevice = 2,
793         DAC960_V1_DCDB_IllegalDataTransfer =	3
794       } __attribute__ ((packed)) Direction:2;		 /* Byte 1 Bits 0-1 */
795       boolean EarlyStatus:1;				 /* Byte 1 Bit 2 */
796       unsigned char :1;					 /* Byte 1 Bit 3 */
797       enum {
798         DAC960_V1_DCDB_Timeout_24_hours =		0,
799         DAC960_V1_DCDB_Timeout_10_seconds =		1,
800         DAC960_V1_DCDB_Timeout_60_seconds =		2,
801         DAC960_V1_DCDB_Timeout_10_minutes =		3
802       } __attribute__ ((packed)) Timeout:2;			 /* Byte 1 Bits 4-5 */
803       boolean NoAutomaticRequestSense:1;			 /* Byte 1 Bit 6 */
804       boolean DisconnectPermitted:1;			 /* Byte 1 Bit 7 */
805       unsigned short TransferLength;			 /* Bytes 2-3 */
806       DAC960_BusAddress32_T BusAddress;			 /* Bytes 4-7 */
807       unsigned char CDBLength:4;				 /* Byte 8 Bits 0-3 */
808       unsigned char TransferLengthHigh4:4;			 /* Byte 8 Bits 4-7 */
809       unsigned char SenseLength;				 /* Byte 9 */
810       unsigned char CDB[12];				 /* Bytes 10-21 */
811       unsigned char SenseData[64];				 /* Bytes 22-85 */
812       unsigned char Status;					 /* Byte 86 */
813       unsigned char :8;					 /* Byte 87 */
814     }
815     DAC960_V1_DCDB_T;
816     
817     
818     /*
819       Define the DAC960 V1 Firmware Scatter/Gather List Type 1 32 Bit Address
820       32 Bit Byte Count structure.
821     */
822     
823     typedef struct DAC960_V1_ScatterGatherSegment
824     {
825       DAC960_BusAddress32_T SegmentDataPointer;		/* Bytes 0-3 */
826       DAC960_ByteCount32_T SegmentByteCount;		/* Bytes 4-7 */
827     }
828     DAC960_V1_ScatterGatherSegment_T;
829     
830     
831     /*
832       Define the 13 Byte DAC960 V1 Firmware Command Mailbox structure.  Bytes 13-15
833       are not used.  The Command Mailbox structure is padded to 16 bytes for
834       efficient access.
835     */
836     
837     typedef union DAC960_V1_CommandMailbox
838     {
839       unsigned int Words[4];				/* Words 0-3 */
840       unsigned char Bytes[16];				/* Bytes 0-15 */
841       struct {
842         DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
843         DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
844         unsigned char Dummy[14];				/* Bytes 2-15 */
845       } __attribute__ ((packed)) Common;
846       struct {
847         DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
848         DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
849         unsigned char Dummy1[6];				/* Bytes 2-7 */
850         DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
851         unsigned char Dummy2[4];				/* Bytes 12-15 */
852       } __attribute__ ((packed)) Type3;
853       struct {
854         DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
855         DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
856         unsigned char Dummy1[5];				/* Bytes 2-6 */
857         unsigned char LogicalDriveNumber:6;			/* Byte 7 Bits 0-6 */
858         boolean AutoRestore:1;				/* Byte 7 Bit 7 */
859         unsigned char Dummy2[8];				/* Bytes 8-15 */
860       } __attribute__ ((packed)) Type3C;
861       struct {
862         DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
863         DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
864         unsigned char Channel;				/* Byte 2 */
865         unsigned char TargetID;				/* Byte 3 */
866         DAC960_V1_PhysicalDeviceState_T DeviceState:5;	/* Byte 4 Bits 0-4 */
867         unsigned char Modifier:3;				/* Byte 4 Bits 5-7 */
868         unsigned char Dummy1[3];				/* Bytes 5-7 */
869         DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
870         unsigned char Dummy2[4];				/* Bytes 12-15 */
871       } __attribute__ ((packed)) Type3D;
872       struct {
873         DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
874         DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
875         DAC960_V1_PerformEventLogOpType_T OperationType;	/* Byte 2 */
876         unsigned char OperationQualifier;			/* Byte 3 */
877         unsigned short SequenceNumber;			/* Bytes 4-5 */
878         unsigned char Dummy1[2];				/* Bytes 6-7 */
879         DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
880         unsigned char Dummy2[4];				/* Bytes 12-15 */
881       } __attribute__ ((packed)) Type3E;
882       struct {
883         DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
884         DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
885         unsigned char Dummy1[2];				/* Bytes 2-3 */
886         unsigned char RebuildRateConstant;			/* Byte 4 */
887         unsigned char Dummy2[3];				/* Bytes 5-7 */
888         DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
889         unsigned char Dummy3[4];				/* Bytes 12-15 */
890       } __attribute__ ((packed)) Type3R;
891       struct {
892         DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
893         DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
894         unsigned short TransferLength;			/* Bytes 2-3 */
895         unsigned int LogicalBlockAddress;			/* Bytes 4-7 */
896         DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
897         unsigned char LogicalDriveNumber;			/* Byte 12 */
898         unsigned char Dummy[3];				/* Bytes 13-15 */
899       } __attribute__ ((packed)) Type4;
900       struct {
901         DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
902         DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
903         struct {
904           unsigned short TransferLength:11;			/* Bytes 2-3 */
905           unsigned char LogicalDriveNumber:5;		/* Byte 3 Bits 3-7 */
906         } __attribute__ ((packed)) LD;
907         unsigned int LogicalBlockAddress;			/* Bytes 4-7 */
908         DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
909         unsigned char ScatterGatherCount:6;			/* Byte 12 Bits 0-5 */
910         enum {
911           DAC960_V1_ScatterGather_32BitAddress_32BitByteCount = 0x0,
912           DAC960_V1_ScatterGather_32BitAddress_16BitByteCount = 0x1,
913           DAC960_V1_ScatterGather_32BitByteCount_32BitAddress = 0x2,
914           DAC960_V1_ScatterGather_16BitByteCount_32BitAddress = 0x3
915         } __attribute__ ((packed)) ScatterGatherType:2;	/* Byte 12 Bits 6-7 */
916         unsigned char Dummy[3];				/* Bytes 13-15 */
917       } __attribute__ ((packed)) Type5;
918       struct {
919         DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
920         DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
921         unsigned char CommandOpcode2;			/* Byte 2 */
922         unsigned char :8;					/* Byte 3 */
923         DAC960_BusAddress32_T CommandMailboxesBusAddress;	/* Bytes 4-7 */
924         DAC960_BusAddress32_T StatusMailboxesBusAddress;	/* Bytes 8-11 */
925         unsigned char Dummy[4];				/* Bytes 12-15 */
926       } __attribute__ ((packed)) TypeX;
927     }
928     DAC960_V1_CommandMailbox_T;
929     
930     
931     /*
932       Define the DAC960 V2 Firmware Command Opcodes.
933     */
934     
935     typedef enum
936     {
937       DAC960_V2_MemCopy =				0x01,
938       DAC960_V2_SCSI_10_Passthru =			0x02,
939       DAC960_V2_SCSI_255_Passthru =			0x03,
940       DAC960_V2_SCSI_10 =				0x04,
941       DAC960_V2_SCSI_256 =				0x05,
942       DAC960_V2_IOCTL =				0x20
943     }
944     __attribute__ ((packed))
945     DAC960_V2_CommandOpcode_T;
946     
947     
948     /*
949       Define the DAC960 V2 Firmware IOCTL Opcodes.
950     */
951     
952     typedef enum
953     {
954       DAC960_V2_GetControllerInfo =			0x01,
955       DAC960_V2_GetLogicalDeviceInfoValid =		0x03,
956       DAC960_V2_GetPhysicalDeviceInfoValid =	0x05,
957       DAC960_V2_GetHealthStatus =			0x11,
958       DAC960_V2_GetEvent =				0x15,
959       DAC960_V2_SetDeviceState =			0x82,
960       DAC960_V2_RebuildDeviceStart =		0x88,
961       DAC960_V2_RebuildDeviceStop =			0x89,
962       DAC960_V2_ConsistencyCheckStart =		0x8C,
963       DAC960_V2_ConsistencyCheckStop =		0x8D,
964       DAC960_V2_SetMemoryMailbox =			0x8E,
965       DAC960_V2_PauseDevice =			0x92,
966       DAC960_V2_TranslatePhysicalToLogicalDevice =	0xC5
967     }
968     __attribute__ ((packed))
969     DAC960_V2_IOCTL_Opcode_T;
970     
971     
972     /*
973       Define the DAC960 V2 Firmware Command Identifier type.
974     */
975     
976     typedef unsigned short DAC960_V2_CommandIdentifier_T;
977     
978     
979     /*
980       Define the DAC960 V2 Firmware Command Status Codes.
981     */
982     
983     #define DAC960_V2_NormalCompletion		0x00
984     #define DAC960_V2_AbormalCompletion		0x02
985     #define DAC960_V2_DeviceNonresponsive		0x0E
986     
987     typedef unsigned char DAC960_V2_CommandStatus_T;
988     
989     
990     /*
991       Define the DAC960 V2 Firmware Memory Type structure.
992     */
993     
994     typedef struct DAC960_V2_MemoryType
995     {
996       enum {
997         DAC960_V2_MemoryType_Reserved =		0x00,
998         DAC960_V2_MemoryType_DRAM =			0x01,
999         DAC960_V2_MemoryType_EDRAM =		0x02,
1000         DAC960_V2_MemoryType_EDO =			0x03,
1001         DAC960_V2_MemoryType_SDRAM =		0x04,
1002         DAC960_V2_MemoryType_Last =			0x1F
1003       } __attribute__ ((packed)) MemoryType:5;		/* Byte 0 Bits 0-4 */
1004       boolean :1;						/* Byte 0 Bit 5 */
1005       boolean MemoryParity:1;				/* Byte 0 Bit 6 */
1006       boolean MemoryECC:1;					/* Byte 0 Bit 7 */
1007     }
1008     DAC960_V2_MemoryType_T;
1009     
1010     
1011     /*
1012       Define the DAC960 V2 Firmware Processor Type structure.
1013     */
1014     
1015     typedef enum
1016     {
1017       DAC960_V2_ProcessorType_i960CA =		0x01,
1018       DAC960_V2_ProcessorType_i960RD =		0x02,
1019       DAC960_V2_ProcessorType_i960RN =		0x03,
1020       DAC960_V2_ProcessorType_i960RP =		0x04,
1021       DAC960_V2_ProcessorType_NorthBay =		0x05,
1022       DAC960_V2_ProcessorType_StrongArm =		0x06,
1023       DAC960_V2_ProcessorType_i960RM =		0x07
1024     }
1025     __attribute__ ((packed))
1026     DAC960_V2_ProcessorType_T;
1027     
1028     
1029     /*
1030       Define the DAC960 V2 Firmware Get Controller Info reply structure.
1031     */
1032     
1033     typedef struct DAC960_V2_ControllerInfo
1034     {
1035       unsigned char :8;					/* Byte 0 */
1036       enum {
1037         DAC960_V2_SCSI_Bus =			0x00,
1038         DAC960_V2_Fibre_Bus =			0x01,
1039         DAC960_V2_PCI_Bus =				0x03
1040       } __attribute__ ((packed)) BusInterfaceType;		/* Byte 1 */
1041       enum {
1042         DAC960_V2_DAC960E =				0x01,
1043         DAC960_V2_DAC960M =				0x08,
1044         DAC960_V2_DAC960PD =			0x10,
1045         DAC960_V2_DAC960PL =			0x11,
1046         DAC960_V2_DAC960PU =			0x12,
1047         DAC960_V2_DAC960PE =			0x13,
1048         DAC960_V2_DAC960PG =			0x14,
1049         DAC960_V2_DAC960PJ =			0x15,
1050         DAC960_V2_DAC960PTL0 =			0x16,
1051         DAC960_V2_DAC960PR =			0x17,
1052         DAC960_V2_DAC960PRL =			0x18,
1053         DAC960_V2_DAC960PT =			0x19,
1054         DAC960_V2_DAC1164P =			0x1A,
1055         DAC960_V2_DAC960PTL1 =			0x1B,
1056         DAC960_V2_EXR2000P =			0x1C,
1057         DAC960_V2_EXR3000P =			0x1D,
1058         DAC960_V2_AcceleRAID352 =			0x1E,
1059         DAC960_V2_AcceleRAID351 =			0x1F,
1060         DAC960_V2_DAC960S =				0x60,
1061         DAC960_V2_DAC960SU =			0x61,
1062         DAC960_V2_DAC960SX =			0x62,
1063         DAC960_V2_DAC960SF =			0x63,
1064         DAC960_V2_DAC960SS =			0x64,
1065         DAC960_V2_DAC960FL =			0x65,
1066         DAC960_V2_DAC960LL =			0x66,
1067         DAC960_V2_DAC960FF =			0x67,
1068         DAC960_V2_DAC960HP =			0x68,
1069         DAC960_V2_RAIDBRICK =			0x69,
1070         DAC960_V2_METEOR_FL =			0x6A,
1071         DAC960_V2_METEOR_FF =			0x6B
1072       } __attribute__ ((packed)) ControllerType;		/* Byte 2 */
1073       unsigned char :8;					/* Byte 3 */
1074       unsigned short BusInterfaceSpeedMHz;			/* Bytes 4-5 */
1075       unsigned char BusWidthBits;				/* Byte 6 */
1076       unsigned char Reserved1[9];				/* Bytes 7-15 */
1077       unsigned char BusInterfaceName[16];			/* Bytes 16-31 */
1078       unsigned char ControllerName[16];			/* Bytes 32-47 */
1079       unsigned char Reserved2[16];				/* Bytes 48-63 */
1080       /* Firmware Release Information */
1081       unsigned char FirmwareMajorVersion;			/* Byte 64 */
1082       unsigned char FirmwareMinorVersion;			/* Byte 65 */
1083       unsigned char FirmwareTurnNumber;			/* Byte 66 */
1084       unsigned char FirmwareBuildNumber;			/* Byte 67 */
1085       unsigned char FirmwareReleaseDay;			/* Byte 68 */
1086       unsigned char FirmwareReleaseMonth;			/* Byte 69 */
1087       unsigned char FirmwareReleaseYearHigh2Digits;		/* Byte 70 */
1088       unsigned char FirmwareReleaseYearLow2Digits;		/* Byte 71 */
1089       /* Hardware Release Information */
1090       unsigned char HardwareRevision;			/* Byte 72 */
1091       unsigned int :24;					/* Bytes 73-75 */
1092       unsigned char HardwareReleaseDay;			/* Byte 76 */
1093       unsigned char HardwareReleaseMonth;			/* Byte 77 */
1094       unsigned char HardwareReleaseYearHigh2Digits;		/* Byte 78 */
1095       unsigned char HardwareReleaseYearLow2Digits;		/* Byte 79 */
1096       /* Hardware Manufacturing Information */
1097       unsigned char ManufacturingBatchNumber;		/* Byte 80 */
1098       unsigned char :8;					/* Byte 81 */
1099       unsigned char ManufacturingPlantNumber;		/* Byte 82 */
1100       unsigned char :8;					/* Byte 83 */
1101       unsigned char HardwareManufacturingDay;		/* Byte 84 */
1102       unsigned char HardwareManufacturingMonth;		/* Byte 85 */
1103       unsigned char HardwareManufacturingYearHigh2Digits;	/* Byte 86 */
1104       unsigned char HardwareManufacturingYearLow2Digits;	/* Byte 87 */
1105       unsigned char MaximumNumberOfPDDperXLDD;		/* Byte 88 */
1106       unsigned char MaximumNumberOfILDDperXLDD;		/* Byte 89 */
1107       unsigned short NonvolatileMemorySizeKB;		/* Bytes 90-91 */
1108       unsigned char MaximumNumberOfXLDD;			/* Byte 92 */
1109       unsigned int :24;					/* Bytes 93-95 */
1110       /* Unique Information per Controller */
1111       unsigned char ControllerSerialNumber[16];		/* Bytes 96-111 */
1112       unsigned char Reserved3[16];				/* Bytes 112-127 */
1113       /* Vendor Information */
1114       unsigned int :24;					/* Bytes 128-130 */
1115       unsigned char OEM_Information;			/* Byte 131 */
1116       unsigned char VendorName[16];				/* Bytes 132-147 */
1117       /* Other Physical/Controller/Operation Information */
1118       boolean BBU_Present:1;				/* Byte 148 Bit 0 */
1119       boolean ActiveActiveClusteringMode:1;			/* Byte 148 Bit 1 */
1120       unsigned char :6;					/* Byte 148 Bits 2-7 */
1121       unsigned char :8;					/* Byte 149 */
1122       unsigned short :16;					/* Bytes 150-151 */
1123       /* Physical Device Scan Information */
1124       boolean PhysicalScanActive:1;				/* Byte 152 Bit 0 */
1125       unsigned char :7;					/* Byte 152 Bits 1-7 */
1126       unsigned char PhysicalDeviceChannelNumber;		/* Byte 153 */
1127       unsigned char PhysicalDeviceTargetID;			/* Byte 154 */
1128       unsigned char PhysicalDeviceLogicalUnit;		/* Byte 155 */
1129       /* Maximum Command Data Transfer Sizes */
1130       unsigned short MaximumDataTransferSizeInBlocks;	/* Bytes 156-157 */
1131       unsigned short MaximumScatterGatherEntries;		/* Bytes 158-159 */
1132       /* Logical/Physical Device Counts */
1133       unsigned short LogicalDevicesPresent;			/* Bytes 160-161 */
1134       unsigned short LogicalDevicesCritical;		/* Bytes 162-163 */
1135       unsigned short LogicalDevicesOffline;			/* Bytes 164-165 */
1136       unsigned short PhysicalDevicesPresent;		/* Bytes 166-167 */
1137       unsigned short PhysicalDisksPresent;			/* Bytes 168-169 */
1138       unsigned short PhysicalDisksCritical;			/* Bytes 170-171 */
1139       unsigned short PhysicalDisksOffline;			/* Bytes 172-173 */
1140       unsigned short MaximumParallelCommands;		/* Bytes 174-175 */
1141       /* Channel and Target ID Information */
1142       unsigned char NumberOfPhysicalChannelsPresent;	/* Byte 176 */
1143       unsigned char NumberOfVirtualChannelsPresent;		/* Byte 177 */
1144       unsigned char NumberOfPhysicalChannelsPossible;	/* Byte 178 */
1145       unsigned char NumberOfVirtualChannelsPossible;	/* Byte 179 */
1146       unsigned char MaximumTargetsPerChannel[16];		/* Bytes 180-195 */
1147       unsigned char Reserved4[12];				/* Bytes 196-207 */
1148       /* Memory/Cache Information */
1149       unsigned short MemorySizeMB;				/* Bytes 208-209 */
1150       unsigned short CacheSizeMB;				/* Bytes 210-211 */
1151       unsigned int ValidCacheSizeInBytes;			/* Bytes 212-215 */
1152       unsigned int DirtyCacheSizeInBytes;			/* Bytes 216-219 */
1153       unsigned short MemorySpeedMHz;			/* Bytes 220-221 */
1154       unsigned char MemoryDataWidthBits;			/* Byte 222 */
1155       DAC960_V2_MemoryType_T MemoryType;			/* Byte 223 */
1156       unsigned char CacheMemoryTypeName[16];		/* Bytes 224-239 */
1157       /* Execution Memory Information */
1158       unsigned short ExecutionMemorySizeMB;			/* Bytes 240-241 */
1159       unsigned short ExecutionL2CacheSizeMB;		/* Bytes 242-243 */
1160       unsigned char Reserved5[8];				/* Bytes 244-251 */
1161       unsigned short ExecutionMemorySpeedMHz;		/* Bytes 252-253 */
1162       unsigned char ExecutionMemoryDataWidthBits;		/* Byte 254 */
1163       DAC960_V2_MemoryType_T ExecutionMemoryType;		/* Byte 255 */
1164       unsigned char ExecutionMemoryTypeName[16];		/* Bytes 256-271 */
1165       /* First CPU Type Information */
1166       unsigned short FirstProcessorSpeedMHz;		/* Bytes 272-273 */
1167       DAC960_V2_ProcessorType_T FirstProcessorType;		/* Byte 274 */
1168       unsigned char FirstProcessorCount;			/* Byte 275 */
1169       unsigned char Reserved6[12];				/* Bytes 276-287 */
1170       unsigned char FirstProcessorName[16];			/* Bytes 288-303 */
1171       /* Second CPU Type Information */
1172       unsigned short SecondProcessorSpeedMHz;		/* Bytes 304-305 */
1173       DAC960_V2_ProcessorType_T SecondProcessorType;	/* Byte 306 */
1174       unsigned char SecondProcessorCount;			/* Byte 307 */
1175       unsigned char Reserved7[12];				/* Bytes 308-319 */
1176       unsigned char SecondProcessorName[16];		/* Bytes 320-335 */
1177       /* Debugging/Profiling/Command Time Tracing Information */
1178       unsigned short CurrentProfilingDataPageNumber;	/* Bytes 336-337 */
1179       unsigned short ProgramsAwaitingProfilingData;		/* Bytes 338-339 */
1180       unsigned short CurrentCommandTimeTraceDataPageNumber;	/* Bytes 340-341 */
1181       unsigned short ProgramsAwaitingCommandTimeTraceData;	/* Bytes 342-343 */
1182       unsigned char Reserved8[8];				/* Bytes 344-351 */
1183       /* Error Counters on Physical Devices */
1184       unsigned short PhysicalDeviceBusResets;		/* Bytes 352-353 */
1185       unsigned short PhysicalDeviceParityErrors;		/* Bytes 355-355 */
1186       unsigned short PhysicalDeviceSoftErrors;		/* Bytes 356-357 */
1187       unsigned short PhysicalDeviceCommandsFailed;		/* Bytes 358-359 */
1188       unsigned short PhysicalDeviceMiscellaneousErrors;	/* Bytes 360-361 */
1189       unsigned short PhysicalDeviceCommandTimeouts;		/* Bytes 362-363 */
1190       unsigned short PhysicalDeviceSelectionTimeouts;	/* Bytes 364-365 */
1191       unsigned short PhysicalDeviceRetriesDone;		/* Bytes 366-367 */
1192       unsigned short PhysicalDeviceAbortsDone;		/* Bytes 368-369 */
1193       unsigned short PhysicalDeviceHostCommandAbortsDone;	/* Bytes 370-371 */
1194       unsigned short PhysicalDevicePredictedFailuresDetected; /* Bytes 372-373 */
1195       unsigned short PhysicalDeviceHostCommandsFailed;	/* Bytes 374-375 */
1196       unsigned char Reserved9[8];				/* Bytes 376-383 */
1197       /* Error Counters on Logical Devices */
1198       unsigned short LogicalDeviceSoftErrors;		/* Bytes 384-385 */
1199       unsigned short LogicalDeviceCommandsFailed;		/* Bytes 386-387 */
1200       unsigned short LogicalDeviceHostCommandAbortsDone;	/* Bytes 388-389 */
1201       unsigned short :16;					/* Bytes 390-391 */
1202       unsigned short ControllerMemoryErrors;		/* Bytes 392-393 */
1203       unsigned short ControllerHostCommandAbortsDone;	/* Bytes 394-395 */
1204       unsigned int :32;					/* Bytes 396-399 */
1205       /* Long Duration Activity Information */
1206       unsigned short BackgroundInitializationsActive;	/* Bytes 400-401 */
1207       unsigned short LogicalDeviceInitializationsActive;	/* Bytes 402-403 */
1208       unsigned short PhysicalDeviceInitializationsActive;	/* Bytes 404-405 */
1209       unsigned short ConsistencyChecksActive;		/* Bytes 406-407 */
1210       unsigned short RebuildsActive;			/* Bytes 408-409 */
1211       unsigned short OnlineExpansionsActive;		/* Bytes 410-411 */
1212       unsigned short PatrolActivitiesActive;		/* Bytes 412-413 */
1213       unsigned char LongOperationStatus;			/* Byte 414 */
1214       unsigned char :8;					/* Byte 415 */
1215       /* Flash ROM Information */
1216       unsigned char FlashType;				/* Byte 416 */
1217       unsigned char :8;					/* Byte 417 */
1218       unsigned short FlashSizeMB;				/* Bytes 418-419 */
1219       unsigned int FlashLimit;				/* Bytes 420-423 */
1220       unsigned int FlashCount;				/* Bytes 424-427 */
1221       unsigned int :32;					/* Bytes 428-431 */
1222       unsigned char FlashTypeName[16];			/* Bytes 432-447 */
1223       /* Firmware Run Time Information */
1224       unsigned char RebuildRate;				/* Byte 448 */
1225       unsigned char BackgroundInitializationRate;		/* Byte 449 */
1226       unsigned char ForegroundInitializationRate;		/* Byte 450 */
1227       unsigned char ConsistencyCheckRate;			/* Byte 451 */
1228       unsigned int :32;					/* Bytes 452-455 */
1229       unsigned int MaximumDP;				/* Bytes 456-459 */
1230       unsigned int FreeDP;					/* Bytes 460-463 */
1231       unsigned int MaximumIOP;				/* Bytes 464-467 */
1232       unsigned int FreeIOP;					/* Bytes 468-471 */
1233       unsigned short MaximumCombLengthInBlocks;		/* Bytes 472-473 */
1234       unsigned short NumberOfConfigurationGroups;		/* Bytes 474-475 */
1235       boolean InstallationAbortStatus:1;			/* Byte 476 Bit 0 */
1236       boolean MaintenanceModeStatus:1;			/* Byte 476 Bit 1 */
1237       unsigned int :6;					/* Byte 476 Bits 2-7 */
1238       unsigned int :24;					/* Bytes 477-479 */
1239       unsigned char Reserved10[32];				/* Bytes 480-511 */
1240       unsigned char Reserved11[512];			/* Bytes 512-1023 */
1241     }
1242     DAC960_V2_ControllerInfo_T;
1243     
1244     
1245     /*
1246       Define the DAC960 V2 Firmware Logical Device State type.
1247     */
1248     
1249     typedef enum
1250     {
1251       DAC960_V2_LogicalDevice_Online =		0x01,
1252       DAC960_V2_LogicalDevice_Offline =		0x08,
1253       DAC960_V2_LogicalDevice_Critical =		0x09
1254     }
1255     __attribute__ ((packed))
1256     DAC960_V2_LogicalDeviceState_T;
1257     
1258     
1259     /*
1260       Define the DAC960 V2 Firmware Get Logical Device Info reply structure.
1261     */
1262     
1263     typedef struct DAC960_V2_LogicalDeviceInfo
1264     {
1265       unsigned char :8;					/* Byte 0 */
1266       unsigned char Channel;				/* Byte 1 */
1267       unsigned char TargetID;				/* Byte 2 */
1268       unsigned char LogicalUnit;				/* Byte 3 */
1269       DAC960_V2_LogicalDeviceState_T LogicalDeviceState;	/* Byte 4 */
1270       unsigned char RAIDLevel;				/* Byte 5 */
1271       unsigned char StripeSize;				/* Byte 6 */
1272       unsigned char CacheLineSize;				/* Byte 7 */
1273       struct {
1274         enum {
1275           DAC960_V2_ReadCacheDisabled =		0x0,
1276           DAC960_V2_ReadCacheEnabled =		0x1,
1277           DAC960_V2_ReadAheadEnabled =		0x2,
1278           DAC960_V2_IntelligentReadAheadEnabled =	0x3,
1279           DAC960_V2_ReadCache_Last =		0x7
1280         } __attribute__ ((packed)) ReadCache:3;		/* Byte 8 Bits 0-2 */
1281         enum {
1282           DAC960_V2_WriteCacheDisabled =		0x0,
1283           DAC960_V2_LogicalDeviceReadOnly =		0x1,
1284           DAC960_V2_WriteCacheEnabled =		0x2,
1285           DAC960_V2_IntelligentWriteCacheEnabled =	0x3,
1286           DAC960_V2_WriteCache_Last =		0x7
1287         } __attribute__ ((packed)) WriteCache:3;		/* Byte 8 Bits 3-5 */
1288         boolean :1;						/* Byte 8 Bit 6 */
1289         boolean LogicalDeviceInitialized:1;			/* Byte 8 Bit 7 */
1290       } LogicalDeviceControl;				/* Byte 8 */
1291       /* Logical Device Operations Status */
1292       boolean ConsistencyCheckInProgress:1;			/* Byte 9 Bit 0 */
1293       boolean RebuildInProgress:1;				/* Byte 9 Bit 1 */
1294       boolean BackgroundInitializationInProgress:1;		/* Byte 9 Bit 2 */
1295       boolean ForegroundInitializationInProgress:1;		/* Byte 9 Bit 3 */
1296       boolean DataMigrationInProgress:1;			/* Byte 9 Bit 4 */
1297       boolean PatrolOperationInProgress:1;			/* Byte 9 Bit 5 */
1298       unsigned char :2;					/* Byte 9 Bits 6-7 */
1299       unsigned char RAID5WriteUpdate;			/* Byte 10 */
1300       unsigned char RAID5Algorithm;				/* Byte 11 */
1301       unsigned short LogicalDeviceNumber;			/* Bytes 12-13 */
1302       /* BIOS Info */
1303       boolean BIOSDisabled:1;				/* Byte 14 Bit 0 */
1304       boolean CDROMBootEnabled:1;				/* Byte 14 Bit 1 */
1305       boolean DriveCoercionEnabled:1;			/* Byte 14 Bit 2 */
1306       boolean WriteSameDisabled:1;				/* Byte 14 Bit 3 */
1307       boolean HBA_ModeEnabled:1;				/* Byte 14 Bit 4 */
1308       enum {
1309         DAC960_V2_Geometry_128_32 =			0x0,
1310         DAC960_V2_Geometry_255_63 =			0x1,
1311         DAC960_V2_Geometry_Reserved1 =		0x2,
1312         DAC960_V2_Geometry_Reserved2 =		0x3
1313       } __attribute__ ((packed)) DriveGeometry:2;		/* Byte 14 Bits 5-6 */
1314       unsigned char :1;					/* Byte 14 Bit 7 */
1315       unsigned char :8;					/* Byte 15 */
1316       /* Error Counters */
1317       unsigned short SoftErrors;				/* Bytes 16-17 */
1318       unsigned short CommandsFailed;			/* Bytes 18-19 */
1319       unsigned short HostCommandAbortsDone;			/* Bytes 20-21 */
1320       unsigned short DeferredWriteErrors;			/* Bytes 22-23 */
1321       unsigned int :32;					/* Bytes 24-27 */
1322       unsigned int :32;					/* Bytes 28-31 */
1323       /* Device Size Information */
1324       unsigned short :16;					/* Bytes 32-33 */
1325       unsigned short DeviceBlockSizeInBytes;		/* Bytes 34-35 */
1326       unsigned int OriginalDeviceSizeIn512ByteBlocksOrMB;	/* Bytes 36-39 */
1327       unsigned int ConfigurableDeviceSizeIn512ByteBlocksOrMB; /* Bytes 40-43 */
1328       unsigned int :32;					/* Bytes 44-47 */
1329       unsigned char LogicalDeviceName[32];			/* Bytes 48-79 */
1330       unsigned char SCSI_InquiryData[36];			/* Bytes 80-115 */
1331       unsigned char Reserved1[12];				/* Bytes 116-127 */
1332       DAC960_ByteCount64_T LastReadBlockNumber;		/* Bytes 128-135 */
1333       DAC960_ByteCount64_T LastWrittenBlockNumber;		/* Bytes 136-143 */
1334       DAC960_ByteCount64_T ConsistencyCheckBlockNumber;	/* Bytes 144-151 */
1335       DAC960_ByteCount64_T RebuildBlockNumber;		/* Bytes 152-159 */
1336       DAC960_ByteCount64_T BackgroundInitializationBlockNumber; /* Bytes 160-167 */
1337       DAC960_ByteCount64_T ForegroundInitializationBlockNumber; /* Bytes 168-175 */
1338       DAC960_ByteCount64_T DataMigrationBlockNumber;	/* Bytes 176-183 */
1339       DAC960_ByteCount64_T PatrolOperationBlockNumber;	/* Bytes 184-191 */
1340       unsigned char Reserved2[64];				/* Bytes 192-255 */
1341     }
1342     DAC960_V2_LogicalDeviceInfo_T;
1343     
1344     
1345     /*
1346       Define the DAC960 V2 Firmware Physical Device State type.
1347     */
1348     
1349     typedef enum
1350     {
1351         DAC960_V2_Device_Unconfigured =		0x00,
1352         DAC960_V2_Device_Online =			0x01,
1353         DAC960_V2_Device_WriteOnly =		0x03,
1354         DAC960_V2_Device_Dead =			0x08,
1355         DAC960_V2_Device_Standby =			0x21,
1356         DAC960_V2_Device_InvalidState =		0xFF
1357     }
1358     __attribute__ ((packed))
1359     DAC960_V2_PhysicalDeviceState_T;
1360     
1361     
1362     /*
1363       Define the DAC960 V2 Firmware Get Physical Device Info reply structure.
1364     */
1365     
1366     typedef struct DAC960_V2_PhysicalDeviceInfo
1367     {
1368       unsigned char :8;					/* Byte 0 */
1369       unsigned char Channel;				/* Byte 1 */
1370       unsigned char TargetID;				/* Byte 2 */
1371       unsigned char LogicalUnit;				/* Byte 3 */
1372       /* Configuration Status Bits */
1373       boolean PhysicalDeviceFaultTolerant:1;		/* Byte 4 Bit 0 */
1374       boolean :1;						/* Byte 4 Bit 1 */
1375       boolean PhysicalDeviceLocalToController:1;		/* Byte 4 Bit 2 */
1376       unsigned char :5;					/* Byte 4 Bits 3-7 */
1377       /* Multiple Host/Controller Status Bits */
1378       boolean RemoteHostSystemDead:1;			/* Byte 5 Bit 0 */
1379       boolean RemoteControllerDead:1;			/* Byte 5 Bit 1 */
1380       unsigned char :6;					/* Byte 5 Bits 2-7 */
1381       DAC960_V2_PhysicalDeviceState_T PhysicalDeviceState;	/* Byte 6 */
1382       unsigned char NegotiatedDataWidthBits;		/* Byte 7 */
1383       unsigned short NegotiatedSynchronousMegaTransfers;	/* Bytes 8-9 */
1384       /* Multiported Physical Device Information */
1385       unsigned char NumberOfPortConnections;		/* Byte 10 */
1386       unsigned char DriveAccessibilityBitmap;		/* Byte 11 */
1387       unsigned int :32;					/* Bytes 12-15 */
1388       unsigned char NetworkAddress[16];			/* Bytes 16-31 */
1389       unsigned short MaximumTags;				/* Bytes 32-33 */
1390       /* Physical Device Operations Status */
1391       boolean ConsistencyCheckInProgress:1;			/* Byte 34 Bit 0 */
1392       boolean RebuildInProgress:1;				/* Byte 34 Bit 1 */
1393       boolean MakingDataConsistentInProgress:1;		/* Byte 34 Bit 2 */
1394       boolean PhysicalDeviceInitializationInProgress:1;	/* Byte 34 Bit 3 */
1395       boolean DataMigrationInProgress:1;			/* Byte 34 Bit 4 */
1396       boolean PatrolOperationInProgress:1;			/* Byte 34 Bit 5 */
1397       unsigned char :2;					/* Byte 34 Bits 6-7 */
1398       unsigned char LongOperationStatus;			/* Byte 35 */
1399       unsigned char ParityErrors;				/* Byte 36 */
1400       unsigned char SoftErrors;				/* Byte 37 */
1401       unsigned char HardErrors;				/* Byte 38 */
1402       unsigned char MiscellaneousErrors;			/* Byte 39 */
1403       unsigned char CommandTimeouts;			/* Byte 40 */
1404       unsigned char Retries;				/* Byte 41 */
1405       unsigned char Aborts;					/* Byte 42 */
1406       unsigned char PredictedFailuresDetected;		/* Byte 43 */
1407       unsigned int :32;					/* Bytes 44-47 */
1408       unsigned short :16;					/* Bytes 48-49 */
1409       unsigned short DeviceBlockSizeInBytes;		/* Bytes 50-51 */
1410       unsigned int OriginalDeviceSizeIn512ByteBlocksOrMB;	/* Bytes 52-55 */
1411       unsigned int ConfigurableDeviceSizeIn512ByteBlocksOrMB; /* Bytes 56-59 */
1412       unsigned int :32;					/* Bytes 60-63 */
1413       unsigned char PhysicalDeviceName[16];			/* Bytes 64-79 */
1414       unsigned char Reserved1[16];				/* Bytes 80-95 */
1415       unsigned char Reserved2[32];				/* Bytes 96-127 */
1416       unsigned char SCSI_InquiryData[36];			/* Bytes 128-163 */
1417       unsigned char Reserved3[12];				/* Bytes 164-175 */
1418       unsigned char Reserved4[16];				/* Bytes 176-191 */
1419       DAC960_ByteCount64_T LastReadBlockNumber;		/* Bytes 192-199 */
1420       DAC960_ByteCount64_T LastWrittenBlockNumber;		/* Bytes 200-207 */
1421       DAC960_ByteCount64_T ConsistencyCheckBlockNumber;	/* Bytes 208-215 */
1422       DAC960_ByteCount64_T RebuildBlockNumber;		/* Bytes 216-223 */
1423       DAC960_ByteCount64_T MakingDataConsistentBlockNumber;	/* Bytes 224-231 */
1424       DAC960_ByteCount64_T DeviceInitializationBlockNumber; /* Bytes 232-239 */
1425       DAC960_ByteCount64_T DataMigrationBlockNumber;	/* Bytes 240-247 */
1426       DAC960_ByteCount64_T PatrolOperationBlockNumber;	/* Bytes 248-255 */
1427       unsigned char Reserved5[256];				/* Bytes 256-511 */
1428     }
1429     DAC960_V2_PhysicalDeviceInfo_T;
1430     
1431     
1432     /*
1433       Define the DAC960 V2 Firmware Health Status Buffer structure.
1434     */
1435     
1436     typedef struct DAC960_V2_HealthStatusBuffer
1437     {
1438       unsigned int MicrosecondsFromControllerStartTime;	/* Bytes 0-3 */
1439       unsigned int MillisecondsFromControllerStartTime;	/* Bytes 4-7 */
1440       unsigned int SecondsFrom1January1970;			/* Bytes 8-11 */
1441       unsigned int :32;					/* Bytes 12-15 */
1442       unsigned int StatusChangeCounter;			/* Bytes 16-19 */
1443       unsigned int :32;					/* Bytes 20-23 */
1444       unsigned int DebugOutputMessageBufferIndex;		/* Bytes 24-27 */
1445       unsigned int CodedMessageBufferIndex;			/* Bytes 28-31 */
1446       unsigned int CurrentTimeTracePageNumber;		/* Bytes 32-35 */
1447       unsigned int CurrentProfilerPageNumber;		/* Bytes 36-39 */
1448       unsigned int NextEventSequenceNumber;			/* Bytes 40-43 */
1449       unsigned int :32;					/* Bytes 44-47 */
1450       unsigned char Reserved1[16];				/* Bytes 48-63 */
1451       unsigned char Reserved2[64];				/* Bytes 64-127 */
1452     }
1453     DAC960_V2_HealthStatusBuffer_T;
1454     
1455     
1456     /*
1457       Define the DAC960 V2 Firmware Get Event reply structure.
1458     */
1459     
1460     typedef struct DAC960_V2_Event
1461     {
1462       unsigned int EventSequenceNumber;			/* Bytes 0-3 */
1463       unsigned int EventTime;				/* Bytes 4-7 */
1464       unsigned int EventCode;				/* Bytes 8-11 */
1465       unsigned char :8;					/* Byte 12 */
1466       unsigned char Channel;				/* Byte 13 */
1467       unsigned char TargetID;				/* Byte 14 */
1468       unsigned char LogicalUnit;				/* Byte 15 */
1469       unsigned int :32;					/* Bytes 16-19 */
1470       unsigned int EventSpecificParameter;			/* Bytes 20-23 */
1471       unsigned char RequestSenseData[40];			/* Bytes 24-63 */
1472     }
1473     DAC960_V2_Event_T;
1474     
1475     
1476     /*
1477       Define the DAC960 V2 Firmware Command Control Bits structure.
1478     */
1479     
1480     typedef struct DAC960_V2_CommandControlBits
1481     {
1482       boolean ForceUnitAccess:1;				/* Byte 0 Bit 0 */
1483       boolean DisablePageOut:1;				/* Byte 0 Bit 1 */
1484       boolean :1;						/* Byte 0 Bit 2 */
1485       boolean AdditionalScatterGatherListMemory:1;		/* Byte 0 Bit 3 */
1486       boolean DataTransferControllerToHost:1;		/* Byte 0 Bit 4 */
1487       boolean :1;						/* Byte 0 Bit 5 */
1488       boolean NoAutoRequestSense:1;				/* Byte 0 Bit 6 */
1489       boolean DisconnectProhibited:1;			/* Byte 0 Bit 7 */
1490     }
1491     DAC960_V2_CommandControlBits_T;
1492     
1493     
1494     /*
1495       Define the DAC960 V2 Firmware Command Timeout structure.
1496     */
1497     
1498     typedef struct DAC960_V2_CommandTimeout
1499     {
1500       unsigned char TimeoutValue:6;				/* Byte 0 Bits 0-5 */
1501       enum {
1502         DAC960_V2_TimeoutScale_Seconds =		0,
1503         DAC960_V2_TimeoutScale_Minutes =		1,
1504         DAC960_V2_TimeoutScale_Hours =		2,
1505         DAC960_V2_TimeoutScale_Reserved =		3
1506       } __attribute__ ((packed)) TimeoutScale:2;		/* Byte 0 Bits 6-7 */
1507     }
1508     DAC960_V2_CommandTimeout_T;
1509     
1510     
1511     /*
1512       Define the DAC960 V2 Firmware Physical Device structure.
1513     */
1514     
1515     typedef struct DAC960_V2_PhysicalDevice
1516     {
1517       unsigned char LogicalUnit;				/* Byte 0 */
1518       unsigned char TargetID;				/* Byte 1 */
1519       unsigned char Channel:3;				/* Byte 2 Bits 0-2 */
1520       unsigned char Controller:5;				/* Byte 2 Bits 3-7 */
1521     }
1522     __attribute__ ((packed))
1523     DAC960_V2_PhysicalDevice_T;
1524     
1525     
1526     /*
1527       Define the DAC960 V2 Firmware Logical Device structure.
1528     */
1529     
1530     typedef struct DAC960_V2_LogicalDevice
1531     {
1532       unsigned short LogicalDeviceNumber;			/* Bytes 0-1 */
1533       unsigned char :3;					/* Byte 2 Bits 0-2 */
1534       unsigned char Controller:5;				/* Byte 2 Bits 3-7 */
1535     }
1536     __attribute__ ((packed))
1537     DAC960_V2_LogicalDevice_T;
1538     
1539     
1540     /*
1541       Define the DAC960 V2 Firmware Operation Device type.
1542     */
1543     
1544     typedef enum
1545     {
1546       DAC960_V2_Physical_Device =			0x00,
1547       DAC960_V2_RAID_Device =			0x01,
1548       DAC960_V2_Physical_Channel =			0x02,
1549       DAC960_V2_RAID_Channel =			0x03,
1550       DAC960_V2_Physical_Controller =		0x04,
1551       DAC960_V2_RAID_Controller =			0x05,
1552       DAC960_V2_Configuration_Group =		0x10
1553     }
1554     __attribute__ ((packed))
1555     DAC960_V2_OperationDevice_T;
1556     
1557     
1558     /*
1559       Define the DAC960 V2 Firmware Translate Physical To Logical Device structure.
1560     */
1561     
1562     typedef struct DAC960_V2_PhysicalToLogicalDevice
1563     {
1564       unsigned short LogicalDeviceNumber;			/* Bytes 0-1 */
1565       unsigned short :16;					/* Bytes 2-3 */
1566       unsigned char PreviousBootController;			/* Byte 4 */
1567       unsigned char PreviousBootChannel;			/* Byte 5 */
1568       unsigned char PreviousBootTargetID;			/* Byte 6 */
1569       unsigned char PreviousBootLogicalUnit;		/* Byte 7 */
1570     }
1571     DAC960_V2_PhysicalToLogicalDevice_T;
1572     
1573     
1574     
1575     /*
1576       Define the DAC960 V2 Firmware Scatter/Gather List Entry structure.
1577     */
1578     
1579     typedef struct DAC960_V2_ScatterGatherSegment
1580     {
1581       DAC960_BusAddress64_T SegmentDataPointer;		/* Bytes 0-7 */
1582       DAC960_ByteCount64_T SegmentByteCount;		/* Bytes 8-15 */
1583     }
1584     DAC960_V2_ScatterGatherSegment_T;
1585     
1586     
1587     /*
1588       Define the DAC960 V2 Firmware Data Transfer Memory Address structure.
1589     */
1590     
1591     typedef union DAC960_V2_DataTransferMemoryAddress
1592     {
1593       DAC960_V2_ScatterGatherSegment_T ScatterGatherSegments[2]; /* Bytes 0-31 */
1594       struct {
1595         unsigned short ScatterGatherList0Length;		/* Bytes 0-1 */
1596         unsigned short ScatterGatherList1Length;		/* Bytes 2-3 */
1597         unsigned short ScatterGatherList2Length;		/* Bytes 4-5 */
1598         unsigned short :16;					/* Bytes 6-7 */
1599         DAC960_BusAddress64_T ScatterGatherList0Address;	/* Bytes 8-15 */
1600         DAC960_BusAddress64_T ScatterGatherList1Address;	/* Bytes 16-23 */
1601         DAC960_BusAddress64_T ScatterGatherList2Address;	/* Bytes 24-31 */
1602       } ExtendedScatterGather;
1603     }
1604     DAC960_V2_DataTransferMemoryAddress_T;
1605     
1606     
1607     /*
1608       Define the 64 Byte DAC960 V2 Firmware Command Mailbox structure.
1609     */
1610     
1611     typedef union DAC960_V2_CommandMailbox
1612     {
1613       unsigned int Words[16];				/* Words 0-15 */
1614       struct {
1615         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1616         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1617         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1618         DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
1619         unsigned char DataTransferPageNumber;		/* Byte 7 */
1620         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1621         unsigned int :24;					/* Bytes 16-18 */
1622         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1623         unsigned char RequestSenseSize;			/* Byte 20 */
1624         unsigned char IOCTL_Opcode;				/* Byte 21 */
1625         unsigned char Reserved[10];				/* Bytes 22-31 */
1626         DAC960_V2_DataTransferMemoryAddress_T
1627           DataTransferMemoryAddress;			/* Bytes 32-63 */
1628       } Common;
1629       struct {
1630         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1631         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1632         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1633         DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
1634         unsigned char DataTransferPageNumber;		/* Byte 7 */
1635         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1636         DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
1637         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1638         unsigned char RequestSenseSize;			/* Byte 20 */
1639         unsigned char CDBLength;				/* Byte 21 */
1640         unsigned char SCSI_CDB[10];				/* Bytes 22-31 */
1641         DAC960_V2_DataTransferMemoryAddress_T
1642           DataTransferMemoryAddress;			/* Bytes 32-63 */
1643       } SCSI_10;
1644       struct {
1645         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1646         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1647         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1648         DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
1649         unsigned char DataTransferPageNumber;		/* Byte 7 */
1650         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1651         DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
1652         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1653         unsigned char RequestSenseSize;			/* Byte 20 */
1654         unsigned char CDBLength;				/* Byte 21 */
1655         unsigned short :16;					/* Bytes 22-23 */
1656         DAC960_BusAddress64_T SCSI_CDB_BusAddress;		/* Bytes 24-31 */
1657         DAC960_V2_DataTransferMemoryAddress_T
1658           DataTransferMemoryAddress;			/* Bytes 32-63 */
1659       } SCSI_255;
1660       struct {
1661         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1662         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1663         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1664         DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
1665         unsigned char DataTransferPageNumber;		/* Byte 7 */
1666         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1667         unsigned short :16;					/* Bytes 16-17 */
1668         unsigned char ControllerNumber;			/* Byte 18 */
1669         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1670         unsigned char RequestSenseSize;			/* Byte 20 */
1671         unsigned char IOCTL_Opcode;				/* Byte 21 */
1672         unsigned char Reserved[10];				/* Bytes 22-31 */
1673         DAC960_V2_DataTransferMemoryAddress_T
1674           DataTransferMemoryAddress;			/* Bytes 32-63 */
1675       } ControllerInfo;
1676       struct {
1677         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1678         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1679         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1680         DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
1681         unsigned char DataTransferPageNumber;		/* Byte 7 */
1682         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1683         DAC960_V2_LogicalDevice_T LogicalDevice;		/* Bytes 16-18 */
1684         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1685         unsigned char RequestSenseSize;			/* Byte 20 */
1686         unsigned char IOCTL_Opcode;				/* Byte 21 */
1687         unsigned char Reserved[10];				/* Bytes 22-31 */
1688         DAC960_V2_DataTransferMemoryAddress_T
1689           DataTransferMemoryAddress;			/* Bytes 32-63 */
1690       } LogicalDeviceInfo;
1691       struct {
1692         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1693         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1694         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1695         DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
1696         unsigned char DataTransferPageNumber;		/* Byte 7 */
1697         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1698         DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
1699         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1700         unsigned char RequestSenseSize;			/* Byte 20 */
1701         unsigned char IOCTL_Opcode;				/* Byte 21 */
1702         unsigned char Reserved[10];				/* Bytes 22-31 */
1703         DAC960_V2_DataTransferMemoryAddress_T
1704           DataTransferMemoryAddress;			/* Bytes 32-63 */
1705       } PhysicalDeviceInfo;
1706       struct {
1707         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1708         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1709         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1710         DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
1711         unsigned char DataTransferPageNumber;		/* Byte 7 */
1712         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1713         unsigned short EventSequenceNumberHigh16;		/* Bytes 16-17 */
1714         unsigned char ControllerNumber;			/* Byte 18 */
1715         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1716         unsigned char RequestSenseSize;			/* Byte 20 */
1717         unsigned char IOCTL_Opcode;				/* Byte 21 */
1718         unsigned short EventSequenceNumberLow16;		/* Bytes 22-23 */
1719         unsigned char Reserved[8];				/* Bytes 24-31 */
1720         DAC960_V2_DataTransferMemoryAddress_T
1721           DataTransferMemoryAddress;			/* Bytes 32-63 */
1722       } GetEvent;
1723       struct {
1724         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1725         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1726         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1727         DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
1728         unsigned char DataTransferPageNumber;		/* Byte 7 */
1729         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1730         DAC960_V2_LogicalDevice_T LogicalDevice;		/* Bytes 16-18 */
1731         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1732         unsigned char RequestSenseSize;			/* Byte 20 */
1733         unsigned char IOCTL_Opcode;				/* Byte 21 */
1734         union {
1735           DAC960_V2_LogicalDeviceState_T LogicalDeviceState;
1736           DAC960_V2_PhysicalDeviceState_T PhysicalDeviceState;
1737         } DeviceState;					/* Byte 22 */
1738         unsigned char Reserved[9];				/* Bytes 23-31 */
1739         DAC960_V2_DataTransferMemoryAddress_T
1740           DataTransferMemoryAddress;			/* Bytes 32-63 */
1741       } SetDeviceState;
1742       struct {
1743         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1744         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1745         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1746         DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
1747         unsigned char DataTransferPageNumber;		/* Byte 7 */
1748         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1749         DAC960_V2_LogicalDevice_T LogicalDevice;		/* Bytes 16-18 */
1750         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1751         unsigned char RequestSenseSize;			/* Byte 20 */
1752         unsigned char IOCTL_Opcode;				/* Byte 21 */
1753         boolean RestoreConsistency:1;			/* Byte 22 Bit 0 */
1754         boolean InitializedAreaOnly:1;			/* Byte 22 Bit 1 */
1755         unsigned char :6;					/* Byte 22 Bits 2-7 */
1756         unsigned char Reserved[9];				/* Bytes 23-31 */
1757         DAC960_V2_DataTransferMemoryAddress_T
1758           DataTransferMemoryAddress;			/* Bytes 32-63 */
1759       } ConsistencyCheck;
1760       struct {
1761         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1762         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1763         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1764         unsigned char FirstCommandMailboxSizeKB;		/* Byte 4 */
1765         unsigned char FirstStatusMailboxSizeKB;		/* Byte 5 */
1766         unsigned char SecondCommandMailboxSizeKB;		/* Byte 6 */
1767         unsigned char SecondStatusMailboxSizeKB;		/* Byte 7 */
1768         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1769         unsigned int :24;					/* Bytes 16-18 */
1770         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1771         unsigned char RequestSenseSize;			/* Byte 20 */
1772         unsigned char IOCTL_Opcode;				/* Byte 21 */
1773         unsigned char HealthStatusBufferSizeKB;		/* Byte 22 */
1774         unsigned char :8;					/* Byte 23 */
1775         DAC960_BusAddress64_T HealthStatusBufferBusAddress; /* Bytes 24-31 */
1776         DAC960_BusAddress64_T FirstCommandMailboxBusAddress; /* Bytes 32-39 */
1777         DAC960_BusAddress64_T FirstStatusMailboxBusAddress; /* Bytes 40-47 */
1778         DAC960_BusAddress64_T SecondCommandMailboxBusAddress; /* Bytes 48-55 */
1779         DAC960_BusAddress64_T SecondStatusMailboxBusAddress; /* Bytes 56-63 */
1780       } SetMemoryMailbox;
1781       struct {
1782         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
1783         DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
1784         DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
1785         DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
1786         unsigned char DataTransferPageNumber;		/* Byte 7 */
1787         DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
1788         DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
1789         DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
1790         unsigned char RequestSenseSize;			/* Byte 20 */
1791         unsigned char IOCTL_Opcode;				/* Byte 21 */
1792         DAC960_V2_OperationDevice_T OperationDevice;	/* Byte 22 */
1793         unsigned char Reserved[9];				/* Bytes 23-31 */
1794         DAC960_V2_DataTransferMemoryAddress_T
1795           DataTransferMemoryAddress;			/* Bytes 32-63 */
1796       } DeviceOperation;
1797     }
1798     __attribute__ ((packed))
1799     DAC960_V2_CommandMailbox_T;
1800     
1801     
1802     /*
1803       Define the DAC960 Driver IOCTL requests.
1804     */
1805     
1806     #define DAC960_IOCTL_GET_CONTROLLER_COUNT	0xDAC001
1807     #define DAC960_IOCTL_GET_CONTROLLER_INFO	0xDAC002
1808     #define DAC960_IOCTL_V1_EXECUTE_COMMAND		0xDAC003
1809     #define DAC960_IOCTL_V2_EXECUTE_COMMAND		0xDAC004
1810     #define DAC960_IOCTL_V2_GET_HEALTH_STATUS	0xDAC005
1811     
1812     
1813     /*
1814       Define the DAC960_IOCTL_GET_CONTROLLER_INFO reply structure.
1815     */
1816     
1817     typedef struct DAC960_ControllerInfo
1818     {
1819       unsigned char ControllerNumber;
1820       unsigned char FirmwareType;
1821       unsigned char Channels;
1822       unsigned char Targets;
1823       unsigned char PCI_Bus;
1824       unsigned char PCI_Device;
1825       unsigned char PCI_Function;
1826       unsigned char IRQ_Channel;
1827       DAC960_PCI_Address_T PCI_Address;
1828       unsigned char ModelName[20];
1829       unsigned char FirmwareVersion[12];
1830     }
1831     DAC960_ControllerInfo_T;
1832     
1833     
1834     /*
1835       Define the User Mode DAC960_IOCTL_V1_EXECUTE_COMMAND request structure.
1836     */
1837     
1838     typedef struct DAC960_V1_UserCommand
1839     {
1840       unsigned char ControllerNumber;
1841       DAC960_V1_CommandMailbox_T CommandMailbox;
1842       int DataTransferLength;
1843       void *DataTransferBuffer;
1844       DAC960_V1_DCDB_T *DCDB;
1845     }
1846     DAC960_V1_UserCommand_T;
1847     
1848     
1849     /*
1850       Define the Kernel Mode DAC960_IOCTL_V1_EXECUTE_COMMAND request structure.
1851     */
1852     
1853     typedef struct DAC960_V1_KernelCommand
1854     {
1855       unsigned char ControllerNumber;
1856       DAC960_V1_CommandMailbox_T CommandMailbox;
1857       int DataTransferLength;
1858       void *DataTransferBuffer;
1859       DAC960_V1_DCDB_T *DCDB;
1860       DAC960_V1_CommandStatus_T CommandStatus;
1861       void (*CompletionFunction)(struct DAC960_V1_KernelCommand *);
1862       void *CompletionData;
1863     }
1864     DAC960_V1_KernelCommand_T;
1865     
1866     
1867     /*
1868       Define the User Mode DAC960_IOCTL_V2_EXECUTE_COMMAND request structure.
1869     */
1870     
1871     typedef struct DAC960_V2_UserCommand
1872     {
1873       unsigned char ControllerNumber;
1874       DAC960_V2_CommandMailbox_T CommandMailbox;
1875       int DataTransferLength;
1876       int RequestSenseLength;
1877       void *DataTransferBuffer;
1878       void *RequestSenseBuffer;
1879     }
1880     DAC960_V2_UserCommand_T;
1881     
1882     
1883     /*
1884       Define the Kernel Mode DAC960_IOCTL_V2_EXECUTE_COMMAND request structure.
1885     */
1886     
1887     typedef struct DAC960_V2_KernelCommand
1888     {
1889       unsigned char ControllerNumber;
1890       DAC960_V2_CommandMailbox_T CommandMailbox;
1891       int DataTransferLength;
1892       int RequestSenseLength;
1893       void *DataTransferBuffer;
1894       void *RequestSenseBuffer;
1895       DAC960_V2_CommandStatus_T CommandStatus;
1896       void (*CompletionFunction)(struct DAC960_V2_KernelCommand *);
1897       void *CompletionData;
1898     }
1899     DAC960_V2_KernelCommand_T;
1900     
1901     
1902     /*
1903       Define the User Mode DAC960_IOCTL_V2_GET_HEALTH_STATUS request structure.
1904     */
1905     
1906     typedef struct DAC960_V2_GetHealthStatus
1907     {
1908       unsigned char ControllerNumber;
1909       DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer;
1910     }
1911     DAC960_V2_GetHealthStatus_T;
1912     
1913     
1914     /*
1915       Import the Kernel Mode IOCTL interface.
1916     */
1917     
1918     extern int DAC960_KernelIOCTL(unsigned int Request, void *Argument);
1919     
1920     
1921     /*
1922       DAC960_DriverVersion protects the private portion of this file.
1923     */
1924     
1925     #ifdef DAC960_DriverVersion
1926     
1927     
1928     /*
1929       Define the maximum Driver Queue Depth and Controller Queue Depth supported
1930       by DAC960 V1 and V2 Firmware Controllers.
1931     */
1932     
1933     #define DAC960_MaxDriverQueueDepth		511
1934     #define DAC960_MaxControllerQueueDepth		512
1935     
1936     
1937     /*
1938       Define the maximum number of Scatter/Gather Segments supported for any
1939       DAC960 V1 and V2 Firmware controller.
1940     */
1941     
1942     #define DAC960_V1_ScatterGatherLimit		33
1943     #define DAC960_V2_ScatterGatherLimit		128
1944     
1945     
1946     /*
1947       Define the number of Command Mailboxes and Status Mailboxes used by the
1948       DAC960 V1 and V2 Firmware Memory Mailbox Interface.
1949     */
1950     
1951     #define DAC960_V1_CommandMailboxCount		256
1952     #define DAC960_V1_StatusMailboxCount		1024
1953     #define DAC960_V2_CommandMailboxCount		512
1954     #define DAC960_V2_StatusMailboxCount		512
1955     
1956     
1957     /*
1958       Define the DAC960 Controller Monitoring Timer Interval.
1959     */
1960     
1961     #define DAC960_MonitoringTimerInterval		(10 * HZ)
1962     
1963     
1964     /*
1965       Define the DAC960 Controller Secondary Monitoring Interval.
1966     */
1967     
1968     #define DAC960_SecondaryMonitoringInterval	(60 * HZ)
1969     
1970     
1971     /*
1972       Define the DAC960 Controller Health Status Monitoring Interval.
1973     */
1974     
1975     #define DAC960_HealthStatusMonitoringInterval	(1 * HZ)
1976     
1977     
1978     /*
1979       Define the DAC960 Controller Progress Reporting Interval.
1980     */
1981     
1982     #define DAC960_ProgressReportingInterval	(60 * HZ)
1983     
1984     
1985     /*
1986       Define the maximum number of Partitions allowed for each Logical Drive.
1987     */
1988     
1989     #define DAC960_MaxPartitions			8
1990     #define DAC960_MaxPartitionsBits		3
1991     
1992     
1993     /*
1994       Define macros to extract the Controller Number, Logical Drive Number, and
1995       Partition Number from a Kernel Device, and to construct a Major Number, Minor
1996       Number, and Kernel Device from the Controller Number, Logical Drive Number,
1997       and Partition Number.  There is one Major Number assigned to each Controller.
1998       The associated Minor Number is divided into the Logical Drive Number and
1999       Partition Number.
2000     */
2001     
2002     #define DAC960_ControllerNumber(Device) \
2003       (MAJOR(Device) - DAC960_MAJOR)
2004     
2005     #define DAC960_LogicalDriveNumber(Device) \
2006       (MINOR(Device) >> DAC960_MaxPartitionsBits)
2007     
2008     #define DAC960_PartitionNumber(Device) \
2009       (MINOR(Device) & (DAC960_MaxPartitions - 1))
2010     
2011     #define DAC960_MajorNumber(ControllerNumber) \
2012       (DAC960_MAJOR + (ControllerNumber))
2013     
2014     #define DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber) \
2015        (((LogicalDriveNumber) << DAC960_MaxPartitionsBits) | (PartitionNumber))
2016     
2017     #define DAC960_MinorCount			(DAC960_MaxLogicalDrives \
2018     						 * DAC960_MaxPartitions)
2019     
2020     #define DAC960_KernelDevice(ControllerNumber,				       \
2021     			    LogicalDriveNumber,				       \
2022     			    PartitionNumber)				       \
2023        MKDEV(DAC960_MajorNumber(ControllerNumber),				       \
2024     	 DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber))
2025     
2026     
2027     /*
2028       Define the DAC960 Controller fixed Block Size and Block Size Bits.
2029     */
2030     
2031     #define DAC960_BlockSize			512
2032     #define DAC960_BlockSizeBits			9
2033     
2034     
2035     /*
2036       Define the number of Command structures that should be allocated as a
2037       group to optimize kernel memory allocation.
2038     */
2039     
2040     #define DAC960_V1_CommandAllocationGroupSize	11
2041     #define DAC960_V2_CommandAllocationGroupSize	29
2042     
2043     
2044     /*
2045       Define the Controller Line Buffer, Progress Buffer, User Message, and
2046       Initial Status Buffer sizes.
2047     */
2048     
2049     #define DAC960_LineBufferSize			100
2050     #define DAC960_ProgressBufferSize		200
2051     #define DAC960_UserMessageSize			200
2052     #define DAC960_InitialStatusBufferSize		(8192-32)
2053     
2054     
2055     /*
2056       Define the DAC960 Controller Firmware Types.
2057     */
2058     
2059     typedef enum
2060     {
2061       DAC960_V1_Controller =			1,
2062       DAC960_V2_Controller =			2
2063     }
2064     DAC960_FirmwareType_T;
2065     
2066     
2067     /*
2068       Define the DAC960 Controller Hardware Types.
2069     */
2070     
2071     typedef enum
2072     {
2073       DAC960_BA_Controller =			1,	/* eXtremeRAID 2000 */
2074       DAC960_LP_Controller =			2,	/* AcceleRAID 352 */
2075       DAC960_LA_Controller =			3,	/* DAC1164P */
2076       DAC960_PG_Controller =			4,	/* DAC960PTL/PJ/PG */
2077       DAC960_PD_Controller =			5	/* DAC960PU/PD/PL */
2078     }
2079     DAC960_HardwareType_T;
2080     
2081     
2082     /*
2083       Define the Driver Message Levels.
2084     */
2085     
2086     typedef enum DAC960_MessageLevel
2087     {
2088       DAC960_AnnounceLevel =			0,
2089       DAC960_InfoLevel =				1,
2090       DAC960_NoticeLevel =				2,
2091       DAC960_WarningLevel =				3,
2092       DAC960_ErrorLevel =				4,
2093       DAC960_ProgressLevel =			5,
2094       DAC960_CriticalLevel =			6,
2095       DAC960_UserCriticalLevel =			7
2096     }
2097     DAC960_MessageLevel_T;
2098     
2099     static char
2100       *DAC960_MessageLevelMap[] =
2101         { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING,
2102           KERN_ERR, KERN_CRIT, KERN_CRIT, KERN_CRIT };
2103     
2104     
2105     /*
2106       Define Driver Message macros.
2107     */
2108     
2109     #define DAC960_Announce(Format, Arguments...) \
2110       DAC960_Message(DAC960_AnnounceLevel, Format, ##Arguments)
2111     
2112     #define DAC960_Info(Format, Arguments...) \
2113       DAC960_Message(DAC960_InfoLevel, Format, ##Arguments)
2114     
2115     #define DAC960_Notice(Format, Arguments...) \
2116       DAC960_Message(DAC960_NoticeLevel, Format, ##Arguments)
2117     
2118     #define DAC960_Warning(Format, Arguments...) \
2119       DAC960_Message(DAC960_WarningLevel, Format, ##Arguments)
2120     
2121     #define DAC960_Error(Format, Arguments...) \
2122       DAC960_Message(DAC960_ErrorLevel, Format, ##Arguments)
2123     
2124     #define DAC960_Progress(Format, Arguments...) \
2125       DAC960_Message(DAC960_ProgressLevel, Format, ##Arguments)
2126     
2127     #define DAC960_Critical(Format, Arguments...) \
2128       DAC960_Message(DAC960_CriticalLevel, Format, ##Arguments)
2129     
2130     #define DAC960_UserCritical(Format, Arguments...) \
2131       DAC960_Message(DAC960_UserCriticalLevel, Format, ##Arguments)
2132     
2133     
2134     /*
2135       Define types for some of the structures that interface with the rest
2136       of the Linux Kernel and I/O Subsystem.
2137     */
2138     
2139     typedef struct buffer_head BufferHeader_T;
2140     typedef struct file File_T;
2141     typedef struct block_device_operations BlockDeviceOperations_T;
2142     typedef struct completion Completion_T;
2143     typedef struct gendisk GenericDiskInfo_T;
2144     typedef struct hd_geometry DiskGeometry_T;
2145     typedef struct hd_struct DiskPartition_T;
2146     typedef struct inode Inode_T;
2147     typedef struct inode_operations InodeOperations_T;
2148     typedef kdev_t KernelDevice_T;
2149     typedef struct list_head ListHead_T;
2150     typedef struct notifier_block NotifierBlock_T;
2151     typedef struct pci_dev PCI_Device_T;
2152     typedef struct proc_dir_entry PROC_DirectoryEntry_T;
2153     typedef unsigned long ProcessorFlags_T;
2154     typedef struct pt_regs Registers_T;
2155     typedef struct request IO_Request_T;
2156     typedef request_queue_t RequestQueue_T;
2157     typedef struct super_block SuperBlock_T;
2158     typedef struct timer_list Timer_T;
2159     typedef wait_queue_head_t WaitQueue_T;
2160     
2161     
2162     /*
2163       Define the DAC960 V1 Firmware Controller Status Mailbox structure.
2164     */
2165     
2166     typedef union DAC960_V1_StatusMailbox
2167     {
2168       unsigned int Word;					/* Word 0 */
2169       struct {
2170         DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 0 */
2171         unsigned char :7;					/* Byte 1 Bits 0-6 */
2172         boolean Valid:1;					/* Byte 1 Bit 7 */
2173         DAC960_V1_CommandStatus_T CommandStatus;		/* Bytes 2-3 */
2174       } Fields;
2175     }
2176     DAC960_V1_StatusMailbox_T;
2177     
2178     
2179     /*
2180       Define the DAC960 V2 Firmware Controller Status Mailbox structure.
2181     */
2182     
2183     typedef union DAC960_V2_StatusMailbox
2184     {
2185       unsigned int Words[2];				/* Words 0-1 */
2186       struct {
2187         DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
2188         DAC960_V2_CommandStatus_T CommandStatus;		/* Byte 2 */
2189         unsigned char RequestSenseLength;			/* Byte 3 */
2190         int DataTransferResidue;				/* Bytes 4-7 */
2191       } Fields;
2192     }
2193     DAC960_V2_StatusMailbox_T;
2194     
2195     
2196     /*
2197       Define the DAC960 Driver Command Types.
2198     */
2199     
2200     typedef enum
2201     {
2202       DAC960_ReadCommand =				1,
2203       DAC960_WriteCommand =				2,
2204       DAC960_ReadRetryCommand =			3,
2205       DAC960_WriteRetryCommand =			4,
2206       DAC960_MonitoringCommand =			5,
2207       DAC960_ImmediateCommand =			6,
2208       DAC960_QueuedCommand =			7
2209     }
2210     DAC960_CommandType_T;
2211     
2212     
2213     /*
2214       Define the DAC960 Driver Command structure.
2215     */
2216     
2217     typedef struct DAC960_Command
2218     {
2219       int CommandIdentifier;
2220       DAC960_CommandType_T CommandType;
2221       struct DAC960_Controller *Controller;
2222       struct DAC960_Command *Next;
2223       Completion_T *Completion;
2224       unsigned int LogicalDriveNumber;
2225       unsigned int BlockNumber;
2226       unsigned int BlockCount;
2227       unsigned int SegmentCount;
2228       BufferHeader_T *BufferHeader;
2229       void *RequestBuffer;
2230       union {
2231         struct {
2232           DAC960_V1_CommandMailbox_T CommandMailbox;
2233           DAC960_V1_KernelCommand_T *KernelCommand;
2234           DAC960_V1_CommandStatus_T CommandStatus;
2235           DAC960_V1_ScatterGatherSegment_T
2236     	ScatterGatherList[DAC960_V1_ScatterGatherLimit]
2237     	__attribute__ ((aligned (sizeof(DAC960_V1_ScatterGatherSegment_T))));
2238           unsigned int EndMarker[0];
2239         } V1;
2240         struct {
2241           DAC960_V2_CommandMailbox_T CommandMailbox;
2242           DAC960_V2_KernelCommand_T *KernelCommand;
2243           DAC960_V2_CommandStatus_T CommandStatus;
2244           unsigned char RequestSenseLength;
2245           int DataTransferResidue;
2246           DAC960_V2_ScatterGatherSegment_T
2247     	ScatterGatherList[DAC960_V2_ScatterGatherLimit]
2248     	__attribute__ ((aligned (sizeof(DAC960_V2_ScatterGatherSegment_T))));
2249           DAC960_SCSI_RequestSense_T RequestSense
2250     	__attribute__ ((aligned (sizeof(int))));
2251           unsigned int EndMarker[0];
2252         } V2;
2253       } FW;
2254     }
2255     DAC960_Command_T;
2256     
2257     
2258     /*
2259       Define the DAC960 Driver Controller structure.
2260     */
2261     
2262     typedef struct DAC960_Controller
2263     {
2264       void *BaseAddress;
2265       void *MemoryMappedAddress;
2266       DAC960_FirmwareType_T FirmwareType;
2267       DAC960_HardwareType_T HardwareType;
2268       DAC960_IO_Address_T IO_Address;
2269       DAC960_PCI_Address_T PCI_Address;
2270       unsigned char ControllerNumber;
2271       unsigned char ControllerName[4];
2272       unsigned char ModelName[20];
2273       unsigned char FullModelName[28];
2274       unsigned char FirmwareVersion[12];
2275       unsigned char Bus;
2276       unsigned char Device;
2277       unsigned char Function;
2278       unsigned char IRQ_Channel;
2279       unsigned char Channels;
2280       unsigned char Targets;
2281       unsigned char MemorySize;
2282       unsigned char LogicalDriveCount;
2283       unsigned short CommandAllocationGroupSize;
2284       unsigned short ControllerQueueDepth;
2285       unsigned short DriverQueueDepth;
2286       unsigned short MaxBlocksPerCommand;
2287       unsigned short ControllerScatterGatherLimit;
2288       unsigned short DriverScatterGatherLimit;
2289       unsigned int ControllerUsageCount;
2290       unsigned int CombinedStatusBufferLength;
2291       unsigned int InitialStatusLength;
2292       unsigned int CurrentStatusLength;
2293       unsigned int ProgressBufferLength;
2294       unsigned int UserStatusLength;
2295       unsigned long MemoryMailboxPagesAddress;
2296       unsigned long MemoryMailboxPagesOrder;
2297       unsigned long MonitoringTimerCount;
2298       unsigned long PrimaryMonitoringTime;
2299       unsigned long SecondaryMonitoringTime;
2300       unsigned long LastProgressReportTime;
2301       unsigned long LastCurrentStatusTime;
2302       boolean ControllerDetectionSuccessful;
2303       boolean ControllerInitialized;
2304       boolean MonitoringCommandDeferred;
2305       boolean EphemeralProgressMessage;
2306       boolean DriveSpinUpMessageDisplayed;
2307       boolean MonitoringAlertMode;
2308       boolean SuppressEnclosureMessages;
2309       Timer_T MonitoringTimer;
2310       GenericDiskInfo_T GenericDiskInfo;
2311       DAC960_Command_T *FreeCommands;
2312       unsigned char *CombinedStatusBuffer;
2313       unsigned char *CurrentStatusBuffer;
2314       RequestQueue_T *RequestQueue;
2315       WaitQueue_T CommandWaitQueue;
2316       WaitQueue_T HealthStatusWaitQueue;
2317       DAC960_Command_T InitialCommand;
2318       DAC960_Command_T *Commands[DAC960_MaxDriverQueueDepth];
2319       PROC_DirectoryEntry_T *ControllerProcEntry;
2320       unsigned int LogicalDriveUsageCount[DAC960_MaxLogicalDrives];
2321       boolean LogicalDriveInitiallyAccessible[DAC960_MaxLogicalDrives];
2322       void (*QueueCommand)(DAC960_Command_T *Command);
2323       boolean (*ReadControllerConfiguration)(struct DAC960_Controller *);
2324       boolean (*ReadDeviceConfiguration)(struct DAC960_Controller *);
2325       boolean (*ReportDeviceConfiguration)(struct DAC960_Controller *);
2326       void (*QueueReadWriteCommand)(DAC960_Command_T *Command);
2327       union {
2328         struct {
2329           unsigned char GeometryTranslationHeads;
2330           unsigned char GeometryTranslationSectors;
2331           unsigned char PendingRebuildFlag;
2332           unsigned short StripeSize;
2333           unsigned short SegmentSize;
2334           unsigned short NewEventLogSequenceNumber;
2335           unsigned short OldEventLogSequenceNumber;
2336           unsigned short DeviceStateChannel;
2337           unsigned short DeviceStateTargetID;
2338           boolean DualModeMemoryMailboxInterface;
2339           boolean SAFTE_EnclosureManagementEnabled;
2340           boolean NeedLogicalDriveInformation;
2341           boolean NeedErrorTableInformation;
2342           boolean NeedDeviceStateInformation;
2343           boolean NeedDeviceInquiryInformation;
2344           boolean NeedDeviceSerialNumberInformation;
2345           boolean NeedRebuildProgress;
2346           boolean NeedConsistencyCheckProgress;
2347           boolean StartDeviceStateScan;
2348           boolean RebuildProgressFirst;
2349           boolean RebuildFlagPending;
2350           boolean RebuildStatusPending;
2351           DAC960_V1_CommandMailbox_T *FirstCommandMailbox;
2352           DAC960_V1_CommandMailbox_T *LastCommandMailbox;
2353           DAC960_V1_CommandMailbox_T *NextCommandMailbox;
2354           DAC960_V1_CommandMailbox_T *PreviousCommandMailbox1;
2355           DAC960_V1_CommandMailbox_T *PreviousCommandMailbox2;
2356           DAC960_V1_StatusMailbox_T *FirstStatusMailbox;
2357           DAC960_V1_StatusMailbox_T *LastStatusMailbox;
2358           DAC960_V1_StatusMailbox_T *NextStatusMailbox;
2359           DAC960_V1_DCDB_T MonitoringDCDB;
2360           DAC960_V1_Enquiry_T Enquiry;
2361           DAC960_V1_Enquiry_T NewEnquiry;
2362           DAC960_V1_ErrorTable_T ErrorTable;
2363           DAC960_V1_ErrorTable_T NewErrorTable;
2364           DAC960_V1_EventLogEntry_T EventLogEntry;
2365           DAC960_V1_RebuildProgress_T RebuildProgress;
2366           DAC960_V1_CommandStatus_T LastRebuildStatus;
2367           DAC960_V1_CommandStatus_T PendingRebuildStatus;
2368           DAC960_V1_LogicalDriveInformationArray_T LogicalDriveInformation;
2369           DAC960_V1_LogicalDriveInformationArray_T NewLogicalDriveInformation;
2370           DAC960_V1_DeviceState_T
2371     	DeviceState[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
2372           DAC960_V1_DeviceState_T NewDeviceState;
2373           DAC960_SCSI_Inquiry_T
2374     	InquiryStandardData[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
2375           DAC960_SCSI_Inquiry_UnitSerialNumber_T
2376     	InquiryUnitSerialNumber[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
2377           int DeviceResetCount[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
2378           boolean DirectCommandActive[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
2379         } V1;
2380         struct {
2381           unsigned int StatusChangeCounter;
2382           unsigned int NextEventSequenceNumber;
2383           unsigned int PhysicalDeviceIndex;
2384           boolean NeedLogicalDeviceInformation;
2385           boolean NeedPhysicalDeviceInformation;
2386           boolean NeedDeviceSerialNumberInformation;
2387           boolean StartLogicalDeviceInformationScan;
2388           boolean StartPhysicalDeviceInformationScan;
2389           DAC960_V2_CommandMailbox_T *FirstCommandMailbox;
2390           DAC960_V2_CommandMailbox_T *LastCommandMailbox;
2391           DAC960_V2_CommandMailbox_T *NextCommandMailbox;
2392           DAC960_V2_CommandMailbox_T *PreviousCommandMailbox1;
2393           DAC960_V2_CommandMailbox_T *PreviousCommandMailbox2;
2394           DAC960_V2_StatusMailbox_T *FirstStatusMailbox;
2395           DAC960_V2_StatusMailbox_T *LastStatusMailbox;
2396           DAC960_V2_StatusMailbox_T *NextStatusMailbox;
2397           DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer;
2398           DAC960_V2_ControllerInfo_T ControllerInformation;
2399           DAC960_V2_ControllerInfo_T NewControllerInformation;
2400           DAC960_V2_LogicalDeviceInfo_T
2401     	*LogicalDeviceInformation[DAC960_MaxLogicalDrives];
2402           DAC960_V2_LogicalDeviceInfo_T NewLogicalDeviceInformation;
2403           DAC960_V2_PhysicalDeviceInfo_T
2404     	*PhysicalDeviceInformation[DAC960_V2_MaxPhysicalDevices];
2405           DAC960_V2_PhysicalDeviceInfo_T NewPhysicalDeviceInformation;
2406           DAC960_SCSI_Inquiry_UnitSerialNumber_T
2407     	*InquiryUnitSerialNumber[DAC960_V2_MaxPhysicalDevices];
2408           DAC960_V2_PhysicalDevice_T
2409     	LogicalDriveToVirtualDevice[DAC960_MaxLogicalDrives];
2410           DAC960_V2_Event_T Event;
2411           boolean LogicalDriveFoundDuringScan[DAC960_MaxLogicalDrives];
2412         } V2;
2413       } FW;
2414       DiskPartition_T DiskPartitions[DAC960_MinorCount];
2415       int PartitionSizes[DAC960_MinorCount];
2416       int BlockSizes[DAC960_MinorCount];
2417       int MaxSectorsPerRequest[DAC960_MinorCount];
2418       unsigned char ProgressBuffer[DAC960_ProgressBufferSize];
2419       unsigned char UserStatusBuffer[DAC960_UserMessageSize];
2420     }
2421     DAC960_Controller_T;
2422     
2423     
2424     /*
2425       Simplify access to Firmware Version Dependent Data Structure Components
2426       and Functions.
2427     */
2428     
2429     #define V1				FW.V1
2430     #define V2				FW.V2
2431     #define DAC960_QueueCommand(Command) \
2432       (Controller->QueueCommand)(Command)
2433     #define DAC960_ReadControllerConfiguration(Controller) \
2434       (Controller->ReadControllerConfiguration)(Controller)
2435     #define DAC960_ReadDeviceConfiguration(Controller) \
2436       (Controller->ReadDeviceConfiguration)(Controller)
2437     #define DAC960_ReportDeviceConfiguration(Controller) \
2438       (Controller->ReportDeviceConfiguration)(Controller)
2439     #define DAC960_QueueReadWriteCommand(Command) \
2440       (Controller->QueueReadWriteCommand)(Command)
2441     
2442     
2443     /*
2444       DAC960_AcquireControllerLock acquires exclusive access to Controller.
2445     */
2446     
2447     static inline
2448     void DAC960_AcquireControllerLock(DAC960_Controller_T *Controller,
2449     				  ProcessorFlags_T *ProcessorFlags)
2450     {
2451       spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
2452     }
2453     
2454     
2455     /*
2456       DAC960_ReleaseControllerLock releases exclusive access to Controller.
2457     */
2458     
2459     static inline
2460     void DAC960_ReleaseControllerLock(DAC960_Controller_T *Controller,
2461     				  ProcessorFlags_T *ProcessorFlags)
2462     {
2463       spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
2464     }
2465     
2466     
2467     /*
2468       DAC960_AcquireControllerLockRF acquires exclusive access to Controller,
2469       but is only called from the request function with the io_request_lock held.
2470     */
2471     
2472     static inline
2473     void DAC960_AcquireControllerLockRF(DAC960_Controller_T *Controller,
2474     				    ProcessorFlags_T *ProcessorFlags)
2475     {
2476     }
2477     
2478     
2479     /*
2480       DAC960_ReleaseControllerLockRF releases exclusive access to Controller,
2481       but is only called from the request function with the io_request_lock held.
2482     */
2483     
2484     static inline
2485     void DAC960_ReleaseControllerLockRF(DAC960_Controller_T *Controller,
2486     				    ProcessorFlags_T *ProcessorFlags)
2487     {
2488     }
2489     
2490     
2491     /*
2492       DAC960_AcquireControllerLockIH acquires exclusive access to Controller,
2493       but is only called from the interrupt handler.
2494     */
2495     
2496     static inline
2497     void DAC960_AcquireControllerLockIH(DAC960_Controller_T *Controller,
2498     				    ProcessorFlags_T *ProcessorFlags)
2499     {
2500       spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
2501     }
2502     
2503     
2504     /*
2505       DAC960_ReleaseControllerLockIH releases exclusive access to Controller,
2506       but is only called from the interrupt handler.
2507     */
2508     
2509     static inline
2510     void DAC960_ReleaseControllerLockIH(DAC960_Controller_T *Controller,
2511     				    ProcessorFlags_T *ProcessorFlags)
2512     {
2513       spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
2514     }
2515     
2516     
2517     /*
2518       Virtual_to_Bus32 maps from Kernel Virtual Addresses to 32 Bit PCI Bus
2519       Addresses.
2520     */
2521     
2522     static inline DAC960_BusAddress32_T Virtual_to_Bus32(void *VirtualAddress)
2523     {
2524       return (DAC960_BusAddress32_T) virt_to_bus(VirtualAddress);
2525     }
2526     
2527     
2528     /*
2529       Bus32_to_Virtual maps from 32 Bit PCI Bus Addresses to Kernel Virtual
2530       Addresses.
2531     */
2532     
2533     static inline void *Bus32_to_Virtual(DAC960_BusAddress32_T BusAddress)
2534     {
2535       return (void *) bus_to_virt(BusAddress);
2536     }
2537     
2538     
2539     /*
2540       Virtual_to_Bus64 maps from Kernel Virtual Addresses to 64 Bit PCI Bus
2541       Addresses.
2542     */
2543     
2544     static inline DAC960_BusAddress64_T Virtual_to_Bus64(void *VirtualAddress)
2545     {
2546       return (DAC960_BusAddress64_T) virt_to_bus(VirtualAddress);
2547     }
2548     
2549     
2550     /*
2551       Define the DAC960 BA Series Controller Interface Register Offsets.
2552     */
2553     
2554     #define DAC960_BA_RegisterWindowSize		0x80
2555     
2556     typedef enum
2557     {
2558       DAC960_BA_InboundDoorBellRegisterOffset =	0x60,
2559       DAC960_BA_OutboundDoorBellRegisterOffset =	0x61,
2560       DAC960_BA_InterruptStatusRegisterOffset =	0x30,
2561       DAC960_BA_InterruptMaskRegisterOffset =	0x34,
2562       DAC960_BA_CommandMailboxBusAddressOffset =	0x50,
2563       DAC960_BA_CommandStatusOffset =		0x58,
2564       DAC960_BA_ErrorStatusRegisterOffset =		0x63
2565     }
2566     DAC960_BA_RegisterOffsets_T;
2567     
2568     
2569     /*
2570       Define the structure of the DAC960 BA Series Inbound Door Bell Register.
2571     */
2572     
2573     typedef union DAC960_BA_InboundDoorBellRegister
2574     {
2575       unsigned char All;
2576       struct {
2577         boolean HardwareMailboxNewCommand:1;		/* Bit 0 */
2578         boolean AcknowledgeHardwareMailboxStatus:1;		/* Bit 1 */
2579         boolean GenerateInterrupt:1;			/* Bit 2 */
2580         boolean ControllerReset:1;				/* Bit 3 */
2581         boolean MemoryMailboxNewCommand:1;			/* Bit 4 */
2582         unsigned char :3;					/* Bits 5-7 */
2583       } Write;
2584       struct {
2585         boolean HardwareMailboxEmpty:1;			/* Bit 0 */
2586         boolean InitializationNotInProgress:1;		/* Bit 1 */
2587         unsigned char :6;					/* Bits 2-7 */
2588       } Read;
2589     }
2590     DAC960_BA_InboundDoorBellRegister_T;
2591     
2592     
2593     /*
2594       Define the structure of the DAC960 BA Series Outbound Door Bell Register.
2595     */
2596     
2597     typedef union DAC960_BA_OutboundDoorBellRegister
2598     {
2599       unsigned char All;
2600       struct {
2601         boolean AcknowledgeHardwareMailboxInterrupt:1;	/* Bit 0 */
2602         boolean AcknowledgeMemoryMailboxInterrupt:1;	/* Bit 1 */
2603         unsigned char :6;					/* Bits 2-7 */
2604       } Write;
2605       struct {
2606         boolean HardwareMailboxStatusAvailable:1;		/* Bit 0 */
2607         boolean MemoryMailboxStatusAvailable:1;		/* Bit 1 */
2608         unsigned char :6;					/* Bits 2-7 */
2609       } Read;
2610     }
2611     DAC960_BA_OutboundDoorBellRegister_T;
2612     
2613     
2614     /*
2615       Define the structure of the DAC960 BA Series Interrupt Mask Register.
2616     */
2617     
2618     typedef union DAC960_BA_InterruptMaskRegister
2619     {
2620       unsigned char All;
2621       struct {
2622         unsigned int :2;					/* Bits 0-1 */
2623         boolean DisableInterrupts:1;			/* Bit 2 */
2624         boolean DisableInterruptsI2O:1;			/* Bit 3 */
2625         unsigned int :4;					/* Bits 4-7 */
2626       } Bits;
2627     }
2628     DAC960_BA_InterruptMaskRegister_T;
2629     
2630     
2631     /*
2632       Define the structure of the DAC960 BA Series Error Status Register.
2633     */
2634     
2635     typedef union DAC960_BA_ErrorStatusRegister
2636     {
2637       unsigned char All;
2638       struct {
2639         unsigned int :2;					/* Bits 0-1 */
2640         boolean ErrorStatusPending:1;			/* Bit 2 */
2641         unsigned int :5;					/* Bits 3-7 */
2642       } Bits;
2643     }
2644     DAC960_BA_ErrorStatusRegister_T;
2645     
2646     
2647     /*
2648       Define inline functions to provide an abstraction for reading and writing the
2649       DAC960 BA Series Controller Interface Registers.
2650     */
2651     
2652     static inline
2653     void DAC960_BA_HardwareMailboxNewCommand(void *ControllerBaseAddress)
2654     {
2655       DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2656       InboundDoorBellRegister.All = 0;
2657       InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
2658       writeb(InboundDoorBellRegister.All,
2659     	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2660     }
2661     
2662     static inline
2663     void DAC960_BA_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
2664     {
2665       DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2666       InboundDoorBellRegister.All = 0;
2667       InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
2668       writeb(InboundDoorBellRegister.All,
2669     	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2670     }
2671     
2672     static inline
2673     void DAC960_BA_GenerateInterrupt(void *ControllerBaseAddress)
2674     {
2675       DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2676       InboundDoorBellRegister.All = 0;
2677       InboundDoorBellRegister.Write.GenerateInterrupt = true;
2678       writeb(InboundDoorBellRegister.All,
2679     	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2680     }
2681     
2682     static inline
2683     void DAC960_BA_ControllerReset(void *ControllerBaseAddress)
2684     {
2685       DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2686       InboundDoorBellRegister.All = 0;
2687       InboundDoorBellRegister.Write.ControllerReset = true;
2688       writeb(InboundDoorBellRegister.All,
2689     	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2690     }
2691     
2692     static inline
2693     void DAC960_BA_MemoryMailboxNewCommand(void *ControllerBaseAddress)
2694     {
2695       DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2696       InboundDoorBellRegister.All = 0;
2697       InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
2698       writeb(InboundDoorBellRegister.All,
2699     	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2700     }
2701     
2702     static inline
2703     boolean DAC960_BA_HardwareMailboxFullP(void *ControllerBaseAddress)
2704     {
2705       DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2706       InboundDoorBellRegister.All =
2707         readb(ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2708       return !InboundDoorBellRegister.Read.HardwareMailboxEmpty;
2709     }
2710     
2711     static inline
2712     boolean DAC960_BA_InitializationInProgressP(void *ControllerBaseAddress)
2713     {
2714       DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2715       InboundDoorBellRegister.All =
2716         readb(ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2717       return !InboundDoorBellRegister.Read.InitializationNotInProgress;
2718     }
2719     
2720     static inline
2721     void DAC960_BA_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
2722     {
2723       DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2724       OutboundDoorBellRegister.All = 0;
2725       OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
2726       writeb(OutboundDoorBellRegister.All,
2727     	 ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
2728     }
2729     
2730     static inline
2731     void DAC960_BA_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
2732     {
2733       DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2734       OutboundDoorBellRegister.All = 0;
2735       OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
2736       writeb(OutboundDoorBellRegister.All,
2737     	 ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
2738     }
2739     
2740     static inline
2741     void DAC960_BA_AcknowledgeInterrupt(void *ControllerBaseAddress)
2742     {
2743       DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2744       OutboundDoorBellRegister.All = 0;
2745       OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
2746       OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
2747       writeb(OutboundDoorBellRegister.All,
2748     	 ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
2749     }
2750     
2751     static inline
2752     boolean DAC960_BA_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
2753     {
2754       DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2755       OutboundDoorBellRegister.All =
2756         readb(ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
2757       return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
2758     }
2759     
2760     static inline
2761     boolean DAC960_BA_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
2762     {
2763       DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2764       OutboundDoorBellRegister.All =
2765         readb(ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
2766       return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
2767     }
2768     
2769     static inline
2770     void DAC960_BA_EnableInterrupts(void *ControllerBaseAddress)
2771     {
2772       DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
2773       InterruptMaskRegister.All = 0xFF;
2774       InterruptMaskRegister.Bits.DisableInterrupts = false;
2775       InterruptMaskRegister.Bits.DisableInterruptsI2O = true;
2776       writeb(InterruptMaskRegister.All,
2777     	 ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
2778     }
2779     
2780     static inline
2781     void DAC960_BA_DisableInterrupts(void *ControllerBaseAddress)
2782     {
2783       DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
2784       InterruptMaskRegister.All = 0xFF;
2785       InterruptMaskRegister.Bits.DisableInterrupts = true;
2786       InterruptMaskRegister.Bits.DisableInterruptsI2O = true;
2787       writeb(InterruptMaskRegister.All,
2788     	 ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
2789     }
2790     
2791     static inline
2792     boolean DAC960_BA_InterruptsEnabledP(void *ControllerBaseAddress)
2793     {
2794       DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
2795       InterruptMaskRegister.All =
2796         readb(ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
2797       return !InterruptMaskRegister.Bits.DisableInterrupts;
2798     }
2799     
2800     static inline
2801     void DAC960_BA_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
2802     				     *MemoryCommandMailbox,
2803     				   DAC960_V2_CommandMailbox_T
2804     				     *CommandMailbox)
2805     {
2806       memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
2807     	 sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
2808       wmb();
2809       MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
2810       mb();
2811     }
2812     
2813     static inline
2814     void DAC960_BA_WriteHardwareMailbox(void *ControllerBaseAddress,
2815     				    DAC960_V2_CommandMailbox_T *CommandMailbox)
2816     {
2817     #ifdef __ia64__
2818       writeq(Virtual_to_Bus64(CommandMailbox),
2819     	 ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset);
2820     #else
2821       writel(Virtual_to_Bus32(CommandMailbox),
2822     	 ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset);
2823     #endif
2824     }
2825     
2826     static inline DAC960_V2_CommandIdentifier_T
2827     DAC960_BA_ReadCommandIdentifier(void *ControllerBaseAddress)
2828     {
2829       return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset);
2830     }
2831     
2832     static inline DAC960_V2_CommandStatus_T
2833     DAC960_BA_ReadCommandStatus(void *ControllerBaseAddress)
2834     {
2835       return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset + 2);
2836     }
2837     
2838     static inline boolean
2839     DAC960_BA_ReadErrorStatus(void *ControllerBaseAddress,
2840     			  unsigned char *ErrorStatus,
2841     			  unsigned char *Parameter0,
2842     			  unsigned char *Parameter1)
2843     {
2844       DAC960_BA_ErrorStatusRegister_T ErrorStatusRegister;
2845       ErrorStatusRegister.All =
2846         readb(ControllerBaseAddress + DAC960_BA_ErrorStatusRegisterOffset);
2847       if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
2848       ErrorStatusRegister.Bits.ErrorStatusPending = false;
2849       *ErrorStatus = ErrorStatusRegister.All;
2850       *Parameter0 =
2851         readb(ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset + 0);
2852       *Parameter1 =
2853         readb(ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset + 1);
2854       writeb(0xFF, ControllerBaseAddress + DAC960_BA_ErrorStatusRegisterOffset);
2855       return true;
2856     }
2857     
2858     
2859     /*
2860       Define the DAC960 LP Series Controller Interface Register Offsets.
2861     */
2862     
2863     #define DAC960_LP_RegisterWindowSize		0x80
2864     
2865     typedef enum
2866     {
2867       DAC960_LP_InboundDoorBellRegisterOffset =	0x20,
2868       DAC960_LP_OutboundDoorBellRegisterOffset =	0x2C,
2869       DAC960_LP_InterruptStatusRegisterOffset =	0x30,
2870       DAC960_LP_InterruptMaskRegisterOffset =	0x34,
2871       DAC960_LP_CommandMailboxBusAddressOffset =	0x10,
2872       DAC960_LP_CommandStatusOffset =		0x18,
2873       DAC960_LP_ErrorStatusRegisterOffset =		0x2E
2874     }
2875     DAC960_LP_RegisterOffsets_T;
2876     
2877     
2878     /*
2879       Define the structure of the DAC960 LP Series Inbound Door Bell Register.
2880     */
2881     
2882     typedef union DAC960_LP_InboundDoorBellRegister
2883     {
2884       unsigned char All;
2885       struct {
2886         boolean HardwareMailboxNewCommand:1;		/* Bit 0 */
2887         boolean AcknowledgeHardwareMailboxStatus:1;		/* Bit 1 */
2888         boolean GenerateInterrupt:1;			/* Bit 2 */
2889         boolean ControllerReset:1;				/* Bit 3 */
2890         boolean MemoryMailboxNewCommand:1;			/* Bit 4 */
2891         unsigned char :3;					/* Bits 5-7 */
2892       } Write;
2893       struct {
2894         boolean HardwareMailboxFull:1;			/* Bit 0 */
2895         boolean InitializationInProgress:1;			/* Bit 1 */
2896         unsigned char :6;					/* Bits 2-7 */
2897       } Read;
2898     }
2899     DAC960_LP_InboundDoorBellRegister_T;
2900     
2901     
2902     /*
2903       Define the structure of the DAC960 LP Series Outbound Door Bell Register.
2904     */
2905     
2906     typedef union DAC960_LP_OutboundDoorBellRegister
2907     {
2908       unsigned char All;
2909       struct {
2910         boolean AcknowledgeHardwareMailboxInterrupt:1;	/* Bit 0 */
2911         boolean AcknowledgeMemoryMailboxInterrupt:1;	/* Bit 1 */
2912         unsigned char :6;					/* Bits 2-7 */
2913       } Write;
2914       struct {
2915         boolean HardwareMailboxStatusAvailable:1;		/* Bit 0 */
2916         boolean MemoryMailboxStatusAvailable:1;		/* Bit 1 */
2917         unsigned char :6;					/* Bits 2-7 */
2918       } Read;
2919     }
2920     DAC960_LP_OutboundDoorBellRegister_T;
2921     
2922     
2923     /*
2924       Define the structure of the DAC960 LP Series Interrupt Mask Register.
2925     */
2926     
2927     typedef union DAC960_LP_InterruptMaskRegister
2928     {
2929       unsigned char All;
2930       struct {
2931         unsigned int :2;					/* Bits 0-1 */
2932         boolean DisableInterrupts:1;			/* Bit 2 */
2933         unsigned int :5;					/* Bits 3-7 */
2934       } Bits;
2935     }
2936     DAC960_LP_InterruptMaskRegister_T;
2937     
2938     
2939     /*
2940       Define the structure of the DAC960 LP Series Error Status Register.
2941     */
2942     
2943     typedef union DAC960_LP_ErrorStatusRegister
2944     {
2945       unsigned char All;
2946       struct {
2947         unsigned int :2;					/* Bits 0-1 */
2948         boolean ErrorStatusPending:1;			/* Bit 2 */
2949         unsigned int :5;					/* Bits 3-7 */
2950       } Bits;
2951     }
2952     DAC960_LP_ErrorStatusRegister_T;
2953     
2954     
2955     /*
2956       Define inline functions to provide an abstraction for reading and writing the
2957       DAC960 LP Series Controller Interface Registers.
2958     */
2959     
2960     static inline
2961     void DAC960_LP_HardwareMailboxNewCommand(void *ControllerBaseAddress)
2962     {
2963       DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
2964       InboundDoorBellRegister.All = 0;
2965       InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
2966       writeb(InboundDoorBellRegister.All,
2967     	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
2968     }
2969     
2970     static inline
2971     void DAC960_LP_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
2972     {
2973       DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
2974       InboundDoorBellRegister.All = 0;
2975       InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
2976       writeb(InboundDoorBellRegister.All,
2977     	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
2978     }
2979     
2980     static inline
2981     void DAC960_LP_GenerateInterrupt(void *ControllerBaseAddress)
2982     {
2983       DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
2984       InboundDoorBellRegister.All = 0;
2985       InboundDoorBellRegister.Write.GenerateInterrupt = true;
2986       writeb(InboundDoorBellRegister.All,
2987     	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
2988     }
2989     
2990     static inline
2991     void DAC960_LP_ControllerReset(void *ControllerBaseAddress)
2992     {
2993       DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
2994       InboundDoorBellRegister.All = 0;
2995       InboundDoorBellRegister.Write.ControllerReset = true;
2996       writeb(InboundDoorBellRegister.All,
2997     	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
2998     }
2999     
3000     static inline
3001     void DAC960_LP_MemoryMailboxNewCommand(void *ControllerBaseAddress)
3002     {
3003       DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
3004       InboundDoorBellRegister.All = 0;
3005       InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
3006       writeb(InboundDoorBellRegister.All,
3007     	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
3008     }
3009     
3010     static inline
3011     boolean DAC960_LP_HardwareMailboxFullP(void *ControllerBaseAddress)
3012     {
3013       DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
3014       InboundDoorBellRegister.All =
3015         readb(ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
3016       return InboundDoorBellRegister.Read.HardwareMailboxFull;
3017     }
3018     
3019     static inline
3020     boolean DAC960_LP_InitializationInProgressP(void *ControllerBaseAddress)
3021     {
3022       DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
3023       InboundDoorBellRegister.All =
3024         readb(ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
3025       return InboundDoorBellRegister.Read.InitializationInProgress;
3026     }
3027     
3028     static inline
3029     void DAC960_LP_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
3030     {
3031       DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3032       OutboundDoorBellRegister.All = 0;
3033       OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3034       writeb(OutboundDoorBellRegister.All,
3035     	 ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
3036     }
3037     
3038     static inline
3039     void DAC960_LP_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
3040     {
3041       DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3042       OutboundDoorBellRegister.All = 0;
3043       OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3044       writeb(OutboundDoorBellRegister.All,
3045     	 ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
3046     }
3047     
3048     static inline
3049     void DAC960_LP_AcknowledgeInterrupt(void *ControllerBaseAddress)
3050     {
3051       DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3052       OutboundDoorBellRegister.All = 0;
3053       OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3054       OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3055       writeb(OutboundDoorBellRegister.All,
3056     	 ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
3057     }
3058     
3059     static inline
3060     boolean DAC960_LP_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
3061     {
3062       DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3063       OutboundDoorBellRegister.All =
3064         readb(ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
3065       return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
3066     }
3067     
3068     static inline
3069     boolean DAC960_LP_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
3070     {
3071       DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3072       OutboundDoorBellRegister.All =
3073         readb(ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
3074       return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
3075     }
3076     
3077     static inline
3078     void DAC960_LP_EnableInterrupts(void *ControllerBaseAddress)
3079     {
3080       DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
3081       InterruptMaskRegister.All = 0xFF;
3082       InterruptMaskRegister.Bits.DisableInterrupts = false;
3083       writeb(InterruptMaskRegister.All,
3084     	 ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
3085     }
3086     
3087     static inline
3088     void DAC960_LP_DisableInterrupts(void *ControllerBaseAddress)
3089     {
3090       DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
3091       InterruptMaskRegister.All = 0xFF;
3092       InterruptMaskRegister.Bits.DisableInterrupts = true;
3093       writeb(InterruptMaskRegister.All,
3094     	 ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
3095     }
3096     
3097     static inline
3098     boolean DAC960_LP_InterruptsEnabledP(void *ControllerBaseAddress)
3099     {
3100       DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
3101       InterruptMaskRegister.All =
3102         readb(ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
3103       return !InterruptMaskRegister.Bits.DisableInterrupts;
3104     }
3105     
3106     static inline
3107     void DAC960_LP_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
3108     				     *MemoryCommandMailbox,
3109     				   DAC960_V2_CommandMailbox_T
3110     				     *CommandMailbox)
3111     {
3112       memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
3113     	 sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
3114       wmb();
3115       MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
3116       mb();
3117     }
3118     
3119     static inline
3120     void DAC960_LP_WriteHardwareMailbox(void *ControllerBaseAddress,
3121     				    DAC960_V2_CommandMailbox_T *CommandMailbox)
3122     {
3123     #ifdef __ia64__
3124       writeq(Virtual_to_Bus64(CommandMailbox),
3125     	 ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset);
3126     #else
3127       writel(Virtual_to_Bus32(CommandMailbox),
3128     	 ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset);
3129     #endif
3130     }
3131     
3132     static inline DAC960_V2_CommandIdentifier_T
3133     DAC960_LP_ReadCommandIdentifier(void *ControllerBaseAddress)
3134     {
3135       return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset);
3136     }
3137     
3138     static inline DAC960_V2_CommandStatus_T
3139     DAC960_LP_ReadCommandStatus(void *ControllerBaseAddress)
3140     {
3141       return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset + 2);
3142     }
3143     
3144     static inline boolean
3145     DAC960_LP_ReadErrorStatus(void *ControllerBaseAddress,
3146     			  unsigned char *ErrorStatus,
3147     			  unsigned char *Parameter0,
3148     			  unsigned char *Parameter1)
3149     {
3150       DAC960_LP_ErrorStatusRegister_T ErrorStatusRegister;
3151       ErrorStatusRegister.All =
3152         readb(ControllerBaseAddress + DAC960_LP_ErrorStatusRegisterOffset);
3153       if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
3154       ErrorStatusRegister.Bits.ErrorStatusPending = false;
3155       *ErrorStatus = ErrorStatusRegister.All;
3156       *Parameter0 =
3157         readb(ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset + 0);
3158       *Parameter1 =
3159         readb(ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset + 1);
3160       writeb(0xFF, ControllerBaseAddress + DAC960_LP_ErrorStatusRegisterOffset);
3161       return true;
3162     }
3163     
3164     
3165     /*
3166       Define the DAC960 LA Series Controller Interface Register Offsets.
3167     */
3168     
3169     #define DAC960_LA_RegisterWindowSize		0x80
3170     
3171     typedef enum
3172     {
3173       DAC960_LA_InboundDoorBellRegisterOffset =	0x60,
3174       DAC960_LA_OutboundDoorBellRegisterOffset =	0x61,
3175       DAC960_LA_InterruptMaskRegisterOffset =	0x34,
3176       DAC960_LA_CommandOpcodeRegisterOffset =	0x50,
3177       DAC960_LA_CommandIdentifierRegisterOffset =	0x51,
3178       DAC960_LA_MailboxRegister2Offset =		0x52,
3179       DAC960_LA_MailboxRegister3Offset =		0x53,
3180       DAC960_LA_MailboxRegister4Offset =		0x54,
3181       DAC960_LA_MailboxRegister5Offset =		0x55,
3182       DAC960_LA_MailboxRegister6Offset =		0x56,
3183       DAC960_LA_MailboxRegister7Offset =		0x57,
3184       DAC960_LA_MailboxRegister8Offset =		0x58,
3185       DAC960_LA_MailboxRegister9Offset =		0x59,
3186       DAC960_LA_MailboxRegister10Offset =		0x5A,
3187       DAC960_LA_MailboxRegister11Offset =		0x5B,
3188       DAC960_LA_MailboxRegister12Offset =		0x5C,
3189       DAC960_LA_StatusCommandIdentifierRegOffset =	0x5D,
3190       DAC960_LA_StatusRegisterOffset =		0x5E,
3191       DAC960_LA_ErrorStatusRegisterOffset =		0x63
3192     }
3193     DAC960_LA_RegisterOffsets_T;
3194     
3195     
3196     /*
3197       Define the structure of the DAC960 LA Series Inbound Door Bell Register.
3198     */
3199     
3200     typedef union DAC960_LA_InboundDoorBellRegister
3201     {
3202       unsigned char All;
3203       struct {
3204         boolean HardwareMailboxNewCommand:1;		/* Bit 0 */
3205         boolean AcknowledgeHardwareMailboxStatus:1;		/* Bit 1 */
3206         boolean GenerateInterrupt:1;			/* Bit 2 */
3207         boolean ControllerReset:1;				/* Bit 3 */
3208         boolean MemoryMailboxNewCommand:1;			/* Bit 4 */
3209         unsigned char :3;					/* Bits 5-7 */
3210       } Write;
3211       struct {
3212         boolean HardwareMailboxEmpty:1;			/* Bit 0 */
3213         boolean InitializationNotInProgress:1;		/* Bit 1 */
3214         unsigned char :6;					/* Bits 2-7 */
3215       } Read;
3216     }
3217     DAC960_LA_InboundDoorBellRegister_T;
3218     
3219     
3220     /*
3221       Define the structure of the DAC960 LA Series Outbound Door Bell Register.
3222     */
3223     
3224     typedef union DAC960_LA_OutboundDoorBellRegister
3225     {
3226       unsigned char All;
3227       struct {
3228         boolean AcknowledgeHardwareMailboxInterrupt:1;	/* Bit 0 */
3229         boolean AcknowledgeMemoryMailboxInterrupt:1;	/* Bit 1 */
3230         unsigned char :6;					/* Bits 2-7 */
3231       } Write;
3232       struct {
3233         boolean HardwareMailboxStatusAvailable:1;		/* Bit 0 */
3234         boolean MemoryMailboxStatusAvailable:1;		/* Bit 1 */
3235         unsigned char :6;					/* Bits 2-7 */
3236       } Read;
3237     }
3238     DAC960_LA_OutboundDoorBellRegister_T;
3239     
3240     
3241     /*
3242       Define the structure of the DAC960 LA Series Interrupt Mask Register.
3243     */
3244     
3245     typedef union DAC960_LA_InterruptMaskRegister
3246     {
3247       unsigned char All;
3248       struct {
3249         unsigned char :2;					/* Bits 0-1 */
3250         boolean DisableInterrupts:1;			/* Bit 2 */
3251         unsigned char :5;					/* Bits 3-7 */
3252       } Bits;
3253     }
3254     DAC960_LA_InterruptMaskRegister_T;
3255     
3256     
3257     /*
3258       Define the structure of the DAC960 LA Series Error Status Register.
3259     */
3260     
3261     typedef union DAC960_LA_ErrorStatusRegister
3262     {
3263       unsigned char All;
3264       struct {
3265         unsigned int :2;					/* Bits 0-1 */
3266         boolean ErrorStatusPending:1;			/* Bit 2 */
3267         unsigned int :5;					/* Bits 3-7 */
3268       } Bits;
3269     }
3270     DAC960_LA_ErrorStatusRegister_T;
3271     
3272     
3273     /*
3274       Define inline functions to provide an abstraction for reading and writing the
3275       DAC960 LA Series Controller Interface Registers.
3276     */
3277     
3278     static inline
3279     void DAC960_LA_HardwareMailboxNewCommand(void *ControllerBaseAddress)
3280     {
3281       DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3282       InboundDoorBellRegister.All = 0;
3283       InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
3284       writeb(InboundDoorBellRegister.All,
3285     	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3286     }
3287     
3288     static inline
3289     void DAC960_LA_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
3290     {
3291       DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3292       InboundDoorBellRegister.All = 0;
3293       InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
3294       writeb(InboundDoorBellRegister.All,
3295     	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3296     }
3297     
3298     static inline
3299     void DAC960_LA_GenerateInterrupt(void *ControllerBaseAddress)
3300     {
3301       DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3302       InboundDoorBellRegister.All = 0;
3303       InboundDoorBellRegister.Write.GenerateInterrupt = true;
3304       writeb(InboundDoorBellRegister.All,
3305     	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3306     }
3307     
3308     static inline
3309     void DAC960_LA_ControllerReset(void *ControllerBaseAddress)
3310     {
3311       DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3312       InboundDoorBellRegister.All = 0;
3313       InboundDoorBellRegister.Write.ControllerReset = true;
3314       writeb(InboundDoorBellRegister.All,
3315     	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3316     }
3317     
3318     static inline
3319     void DAC960_LA_MemoryMailboxNewCommand(void *ControllerBaseAddress)
3320     {
3321       DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3322       InboundDoorBellRegister.All = 0;
3323       InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
3324       writeb(InboundDoorBellRegister.All,
3325     	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3326     }
3327     
3328     static inline
3329     boolean DAC960_LA_HardwareMailboxFullP(void *ControllerBaseAddress)
3330     {
3331       DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3332       InboundDoorBellRegister.All =
3333         readb(ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3334       return !InboundDoorBellRegister.Read.HardwareMailboxEmpty;
3335     }
3336     
3337     static inline
3338     boolean DAC960_LA_InitializationInProgressP(void *ControllerBaseAddress)
3339     {
3340       DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3341       InboundDoorBellRegister.All =
3342         readb(ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3343       return !InboundDoorBellRegister.Read.InitializationNotInProgress;
3344     }
3345     
3346     static inline
3347     void DAC960_LA_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
3348     {
3349       DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3350       OutboundDoorBellRegister.All = 0;
3351       OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3352       writeb(OutboundDoorBellRegister.All,
3353     	 ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
3354     }
3355     
3356     static inline
3357     void DAC960_LA_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
3358     {
3359       DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3360       OutboundDoorBellRegister.All = 0;
3361       OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3362       writeb(OutboundDoorBellRegister.All,
3363     	 ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
3364     }
3365     
3366     static inline
3367     void DAC960_LA_AcknowledgeInterrupt(void *ControllerBaseAddress)
3368     {
3369       DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3370       OutboundDoorBellRegister.All = 0;
3371       OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3372       OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3373       writeb(OutboundDoorBellRegister.All,
3374     	 ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
3375     }
3376     
3377     static inline
3378     boolean DAC960_LA_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
3379     {
3380       DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3381       OutboundDoorBellRegister.All =
3382         readb(ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
3383       return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
3384     }
3385     
3386     static inline
3387     boolean DAC960_LA_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
3388     {
3389       DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3390       OutboundDoorBellRegister.All =
3391         readb(ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
3392       return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
3393     }
3394     
3395     static inline
3396     void DAC960_LA_EnableInterrupts(void *ControllerBaseAddress)
3397     {
3398       DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
3399       InterruptMaskRegister.All = 0xFF;
3400       InterruptMaskRegister.Bits.DisableInterrupts = false;
3401       writeb(InterruptMaskRegister.All,
3402     	 ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
3403     }
3404     
3405     static inline
3406     void DAC960_LA_DisableInterrupts(void *ControllerBaseAddress)
3407     {
3408       DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
3409       InterruptMaskRegister.All = 0xFF;
3410       InterruptMaskRegister.Bits.DisableInterrupts = true;
3411       writeb(InterruptMaskRegister.All,
3412     	 ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
3413     }
3414     
3415     static inline
3416     boolean DAC960_LA_InterruptsEnabledP(void *ControllerBaseAddress)
3417     {
3418       DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
3419       InterruptMaskRegister.All =
3420         readb(ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
3421       return !InterruptMaskRegister.Bits.DisableInterrupts;
3422     }
3423     
3424     static inline
3425     void DAC960_LA_WriteCommandMailbox(DAC960_V1_CommandMailbox_T
3426     				     *MemoryCommandMailbox,
3427     				   DAC960_V1_CommandMailbox_T
3428     				     *CommandMailbox)
3429     {
3430       MemoryCommandMailbox->Words[1] = CommandMailbox->Words[1];
3431       MemoryCommandMailbox->Words[2] = CommandMailbox->Words[2];
3432       MemoryCommandMailbox->Words[3] = CommandMailbox->Words[3];
3433       wmb();
3434       MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
3435       mb();
3436     }
3437     
3438     static inline
3439     void DAC960_LA_WriteHardwareMailbox(void *ControllerBaseAddress,
3440     				    DAC960_V1_CommandMailbox_T *CommandMailbox)
3441     {
3442       writel(CommandMailbox->Words[0],
3443     	 ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
3444       writel(CommandMailbox->Words[1],
3445     	 ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
3446       writel(CommandMailbox->Words[2],
3447     	 ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
3448       writeb(CommandMailbox->Bytes[12],
3449     	 ControllerBaseAddress + DAC960_LA_MailboxRegister12Offset);
3450     }
3451     
3452     static inline DAC960_V1_CommandIdentifier_T
3453     DAC960_LA_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
3454     {
3455       return readb(ControllerBaseAddress
3456     	       + DAC960_LA_StatusCommandIdentifierRegOffset);
3457     }
3458     
3459     static inline DAC960_V1_CommandStatus_T
3460     DAC960_LA_ReadStatusRegister(void *ControllerBaseAddress)
3461     {
3462       return readw(ControllerBaseAddress + DAC960_LA_StatusRegisterOffset);
3463     }
3464     
3465     static inline boolean
3466     DAC960_LA_ReadErrorStatus(void *ControllerBaseAddress,
3467     			  unsigned char *ErrorStatus,
3468     			  unsigned char *Parameter0,
3469     			  unsigned char *Parameter1)
3470     {
3471       DAC960_LA_ErrorStatusRegister_T ErrorStatusRegister;
3472       ErrorStatusRegister.All =
3473         readb(ControllerBaseAddress + DAC960_LA_ErrorStatusRegisterOffset);
3474       if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
3475       ErrorStatusRegister.Bits.ErrorStatusPending = false;
3476       *ErrorStatus = ErrorStatusRegister.All;
3477       *Parameter0 =
3478         readb(ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
3479       *Parameter1 =
3480         readb(ControllerBaseAddress + DAC960_LA_CommandIdentifierRegisterOffset);
3481       writeb(0xFF, ControllerBaseAddress + DAC960_LA_ErrorStatusRegisterOffset);
3482       return true;
3483     }
3484     
3485     static inline
3486     void DAC960_LA_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
3487     {
3488     #ifdef __i386__
3489       void *ControllerBaseAddress = Controller->BaseAddress;
3490       writel(0x743C485E,
3491     	 ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
3492       writel((unsigned long) Controller->V1.FirstCommandMailbox,
3493     	 ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
3494       writew(Controller->V1.NextCommandMailbox - Controller->V1.FirstCommandMailbox,
3495     	 ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
3496       writew(Controller->V1.NextStatusMailbox - Controller->V1.FirstStatusMailbox,
3497     	 ControllerBaseAddress + DAC960_LA_MailboxRegister10Offset);
3498     #endif
3499     }
3500     
3501     static inline
3502     void DAC960_LA_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
3503     					void **MemoryMailboxAddress,
3504     					short *NextCommandMailboxIndex,
3505     					short *NextStatusMailboxIndex)
3506     {
3507     #ifdef __i386__
3508       void *ControllerBaseAddress = Controller->BaseAddress;
3509       if (readl(ControllerBaseAddress
3510     	    + DAC960_LA_CommandOpcodeRegisterOffset) != 0x743C485E)
3511         return;
3512       *MemoryMailboxAddress =
3513         (void *) readl(ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
3514       *NextCommandMailboxIndex =
3515         readw(ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
3516       *NextStatusMailboxIndex =
3517         readw(ControllerBaseAddress + DAC960_LA_MailboxRegister10Offset);
3518     #endif
3519     }
3520     
3521     
3522     /*
3523       Define the DAC960 PG Series Controller Interface Register Offsets.
3524     */
3525     
3526     #define DAC960_PG_RegisterWindowSize		0x2000
3527     
3528     typedef enum
3529     {
3530       DAC960_PG_InboundDoorBellRegisterOffset =	0x0020,
3531       DAC960_PG_OutboundDoorBellRegisterOffset =	0x002C,
3532       DAC960_PG_InterruptMaskRegisterOffset =	0x0034,
3533       DAC960_PG_CommandOpcodeRegisterOffset =	0x1000,
3534       DAC960_PG_CommandIdentifierRegisterOffset =	0x1001,
3535       DAC960_PG_MailboxRegister2Offset =		0x1002,
3536       DAC960_PG_MailboxRegister3Offset =		0x1003,
3537       DAC960_PG_MailboxRegister4Offset =		0x1004,
3538       DAC960_PG_MailboxRegister5Offset =		0x1005,
3539       DAC960_PG_MailboxRegister6Offset =		0x1006,
3540       DAC960_PG_MailboxRegister7Offset =		0x1007,
3541       DAC960_PG_MailboxRegister8Offset =		0x1008,
3542       DAC960_PG_MailboxRegister9Offset =		0x1009,
3543       DAC960_PG_MailboxRegister10Offset =		0x100A,
3544       DAC960_PG_MailboxRegister11Offset =		0x100B,
3545       DAC960_PG_MailboxRegister12Offset =		0x100C,
3546       DAC960_PG_StatusCommandIdentifierRegOffset =	0x1018,
3547       DAC960_PG_StatusRegisterOffset =		0x101A,
3548       DAC960_PG_ErrorStatusRegisterOffset =		0x103F
3549     }
3550     DAC960_PG_RegisterOffsets_T;
3551     
3552     
3553     /*
3554       Define the structure of the DAC960 PG Series Inbound Door Bell Register.
3555     */
3556     
3557     typedef union DAC960_PG_InboundDoorBellRegister
3558     {
3559       unsigned int All;
3560       struct {
3561         boolean HardwareMailboxNewCommand:1;		/* Bit 0 */
3562         boolean AcknowledgeHardwareMailboxStatus:1;		/* Bit 1 */
3563         boolean GenerateInterrupt:1;			/* Bit 2 */
3564         boolean ControllerReset:1;				/* Bit 3 */
3565         boolean MemoryMailboxNewCommand:1;			/* Bit 4 */
3566         unsigned int :27;					/* Bits 5-31 */
3567       } Write;
3568       struct {
3569         boolean HardwareMailboxFull:1;			/* Bit 0 */
3570         boolean InitializationInProgress:1;			/* Bit 1 */
3571         unsigned int :30;					/* Bits 2-31 */
3572       } Read;
3573     }
3574     DAC960_PG_InboundDoorBellRegister_T;
3575     
3576     
3577     /*
3578       Define the structure of the DAC960 PG Series Outbound Door Bell Register.
3579     */
3580     
3581     typedef union DAC960_PG_OutboundDoorBellRegister
3582     {
3583       unsigned int All;
3584       struct {
3585         boolean AcknowledgeHardwareMailboxInterrupt:1;	/* Bit 0 */
3586         boolean AcknowledgeMemoryMailboxInterrupt:1;	/* Bit 1 */
3587         unsigned int :30;					/* Bits 2-31 */
3588       } Write;
3589       struct {
3590         boolean HardwareMailboxStatusAvailable:1;		/* Bit 0 */
3591         boolean MemoryMailboxStatusAvailable:1;		/* Bit 1 */
3592         unsigned int :30;					/* Bits 2-31 */
3593       } Read;
3594     }
3595     DAC960_PG_OutboundDoorBellRegister_T;
3596     
3597     
3598     /*
3599       Define the structure of the DAC960 PG Series Interrupt Mask Register.
3600     */
3601     
3602     typedef union DAC960_PG_InterruptMaskRegister
3603     {
3604       unsigned int All;
3605       struct {
3606         unsigned int MessageUnitInterruptMask1:2;		/* Bits 0-1 */
3607         boolean DisableInterrupts:1;			/* Bit 2 */
3608         unsigned int MessageUnitInterruptMask2:5;		/* Bits 3-7 */
3609         unsigned int Reserved0:24;				/* Bits 8-31 */
3610       } Bits;
3611     }
3612     DAC960_PG_InterruptMaskRegister_T;
3613     
3614     
3615     /*
3616       Define the structure of the DAC960 PG Series Error Status Register.
3617     */
3618     
3619     typedef union DAC960_PG_ErrorStatusRegister
3620     {
3621       unsigned char All;
3622       struct {
3623         unsigned int :2;					/* Bits 0-1 */
3624         boolean ErrorStatusPending:1;			/* Bit 2 */
3625         unsigned int :5;					/* Bits 3-7 */
3626       } Bits;
3627     }
3628     DAC960_PG_ErrorStatusRegister_T;
3629     
3630     
3631     /*
3632       Define inline functions to provide an abstraction for reading and writing the
3633       DAC960 PG Series Controller Interface Registers.
3634     */
3635     
3636     static inline
3637     void DAC960_PG_HardwareMailboxNewCommand(void *ControllerBaseAddress)
3638     {
3639       DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3640       InboundDoorBellRegister.All = 0;
3641       InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
3642       writel(InboundDoorBellRegister.All,
3643     	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3644     }
3645     
3646     static inline
3647     void DAC960_PG_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
3648     {
3649       DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3650       InboundDoorBellRegister.All = 0;
3651       InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
3652       writel(InboundDoorBellRegister.All,
3653     	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3654     }
3655     
3656     static inline
3657     void DAC960_PG_GenerateInterrupt(void *ControllerBaseAddress)
3658     {
3659       DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3660       InboundDoorBellRegister.All = 0;
3661       InboundDoorBellRegister.Write.GenerateInterrupt = true;
3662       writel(InboundDoorBellRegister.All,
3663     	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3664     }
3665     
3666     static inline
3667     void DAC960_PG_ControllerReset(void *ControllerBaseAddress)
3668     {
3669       DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3670       InboundDoorBellRegister.All = 0;
3671       InboundDoorBellRegister.Write.ControllerReset = true;
3672       writel(InboundDoorBellRegister.All,
3673     	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3674     }
3675     
3676     static inline
3677     void DAC960_PG_MemoryMailboxNewCommand(void *ControllerBaseAddress)
3678     {
3679       DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3680       InboundDoorBellRegister.All = 0;
3681       InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
3682       writel(InboundDoorBellRegister.All,
3683     	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3684     }
3685     
3686     static inline
3687     boolean DAC960_PG_HardwareMailboxFullP(void *ControllerBaseAddress)
3688     {
3689       DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3690       InboundDoorBellRegister.All =
3691         readl(ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3692       return InboundDoorBellRegister.Read.HardwareMailboxFull;
3693     }
3694     
3695     static inline
3696     boolean DAC960_PG_InitializationInProgressP(void *ControllerBaseAddress)
3697     {
3698       DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3699       InboundDoorBellRegister.All =
3700         readl(ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3701       return InboundDoorBellRegister.Read.InitializationInProgress;
3702     }
3703     
3704     static inline
3705     void DAC960_PG_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
3706     {
3707       DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3708       OutboundDoorBellRegister.All = 0;
3709       OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3710       writel(OutboundDoorBellRegister.All,
3711     	 ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
3712     }
3713     
3714     static inline
3715     void DAC960_PG_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
3716     {
3717       DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3718       OutboundDoorBellRegister.All = 0;
3719       OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3720       writel(OutboundDoorBellRegister.All,
3721     	 ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
3722     }
3723     
3724     static inline
3725     void DAC960_PG_AcknowledgeInterrupt(void *ControllerBaseAddress)
3726     {
3727       DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3728       OutboundDoorBellRegister.All = 0;
3729       OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3730       OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3731       writel(OutboundDoorBellRegister.All,
3732     	 ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
3733     }
3734     
3735     static inline
3736     boolean DAC960_PG_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
3737     {
3738       DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3739       OutboundDoorBellRegister.All =
3740         readl(ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
3741       return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
3742     }
3743     
3744     static inline
3745     boolean DAC960_PG_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
3746     {
3747       DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3748       OutboundDoorBellRegister.All =
3749         readl(ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
3750       return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
3751     }
3752     
3753     static inline
3754     void DAC960_PG_EnableInterrupts(void *ControllerBaseAddress)
3755     {
3756       DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
3757       InterruptMaskRegister.All = 0;
3758       InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3;
3759       InterruptMaskRegister.Bits.DisableInterrupts = false;
3760       InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F;
3761       writel(InterruptMaskRegister.All,
3762     	 ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
3763     }
3764     
3765     static inline
3766     void DAC960_PG_DisableInterrupts(void *ControllerBaseAddress)
3767     {
3768       DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
3769       InterruptMaskRegister.All = 0;
3770       InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3;
3771       InterruptMaskRegister.Bits.DisableInterrupts = true;
3772       InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F;
3773       writel(InterruptMaskRegister.All,
3774     	 ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
3775     }
3776     
3777     static inline
3778     boolean DAC960_PG_InterruptsEnabledP(void *ControllerBaseAddress)
3779     {
3780       DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
3781       InterruptMaskRegister.All =
3782         readl(ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
3783       return !InterruptMaskRegister.Bits.DisableInterrupts;
3784     }
3785     
3786     static inline
3787     void DAC960_PG_WriteCommandMailbox(DAC960_V1_CommandMailbox_T
3788     				     *MemoryCommandMailbox,
3789     				   DAC960_V1_CommandMailbox_T
3790     				     *CommandMailbox)
3791     {
3792       MemoryCommandMailbox->Words[1] = CommandMailbox->Words[1];
3793       MemoryCommandMailbox->Words[2] = CommandMailbox->Words[2];
3794       MemoryCommandMailbox->Words[3] = CommandMailbox->Words[3];
3795       wmb();
3796       MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
3797       mb();
3798     }
3799     
3800     static inline
3801     void DAC960_PG_WriteHardwareMailbox(void *ControllerBaseAddress,
3802     				    DAC960_V1_CommandMailbox_T *CommandMailbox)
3803     {
3804       writel(CommandMailbox->Words[0],
3805     	 ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
3806       writel(CommandMailbox->Words[1],
3807     	 ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
3808       writel(CommandMailbox->Words[2],
3809     	 ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
3810       writeb(CommandMailbox->Bytes[12],
3811     	 ControllerBaseAddress + DAC960_PG_MailboxRegister12Offset);
3812     }
3813     
3814     static inline DAC960_V1_CommandIdentifier_T
3815     DAC960_PG_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
3816     {
3817       return readb(ControllerBaseAddress
3818     	       + DAC960_PG_StatusCommandIdentifierRegOffset);
3819     }
3820     
3821     static inline DAC960_V1_CommandStatus_T
3822     DAC960_PG_ReadStatusRegister(void *ControllerBaseAddress)
3823     {
3824       return readw(ControllerBaseAddress + DAC960_PG_StatusRegisterOffset);
3825     }
3826     
3827     static inline boolean
3828     DAC960_PG_ReadErrorStatus(void *ControllerBaseAddress,
3829     			  unsigned char *ErrorStatus,
3830     			  unsigned char *Parameter0,
3831     			  unsigned char *Parameter1)
3832     {
3833       DAC960_PG_ErrorStatusRegister_T ErrorStatusRegister;
3834       ErrorStatusRegister.All =
3835         readb(ControllerBaseAddress + DAC960_PG_ErrorStatusRegisterOffset);
3836       if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
3837       ErrorStatusRegister.Bits.ErrorStatusPending = false;
3838       *ErrorStatus = ErrorStatusRegister.All;
3839       *Parameter0 =
3840         readb(ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
3841       *Parameter1 =
3842         readb(ControllerBaseAddress + DAC960_PG_CommandIdentifierRegisterOffset);
3843       writeb(0, ControllerBaseAddress + DAC960_PG_ErrorStatusRegisterOffset);
3844       return true;
3845     }
3846     
3847     static inline
3848     void DAC960_PG_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
3849     {
3850     #ifdef __i386__
3851       void *ControllerBaseAddress = Controller->BaseAddress;
3852       writel(0x743C485E,
3853     	 ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
3854       writel((unsigned long) Controller->V1.FirstCommandMailbox,
3855     	 ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
3856       writew(Controller->V1.NextCommandMailbox - Controller->V1.FirstCommandMailbox,
3857     	 ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
3858       writew(Controller->V1.NextStatusMailbox - Controller->V1.FirstStatusMailbox,
3859     	 ControllerBaseAddress + DAC960_PG_MailboxRegister10Offset);
3860     #endif
3861     }
3862     
3863     static inline
3864     void DAC960_PG_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
3865     					void **MemoryMailboxAddress,
3866     					short *NextCommandMailboxIndex,
3867     					short *NextStatusMailboxIndex)
3868     {
3869     #ifdef __i386__
3870       void *ControllerBaseAddress = Controller->BaseAddress;
3871       if (readl(ControllerBaseAddress
3872     	    + DAC960_PG_CommandOpcodeRegisterOffset) != 0x743C485E)
3873         return;
3874       *MemoryMailboxAddress =
3875         (void *) readl(ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
3876       *NextCommandMailboxIndex =
3877         readw(ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
3878       *NextStatusMailboxIndex =
3879         readw(ControllerBaseAddress + DAC960_PG_MailboxRegister10Offset);
3880     #endif
3881     }
3882     
3883     
3884     /*
3885       Define the DAC960 PD Series Controller Interface Register Offsets.
3886     */
3887     
3888     #define DAC960_PD_RegisterWindowSize		0x80
3889     
3890     typedef enum
3891     {
3892       DAC960_PD_CommandOpcodeRegisterOffset =	0x00,
3893       DAC960_PD_CommandIdentifierRegisterOffset =	0x01,
3894       DAC960_PD_MailboxRegister2Offset =		0x02,
3895       DAC960_PD_MailboxRegister3Offset =		0x03,
3896       DAC960_PD_MailboxRegister4Offset =		0x04,
3897       DAC960_PD_MailboxRegister5Offset =		0x05,
3898       DAC960_PD_MailboxRegister6Offset =		0x06,
3899       DAC960_PD_MailboxRegister7Offset =		0x07,
3900       DAC960_PD_MailboxRegister8Offset =		0x08,
3901       DAC960_PD_MailboxRegister9Offset =		0x09,
3902       DAC960_PD_MailboxRegister10Offset =		0x0A,
3903       DAC960_PD_MailboxRegister11Offset =		0x0B,
3904       DAC960_PD_MailboxRegister12Offset =		0x0C,
3905       DAC960_PD_StatusCommandIdentifierRegOffset =	0x0D,
3906       DAC960_PD_StatusRegisterOffset =		0x0E,
3907       DAC960_PD_ErrorStatusRegisterOffset =		0x3F,
3908       DAC960_PD_InboundDoorBellRegisterOffset =	0x40,
3909       DAC960_PD_OutboundDoorBellRegisterOffset =	0x41,
3910       DAC960_PD_InterruptEnableRegisterOffset =	0x43
3911     }
3912     DAC960_PD_RegisterOffsets_T;
3913     
3914     
3915     /*
3916       Define the structure of the DAC960 PD Series Inbound Door Bell Register.
3917     */
3918     
3919     typedef union DAC960_PD_InboundDoorBellRegister
3920     {
3921       unsigned char All;
3922       struct {
3923         boolean NewCommand:1;				/* Bit 0 */
3924         boolean AcknowledgeStatus:1;			/* Bit 1 */
3925         boolean GenerateInterrupt:1;			/* Bit 2 */
3926         boolean ControllerReset:1;				/* Bit 3 */
3927         unsigned char :4;					/* Bits 4-7 */
3928       } Write;
3929       struct {
3930         boolean MailboxFull:1;				/* Bit 0 */
3931         boolean InitializationInProgress:1;			/* Bit 1 */
3932         unsigned char :6;					/* Bits 2-7 */
3933       } Read;
3934     }
3935     DAC960_PD_InboundDoorBellRegister_T;
3936     
3937     
3938     /*
3939       Define the structure of the DAC960 PD Series Outbound Door Bell Register.
3940     */
3941     
3942     typedef union DAC960_PD_OutboundDoorBellRegister
3943     {
3944       unsigned char All;
3945       struct {
3946         boolean AcknowledgeInterrupt:1;			/* Bit 0 */
3947         unsigned char :7;					/* Bits 1-7 */
3948       } Write;
3949       struct {
3950         boolean StatusAvailable:1;				/* Bit 0 */
3951         unsigned char :7;					/* Bits 1-7 */
3952       } Read;
3953     }
3954     DAC960_PD_OutboundDoorBellRegister_T;
3955     
3956     
3957     /*
3958       Define the structure of the DAC960 PD Series Interrupt Enable Register.
3959     */
3960     
3961     typedef union DAC960_PD_InterruptEnableRegister
3962     {
3963       unsigned char All;
3964       struct {
3965         boolean EnableInterrupts:1;				/* Bit 0 */
3966         unsigned char :7;					/* Bits 1-7 */
3967       } Bits;
3968     }
3969     DAC960_PD_InterruptEnableRegister_T;
3970     
3971     
3972     /*
3973       Define the structure of the DAC960 PD Series Error Status Register.
3974     */
3975     
3976     typedef union DAC960_PD_ErrorStatusRegister
3977     {
3978       unsigned char All;
3979       struct {
3980         unsigned int :2;					/* Bits 0-1 */
3981         boolean ErrorStatusPending:1;			/* Bit 2 */
3982         unsigned int :5;					/* Bits 3-7 */
3983       } Bits;
3984     }
3985     DAC960_PD_ErrorStatusRegister_T;
3986     
3987     
3988     /*
3989       Define inline functions to provide an abstraction for reading and writing the
3990       DAC960 PD Series Controller Interface Registers.
3991     */
3992     
3993     static inline
3994     void DAC960_PD_NewCommand(void *ControllerBaseAddress)
3995     {
3996       DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
3997       InboundDoorBellRegister.All = 0;
3998       InboundDoorBellRegister.Write.NewCommand = true;
3999       writeb(InboundDoorBellRegister.All,
4000     	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4001     }
4002     
4003     static inline
4004     void DAC960_PD_AcknowledgeStatus(void *ControllerBaseAddress)
4005     {
4006       DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4007       InboundDoorBellRegister.All = 0;
4008       InboundDoorBellRegister.Write.AcknowledgeStatus = true;
4009       writeb(InboundDoorBellRegister.All,
4010     	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4011     }
4012     
4013     static inline
4014     void DAC960_PD_GenerateInterrupt(void *ControllerBaseAddress)
4015     {
4016       DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4017       InboundDoorBellRegister.All = 0;
4018       InboundDoorBellRegister.Write.GenerateInterrupt = true;
4019       writeb(InboundDoorBellRegister.All,
4020     	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4021     }
4022     
4023     static inline
4024     void DAC960_PD_ControllerReset(void *ControllerBaseAddress)
4025     {
4026       DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4027       InboundDoorBellRegister.All = 0;
4028       InboundDoorBellRegister.Write.ControllerReset = true;
4029       writeb(InboundDoorBellRegister.All,
4030     	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4031     }
4032     
4033     static inline
4034     boolean DAC960_PD_MailboxFullP(void *ControllerBaseAddress)
4035     {
4036       DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4037       InboundDoorBellRegister.All =
4038         readb(ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4039       return InboundDoorBellRegister.Read.MailboxFull;
4040     }
4041     
4042     static inline
4043     boolean DAC960_PD_InitializationInProgressP(void *ControllerBaseAddress)
4044     {
4045       DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4046       InboundDoorBellRegister.All =
4047         readb(ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4048       return InboundDoorBellRegister.Read.InitializationInProgress;
4049     }
4050     
4051     static inline
4052     void DAC960_PD_AcknowledgeInterrupt(void *ControllerBaseAddress)
4053     {
4054       DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister;
4055       OutboundDoorBellRegister.All = 0;
4056       OutboundDoorBellRegister.Write.AcknowledgeInterrupt = true;
4057       writeb(OutboundDoorBellRegister.All,
4058     	 ControllerBaseAddress + DAC960_PD_OutboundDoorBellRegisterOffset);
4059     }
4060     
4061     static inline
4062     boolean DAC960_PD_StatusAvailableP(void *ControllerBaseAddress)
4063     {
4064       DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister;
4065       OutboundDoorBellRegister.All =
4066         readb(ControllerBaseAddress + DAC960_PD_OutboundDoorBellRegisterOffset);
4067       return OutboundDoorBellRegister.Read.StatusAvailable;
4068     }
4069     
4070     static inline
4071     void DAC960_PD_EnableInterrupts(void *ControllerBaseAddress)
4072     {
4073       DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
4074       InterruptEnableRegister.All = 0;
4075       InterruptEnableRegister.Bits.EnableInterrupts = true;
4076       writeb(InterruptEnableRegister.All,
4077     	 ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
4078     }
4079     
4080     static inline
4081     void DAC960_PD_DisableInterrupts(void *ControllerBaseAddress)
4082     {
4083       DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
4084       InterruptEnableRegister.All = 0;
4085       InterruptEnableRegister.Bits.EnableInterrupts = false;
4086       writeb(InterruptEnableRegister.All,
4087     	 ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
4088     }
4089     
4090     static inline
4091     boolean DAC960_PD_InterruptsEnabledP(void *ControllerBaseAddress)
4092     {
4093       DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
4094       InterruptEnableRegister.All =
4095         readb(ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
4096       return InterruptEnableRegister.Bits.EnableInterrupts;
4097     }
4098     
4099     static inline
4100     void DAC960_PD_WriteCommandMailbox(void *ControllerBaseAddress,
4101     				   DAC960_V1_CommandMailbox_T *CommandMailbox)
4102     {
4103       writel(CommandMailbox->Words[0],
4104     	 ControllerBaseAddress + DAC960_PD_CommandOpcodeRegisterOffset);
4105       writel(CommandMailbox->Words[1],
4106     	 ControllerBaseAddress + DAC960_PD_MailboxRegister4Offset);
4107       writel(CommandMailbox->Words[2],
4108     	 ControllerBaseAddress + DAC960_PD_MailboxRegister8Offset);
4109       writeb(CommandMailbox->Bytes[12],
4110     	 ControllerBaseAddress + DAC960_PD_MailboxRegister12Offset);
4111     }
4112     
4113     static inline DAC960_V1_CommandIdentifier_T
4114     DAC960_PD_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
4115     {
4116       return readb(ControllerBaseAddress
4117     	       + DAC960_PD_StatusCommandIdentifierRegOffset);
4118     }
4119     
4120     static inline DAC960_V1_CommandStatus_T
4121     DAC960_PD_ReadStatusRegister(void *ControllerBaseAddress)
4122     {
4123       return readw(ControllerBaseAddress + DAC960_PD_StatusRegisterOffset);
4124     }
4125     
4126     static inline boolean
4127     DAC960_PD_ReadErrorStatus(void *ControllerBaseAddress,
4128     			  unsigned char *ErrorStatus,
4129     			  unsigned char *Parameter0,
4130     			  unsigned char *Parameter1)
4131     {
4132       DAC960_PD_ErrorStatusRegister_T ErrorStatusRegister;
4133       ErrorStatusRegister.All =
4134         readb(ControllerBaseAddress + DAC960_PD_ErrorStatusRegisterOffset);
4135       if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
4136       ErrorStatusRegister.Bits.ErrorStatusPending = false;
4137       *ErrorStatus = ErrorStatusRegister.All;
4138       *Parameter0 =
4139         readb(ControllerBaseAddress + DAC960_PD_CommandOpcodeRegisterOffset);
4140       *Parameter1 =
4141         readb(ControllerBaseAddress + DAC960_PD_CommandIdentifierRegisterOffset);
4142       writeb(0, ControllerBaseAddress + DAC960_PD_ErrorStatusRegisterOffset);
4143       return true;
4144     }
4145     
4146     
4147     /*
4148       Define prototypes for the forward referenced DAC960 Driver Internal Functions.
4149     */
4150     
4151     static void DAC960_FinalizeController(DAC960_Controller_T *);
4152     static int DAC960_Finalize(NotifierBlock_T *, unsigned long, void *);
4153     static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *);
4154     static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *);
4155     static void DAC960_RequestFunction(RequestQueue_T *);
4156     static void DAC960_BA_InterruptHandler(int, void *, Registers_T *);
4157     static void DAC960_LP_InterruptHandler(int, void *, Registers_T *);
4158     static void DAC960_LA_InterruptHandler(int, void *, Registers_T *);
4159     static void DAC960_PG_InterruptHandler(int, void *, Registers_T *);
4160     static void DAC960_PD_InterruptHandler(int, void *, Registers_T *);
4161     static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *);
4162     static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *);
4163     static void DAC960_MonitoringTimerFunction(unsigned long);
4164     static int DAC960_Open(Inode_T *, File_T *);
4165     static int DAC960_Release(Inode_T *, File_T *);
4166     static int DAC960_IOCTL(Inode_T *, File_T *, unsigned int, unsigned long);
4167     static int DAC960_UserIOCTL(Inode_T *, File_T *, unsigned int, unsigned long);
4168     static void DAC960_Message(DAC960_MessageLevel_T, unsigned char *,
4169     			   DAC960_Controller_T *, ...);
4170     static void DAC960_CreateProcEntries(void);
4171     static void DAC960_DestroyProcEntries(void);
4172     
4173     
4174     /*
4175       Export the Kernel Mode IOCTL interface.
4176     */
4177     
4178     EXPORT_SYMBOL(DAC960_KernelIOCTL);
4179     
4180     
4181     #endif /* DAC960_DriverVersion */
4182