Merge master.kernel.org:/home/rmk/linux-2.6-serial
[linux-2.6] / 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   DAC960_GEM_Controller =                       7,      /* AcceleRAID 4/5/600 */
2119 }
2120 DAC960_HardwareType_T;
2121
2122
2123 /*
2124   Define the Driver Message Levels.
2125 */
2126
2127 typedef enum DAC960_MessageLevel
2128 {
2129   DAC960_AnnounceLevel =                        0,
2130   DAC960_InfoLevel =                            1,
2131   DAC960_NoticeLevel =                          2,
2132   DAC960_WarningLevel =                         3,
2133   DAC960_ErrorLevel =                           4,
2134   DAC960_ProgressLevel =                        5,
2135   DAC960_CriticalLevel =                        6,
2136   DAC960_UserCriticalLevel =                    7
2137 }
2138 DAC960_MessageLevel_T;
2139
2140 static char
2141   *DAC960_MessageLevelMap[] =
2142     { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING,
2143       KERN_ERR, KERN_CRIT, KERN_CRIT, KERN_CRIT };
2144
2145
2146 /*
2147   Define Driver Message macros.
2148 */
2149
2150 #define DAC960_Announce(Format, Arguments...) \
2151   DAC960_Message(DAC960_AnnounceLevel, Format, ##Arguments)
2152
2153 #define DAC960_Info(Format, Arguments...) \
2154   DAC960_Message(DAC960_InfoLevel, Format, ##Arguments)
2155
2156 #define DAC960_Notice(Format, Arguments...) \
2157   DAC960_Message(DAC960_NoticeLevel, Format, ##Arguments)
2158
2159 #define DAC960_Warning(Format, Arguments...) \
2160   DAC960_Message(DAC960_WarningLevel, Format, ##Arguments)
2161
2162 #define DAC960_Error(Format, Arguments...) \
2163   DAC960_Message(DAC960_ErrorLevel, Format, ##Arguments)
2164
2165 #define DAC960_Progress(Format, Arguments...) \
2166   DAC960_Message(DAC960_ProgressLevel, Format, ##Arguments)
2167
2168 #define DAC960_Critical(Format, Arguments...) \
2169   DAC960_Message(DAC960_CriticalLevel, Format, ##Arguments)
2170
2171 #define DAC960_UserCritical(Format, Arguments...) \
2172   DAC960_Message(DAC960_UserCriticalLevel, Format, ##Arguments)
2173
2174
2175 struct DAC960_privdata {
2176         DAC960_HardwareType_T   HardwareType;
2177         DAC960_FirmwareType_T   FirmwareType;
2178         irqreturn_t (*InterruptHandler)(int, void *, struct pt_regs *);
2179         unsigned int            MemoryWindowSize;
2180 };
2181
2182
2183 /*
2184   Define the DAC960 V1 Firmware Controller Status Mailbox structure.
2185 */
2186
2187 typedef union DAC960_V1_StatusMailbox
2188 {
2189   unsigned int Word;                                    /* Word 0 */
2190   struct {
2191     DAC960_V1_CommandIdentifier_T CommandIdentifier;    /* Byte 0 */
2192     unsigned char :7;                                   /* Byte 1 Bits 0-6 */
2193     boolean Valid:1;                                    /* Byte 1 Bit 7 */
2194     DAC960_V1_CommandStatus_T CommandStatus;            /* Bytes 2-3 */
2195   } Fields;
2196 }
2197 DAC960_V1_StatusMailbox_T;
2198
2199
2200 /*
2201   Define the DAC960 V2 Firmware Controller Status Mailbox structure.
2202 */
2203
2204 typedef union DAC960_V2_StatusMailbox
2205 {
2206   unsigned int Words[2];                                /* Words 0-1 */
2207   struct {
2208     DAC960_V2_CommandIdentifier_T CommandIdentifier;    /* Bytes 0-1 */
2209     DAC960_V2_CommandStatus_T CommandStatus;            /* Byte 2 */
2210     unsigned char RequestSenseLength;                   /* Byte 3 */
2211     int DataTransferResidue;                            /* Bytes 4-7 */
2212   } Fields;
2213 }
2214 DAC960_V2_StatusMailbox_T;
2215
2216
2217 /*
2218   Define the DAC960 Driver Command Types.
2219 */
2220
2221 typedef enum
2222 {
2223   DAC960_ReadCommand =                          1,
2224   DAC960_WriteCommand =                         2,
2225   DAC960_ReadRetryCommand =                     3,
2226   DAC960_WriteRetryCommand =                    4,
2227   DAC960_MonitoringCommand =                    5,
2228   DAC960_ImmediateCommand =                     6,
2229   DAC960_QueuedCommand =                        7
2230 }
2231 DAC960_CommandType_T;
2232
2233
2234 /*
2235   Define the DAC960 Driver Command structure.
2236 */
2237
2238 typedef struct DAC960_Command
2239 {
2240   int CommandIdentifier;
2241   DAC960_CommandType_T CommandType;
2242   struct DAC960_Controller *Controller;
2243   struct DAC960_Command *Next;
2244   struct completion *Completion;
2245   unsigned int LogicalDriveNumber;
2246   unsigned int BlockNumber;
2247   unsigned int BlockCount;
2248   unsigned int SegmentCount;
2249   int   DmaDirection;
2250   struct scatterlist *cmd_sglist;
2251   struct request *Request;
2252   union {
2253     struct {
2254       DAC960_V1_CommandMailbox_T CommandMailbox;
2255       DAC960_V1_KernelCommand_T *KernelCommand;
2256       DAC960_V1_CommandStatus_T CommandStatus;
2257       DAC960_V1_ScatterGatherSegment_T *ScatterGatherList;
2258       dma_addr_t ScatterGatherListDMA;
2259       struct scatterlist ScatterList[DAC960_V1_ScatterGatherLimit];
2260       unsigned int EndMarker[0];
2261     } V1;
2262     struct {
2263       DAC960_V2_CommandMailbox_T CommandMailbox;
2264       DAC960_V2_KernelCommand_T *KernelCommand;
2265       DAC960_V2_CommandStatus_T CommandStatus;
2266       unsigned char RequestSenseLength;
2267       int DataTransferResidue;
2268       DAC960_V2_ScatterGatherSegment_T *ScatterGatherList;
2269       dma_addr_t ScatterGatherListDMA;
2270       DAC960_SCSI_RequestSense_T *RequestSense;
2271       dma_addr_t RequestSenseDMA;
2272       struct scatterlist ScatterList[DAC960_V2_ScatterGatherLimit];
2273       unsigned int EndMarker[0];
2274     } V2;
2275   } FW;
2276 }
2277 DAC960_Command_T;
2278
2279
2280 /*
2281   Define the DAC960 Driver Controller structure.
2282 */
2283
2284 typedef struct DAC960_Controller
2285 {
2286   void __iomem *BaseAddress;
2287   void __iomem *MemoryMappedAddress;
2288   DAC960_FirmwareType_T FirmwareType;
2289   DAC960_HardwareType_T HardwareType;
2290   DAC960_IO_Address_T IO_Address;
2291   DAC960_PCI_Address_T PCI_Address;
2292   struct pci_dev *PCIDevice;
2293   unsigned char ControllerNumber;
2294   unsigned char ControllerName[4];
2295   unsigned char ModelName[20];
2296   unsigned char FullModelName[28];
2297   unsigned char FirmwareVersion[12];
2298   unsigned char Bus;
2299   unsigned char Device;
2300   unsigned char Function;
2301   unsigned char IRQ_Channel;
2302   unsigned char Channels;
2303   unsigned char Targets;
2304   unsigned char MemorySize;
2305   unsigned char LogicalDriveCount;
2306   unsigned short CommandAllocationGroupSize;
2307   unsigned short ControllerQueueDepth;
2308   unsigned short DriverQueueDepth;
2309   unsigned short MaxBlocksPerCommand;
2310   unsigned short ControllerScatterGatherLimit;
2311   unsigned short DriverScatterGatherLimit;
2312   u64           BounceBufferLimit;
2313   unsigned int CombinedStatusBufferLength;
2314   unsigned int InitialStatusLength;
2315   unsigned int CurrentStatusLength;
2316   unsigned int ProgressBufferLength;
2317   unsigned int UserStatusLength;
2318   struct dma_loaf DmaPages;
2319   unsigned long MonitoringTimerCount;
2320   unsigned long PrimaryMonitoringTime;
2321   unsigned long SecondaryMonitoringTime;
2322   unsigned long ShutdownMonitoringTimer;
2323   unsigned long LastProgressReportTime;
2324   unsigned long LastCurrentStatusTime;
2325   boolean ControllerInitialized;
2326   boolean MonitoringCommandDeferred;
2327   boolean EphemeralProgressMessage;
2328   boolean DriveSpinUpMessageDisplayed;
2329   boolean MonitoringAlertMode;
2330   boolean SuppressEnclosureMessages;
2331   struct timer_list MonitoringTimer;
2332   struct gendisk *disks[DAC960_MaxLogicalDrives];
2333   struct pci_pool *ScatterGatherPool;
2334   DAC960_Command_T *FreeCommands;
2335   unsigned char *CombinedStatusBuffer;
2336   unsigned char *CurrentStatusBuffer;
2337   struct request_queue *RequestQueue[DAC960_MaxLogicalDrives];
2338   int req_q_index;
2339   spinlock_t queue_lock;
2340   wait_queue_head_t CommandWaitQueue;
2341   wait_queue_head_t HealthStatusWaitQueue;
2342   DAC960_Command_T InitialCommand;
2343   DAC960_Command_T *Commands[DAC960_MaxDriverQueueDepth];
2344   struct proc_dir_entry *ControllerProcEntry;
2345   boolean LogicalDriveInitiallyAccessible[DAC960_MaxLogicalDrives];
2346   void (*QueueCommand)(DAC960_Command_T *Command);
2347   boolean (*ReadControllerConfiguration)(struct DAC960_Controller *);
2348   boolean (*ReadDeviceConfiguration)(struct DAC960_Controller *);
2349   boolean (*ReportDeviceConfiguration)(struct DAC960_Controller *);
2350   void (*QueueReadWriteCommand)(DAC960_Command_T *Command);
2351   union {
2352     struct {
2353       unsigned char GeometryTranslationHeads;
2354       unsigned char GeometryTranslationSectors;
2355       unsigned char PendingRebuildFlag;
2356       unsigned short StripeSize;
2357       unsigned short SegmentSize;
2358       unsigned short NewEventLogSequenceNumber;
2359       unsigned short OldEventLogSequenceNumber;
2360       unsigned short DeviceStateChannel;
2361       unsigned short DeviceStateTargetID;
2362       boolean DualModeMemoryMailboxInterface;
2363       boolean BackgroundInitializationStatusSupported;
2364       boolean SAFTE_EnclosureManagementEnabled;
2365       boolean NeedLogicalDriveInformation;
2366       boolean NeedErrorTableInformation;
2367       boolean NeedDeviceStateInformation;
2368       boolean NeedDeviceInquiryInformation;
2369       boolean NeedDeviceSerialNumberInformation;
2370       boolean NeedRebuildProgress;
2371       boolean NeedConsistencyCheckProgress;
2372       boolean NeedBackgroundInitializationStatus;
2373       boolean StartDeviceStateScan;
2374       boolean RebuildProgressFirst;
2375       boolean RebuildFlagPending;
2376       boolean RebuildStatusPending;
2377
2378       dma_addr_t        FirstCommandMailboxDMA;
2379       DAC960_V1_CommandMailbox_T *FirstCommandMailbox;
2380       DAC960_V1_CommandMailbox_T *LastCommandMailbox;
2381       DAC960_V1_CommandMailbox_T *NextCommandMailbox;
2382       DAC960_V1_CommandMailbox_T *PreviousCommandMailbox1;
2383       DAC960_V1_CommandMailbox_T *PreviousCommandMailbox2;
2384
2385       dma_addr_t        FirstStatusMailboxDMA;
2386       DAC960_V1_StatusMailbox_T *FirstStatusMailbox;
2387       DAC960_V1_StatusMailbox_T *LastStatusMailbox;
2388       DAC960_V1_StatusMailbox_T *NextStatusMailbox;
2389
2390       DAC960_V1_DCDB_T *MonitoringDCDB;
2391       dma_addr_t MonitoringDCDB_DMA;
2392
2393       DAC960_V1_Enquiry_T Enquiry;
2394       DAC960_V1_Enquiry_T *NewEnquiry;
2395       dma_addr_t NewEnquiryDMA;
2396
2397       DAC960_V1_ErrorTable_T ErrorTable;
2398       DAC960_V1_ErrorTable_T *NewErrorTable;
2399       dma_addr_t NewErrorTableDMA;
2400
2401       DAC960_V1_EventLogEntry_T *EventLogEntry;
2402       dma_addr_t EventLogEntryDMA;
2403
2404       DAC960_V1_RebuildProgress_T *RebuildProgress;
2405       dma_addr_t RebuildProgressDMA;
2406       DAC960_V1_CommandStatus_T LastRebuildStatus;
2407       DAC960_V1_CommandStatus_T PendingRebuildStatus;
2408
2409       DAC960_V1_LogicalDriveInformationArray_T LogicalDriveInformation;
2410       DAC960_V1_LogicalDriveInformationArray_T *NewLogicalDriveInformation;
2411       dma_addr_t NewLogicalDriveInformationDMA;
2412
2413       DAC960_V1_BackgroundInitializationStatus_T
2414                 *BackgroundInitializationStatus;
2415       dma_addr_t BackgroundInitializationStatusDMA;
2416       DAC960_V1_BackgroundInitializationStatus_T
2417                 LastBackgroundInitializationStatus;
2418
2419       DAC960_V1_DeviceState_T
2420         DeviceState[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
2421       DAC960_V1_DeviceState_T *NewDeviceState;
2422       dma_addr_t        NewDeviceStateDMA;
2423
2424       DAC960_SCSI_Inquiry_T
2425         InquiryStandardData[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
2426       DAC960_SCSI_Inquiry_T *NewInquiryStandardData;
2427       dma_addr_t NewInquiryStandardDataDMA;
2428
2429       DAC960_SCSI_Inquiry_UnitSerialNumber_T
2430         InquiryUnitSerialNumber[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
2431       DAC960_SCSI_Inquiry_UnitSerialNumber_T *NewInquiryUnitSerialNumber;
2432       dma_addr_t NewInquiryUnitSerialNumberDMA;
2433
2434       int DeviceResetCount[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
2435       boolean DirectCommandActive[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
2436     } V1;
2437     struct {
2438       unsigned int StatusChangeCounter;
2439       unsigned int NextEventSequenceNumber;
2440       unsigned int PhysicalDeviceIndex;
2441       boolean NeedLogicalDeviceInformation;
2442       boolean NeedPhysicalDeviceInformation;
2443       boolean NeedDeviceSerialNumberInformation;
2444       boolean StartLogicalDeviceInformationScan;
2445       boolean StartPhysicalDeviceInformationScan;
2446       struct pci_pool *RequestSensePool;
2447
2448       dma_addr_t        FirstCommandMailboxDMA;
2449       DAC960_V2_CommandMailbox_T *FirstCommandMailbox;
2450       DAC960_V2_CommandMailbox_T *LastCommandMailbox;
2451       DAC960_V2_CommandMailbox_T *NextCommandMailbox;
2452       DAC960_V2_CommandMailbox_T *PreviousCommandMailbox1;
2453       DAC960_V2_CommandMailbox_T *PreviousCommandMailbox2;
2454
2455       dma_addr_t        FirstStatusMailboxDMA;
2456       DAC960_V2_StatusMailbox_T *FirstStatusMailbox;
2457       DAC960_V2_StatusMailbox_T *LastStatusMailbox;
2458       DAC960_V2_StatusMailbox_T *NextStatusMailbox;
2459
2460       dma_addr_t        HealthStatusBufferDMA;
2461       DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer;
2462
2463       DAC960_V2_ControllerInfo_T ControllerInformation;
2464       DAC960_V2_ControllerInfo_T *NewControllerInformation;
2465       dma_addr_t        NewControllerInformationDMA;
2466
2467       DAC960_V2_LogicalDeviceInfo_T
2468         *LogicalDeviceInformation[DAC960_MaxLogicalDrives];
2469       DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInformation;
2470       dma_addr_t         NewLogicalDeviceInformationDMA;
2471
2472       DAC960_V2_PhysicalDeviceInfo_T
2473         *PhysicalDeviceInformation[DAC960_V2_MaxPhysicalDevices];
2474       DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInformation;
2475       dma_addr_t        NewPhysicalDeviceInformationDMA;
2476
2477       DAC960_SCSI_Inquiry_UnitSerialNumber_T *NewInquiryUnitSerialNumber;
2478       dma_addr_t        NewInquiryUnitSerialNumberDMA;
2479       DAC960_SCSI_Inquiry_UnitSerialNumber_T
2480         *InquiryUnitSerialNumber[DAC960_V2_MaxPhysicalDevices];
2481
2482       DAC960_V2_Event_T *Event;
2483       dma_addr_t EventDMA;
2484
2485       DAC960_V2_PhysicalToLogicalDevice_T *PhysicalToLogicalDevice;
2486       dma_addr_t PhysicalToLogicalDeviceDMA;
2487
2488       DAC960_V2_PhysicalDevice_T
2489         LogicalDriveToVirtualDevice[DAC960_MaxLogicalDrives];
2490       boolean LogicalDriveFoundDuringScan[DAC960_MaxLogicalDrives];
2491     } V2;
2492   } FW;
2493   unsigned char ProgressBuffer[DAC960_ProgressBufferSize];
2494   unsigned char UserStatusBuffer[DAC960_UserMessageSize];
2495 }
2496 DAC960_Controller_T;
2497
2498
2499 /*
2500   Simplify access to Firmware Version Dependent Data Structure Components
2501   and Functions.
2502 */
2503
2504 #define V1                              FW.V1
2505 #define V2                              FW.V2
2506 #define DAC960_QueueCommand(Command) \
2507   (Controller->QueueCommand)(Command)
2508 #define DAC960_ReadControllerConfiguration(Controller) \
2509   (Controller->ReadControllerConfiguration)(Controller)
2510 #define DAC960_ReadDeviceConfiguration(Controller) \
2511   (Controller->ReadDeviceConfiguration)(Controller)
2512 #define DAC960_ReportDeviceConfiguration(Controller) \
2513   (Controller->ReportDeviceConfiguration)(Controller)
2514 #define DAC960_QueueReadWriteCommand(Command) \
2515   (Controller->QueueReadWriteCommand)(Command)
2516
2517 /*
2518  * dma_addr_writeql is provided to write dma_addr_t types
2519  * to a 64-bit pci address space register.  The controller
2520  * will accept having the register written as two 32-bit
2521  * values.
2522  *
2523  * In HIGHMEM kernels, dma_addr_t is a 64-bit value.
2524  * without HIGHMEM,  dma_addr_t is a 32-bit value.
2525  *
2526  * The compiler should always fix up the assignment
2527  * to u.wq appropriately, depending upon the size of
2528  * dma_addr_t.
2529  */
2530 static inline
2531 void dma_addr_writeql(dma_addr_t addr, void __iomem *write_address)
2532 {
2533         union {
2534                 u64 wq;
2535                 uint wl[2];
2536         } u;
2537
2538         u.wq = addr;
2539
2540         writel(u.wl[0], write_address);
2541         writel(u.wl[1], write_address + 4);
2542 }
2543
2544 /*
2545   Define the DAC960 GEM Series Controller Interface Register Offsets.
2546  */
2547
2548 #define DAC960_GEM_RegisterWindowSize   0x600
2549
2550 typedef enum
2551 {
2552   DAC960_GEM_InboundDoorBellRegisterReadSetOffset   =   0x214,
2553   DAC960_GEM_InboundDoorBellRegisterClearOffset     =   0x218,
2554   DAC960_GEM_OutboundDoorBellRegisterReadSetOffset  =   0x224,
2555   DAC960_GEM_OutboundDoorBellRegisterClearOffset    =   0x228,
2556   DAC960_GEM_InterruptStatusRegisterOffset          =   0x208,
2557   DAC960_GEM_InterruptMaskRegisterReadSetOffset     =   0x22C,
2558   DAC960_GEM_InterruptMaskRegisterClearOffset       =   0x230,
2559   DAC960_GEM_CommandMailboxBusAddressOffset         =   0x510,
2560   DAC960_GEM_CommandStatusOffset                    =   0x518,
2561   DAC960_GEM_ErrorStatusRegisterReadSetOffset       =   0x224,
2562   DAC960_GEM_ErrorStatusRegisterClearOffset         =   0x228,
2563 }
2564 DAC960_GEM_RegisterOffsets_T;
2565
2566 /*
2567   Define the structure of the DAC960 GEM Series Inbound Door Bell
2568  */
2569
2570 typedef union DAC960_GEM_InboundDoorBellRegister
2571 {
2572   unsigned int All;
2573   struct {
2574     unsigned int :24;
2575     boolean HardwareMailboxNewCommand:1;
2576     boolean AcknowledgeHardwareMailboxStatus:1;
2577     boolean GenerateInterrupt:1;
2578     boolean ControllerReset:1;
2579     boolean MemoryMailboxNewCommand:1;
2580     unsigned int :3;
2581   } Write;
2582   struct {
2583     unsigned int :24;
2584     boolean HardwareMailboxFull:1;
2585     boolean InitializationInProgress:1;
2586     unsigned int :6;
2587   } Read;
2588 }
2589 DAC960_GEM_InboundDoorBellRegister_T;
2590
2591 /*
2592   Define the structure of the DAC960 GEM Series Outbound Door Bell Register.
2593  */
2594 typedef union DAC960_GEM_OutboundDoorBellRegister
2595 {
2596   unsigned int All;
2597   struct {
2598     unsigned int :24;
2599     boolean AcknowledgeHardwareMailboxInterrupt:1;
2600     boolean AcknowledgeMemoryMailboxInterrupt:1;
2601     unsigned int :6;
2602   } Write;
2603   struct {
2604     unsigned int :24;
2605     boolean HardwareMailboxStatusAvailable:1;
2606     boolean MemoryMailboxStatusAvailable:1;
2607     unsigned int :6;
2608   } Read;
2609 }
2610 DAC960_GEM_OutboundDoorBellRegister_T;
2611
2612 /*
2613   Define the structure of the DAC960 GEM Series Interrupt Mask Register.
2614  */
2615 typedef union DAC960_GEM_InterruptMaskRegister
2616 {
2617   unsigned int All;
2618   struct {
2619     unsigned int :16;
2620     unsigned int :8;
2621     unsigned int HardwareMailboxInterrupt:1;
2622     unsigned int MemoryMailboxInterrupt:1;
2623     unsigned int :6;
2624   } Bits;
2625 }
2626 DAC960_GEM_InterruptMaskRegister_T;
2627
2628 /*
2629   Define the structure of the DAC960 GEM Series Error Status Register.
2630  */
2631
2632 typedef union DAC960_GEM_ErrorStatusRegister
2633 {
2634   unsigned int All;
2635   struct {
2636     unsigned int :24;
2637     unsigned int :5;
2638     boolean ErrorStatusPending:1;
2639     unsigned int :2;
2640   } Bits;
2641 }
2642 DAC960_GEM_ErrorStatusRegister_T;
2643
2644 /*
2645   Define inline functions to provide an abstraction for reading and writing the
2646   DAC960 GEM Series Controller Interface Registers.
2647 */
2648
2649 static inline
2650 void DAC960_GEM_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress)
2651 {
2652   DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
2653   InboundDoorBellRegister.All = 0;
2654   InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
2655   writel(InboundDoorBellRegister.All,
2656          ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
2657 }
2658
2659 static inline
2660 void DAC960_GEM_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress)
2661 {
2662   DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
2663   InboundDoorBellRegister.All = 0;
2664   InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
2665   writel(InboundDoorBellRegister.All,
2666          ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterClearOffset);
2667 }
2668
2669 static inline
2670 void DAC960_GEM_GenerateInterrupt(void __iomem *ControllerBaseAddress)
2671 {
2672   DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
2673   InboundDoorBellRegister.All = 0;
2674   InboundDoorBellRegister.Write.GenerateInterrupt = true;
2675   writel(InboundDoorBellRegister.All,
2676          ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
2677 }
2678
2679 static inline
2680 void DAC960_GEM_ControllerReset(void __iomem *ControllerBaseAddress)
2681 {
2682   DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
2683   InboundDoorBellRegister.All = 0;
2684   InboundDoorBellRegister.Write.ControllerReset = true;
2685   writel(InboundDoorBellRegister.All,
2686          ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
2687 }
2688
2689 static inline
2690 void DAC960_GEM_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
2691 {
2692   DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
2693   InboundDoorBellRegister.All = 0;
2694   InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
2695   writel(InboundDoorBellRegister.All,
2696          ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
2697 }
2698
2699 static inline
2700 boolean DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
2701 {
2702   DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
2703   InboundDoorBellRegister.All =
2704     readl(ControllerBaseAddress +
2705           DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
2706   return InboundDoorBellRegister.Read.HardwareMailboxFull;
2707 }
2708
2709 static inline
2710 boolean DAC960_GEM_InitializationInProgressP(void __iomem *ControllerBaseAddress)
2711 {
2712   DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
2713   InboundDoorBellRegister.All =
2714     readl(ControllerBaseAddress +
2715           DAC960_GEM_InboundDoorBellRegisterReadSetOffset);
2716   return InboundDoorBellRegister.Read.InitializationInProgress;
2717 }
2718
2719 static inline
2720 void DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress)
2721 {
2722   DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2723   OutboundDoorBellRegister.All = 0;
2724   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
2725   writel(OutboundDoorBellRegister.All,
2726          ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset);
2727 }
2728
2729 static inline
2730 void DAC960_GEM_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress)
2731 {
2732   DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2733   OutboundDoorBellRegister.All = 0;
2734   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
2735   writel(OutboundDoorBellRegister.All,
2736          ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset);
2737 }
2738
2739 static inline
2740 void DAC960_GEM_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
2741 {
2742   DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2743   OutboundDoorBellRegister.All = 0;
2744   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
2745   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
2746   writel(OutboundDoorBellRegister.All,
2747          ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset);
2748 }
2749
2750 static inline
2751 boolean DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
2752 {
2753   DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2754   OutboundDoorBellRegister.All =
2755     readl(ControllerBaseAddress +
2756           DAC960_GEM_OutboundDoorBellRegisterReadSetOffset);
2757   return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
2758 }
2759
2760 static inline
2761 boolean DAC960_GEM_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
2762 {
2763   DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2764   OutboundDoorBellRegister.All =
2765     readl(ControllerBaseAddress +
2766           DAC960_GEM_OutboundDoorBellRegisterReadSetOffset);
2767   return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
2768 }
2769
2770 static inline
2771 void DAC960_GEM_EnableInterrupts(void __iomem *ControllerBaseAddress)
2772 {
2773   DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister;
2774   InterruptMaskRegister.All = 0;
2775   InterruptMaskRegister.Bits.HardwareMailboxInterrupt = true;
2776   InterruptMaskRegister.Bits.MemoryMailboxInterrupt = true;
2777   writel(InterruptMaskRegister.All,
2778          ControllerBaseAddress + DAC960_GEM_InterruptMaskRegisterClearOffset);
2779 }
2780
2781 static inline
2782 void DAC960_GEM_DisableInterrupts(void __iomem *ControllerBaseAddress)
2783 {
2784   DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister;
2785   InterruptMaskRegister.All = 0;
2786   InterruptMaskRegister.Bits.HardwareMailboxInterrupt = true;
2787   InterruptMaskRegister.Bits.MemoryMailboxInterrupt = true;
2788   writel(InterruptMaskRegister.All,
2789          ControllerBaseAddress + DAC960_GEM_InterruptMaskRegisterReadSetOffset);
2790 }
2791
2792 static inline
2793 boolean DAC960_GEM_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
2794 {
2795   DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister;
2796   InterruptMaskRegister.All =
2797     readl(ControllerBaseAddress +
2798           DAC960_GEM_InterruptMaskRegisterReadSetOffset);
2799   return !(InterruptMaskRegister.Bits.HardwareMailboxInterrupt ||
2800            InterruptMaskRegister.Bits.MemoryMailboxInterrupt);
2801 }
2802
2803 static inline
2804 void DAC960_GEM_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
2805                                      *MemoryCommandMailbox,
2806                                    DAC960_V2_CommandMailbox_T
2807                                      *CommandMailbox)
2808 {
2809   memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
2810          sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
2811   wmb();
2812   MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
2813   mb();
2814 }
2815
2816 static inline
2817 void DAC960_GEM_WriteHardwareMailbox(void __iomem *ControllerBaseAddress,
2818                                     dma_addr_t CommandMailboxDMA)
2819 {
2820         dma_addr_writeql(CommandMailboxDMA,
2821                 ControllerBaseAddress +
2822                 DAC960_GEM_CommandMailboxBusAddressOffset);
2823 }
2824
2825 static inline DAC960_V2_CommandIdentifier_T
2826 DAC960_GEM_ReadCommandIdentifier(void __iomem *ControllerBaseAddress)
2827 {
2828   return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset);
2829 }
2830
2831 static inline DAC960_V2_CommandStatus_T
2832 DAC960_GEM_ReadCommandStatus(void __iomem *ControllerBaseAddress)
2833 {
2834   return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset + 2);
2835 }
2836
2837 static inline boolean
2838 DAC960_GEM_ReadErrorStatus(void __iomem *ControllerBaseAddress,
2839                           unsigned char *ErrorStatus,
2840                           unsigned char *Parameter0,
2841                           unsigned char *Parameter1)
2842 {
2843   DAC960_GEM_ErrorStatusRegister_T ErrorStatusRegister;
2844   ErrorStatusRegister.All =
2845     readl(ControllerBaseAddress + DAC960_GEM_ErrorStatusRegisterReadSetOffset);
2846   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
2847   ErrorStatusRegister.Bits.ErrorStatusPending = false;
2848   *ErrorStatus = ErrorStatusRegister.All;
2849   *Parameter0 =
2850     readb(ControllerBaseAddress + DAC960_GEM_CommandMailboxBusAddressOffset + 0);
2851   *Parameter1 =
2852     readb(ControllerBaseAddress + DAC960_GEM_CommandMailboxBusAddressOffset + 1);
2853   writel(0x03000000, ControllerBaseAddress +
2854          DAC960_GEM_ErrorStatusRegisterClearOffset);
2855   return true;
2856 }
2857
2858 /*
2859   Define the DAC960 BA Series Controller Interface Register Offsets.
2860 */
2861
2862 #define DAC960_BA_RegisterWindowSize            0x80
2863
2864 typedef enum
2865 {
2866   DAC960_BA_InboundDoorBellRegisterOffset =     0x60,
2867   DAC960_BA_OutboundDoorBellRegisterOffset =    0x61,
2868   DAC960_BA_InterruptStatusRegisterOffset =     0x30,
2869   DAC960_BA_InterruptMaskRegisterOffset =       0x34,
2870   DAC960_BA_CommandMailboxBusAddressOffset =    0x50,
2871   DAC960_BA_CommandStatusOffset =               0x58,
2872   DAC960_BA_ErrorStatusRegisterOffset =         0x63
2873 }
2874 DAC960_BA_RegisterOffsets_T;
2875
2876
2877 /*
2878   Define the structure of the DAC960 BA Series Inbound Door Bell Register.
2879 */
2880
2881 typedef union DAC960_BA_InboundDoorBellRegister
2882 {
2883   unsigned char All;
2884   struct {
2885     boolean HardwareMailboxNewCommand:1;                /* Bit 0 */
2886     boolean AcknowledgeHardwareMailboxStatus:1;         /* Bit 1 */
2887     boolean GenerateInterrupt:1;                        /* Bit 2 */
2888     boolean ControllerReset:1;                          /* Bit 3 */
2889     boolean MemoryMailboxNewCommand:1;                  /* Bit 4 */
2890     unsigned char :3;                                   /* Bits 5-7 */
2891   } Write;
2892   struct {
2893     boolean HardwareMailboxEmpty:1;                     /* Bit 0 */
2894     boolean InitializationNotInProgress:1;              /* Bit 1 */
2895     unsigned char :6;                                   /* Bits 2-7 */
2896   } Read;
2897 }
2898 DAC960_BA_InboundDoorBellRegister_T;
2899
2900
2901 /*
2902   Define the structure of the DAC960 BA Series Outbound Door Bell Register.
2903 */
2904
2905 typedef union DAC960_BA_OutboundDoorBellRegister
2906 {
2907   unsigned char All;
2908   struct {
2909     boolean AcknowledgeHardwareMailboxInterrupt:1;      /* Bit 0 */
2910     boolean AcknowledgeMemoryMailboxInterrupt:1;        /* Bit 1 */
2911     unsigned char :6;                                   /* Bits 2-7 */
2912   } Write;
2913   struct {
2914     boolean HardwareMailboxStatusAvailable:1;           /* Bit 0 */
2915     boolean MemoryMailboxStatusAvailable:1;             /* Bit 1 */
2916     unsigned char :6;                                   /* Bits 2-7 */
2917   } Read;
2918 }
2919 DAC960_BA_OutboundDoorBellRegister_T;
2920
2921
2922 /*
2923   Define the structure of the DAC960 BA Series Interrupt Mask Register.
2924 */
2925
2926 typedef union DAC960_BA_InterruptMaskRegister
2927 {
2928   unsigned char All;
2929   struct {
2930     unsigned int :2;                                    /* Bits 0-1 */
2931     boolean DisableInterrupts:1;                        /* Bit 2 */
2932     boolean DisableInterruptsI2O:1;                     /* Bit 3 */
2933     unsigned int :4;                                    /* Bits 4-7 */
2934   } Bits;
2935 }
2936 DAC960_BA_InterruptMaskRegister_T;
2937
2938
2939 /*
2940   Define the structure of the DAC960 BA Series Error Status Register.
2941 */
2942
2943 typedef union DAC960_BA_ErrorStatusRegister
2944 {
2945   unsigned char All;
2946   struct {
2947     unsigned int :2;                                    /* Bits 0-1 */
2948     boolean ErrorStatusPending:1;                       /* Bit 2 */
2949     unsigned int :5;                                    /* Bits 3-7 */
2950   } Bits;
2951 }
2952 DAC960_BA_ErrorStatusRegister_T;
2953
2954
2955 /*
2956   Define inline functions to provide an abstraction for reading and writing the
2957   DAC960 BA Series Controller Interface Registers.
2958 */
2959
2960 static inline
2961 void DAC960_BA_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress)
2962 {
2963   DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2964   InboundDoorBellRegister.All = 0;
2965   InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
2966   writeb(InboundDoorBellRegister.All,
2967          ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2968 }
2969
2970 static inline
2971 void DAC960_BA_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress)
2972 {
2973   DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2974   InboundDoorBellRegister.All = 0;
2975   InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
2976   writeb(InboundDoorBellRegister.All,
2977          ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2978 }
2979
2980 static inline
2981 void DAC960_BA_GenerateInterrupt(void __iomem *ControllerBaseAddress)
2982 {
2983   DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2984   InboundDoorBellRegister.All = 0;
2985   InboundDoorBellRegister.Write.GenerateInterrupt = true;
2986   writeb(InboundDoorBellRegister.All,
2987          ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2988 }
2989
2990 static inline
2991 void DAC960_BA_ControllerReset(void __iomem *ControllerBaseAddress)
2992 {
2993   DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
2994   InboundDoorBellRegister.All = 0;
2995   InboundDoorBellRegister.Write.ControllerReset = true;
2996   writeb(InboundDoorBellRegister.All,
2997          ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
2998 }
2999
3000 static inline
3001 void DAC960_BA_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
3002 {
3003   DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
3004   InboundDoorBellRegister.All = 0;
3005   InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
3006   writeb(InboundDoorBellRegister.All,
3007          ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
3008 }
3009
3010 static inline
3011 boolean DAC960_BA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
3012 {
3013   DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
3014   InboundDoorBellRegister.All =
3015     readb(ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
3016   return !InboundDoorBellRegister.Read.HardwareMailboxEmpty;
3017 }
3018
3019 static inline
3020 boolean DAC960_BA_InitializationInProgressP(void __iomem *ControllerBaseAddress)
3021 {
3022   DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
3023   InboundDoorBellRegister.All =
3024     readb(ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
3025   return !InboundDoorBellRegister.Read.InitializationNotInProgress;
3026 }
3027
3028 static inline
3029 void DAC960_BA_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress)
3030 {
3031   DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3032   OutboundDoorBellRegister.All = 0;
3033   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3034   writeb(OutboundDoorBellRegister.All,
3035          ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
3036 }
3037
3038 static inline
3039 void DAC960_BA_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress)
3040 {
3041   DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3042   OutboundDoorBellRegister.All = 0;
3043   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3044   writeb(OutboundDoorBellRegister.All,
3045          ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
3046 }
3047
3048 static inline
3049 void DAC960_BA_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
3050 {
3051   DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3052   OutboundDoorBellRegister.All = 0;
3053   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3054   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3055   writeb(OutboundDoorBellRegister.All,
3056          ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
3057 }
3058
3059 static inline
3060 boolean DAC960_BA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
3061 {
3062   DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3063   OutboundDoorBellRegister.All =
3064     readb(ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
3065   return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
3066 }
3067
3068 static inline
3069 boolean DAC960_BA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
3070 {
3071   DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3072   OutboundDoorBellRegister.All =
3073     readb(ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
3074   return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
3075 }
3076
3077 static inline
3078 void DAC960_BA_EnableInterrupts(void __iomem *ControllerBaseAddress)
3079 {
3080   DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
3081   InterruptMaskRegister.All = 0xFF;
3082   InterruptMaskRegister.Bits.DisableInterrupts = false;
3083   InterruptMaskRegister.Bits.DisableInterruptsI2O = true;
3084   writeb(InterruptMaskRegister.All,
3085          ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
3086 }
3087
3088 static inline
3089 void DAC960_BA_DisableInterrupts(void __iomem *ControllerBaseAddress)
3090 {
3091   DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
3092   InterruptMaskRegister.All = 0xFF;
3093   InterruptMaskRegister.Bits.DisableInterrupts = true;
3094   InterruptMaskRegister.Bits.DisableInterruptsI2O = true;
3095   writeb(InterruptMaskRegister.All,
3096          ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
3097 }
3098
3099 static inline
3100 boolean DAC960_BA_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
3101 {
3102   DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
3103   InterruptMaskRegister.All =
3104     readb(ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
3105   return !InterruptMaskRegister.Bits.DisableInterrupts;
3106 }
3107
3108 static inline
3109 void DAC960_BA_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
3110                                      *MemoryCommandMailbox,
3111                                    DAC960_V2_CommandMailbox_T
3112                                      *CommandMailbox)
3113 {
3114   memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
3115          sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
3116   wmb();
3117   MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
3118   mb();
3119 }
3120
3121
3122 static inline
3123 void DAC960_BA_WriteHardwareMailbox(void __iomem *ControllerBaseAddress,
3124                                     dma_addr_t CommandMailboxDMA)
3125 {
3126         dma_addr_writeql(CommandMailboxDMA,
3127                 ControllerBaseAddress +
3128                 DAC960_BA_CommandMailboxBusAddressOffset);
3129 }
3130
3131 static inline DAC960_V2_CommandIdentifier_T
3132 DAC960_BA_ReadCommandIdentifier(void __iomem *ControllerBaseAddress)
3133 {
3134   return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset);
3135 }
3136
3137 static inline DAC960_V2_CommandStatus_T
3138 DAC960_BA_ReadCommandStatus(void __iomem *ControllerBaseAddress)
3139 {
3140   return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset + 2);
3141 }
3142
3143 static inline boolean
3144 DAC960_BA_ReadErrorStatus(void __iomem *ControllerBaseAddress,
3145                           unsigned char *ErrorStatus,
3146                           unsigned char *Parameter0,
3147                           unsigned char *Parameter1)
3148 {
3149   DAC960_BA_ErrorStatusRegister_T ErrorStatusRegister;
3150   ErrorStatusRegister.All =
3151     readb(ControllerBaseAddress + DAC960_BA_ErrorStatusRegisterOffset);
3152   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
3153   ErrorStatusRegister.Bits.ErrorStatusPending = false;
3154   *ErrorStatus = ErrorStatusRegister.All;
3155   *Parameter0 =
3156     readb(ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset + 0);
3157   *Parameter1 =
3158     readb(ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset + 1);
3159   writeb(0xFF, ControllerBaseAddress + DAC960_BA_ErrorStatusRegisterOffset);
3160   return true;
3161 }
3162
3163
3164 /*
3165   Define the DAC960 LP Series Controller Interface Register Offsets.
3166 */
3167
3168 #define DAC960_LP_RegisterWindowSize            0x80
3169
3170 typedef enum
3171 {
3172   DAC960_LP_InboundDoorBellRegisterOffset =     0x20,
3173   DAC960_LP_OutboundDoorBellRegisterOffset =    0x2C,
3174   DAC960_LP_InterruptStatusRegisterOffset =     0x30,
3175   DAC960_LP_InterruptMaskRegisterOffset =       0x34,
3176   DAC960_LP_CommandMailboxBusAddressOffset =    0x10,
3177   DAC960_LP_CommandStatusOffset =               0x18,
3178   DAC960_LP_ErrorStatusRegisterOffset =         0x2E
3179 }
3180 DAC960_LP_RegisterOffsets_T;
3181
3182
3183 /*
3184   Define the structure of the DAC960 LP Series Inbound Door Bell Register.
3185 */
3186
3187 typedef union DAC960_LP_InboundDoorBellRegister
3188 {
3189   unsigned char All;
3190   struct {
3191     boolean HardwareMailboxNewCommand:1;                /* Bit 0 */
3192     boolean AcknowledgeHardwareMailboxStatus:1;         /* Bit 1 */
3193     boolean GenerateInterrupt:1;                        /* Bit 2 */
3194     boolean ControllerReset:1;                          /* Bit 3 */
3195     boolean MemoryMailboxNewCommand:1;                  /* Bit 4 */
3196     unsigned char :3;                                   /* Bits 5-7 */
3197   } Write;
3198   struct {
3199     boolean HardwareMailboxFull:1;                      /* Bit 0 */
3200     boolean InitializationInProgress:1;                 /* Bit 1 */
3201     unsigned char :6;                                   /* Bits 2-7 */
3202   } Read;
3203 }
3204 DAC960_LP_InboundDoorBellRegister_T;
3205
3206
3207 /*
3208   Define the structure of the DAC960 LP Series Outbound Door Bell Register.
3209 */
3210
3211 typedef union DAC960_LP_OutboundDoorBellRegister
3212 {
3213   unsigned char All;
3214   struct {
3215     boolean AcknowledgeHardwareMailboxInterrupt:1;      /* Bit 0 */
3216     boolean AcknowledgeMemoryMailboxInterrupt:1;        /* Bit 1 */
3217     unsigned char :6;                                   /* Bits 2-7 */
3218   } Write;
3219   struct {
3220     boolean HardwareMailboxStatusAvailable:1;           /* Bit 0 */
3221     boolean MemoryMailboxStatusAvailable:1;             /* Bit 1 */
3222     unsigned char :6;                                   /* Bits 2-7 */
3223   } Read;
3224 }
3225 DAC960_LP_OutboundDoorBellRegister_T;
3226
3227
3228 /*
3229   Define the structure of the DAC960 LP Series Interrupt Mask Register.
3230 */
3231
3232 typedef union DAC960_LP_InterruptMaskRegister
3233 {
3234   unsigned char All;
3235   struct {
3236     unsigned int :2;                                    /* Bits 0-1 */
3237     boolean DisableInterrupts:1;                        /* Bit 2 */
3238     unsigned int :5;                                    /* Bits 3-7 */
3239   } Bits;
3240 }
3241 DAC960_LP_InterruptMaskRegister_T;
3242
3243
3244 /*
3245   Define the structure of the DAC960 LP Series Error Status Register.
3246 */
3247
3248 typedef union DAC960_LP_ErrorStatusRegister
3249 {
3250   unsigned char All;
3251   struct {
3252     unsigned int :2;                                    /* Bits 0-1 */
3253     boolean ErrorStatusPending:1;                       /* Bit 2 */
3254     unsigned int :5;                                    /* Bits 3-7 */
3255   } Bits;
3256 }
3257 DAC960_LP_ErrorStatusRegister_T;
3258
3259
3260 /*
3261   Define inline functions to provide an abstraction for reading and writing the
3262   DAC960 LP Series Controller Interface Registers.
3263 */
3264
3265 static inline
3266 void DAC960_LP_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress)
3267 {
3268   DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
3269   InboundDoorBellRegister.All = 0;
3270   InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
3271   writeb(InboundDoorBellRegister.All,
3272          ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
3273 }
3274
3275 static inline
3276 void DAC960_LP_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress)
3277 {
3278   DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
3279   InboundDoorBellRegister.All = 0;
3280   InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
3281   writeb(InboundDoorBellRegister.All,
3282          ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
3283 }
3284
3285 static inline
3286 void DAC960_LP_GenerateInterrupt(void __iomem *ControllerBaseAddress)
3287 {
3288   DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
3289   InboundDoorBellRegister.All = 0;
3290   InboundDoorBellRegister.Write.GenerateInterrupt = true;
3291   writeb(InboundDoorBellRegister.All,
3292          ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
3293 }
3294
3295 static inline
3296 void DAC960_LP_ControllerReset(void __iomem *ControllerBaseAddress)
3297 {
3298   DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
3299   InboundDoorBellRegister.All = 0;
3300   InboundDoorBellRegister.Write.ControllerReset = true;
3301   writeb(InboundDoorBellRegister.All,
3302          ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
3303 }
3304
3305 static inline
3306 void DAC960_LP_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
3307 {
3308   DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
3309   InboundDoorBellRegister.All = 0;
3310   InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
3311   writeb(InboundDoorBellRegister.All,
3312          ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
3313 }
3314
3315 static inline
3316 boolean DAC960_LP_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
3317 {
3318   DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
3319   InboundDoorBellRegister.All =
3320     readb(ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
3321   return InboundDoorBellRegister.Read.HardwareMailboxFull;
3322 }
3323
3324 static inline
3325 boolean DAC960_LP_InitializationInProgressP(void __iomem *ControllerBaseAddress)
3326 {
3327   DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
3328   InboundDoorBellRegister.All =
3329     readb(ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
3330   return InboundDoorBellRegister.Read.InitializationInProgress;
3331 }
3332
3333 static inline
3334 void DAC960_LP_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress)
3335 {
3336   DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3337   OutboundDoorBellRegister.All = 0;
3338   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3339   writeb(OutboundDoorBellRegister.All,
3340          ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
3341 }
3342
3343 static inline
3344 void DAC960_LP_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress)
3345 {
3346   DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3347   OutboundDoorBellRegister.All = 0;
3348   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3349   writeb(OutboundDoorBellRegister.All,
3350          ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
3351 }
3352
3353 static inline
3354 void DAC960_LP_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
3355 {
3356   DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3357   OutboundDoorBellRegister.All = 0;
3358   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3359   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3360   writeb(OutboundDoorBellRegister.All,
3361          ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
3362 }
3363
3364 static inline
3365 boolean DAC960_LP_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
3366 {
3367   DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3368   OutboundDoorBellRegister.All =
3369     readb(ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
3370   return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
3371 }
3372
3373 static inline
3374 boolean DAC960_LP_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
3375 {
3376   DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3377   OutboundDoorBellRegister.All =
3378     readb(ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
3379   return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
3380 }
3381
3382 static inline
3383 void DAC960_LP_EnableInterrupts(void __iomem *ControllerBaseAddress)
3384 {
3385   DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
3386   InterruptMaskRegister.All = 0xFF;
3387   InterruptMaskRegister.Bits.DisableInterrupts = false;
3388   writeb(InterruptMaskRegister.All,
3389          ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
3390 }
3391
3392 static inline
3393 void DAC960_LP_DisableInterrupts(void __iomem *ControllerBaseAddress)
3394 {
3395   DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
3396   InterruptMaskRegister.All = 0xFF;
3397   InterruptMaskRegister.Bits.DisableInterrupts = true;
3398   writeb(InterruptMaskRegister.All,
3399          ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
3400 }
3401
3402 static inline
3403 boolean DAC960_LP_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
3404 {
3405   DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
3406   InterruptMaskRegister.All =
3407     readb(ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
3408   return !InterruptMaskRegister.Bits.DisableInterrupts;
3409 }
3410
3411 static inline
3412 void DAC960_LP_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
3413                                      *MemoryCommandMailbox,
3414                                    DAC960_V2_CommandMailbox_T
3415                                      *CommandMailbox)
3416 {
3417   memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
3418          sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
3419   wmb();
3420   MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
3421   mb();
3422 }
3423
3424 static inline
3425 void DAC960_LP_WriteHardwareMailbox(void __iomem *ControllerBaseAddress,
3426                                     dma_addr_t CommandMailboxDMA)
3427 {
3428         dma_addr_writeql(CommandMailboxDMA,
3429                 ControllerBaseAddress +
3430                 DAC960_LP_CommandMailboxBusAddressOffset);
3431 }
3432
3433 static inline DAC960_V2_CommandIdentifier_T
3434 DAC960_LP_ReadCommandIdentifier(void __iomem *ControllerBaseAddress)
3435 {
3436   return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset);
3437 }
3438
3439 static inline DAC960_V2_CommandStatus_T
3440 DAC960_LP_ReadCommandStatus(void __iomem *ControllerBaseAddress)
3441 {
3442   return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset + 2);
3443 }
3444
3445 static inline boolean
3446 DAC960_LP_ReadErrorStatus(void __iomem *ControllerBaseAddress,
3447                           unsigned char *ErrorStatus,
3448                           unsigned char *Parameter0,
3449                           unsigned char *Parameter1)
3450 {
3451   DAC960_LP_ErrorStatusRegister_T ErrorStatusRegister;
3452   ErrorStatusRegister.All =
3453     readb(ControllerBaseAddress + DAC960_LP_ErrorStatusRegisterOffset);
3454   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
3455   ErrorStatusRegister.Bits.ErrorStatusPending = false;
3456   *ErrorStatus = ErrorStatusRegister.All;
3457   *Parameter0 =
3458     readb(ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset + 0);
3459   *Parameter1 =
3460     readb(ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset + 1);
3461   writeb(0xFF, ControllerBaseAddress + DAC960_LP_ErrorStatusRegisterOffset);
3462   return true;
3463 }
3464
3465
3466 /*
3467   Define the DAC960 LA Series Controller Interface Register Offsets.
3468 */
3469
3470 #define DAC960_LA_RegisterWindowSize            0x80
3471
3472 typedef enum
3473 {
3474   DAC960_LA_InboundDoorBellRegisterOffset =     0x60,
3475   DAC960_LA_OutboundDoorBellRegisterOffset =    0x61,
3476   DAC960_LA_InterruptMaskRegisterOffset =       0x34,
3477   DAC960_LA_CommandOpcodeRegisterOffset =       0x50,
3478   DAC960_LA_CommandIdentifierRegisterOffset =   0x51,
3479   DAC960_LA_MailboxRegister2Offset =            0x52,
3480   DAC960_LA_MailboxRegister3Offset =            0x53,
3481   DAC960_LA_MailboxRegister4Offset =            0x54,
3482   DAC960_LA_MailboxRegister5Offset =            0x55,
3483   DAC960_LA_MailboxRegister6Offset =            0x56,
3484   DAC960_LA_MailboxRegister7Offset =            0x57,
3485   DAC960_LA_MailboxRegister8Offset =            0x58,
3486   DAC960_LA_MailboxRegister9Offset =            0x59,
3487   DAC960_LA_MailboxRegister10Offset =           0x5A,
3488   DAC960_LA_MailboxRegister11Offset =           0x5B,
3489   DAC960_LA_MailboxRegister12Offset =           0x5C,
3490   DAC960_LA_StatusCommandIdentifierRegOffset =  0x5D,
3491   DAC960_LA_StatusRegisterOffset =              0x5E,
3492   DAC960_LA_ErrorStatusRegisterOffset =         0x63
3493 }
3494 DAC960_LA_RegisterOffsets_T;
3495
3496
3497 /*
3498   Define the structure of the DAC960 LA Series Inbound Door Bell Register.
3499 */
3500
3501 typedef union DAC960_LA_InboundDoorBellRegister
3502 {
3503   unsigned char All;
3504   struct {
3505     boolean HardwareMailboxNewCommand:1;                /* Bit 0 */
3506     boolean AcknowledgeHardwareMailboxStatus:1;         /* Bit 1 */
3507     boolean GenerateInterrupt:1;                        /* Bit 2 */
3508     boolean ControllerReset:1;                          /* Bit 3 */
3509     boolean MemoryMailboxNewCommand:1;                  /* Bit 4 */
3510     unsigned char :3;                                   /* Bits 5-7 */
3511   } Write;
3512   struct {
3513     boolean HardwareMailboxEmpty:1;                     /* Bit 0 */
3514     boolean InitializationNotInProgress:1;              /* Bit 1 */
3515     unsigned char :6;                                   /* Bits 2-7 */
3516   } Read;
3517 }
3518 DAC960_LA_InboundDoorBellRegister_T;
3519
3520
3521 /*
3522   Define the structure of the DAC960 LA Series Outbound Door Bell Register.
3523 */
3524
3525 typedef union DAC960_LA_OutboundDoorBellRegister
3526 {
3527   unsigned char All;
3528   struct {
3529     boolean AcknowledgeHardwareMailboxInterrupt:1;      /* Bit 0 */
3530     boolean AcknowledgeMemoryMailboxInterrupt:1;        /* Bit 1 */
3531     unsigned char :6;                                   /* Bits 2-7 */
3532   } Write;
3533   struct {
3534     boolean HardwareMailboxStatusAvailable:1;           /* Bit 0 */
3535     boolean MemoryMailboxStatusAvailable:1;             /* Bit 1 */
3536     unsigned char :6;                                   /* Bits 2-7 */
3537   } Read;
3538 }
3539 DAC960_LA_OutboundDoorBellRegister_T;
3540
3541
3542 /*
3543   Define the structure of the DAC960 LA Series Interrupt Mask Register.
3544 */
3545
3546 typedef union DAC960_LA_InterruptMaskRegister
3547 {
3548   unsigned char All;
3549   struct {
3550     unsigned char :2;                                   /* Bits 0-1 */
3551     boolean DisableInterrupts:1;                        /* Bit 2 */
3552     unsigned char :5;                                   /* Bits 3-7 */
3553   } Bits;
3554 }
3555 DAC960_LA_InterruptMaskRegister_T;
3556
3557
3558 /*
3559   Define the structure of the DAC960 LA Series Error Status Register.
3560 */
3561
3562 typedef union DAC960_LA_ErrorStatusRegister
3563 {
3564   unsigned char All;
3565   struct {
3566     unsigned int :2;                                    /* Bits 0-1 */
3567     boolean ErrorStatusPending:1;                       /* Bit 2 */
3568     unsigned int :5;                                    /* Bits 3-7 */
3569   } Bits;
3570 }
3571 DAC960_LA_ErrorStatusRegister_T;
3572
3573
3574 /*
3575   Define inline functions to provide an abstraction for reading and writing the
3576   DAC960 LA Series Controller Interface Registers.
3577 */
3578
3579 static inline
3580 void DAC960_LA_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress)
3581 {
3582   DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3583   InboundDoorBellRegister.All = 0;
3584   InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
3585   writeb(InboundDoorBellRegister.All,
3586          ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3587 }
3588
3589 static inline
3590 void DAC960_LA_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress)
3591 {
3592   DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3593   InboundDoorBellRegister.All = 0;
3594   InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
3595   writeb(InboundDoorBellRegister.All,
3596          ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3597 }
3598
3599 static inline
3600 void DAC960_LA_GenerateInterrupt(void __iomem *ControllerBaseAddress)
3601 {
3602   DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3603   InboundDoorBellRegister.All = 0;
3604   InboundDoorBellRegister.Write.GenerateInterrupt = true;
3605   writeb(InboundDoorBellRegister.All,
3606          ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3607 }
3608
3609 static inline
3610 void DAC960_LA_ControllerReset(void __iomem *ControllerBaseAddress)
3611 {
3612   DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3613   InboundDoorBellRegister.All = 0;
3614   InboundDoorBellRegister.Write.ControllerReset = true;
3615   writeb(InboundDoorBellRegister.All,
3616          ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3617 }
3618
3619 static inline
3620 void DAC960_LA_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
3621 {
3622   DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3623   InboundDoorBellRegister.All = 0;
3624   InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
3625   writeb(InboundDoorBellRegister.All,
3626          ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3627 }
3628
3629 static inline
3630 boolean DAC960_LA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
3631 {
3632   DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3633   InboundDoorBellRegister.All =
3634     readb(ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3635   return !InboundDoorBellRegister.Read.HardwareMailboxEmpty;
3636 }
3637
3638 static inline
3639 boolean DAC960_LA_InitializationInProgressP(void __iomem *ControllerBaseAddress)
3640 {
3641   DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
3642   InboundDoorBellRegister.All =
3643     readb(ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
3644   return !InboundDoorBellRegister.Read.InitializationNotInProgress;
3645 }
3646
3647 static inline
3648 void DAC960_LA_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress)
3649 {
3650   DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3651   OutboundDoorBellRegister.All = 0;
3652   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3653   writeb(OutboundDoorBellRegister.All,
3654          ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
3655 }
3656
3657 static inline
3658 void DAC960_LA_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress)
3659 {
3660   DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3661   OutboundDoorBellRegister.All = 0;
3662   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3663   writeb(OutboundDoorBellRegister.All,
3664          ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
3665 }
3666
3667 static inline
3668 void DAC960_LA_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
3669 {
3670   DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3671   OutboundDoorBellRegister.All = 0;
3672   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3673   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3674   writeb(OutboundDoorBellRegister.All,
3675          ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
3676 }
3677
3678 static inline
3679 boolean DAC960_LA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
3680 {
3681   DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3682   OutboundDoorBellRegister.All =
3683     readb(ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
3684   return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
3685 }
3686
3687 static inline
3688 boolean DAC960_LA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
3689 {
3690   DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3691   OutboundDoorBellRegister.All =
3692     readb(ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
3693   return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
3694 }
3695
3696 static inline
3697 void DAC960_LA_EnableInterrupts(void __iomem *ControllerBaseAddress)
3698 {
3699   DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
3700   InterruptMaskRegister.All = 0xFF;
3701   InterruptMaskRegister.Bits.DisableInterrupts = false;
3702   writeb(InterruptMaskRegister.All,
3703          ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
3704 }
3705
3706 static inline
3707 void DAC960_LA_DisableInterrupts(void __iomem *ControllerBaseAddress)
3708 {
3709   DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
3710   InterruptMaskRegister.All = 0xFF;
3711   InterruptMaskRegister.Bits.DisableInterrupts = true;
3712   writeb(InterruptMaskRegister.All,
3713          ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
3714 }
3715
3716 static inline
3717 boolean DAC960_LA_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
3718 {
3719   DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
3720   InterruptMaskRegister.All =
3721     readb(ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
3722   return !InterruptMaskRegister.Bits.DisableInterrupts;
3723 }
3724
3725 static inline
3726 void DAC960_LA_WriteCommandMailbox(DAC960_V1_CommandMailbox_T
3727                                      *MemoryCommandMailbox,
3728                                    DAC960_V1_CommandMailbox_T
3729                                      *CommandMailbox)
3730 {
3731   MemoryCommandMailbox->Words[1] = CommandMailbox->Words[1];
3732   MemoryCommandMailbox->Words[2] = CommandMailbox->Words[2];
3733   MemoryCommandMailbox->Words[3] = CommandMailbox->Words[3];
3734   wmb();
3735   MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
3736   mb();
3737 }
3738
3739 static inline
3740 void DAC960_LA_WriteHardwareMailbox(void __iomem *ControllerBaseAddress,
3741                                     DAC960_V1_CommandMailbox_T *CommandMailbox)
3742 {
3743   writel(CommandMailbox->Words[0],
3744          ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
3745   writel(CommandMailbox->Words[1],
3746          ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
3747   writel(CommandMailbox->Words[2],
3748          ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
3749   writeb(CommandMailbox->Bytes[12],
3750          ControllerBaseAddress + DAC960_LA_MailboxRegister12Offset);
3751 }
3752
3753 static inline DAC960_V1_CommandIdentifier_T
3754 DAC960_LA_ReadStatusCommandIdentifier(void __iomem *ControllerBaseAddress)
3755 {
3756   return readb(ControllerBaseAddress
3757                + DAC960_LA_StatusCommandIdentifierRegOffset);
3758 }
3759
3760 static inline DAC960_V1_CommandStatus_T
3761 DAC960_LA_ReadStatusRegister(void __iomem *ControllerBaseAddress)
3762 {
3763   return readw(ControllerBaseAddress + DAC960_LA_StatusRegisterOffset);
3764 }
3765
3766 static inline boolean
3767 DAC960_LA_ReadErrorStatus(void __iomem *ControllerBaseAddress,
3768                           unsigned char *ErrorStatus,
3769                           unsigned char *Parameter0,
3770                           unsigned char *Parameter1)
3771 {
3772   DAC960_LA_ErrorStatusRegister_T ErrorStatusRegister;
3773   ErrorStatusRegister.All =
3774     readb(ControllerBaseAddress + DAC960_LA_ErrorStatusRegisterOffset);
3775   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
3776   ErrorStatusRegister.Bits.ErrorStatusPending = false;
3777   *ErrorStatus = ErrorStatusRegister.All;
3778   *Parameter0 =
3779     readb(ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
3780   *Parameter1 =
3781     readb(ControllerBaseAddress + DAC960_LA_CommandIdentifierRegisterOffset);
3782   writeb(0xFF, ControllerBaseAddress + DAC960_LA_ErrorStatusRegisterOffset);
3783   return true;
3784 }
3785
3786 /*
3787   Define the DAC960 PG Series Controller Interface Register Offsets.
3788 */
3789
3790 #define DAC960_PG_RegisterWindowSize            0x2000
3791
3792 typedef enum
3793 {
3794   DAC960_PG_InboundDoorBellRegisterOffset =     0x0020,
3795   DAC960_PG_OutboundDoorBellRegisterOffset =    0x002C,
3796   DAC960_PG_InterruptMaskRegisterOffset =       0x0034,
3797   DAC960_PG_CommandOpcodeRegisterOffset =       0x1000,
3798   DAC960_PG_CommandIdentifierRegisterOffset =   0x1001,
3799   DAC960_PG_MailboxRegister2Offset =            0x1002,
3800   DAC960_PG_MailboxRegister3Offset =            0x1003,
3801   DAC960_PG_MailboxRegister4Offset =            0x1004,
3802   DAC960_PG_MailboxRegister5Offset =            0x1005,
3803   DAC960_PG_MailboxRegister6Offset =            0x1006,
3804   DAC960_PG_MailboxRegister7Offset =            0x1007,
3805   DAC960_PG_MailboxRegister8Offset =            0x1008,
3806   DAC960_PG_MailboxRegister9Offset =            0x1009,
3807   DAC960_PG_MailboxRegister10Offset =           0x100A,
3808   DAC960_PG_MailboxRegister11Offset =           0x100B,
3809   DAC960_PG_MailboxRegister12Offset =           0x100C,
3810   DAC960_PG_StatusCommandIdentifierRegOffset =  0x1018,
3811   DAC960_PG_StatusRegisterOffset =              0x101A,
3812   DAC960_PG_ErrorStatusRegisterOffset =         0x103F
3813 }
3814 DAC960_PG_RegisterOffsets_T;
3815
3816
3817 /*
3818   Define the structure of the DAC960 PG Series Inbound Door Bell Register.
3819 */
3820
3821 typedef union DAC960_PG_InboundDoorBellRegister
3822 {
3823   unsigned int All;
3824   struct {
3825     boolean HardwareMailboxNewCommand:1;                /* Bit 0 */
3826     boolean AcknowledgeHardwareMailboxStatus:1;         /* Bit 1 */
3827     boolean GenerateInterrupt:1;                        /* Bit 2 */
3828     boolean ControllerReset:1;                          /* Bit 3 */
3829     boolean MemoryMailboxNewCommand:1;                  /* Bit 4 */
3830     unsigned int :27;                                   /* Bits 5-31 */
3831   } Write;
3832   struct {
3833     boolean HardwareMailboxFull:1;                      /* Bit 0 */
3834     boolean InitializationInProgress:1;                 /* Bit 1 */
3835     unsigned int :30;                                   /* Bits 2-31 */
3836   } Read;
3837 }
3838 DAC960_PG_InboundDoorBellRegister_T;
3839
3840
3841 /*
3842   Define the structure of the DAC960 PG Series Outbound Door Bell Register.
3843 */
3844
3845 typedef union DAC960_PG_OutboundDoorBellRegister
3846 {
3847   unsigned int All;
3848   struct {
3849     boolean AcknowledgeHardwareMailboxInterrupt:1;      /* Bit 0 */
3850     boolean AcknowledgeMemoryMailboxInterrupt:1;        /* Bit 1 */
3851     unsigned int :30;                                   /* Bits 2-31 */
3852   } Write;
3853   struct {
3854     boolean HardwareMailboxStatusAvailable:1;           /* Bit 0 */
3855     boolean MemoryMailboxStatusAvailable:1;             /* Bit 1 */
3856     unsigned int :30;                                   /* Bits 2-31 */
3857   } Read;
3858 }
3859 DAC960_PG_OutboundDoorBellRegister_T;
3860
3861
3862 /*
3863   Define the structure of the DAC960 PG Series Interrupt Mask Register.
3864 */
3865
3866 typedef union DAC960_PG_InterruptMaskRegister
3867 {
3868   unsigned int All;
3869   struct {
3870     unsigned int MessageUnitInterruptMask1:2;           /* Bits 0-1 */
3871     boolean DisableInterrupts:1;                        /* Bit 2 */
3872     unsigned int MessageUnitInterruptMask2:5;           /* Bits 3-7 */
3873     unsigned int Reserved0:24;                          /* Bits 8-31 */
3874   } Bits;
3875 }
3876 DAC960_PG_InterruptMaskRegister_T;
3877
3878
3879 /*
3880   Define the structure of the DAC960 PG Series Error Status Register.
3881 */
3882
3883 typedef union DAC960_PG_ErrorStatusRegister
3884 {
3885   unsigned char All;
3886   struct {
3887     unsigned int :2;                                    /* Bits 0-1 */
3888     boolean ErrorStatusPending:1;                       /* Bit 2 */
3889     unsigned int :5;                                    /* Bits 3-7 */
3890   } Bits;
3891 }
3892 DAC960_PG_ErrorStatusRegister_T;
3893
3894
3895 /*
3896   Define inline functions to provide an abstraction for reading and writing the
3897   DAC960 PG Series Controller Interface Registers.
3898 */
3899
3900 static inline
3901 void DAC960_PG_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress)
3902 {
3903   DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3904   InboundDoorBellRegister.All = 0;
3905   InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
3906   writel(InboundDoorBellRegister.All,
3907          ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3908 }
3909
3910 static inline
3911 void DAC960_PG_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress)
3912 {
3913   DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3914   InboundDoorBellRegister.All = 0;
3915   InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
3916   writel(InboundDoorBellRegister.All,
3917          ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3918 }
3919
3920 static inline
3921 void DAC960_PG_GenerateInterrupt(void __iomem *ControllerBaseAddress)
3922 {
3923   DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3924   InboundDoorBellRegister.All = 0;
3925   InboundDoorBellRegister.Write.GenerateInterrupt = true;
3926   writel(InboundDoorBellRegister.All,
3927          ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3928 }
3929
3930 static inline
3931 void DAC960_PG_ControllerReset(void __iomem *ControllerBaseAddress)
3932 {
3933   DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3934   InboundDoorBellRegister.All = 0;
3935   InboundDoorBellRegister.Write.ControllerReset = true;
3936   writel(InboundDoorBellRegister.All,
3937          ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3938 }
3939
3940 static inline
3941 void DAC960_PG_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
3942 {
3943   DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3944   InboundDoorBellRegister.All = 0;
3945   InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
3946   writel(InboundDoorBellRegister.All,
3947          ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3948 }
3949
3950 static inline
3951 boolean DAC960_PG_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
3952 {
3953   DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3954   InboundDoorBellRegister.All =
3955     readl(ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3956   return InboundDoorBellRegister.Read.HardwareMailboxFull;
3957 }
3958
3959 static inline
3960 boolean DAC960_PG_InitializationInProgressP(void __iomem *ControllerBaseAddress)
3961 {
3962   DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
3963   InboundDoorBellRegister.All =
3964     readl(ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
3965   return InboundDoorBellRegister.Read.InitializationInProgress;
3966 }
3967
3968 static inline
3969 void DAC960_PG_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress)
3970 {
3971   DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3972   OutboundDoorBellRegister.All = 0;
3973   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3974   writel(OutboundDoorBellRegister.All,
3975          ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
3976 }
3977
3978 static inline
3979 void DAC960_PG_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress)
3980 {
3981   DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3982   OutboundDoorBellRegister.All = 0;
3983   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3984   writel(OutboundDoorBellRegister.All,
3985          ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
3986 }
3987
3988 static inline
3989 void DAC960_PG_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
3990 {
3991   DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
3992   OutboundDoorBellRegister.All = 0;
3993   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
3994   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
3995   writel(OutboundDoorBellRegister.All,
3996          ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
3997 }
3998
3999 static inline
4000 boolean DAC960_PG_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
4001 {
4002   DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
4003   OutboundDoorBellRegister.All =
4004     readl(ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
4005   return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
4006 }
4007
4008 static inline
4009 boolean DAC960_PG_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
4010 {
4011   DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
4012   OutboundDoorBellRegister.All =
4013     readl(ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
4014   return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
4015 }
4016
4017 static inline
4018 void DAC960_PG_EnableInterrupts(void __iomem *ControllerBaseAddress)
4019 {
4020   DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
4021   InterruptMaskRegister.All = 0;
4022   InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3;
4023   InterruptMaskRegister.Bits.DisableInterrupts = false;
4024   InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F;
4025   writel(InterruptMaskRegister.All,
4026          ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
4027 }
4028
4029 static inline
4030 void DAC960_PG_DisableInterrupts(void __iomem *ControllerBaseAddress)
4031 {
4032   DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
4033   InterruptMaskRegister.All = 0;
4034   InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3;
4035   InterruptMaskRegister.Bits.DisableInterrupts = true;
4036   InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F;
4037   writel(InterruptMaskRegister.All,
4038          ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
4039 }
4040
4041 static inline
4042 boolean DAC960_PG_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
4043 {
4044   DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
4045   InterruptMaskRegister.All =
4046     readl(ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
4047   return !InterruptMaskRegister.Bits.DisableInterrupts;
4048 }
4049
4050 static inline
4051 void DAC960_PG_WriteCommandMailbox(DAC960_V1_CommandMailbox_T
4052                                      *MemoryCommandMailbox,
4053                                    DAC960_V1_CommandMailbox_T
4054                                      *CommandMailbox)
4055 {
4056   MemoryCommandMailbox->Words[1] = CommandMailbox->Words[1];
4057   MemoryCommandMailbox->Words[2] = CommandMailbox->Words[2];
4058   MemoryCommandMailbox->Words[3] = CommandMailbox->Words[3];
4059   wmb();
4060   MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
4061   mb();
4062 }
4063
4064 static inline
4065 void DAC960_PG_WriteHardwareMailbox(void __iomem *ControllerBaseAddress,
4066                                     DAC960_V1_CommandMailbox_T *CommandMailbox)
4067 {
4068   writel(CommandMailbox->Words[0],
4069          ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
4070   writel(CommandMailbox->Words[1],
4071          ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
4072   writel(CommandMailbox->Words[2],
4073          ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
4074   writeb(CommandMailbox->Bytes[12],
4075          ControllerBaseAddress + DAC960_PG_MailboxRegister12Offset);
4076 }
4077
4078 static inline DAC960_V1_CommandIdentifier_T
4079 DAC960_PG_ReadStatusCommandIdentifier(void __iomem *ControllerBaseAddress)
4080 {
4081   return readb(ControllerBaseAddress
4082                + DAC960_PG_StatusCommandIdentifierRegOffset);
4083 }
4084
4085 static inline DAC960_V1_CommandStatus_T
4086 DAC960_PG_ReadStatusRegister(void __iomem *ControllerBaseAddress)
4087 {
4088   return readw(ControllerBaseAddress + DAC960_PG_StatusRegisterOffset);
4089 }
4090
4091 static inline boolean
4092 DAC960_PG_ReadErrorStatus(void __iomem *ControllerBaseAddress,
4093                           unsigned char *ErrorStatus,
4094                           unsigned char *Parameter0,
4095                           unsigned char *Parameter1)
4096 {
4097   DAC960_PG_ErrorStatusRegister_T ErrorStatusRegister;
4098   ErrorStatusRegister.All =
4099     readb(ControllerBaseAddress + DAC960_PG_ErrorStatusRegisterOffset);
4100   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
4101   ErrorStatusRegister.Bits.ErrorStatusPending = false;
4102   *ErrorStatus = ErrorStatusRegister.All;
4103   *Parameter0 =
4104     readb(ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
4105   *Parameter1 =
4106     readb(ControllerBaseAddress + DAC960_PG_CommandIdentifierRegisterOffset);
4107   writeb(0, ControllerBaseAddress + DAC960_PG_ErrorStatusRegisterOffset);
4108   return true;
4109 }
4110
4111 /*
4112   Define the DAC960 PD Series Controller Interface Register Offsets.
4113 */
4114
4115 #define DAC960_PD_RegisterWindowSize            0x80
4116
4117 typedef enum
4118 {
4119   DAC960_PD_CommandOpcodeRegisterOffset =       0x00,
4120   DAC960_PD_CommandIdentifierRegisterOffset =   0x01,
4121   DAC960_PD_MailboxRegister2Offset =            0x02,
4122   DAC960_PD_MailboxRegister3Offset =            0x03,
4123   DAC960_PD_MailboxRegister4Offset =            0x04,
4124   DAC960_PD_MailboxRegister5Offset =            0x05,
4125   DAC960_PD_MailboxRegister6Offset =            0x06,
4126   DAC960_PD_MailboxRegister7Offset =            0x07,
4127   DAC960_PD_MailboxRegister8Offset =            0x08,
4128   DAC960_PD_MailboxRegister9Offset =            0x09,
4129   DAC960_PD_MailboxRegister10Offset =           0x0A,
4130   DAC960_PD_MailboxRegister11Offset =           0x0B,
4131   DAC960_PD_MailboxRegister12Offset =           0x0C,
4132   DAC960_PD_StatusCommandIdentifierRegOffset =  0x0D,
4133   DAC960_PD_StatusRegisterOffset =              0x0E,
4134   DAC960_PD_ErrorStatusRegisterOffset =         0x3F,
4135   DAC960_PD_InboundDoorBellRegisterOffset =     0x40,
4136   DAC960_PD_OutboundDoorBellRegisterOffset =    0x41,
4137   DAC960_PD_InterruptEnableRegisterOffset =     0x43
4138 }
4139 DAC960_PD_RegisterOffsets_T;
4140
4141
4142 /*
4143   Define the structure of the DAC960 PD Series Inbound Door Bell Register.
4144 */
4145
4146 typedef union DAC960_PD_InboundDoorBellRegister
4147 {
4148   unsigned char All;
4149   struct {
4150     boolean NewCommand:1;                               /* Bit 0 */
4151     boolean AcknowledgeStatus:1;                        /* Bit 1 */
4152     boolean GenerateInterrupt:1;                        /* Bit 2 */
4153     boolean ControllerReset:1;                          /* Bit 3 */
4154     unsigned char :4;                                   /* Bits 4-7 */
4155   } Write;
4156   struct {
4157     boolean MailboxFull:1;                              /* Bit 0 */
4158     boolean InitializationInProgress:1;                 /* Bit 1 */
4159     unsigned char :6;                                   /* Bits 2-7 */
4160   } Read;
4161 }
4162 DAC960_PD_InboundDoorBellRegister_T;
4163
4164
4165 /*
4166   Define the structure of the DAC960 PD Series Outbound Door Bell Register.
4167 */
4168
4169 typedef union DAC960_PD_OutboundDoorBellRegister
4170 {
4171   unsigned char All;
4172   struct {
4173     boolean AcknowledgeInterrupt:1;                     /* Bit 0 */
4174     unsigned char :7;                                   /* Bits 1-7 */
4175   } Write;
4176   struct {
4177     boolean StatusAvailable:1;                          /* Bit 0 */
4178     unsigned char :7;                                   /* Bits 1-7 */
4179   } Read;
4180 }
4181 DAC960_PD_OutboundDoorBellRegister_T;
4182
4183
4184 /*
4185   Define the structure of the DAC960 PD Series Interrupt Enable Register.
4186 */
4187
4188 typedef union DAC960_PD_InterruptEnableRegister
4189 {
4190   unsigned char All;
4191   struct {
4192     boolean EnableInterrupts:1;                         /* Bit 0 */
4193     unsigned char :7;                                   /* Bits 1-7 */
4194   } Bits;
4195 }
4196 DAC960_PD_InterruptEnableRegister_T;
4197
4198
4199 /*
4200   Define the structure of the DAC960 PD Series Error Status Register.
4201 */
4202
4203 typedef union DAC960_PD_ErrorStatusRegister
4204 {
4205   unsigned char All;
4206   struct {
4207     unsigned int :2;                                    /* Bits 0-1 */
4208     boolean ErrorStatusPending:1;                       /* Bit 2 */
4209     unsigned int :5;                                    /* Bits 3-7 */
4210   } Bits;
4211 }
4212 DAC960_PD_ErrorStatusRegister_T;
4213
4214
4215 /*
4216   Define inline functions to provide an abstraction for reading and writing the
4217   DAC960 PD Series Controller Interface Registers.
4218 */
4219
4220 static inline
4221 void DAC960_PD_NewCommand(void __iomem *ControllerBaseAddress)
4222 {
4223   DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4224   InboundDoorBellRegister.All = 0;
4225   InboundDoorBellRegister.Write.NewCommand = true;
4226   writeb(InboundDoorBellRegister.All,
4227          ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4228 }
4229
4230 static inline
4231 void DAC960_PD_AcknowledgeStatus(void __iomem *ControllerBaseAddress)
4232 {
4233   DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4234   InboundDoorBellRegister.All = 0;
4235   InboundDoorBellRegister.Write.AcknowledgeStatus = true;
4236   writeb(InboundDoorBellRegister.All,
4237          ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4238 }
4239
4240 static inline
4241 void DAC960_PD_GenerateInterrupt(void __iomem *ControllerBaseAddress)
4242 {
4243   DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4244   InboundDoorBellRegister.All = 0;
4245   InboundDoorBellRegister.Write.GenerateInterrupt = true;
4246   writeb(InboundDoorBellRegister.All,
4247          ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4248 }
4249
4250 static inline
4251 void DAC960_PD_ControllerReset(void __iomem *ControllerBaseAddress)
4252 {
4253   DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4254   InboundDoorBellRegister.All = 0;
4255   InboundDoorBellRegister.Write.ControllerReset = true;
4256   writeb(InboundDoorBellRegister.All,
4257          ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4258 }
4259
4260 static inline
4261 boolean DAC960_PD_MailboxFullP(void __iomem *ControllerBaseAddress)
4262 {
4263   DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4264   InboundDoorBellRegister.All =
4265     readb(ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4266   return InboundDoorBellRegister.Read.MailboxFull;
4267 }
4268
4269 static inline
4270 boolean DAC960_PD_InitializationInProgressP(void __iomem *ControllerBaseAddress)
4271 {
4272   DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
4273   InboundDoorBellRegister.All =
4274     readb(ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
4275   return InboundDoorBellRegister.Read.InitializationInProgress;
4276 }
4277
4278 static inline
4279 void DAC960_PD_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
4280 {
4281   DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister;
4282   OutboundDoorBellRegister.All = 0;
4283   OutboundDoorBellRegister.Write.AcknowledgeInterrupt = true;
4284   writeb(OutboundDoorBellRegister.All,
4285          ControllerBaseAddress + DAC960_PD_OutboundDoorBellRegisterOffset);
4286 }
4287
4288 static inline
4289 boolean DAC960_PD_StatusAvailableP(void __iomem *ControllerBaseAddress)
4290 {
4291   DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister;
4292   OutboundDoorBellRegister.All =
4293     readb(ControllerBaseAddress + DAC960_PD_OutboundDoorBellRegisterOffset);
4294   return OutboundDoorBellRegister.Read.StatusAvailable;
4295 }
4296
4297 static inline
4298 void DAC960_PD_EnableInterrupts(void __iomem *ControllerBaseAddress)
4299 {
4300   DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
4301   InterruptEnableRegister.All = 0;
4302   InterruptEnableRegister.Bits.EnableInterrupts = true;
4303   writeb(InterruptEnableRegister.All,
4304          ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
4305 }
4306
4307 static inline
4308 void DAC960_PD_DisableInterrupts(void __iomem *ControllerBaseAddress)
4309 {
4310   DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
4311   InterruptEnableRegister.All = 0;
4312   InterruptEnableRegister.Bits.EnableInterrupts = false;
4313   writeb(InterruptEnableRegister.All,
4314          ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
4315 }
4316
4317 static inline
4318 boolean DAC960_PD_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
4319 {
4320   DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
4321   InterruptEnableRegister.All =
4322     readb(ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
4323   return InterruptEnableRegister.Bits.EnableInterrupts;
4324 }
4325
4326 static inline
4327 void DAC960_PD_WriteCommandMailbox(void __iomem *ControllerBaseAddress,
4328                                    DAC960_V1_CommandMailbox_T *CommandMailbox)
4329 {
4330   writel(CommandMailbox->Words[0],
4331          ControllerBaseAddress + DAC960_PD_CommandOpcodeRegisterOffset);
4332   writel(CommandMailbox->Words[1],
4333          ControllerBaseAddress + DAC960_PD_MailboxRegister4Offset);
4334   writel(CommandMailbox->Words[2],
4335          ControllerBaseAddress + DAC960_PD_MailboxRegister8Offset);
4336   writeb(CommandMailbox->Bytes[12],
4337          ControllerBaseAddress + DAC960_PD_MailboxRegister12Offset);
4338 }
4339
4340 static inline DAC960_V1_CommandIdentifier_T
4341 DAC960_PD_ReadStatusCommandIdentifier(void __iomem *ControllerBaseAddress)
4342 {
4343   return readb(ControllerBaseAddress
4344                + DAC960_PD_StatusCommandIdentifierRegOffset);
4345 }
4346
4347 static inline DAC960_V1_CommandStatus_T
4348 DAC960_PD_ReadStatusRegister(void __iomem *ControllerBaseAddress)
4349 {
4350   return readw(ControllerBaseAddress + DAC960_PD_StatusRegisterOffset);
4351 }
4352
4353 static inline boolean
4354 DAC960_PD_ReadErrorStatus(void __iomem *ControllerBaseAddress,
4355                           unsigned char *ErrorStatus,
4356                           unsigned char *Parameter0,
4357                           unsigned char *Parameter1)
4358 {
4359   DAC960_PD_ErrorStatusRegister_T ErrorStatusRegister;
4360   ErrorStatusRegister.All =
4361     readb(ControllerBaseAddress + DAC960_PD_ErrorStatusRegisterOffset);
4362   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
4363   ErrorStatusRegister.Bits.ErrorStatusPending = false;
4364   *ErrorStatus = ErrorStatusRegister.All;
4365   *Parameter0 =
4366     readb(ControllerBaseAddress + DAC960_PD_CommandOpcodeRegisterOffset);
4367   *Parameter1 =
4368     readb(ControllerBaseAddress + DAC960_PD_CommandIdentifierRegisterOffset);
4369   writeb(0, ControllerBaseAddress + DAC960_PD_ErrorStatusRegisterOffset);
4370   return true;
4371 }
4372
4373 static inline void DAC960_P_To_PD_TranslateEnquiry(void *Enquiry)
4374 {
4375   memcpy(Enquiry + 132, Enquiry + 36, 64);
4376   memset(Enquiry + 36, 0, 96);
4377 }
4378
4379 static inline void DAC960_P_To_PD_TranslateDeviceState(void *DeviceState)
4380 {
4381   memcpy(DeviceState + 2, DeviceState + 3, 1);
4382   memcpy(DeviceState + 4, DeviceState + 5, 2);
4383   memcpy(DeviceState + 6, DeviceState + 8, 4);
4384 }
4385
4386 static inline
4387 void DAC960_PD_To_P_TranslateReadWriteCommand(DAC960_V1_CommandMailbox_T
4388                                               *CommandMailbox)
4389 {
4390   int LogicalDriveNumber = CommandMailbox->Type5.LD.LogicalDriveNumber;
4391   CommandMailbox->Bytes[3] &= 0x7;
4392   CommandMailbox->Bytes[3] |= CommandMailbox->Bytes[7] << 6;
4393   CommandMailbox->Bytes[7] = LogicalDriveNumber;
4394 }
4395
4396 static inline
4397 void DAC960_P_To_PD_TranslateReadWriteCommand(DAC960_V1_CommandMailbox_T
4398                                               *CommandMailbox)
4399 {
4400   int LogicalDriveNumber = CommandMailbox->Bytes[7];
4401   CommandMailbox->Bytes[7] = CommandMailbox->Bytes[3] >> 6;
4402   CommandMailbox->Bytes[3] &= 0x7;
4403   CommandMailbox->Bytes[3] |= LogicalDriveNumber << 3;
4404 }
4405
4406
4407 /*
4408   Define prototypes for the forward referenced DAC960 Driver Internal Functions.
4409 */
4410
4411 static void DAC960_FinalizeController(DAC960_Controller_T *);
4412 static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *);
4413 static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *); 
4414 static void DAC960_RequestFunction(struct request_queue *);
4415 static irqreturn_t DAC960_BA_InterruptHandler(int, void *, struct pt_regs *);
4416 static irqreturn_t DAC960_LP_InterruptHandler(int, void *, struct pt_regs *);
4417 static irqreturn_t DAC960_LA_InterruptHandler(int, void *, struct pt_regs *);
4418 static irqreturn_t DAC960_PG_InterruptHandler(int, void *, struct pt_regs *);
4419 static irqreturn_t DAC960_PD_InterruptHandler(int, void *, struct pt_regs *);
4420 static irqreturn_t DAC960_P_InterruptHandler(int, void *, struct pt_regs *);
4421 static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *);
4422 static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *);
4423 static void DAC960_MonitoringTimerFunction(unsigned long);
4424 static void DAC960_Message(DAC960_MessageLevel_T, unsigned char *,
4425                            DAC960_Controller_T *, ...);
4426 static void DAC960_CreateProcEntries(DAC960_Controller_T *);
4427 static void DAC960_DestroyProcEntries(DAC960_Controller_T *);
4428
4429 #endif /* DAC960_DriverVersion */