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