~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/block/DAC960.h

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.