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