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