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