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