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