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