Import 2.3.25pre1
[davej-history.git] / drivers / block / DAC960.h
blob2ff757786385afe3e68cbeb50d46bd2a12865e7d
1 /*
3 Linux Driver for Mylex DAC960 and DAC1100 PCI RAID Controllers
5 Copyright 1998-1999 by Leonard N. Zubkoff <lnz@dandelion.com>
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.
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.
16 The author respectfully requests that any modifications to this software be
17 sent directly to him for evaluation and testing.
23 Define the maximum number of DAC960 Controllers supported by this driver.
26 #define DAC960_MaxControllers 8
30 Define the maximum number of Controller Channels supported by this driver.
33 #define DAC960_MaxChannels 3
37 Define the maximum number of Targets per Channel supported by this driver.
40 #define DAC960_MaxTargets 16
44 Define the maximum number of Logical Drives supported by any DAC960 model.
47 #define DAC960_MaxLogicalDrives 32
51 Define a Boolean data type.
54 typedef enum { false, true } __attribute__ ((packed)) boolean;
58 Define a 32 bit I/O Address data type.
61 typedef unsigned int DAC960_IO_Address_T;
65 Define a 32 bit PCI Bus Address data type.
68 typedef unsigned int DAC960_PCI_Address_T;
72 Define a 32 bit Bus Address data type.
75 typedef unsigned int DAC960_BusAddress_T;
79 Define a 32 bit Byte Count data type.
82 typedef unsigned int DAC960_ByteCount_T;
86 Define the DAC960 Command Opcodes.
89 typedef enum
91 /* I/O Commands */
92 DAC960_ReadExtended = 0x33,
93 DAC960_WriteExtended = 0x34,
94 DAC960_ReadAheadExtended = 0x35,
95 DAC960_ReadExtendedWithScatterGather = 0xB3,
96 DAC960_WriteExtendedWithScatterGather = 0xB4,
97 DAC960_Read = 0x36,
98 DAC960_ReadWithOldScatterGather = 0xB6,
99 DAC960_Write = 0x37,
100 DAC960_WriteWithOldScatterGather = 0xB7,
101 DAC960_DCDB = 0x04,
102 DAC960_DCDBWithScatterGather = 0x84,
103 DAC960_Flush = 0x0A,
104 /* Controller Status Related Commands */
105 DAC960_Enquiry = 0x53,
106 DAC960_Enquiry2 = 0x1C,
107 DAC960_GetLogicalDriveElement = 0x55,
108 DAC960_GetLogicalDriveInformation = 0x19,
109 DAC960_IOPortRead = 0x39,
110 DAC960_IOPortWrite = 0x3A,
111 DAC960_GetSDStats = 0x3E,
112 DAC960_GetPDStats = 0x3F,
113 DAC960_PerformEventLogOperation = 0x72,
114 /* Device Related Commands */
115 DAC960_StartDevice = 0x10,
116 DAC960_GetDeviceState = 0x50,
117 DAC960_StopChannel = 0x13,
118 DAC960_StartChannel = 0x12,
119 DAC960_ResetChannel = 0x1A,
120 /* Commands Associated with Data Consistency and Errors */
121 DAC960_Rebuild = 0x09,
122 DAC960_RebuildAsync = 0x16,
123 DAC960_CheckConsistency = 0x0F,
124 DAC960_CheckConsistencyAsync = 0x1E,
125 DAC960_RebuildStat = 0x0C,
126 DAC960_GetRebuildProgress = 0x27,
127 DAC960_RebuildControl = 0x1F,
128 DAC960_ReadBadBlockTable = 0x0B,
129 DAC960_ReadBadDataTable = 0x25,
130 DAC960_ClearBadDataTable = 0x26,
131 DAC960_GetErrorTable = 0x17,
132 DAC960_AddCapacityAsync = 0x2A,
133 /* Configuration Related Commands */
134 DAC960_ReadConfig2 = 0x3D,
135 DAC960_WriteConfig2 = 0x3C,
136 DAC960_ReadConfigurationOnDisk = 0x4A,
137 DAC960_WriteConfigurationOnDisk = 0x4B,
138 DAC960_ReadConfiguration = 0x4E,
139 DAC960_ReadBackupConfiguration = 0x4D,
140 DAC960_WriteConfiguration = 0x4F,
141 DAC960_AddConfiguration = 0x4C,
142 DAC960_ReadConfigurationLabel = 0x48,
143 DAC960_WriteConfigurationLabel = 0x49,
144 /* Firmware Upgrade Related Commands */
145 DAC960_LoadImage = 0x20,
146 DAC960_StoreImage = 0x21,
147 DAC960_ProgramImage = 0x22,
148 /* Diagnostic Commands */
149 DAC960_SetDiagnosticMode = 0x31,
150 DAC960_RunDiagnostic = 0x32,
151 /* Subsystem Service Commands */
152 DAC960_GetSubsystemData = 0x70,
153 DAC960_SetSubsystemParameters = 0x71
155 __attribute__ ((packed))
156 DAC960_CommandOpcode_T;
160 Define the DAC960 Command Identifier type.
163 typedef unsigned char DAC960_CommandIdentifier_T;
167 Define the DAC960 Command Status Codes.
170 #define DAC960_NormalCompletion 0x0000 /* Common */
171 #define DAC960_CheckConditionReceived 0x0002 /* Common */
172 #define DAC960_NoDeviceAtAddress 0x0102 /* Common */
173 #define DAC960_InvalidDeviceAddress 0x0105 /* Common */
174 #define DAC960_InvalidParameter 0x0105 /* Common */
175 #define DAC960_IrrecoverableDataError 0x0001 /* I/O */
176 #define DAC960_LogicalDriveNonexistentOrOffline 0x0002 /* I/O */
177 #define DAC960_AccessBeyondEndOfLogicalDrive 0x0105 /* I/O */
178 #define DAC960_BadDataEncountered 0x010C /* I/O */
179 #define DAC960_DeviceBusy 0x0008 /* DCDB */
180 #define DAC960_DeviceNonresponsive 0x000E /* DCDB */
181 #define DAC960_CommandTerminatedAbnormally 0x000F /* DCDB */
182 #define DAC960_UnableToStartDevice 0x0002 /* Device */
183 #define DAC960_InvalidChannelOrTargetOrModifier 0x0105 /* Device */
184 #define DAC960_ChannelBusy 0x0106 /* Device */
185 #define DAC960_ChannelNotStopped 0x0002 /* Device */
186 #define DAC960_AttemptToRebuildOnlineDrive 0x0002 /* Consistency */
187 #define DAC960_RebuildBadBlocksEncountered 0x0003 /* Consistency */
188 #define DAC960_NewDiskFailedDuringRebuild 0x0004 /* Consistency */
189 #define DAC960_RebuildOrCheckAlreadyInProgress 0x0106 /* Consistency */
190 #define DAC960_DependentDiskIsDead 0x0002 /* Consistency */
191 #define DAC960_InconsistentBlocksFound 0x0003 /* Consistency */
192 #define DAC960_InvalidOrNonredundantLogicalDrive 0x0105 /* Consistency */
193 #define DAC960_NoRebuildOrCheckInProgress 0x0105 /* Consistency */
194 #define DAC960_RebuildInProgress_DataValid 0x0000 /* Consistency */
195 #define DAC960_RebuildFailed_LogicalDriveFailure 0x0002 /* Consistency */
196 #define DAC960_RebuildFailed_BadBlocksOnOther 0x0003 /* Consistency */
197 #define DAC960_RebuildFailed_NewDriveFailed 0x0004 /* Consistency */
198 #define DAC960_RebuildSuccessful 0x0100 /* Consistency */
199 #define DAC960_AddCapacityInProgress 0x0004 /* Consistency */
200 #define DAC960_AddCapacityFailedOrSuspended 0x00F4 /* Consistency */
201 #define DAC960_Config2ChecksumError 0x0002 /* Configuration */
202 #define DAC960_ConfigurationSuspended 0x0106 /* Configuration */
203 #define DAC960_FailedToConfigureNVRAM 0x0105 /* Configuration */
204 #define DAC960_ConfigurationNotSavedStateChange 0x0106 /* Configuration */
205 #define DAC960_SubsystemNotInstalled 0x0001 /* Subsystem */
206 #define DAC960_SubsystemFailed 0x0002 /* Subsystem */
207 #define DAC960_SubsystemBusy 0x0106 /* Subsystem */
209 typedef unsigned short DAC960_CommandStatus_T;
213 Define the Enquiry reply structure.
216 typedef struct DAC960_Enquiry
218 unsigned char NumberOfLogicalDrives; /* Byte 0 */
219 unsigned int :24; /* Bytes 1-3 */
220 unsigned int LogicalDriveSizes[32]; /* Bytes 4-131 */
221 unsigned short FlashAge; /* Bytes 132-133 */
222 struct {
223 boolean DeferredWriteError:1; /* Byte 134 Bit 0 */
224 boolean BatteryLow:1; /* Byte 134 Bit 1 */
225 unsigned char :6; /* Byte 134 Bits 2-7 */
226 } StatusFlags;
227 unsigned char :8; /* Byte 135 */
228 unsigned char MinorFirmwareVersion; /* Byte 136 */
229 unsigned char MajorFirmwareVersion; /* Byte 137 */
230 enum {
231 DAC960_NoStandbyRebuildOrCheckInProgress = 0x00,
232 DAC960_StandbyRebuildInProgress = 0x01,
233 DAC960_BackgroundRebuildInProgress = 0x02,
234 DAC960_BackgroundCheckInProgress = 0x03,
235 DAC960_StandbyRebuildCompletedWithError = 0xFF,
236 DAC960_BackgroundRebuildOrCheckFailed_DriveFailed = 0xF0,
237 DAC960_BackgroundRebuildOrCheckFailed_LogicalDriveFailed = 0xF1,
238 DAC960_BackgroundRebuildOrCheckFailed_OtherCauses = 0xF2,
239 DAC960_BackgroundRebuildOrCheckSuccessfullyTerminated = 0xF3
240 } __attribute__ ((packed)) RebuildFlag; /* Byte 138 */
241 unsigned char MaxCommands; /* Byte 139 */
242 unsigned char OfflineLogicalDriveCount; /* Byte 140 */
243 unsigned char :8; /* Byte 141 */
244 unsigned short EventLogSequenceNumber; /* Bytes 142-143 */
245 unsigned char CriticalLogicalDriveCount; /* Byte 144 */
246 unsigned int :24; /* Bytes 145-147 */
247 unsigned char DeadDriveCount; /* Byte 148 */
248 unsigned char :8; /* Byte 149 */
249 unsigned char RebuildCount; /* Byte 150 */
250 struct {
251 unsigned char :3; /* Byte 151 Bits 0-2 */
252 boolean BatteryBackupUnitPresent:1; /* Byte 151 Bit 3 */
253 unsigned char :3; /* Byte 151 Bits 4-6 */
254 unsigned char :1; /* Byte 151 Bit 7 */
255 } MiscFlags;
256 struct {
257 unsigned char TargetID;
258 unsigned char Channel;
259 } DeadDrives[21]; /* Bytes 152-194 */
260 unsigned char Reserved[62]; /* Bytes 195-255 */
262 __attribute__ ((packed))
263 DAC960_Enquiry_T;
267 Define the Enquiry2 reply structure.
270 typedef struct DAC960_Enquiry2
272 struct {
273 enum {
274 DAC960_P_PD_PU = 0x01,
275 DAC960_PL = 0x02,
276 DAC960_PG = 0x10,
277 DAC960_PJ = 0x11,
278 DAC960_PR = 0x12,
279 DAC960_PT = 0x13,
280 DAC960_PTL0 = 0x14,
281 DAC960_PRL = 0x15,
282 DAC960_PTL1 = 0x16,
283 DAC1164_P = 0x20
284 } __attribute__ ((packed)) SubModel; /* Byte 0 */
285 unsigned char ActualChannels; /* Byte 1 */
286 enum {
287 DAC960_FiveChannelBoard = 0x01,
288 DAC960_ThreeChannelBoard = 0x02,
289 DAC960_TwoChannelBoard = 0x03,
290 DAC960_ThreeChannelASIC_DAC = 0x04
291 } __attribute__ ((packed)) Model; /* Byte 2 */
292 enum {
293 DAC960_EISA_Controller = 0x01,
294 DAC960_MicroChannel_Controller = 0x02,
295 DAC960_PCI_Controller = 0x03,
296 DAC960_SCSItoSCSI_Controller = 0x08
297 } __attribute__ ((packed)) ProductFamily; /* Byte 3 */
298 } HardwareID; /* Bytes 0-3 */
299 /* MajorVersion.MinorVersion-FirmwareType-TurnID */
300 struct {
301 unsigned char MajorVersion; /* Byte 4 */
302 unsigned char MinorVersion; /* Byte 5 */
303 unsigned char TurnID; /* Byte 6 */
304 char FirmwareType; /* Byte 7 */
305 } FirmwareID; /* Bytes 4-7 */
306 unsigned char :8; /* Byte 8 */
307 unsigned int :24; /* Bytes 9-11 */
308 unsigned char ConfiguredChannels; /* Byte 12 */
309 unsigned char ActualChannels; /* Byte 13 */
310 unsigned char MaxTargets; /* Byte 14 */
311 unsigned char MaxTags; /* Byte 15 */
312 unsigned char MaxLogicalDrives; /* Byte 16 */
313 unsigned char MaxArms; /* Byte 17 */
314 unsigned char MaxSpans; /* Byte 18 */
315 unsigned char :8; /* Byte 19 */
316 unsigned int :32; /* Bytes 20-23 */
317 unsigned int MemorySize; /* Bytes 24-27 */
318 unsigned int CacheSize; /* Bytes 28-31 */
319 unsigned int FlashMemorySize; /* Bytes 32-35 */
320 unsigned int NonVolatileMemorySize; /* Bytes 36-39 */
321 struct {
322 enum {
323 DAC960_DRAM = 0x00,
324 DAC960_EDO = 0x01,
325 DAC960_SDRAM = 0x02
326 } __attribute__ ((packed)) RamType:3; /* Byte 40 Bits 0-2 */
327 enum {
328 DAC960_None = 0x00,
329 DAC960_Parity = 0x01,
330 DAC960_ECC = 0x02
331 } __attribute__ ((packed)) ErrorCorrection:3; /* Byte 40 Bits 3-5 */
332 boolean FastPageMode:1; /* Byte 40 Bit 6 */
333 boolean LowPowerMemory:1; /* Byte 40 Bit 7 */
334 unsigned char :8; /* Bytes 41 */
335 } MemoryType;
336 unsigned short ClockSpeed; /* Bytes 42-43 */
337 unsigned short MemorySpeed; /* Bytes 44-45 */
338 unsigned short HardwareSpeed; /* Bytes 46-47 */
339 unsigned int :32; /* Bytes 48-51 */
340 unsigned int :32; /* Bytes 52-55 */
341 unsigned char :8; /* Byte 56 */
342 unsigned char :8; /* Byte 57 */
343 unsigned short :16; /* Bytes 58-59 */
344 unsigned short MaxCommands; /* Bytes 60-61 */
345 unsigned short MaxScatterGatherEntries; /* Bytes 62-63 */
346 unsigned short MaxDriveCommands; /* Bytes 64-65 */
347 unsigned short MaxIODescriptors; /* Bytes 66-67 */
348 unsigned short MaxCombinedSectors; /* Bytes 68-69 */
349 unsigned char Latency; /* Byte 70 */
350 unsigned char :8; /* Byte 71 */
351 unsigned char SCSITimeout; /* Byte 72 */
352 unsigned char :8; /* Byte 73 */
353 unsigned short MinFreeLines; /* Bytes 74-75 */
354 unsigned int :32; /* Bytes 76-79 */
355 unsigned int :32; /* Bytes 80-83 */
356 unsigned char RebuildRateConstant; /* Byte 84 */
357 unsigned char :8; /* Byte 85 */
358 unsigned char :8; /* Byte 86 */
359 unsigned char :8; /* Byte 87 */
360 unsigned int :32; /* Bytes 88-91 */
361 unsigned int :32; /* Bytes 92-95 */
362 unsigned short PhysicalDriveBlockSize; /* Bytes 96-97 */
363 unsigned short LogicalDriveBlockSize; /* Bytes 98-99 */
364 unsigned short MaxBlocksPerCommand; /* Bytes 100-101 */
365 unsigned short BlockFactor; /* Bytes 102-103 */
366 unsigned short CacheLineSize; /* Bytes 104-105 */
367 struct {
368 enum {
369 DAC960_Narrow_8bit = 0x00,
370 DAC960_Wide_16bit = 0x01,
371 DAC960_Wide_32bit = 0x02
372 } __attribute__ ((packed)) BusWidth:2; /* Byte 106 Bits 0-1 */
373 enum {
374 DAC960_Fast = 0x00,
375 DAC960_Ultra = 0x01,
376 DAC960_Ultra2 = 0x02
377 } __attribute__ ((packed)) BusSpeed:2; /* Byte 106 Bits 2-3 */
378 boolean Differential:1; /* Byte 106 Bit 4 */
379 unsigned char :3; /* Byte 106 Bits 5-7 */
380 } SCSICapability;
381 unsigned char :8; /* Byte 107 */
382 unsigned int :32; /* Bytes 108-111 */
383 unsigned short FirmwareBuildNumber; /* Bytes 112-113 */
384 enum {
385 DAC960_AEMI = 0x01,
386 DAC960_OEM1 = 0x02,
387 DAC960_OEM2 = 0x04,
388 DAC960_OEM3 = 0x08,
389 DAC960_Conner = 0x10,
390 DAC960_SAFTE = 0x20
391 } __attribute__ ((packed)) FaultManagementType; /* Byte 114 */
392 unsigned char :8; /* Byte 115 */
393 struct {
394 boolean Clustering:1; /* Byte 116 Bit 0 */
395 boolean MylexOnlineRAIDExpansion:1; /* Byte 116 Bit 1 */
396 unsigned int :30; /* Bytes 116-119 */
397 } FirmwareFeatures;
398 unsigned int :32; /* Bytes 120-123 */
399 unsigned int :32; /* Bytes 124-127 */
401 DAC960_Enquiry2_T;
405 Define the Logical Drive State type.
408 typedef enum
410 DAC960_LogicalDrive_Online = 0x03,
411 DAC960_LogicalDrive_Critical = 0x04,
412 DAC960_LogicalDrive_Offline = 0xFF
414 __attribute__ ((packed))
415 DAC960_LogicalDriveState_T;
419 Define the Get Logical Drive Information reply structure.
422 typedef struct DAC960_LogicalDriveInformation
424 unsigned int LogicalDriveSize; /* Bytes 0-3 */
425 DAC960_LogicalDriveState_T LogicalDriveState; /* Byte 4 */
426 unsigned char RAIDLevel:7; /* Byte 5 Bits 0-6 */
427 boolean WriteBack:1; /* Byte 5 Bit 7 */
428 unsigned int :16; /* Bytes 6-7 */
430 DAC960_LogicalDriveInformation_T;
434 Define the Perform Event Log Operation Types.
437 typedef enum
439 DAC960_GetEventLogEntry = 0x00
441 __attribute__ ((packed))
442 DAC960_PerformEventLogOpType_T;
446 Define the Get Event Log Entry reply structure.
449 typedef struct DAC960_EventLogEntry
451 unsigned char MessageType; /* Byte 0 */
452 unsigned char MessageLength; /* Byte 1 */
453 unsigned char TargetID:5; /* Byte 2 Bits 0-4 */
454 unsigned char Channel:3; /* Byte 2 Bits 5-7 */
455 unsigned char LogicalUnit:6; /* Byte 3 Bits 0-5 */
456 unsigned char :2; /* Byte 3 Bits 6-7 */
457 unsigned short SequenceNumber; /* Bytes 4-5 */
458 unsigned char ErrorCode:7; /* Byte 6 Bits 0-6 */
459 boolean Valid:1; /* Byte 6 Bit 7 */
460 unsigned char SegmentNumber; /* Byte 7 */
461 unsigned char SenseKey:4; /* Byte 8 Bits 0-3 */
462 unsigned char :1; /* Byte 8 Bit 4 */
463 boolean ILI:1; /* Byte 8 Bit 5 */
464 boolean EOM:1; /* Byte 8 Bit 6 */
465 boolean Filemark:1; /* Byte 8 Bit 7 */
466 unsigned char Information[4]; /* Bytes 9-12 */
467 unsigned char AdditionalSenseLength; /* Byte 13 */
468 unsigned char CommandSpecificInformation[4]; /* Bytes 14-17 */
469 unsigned char AdditionalSenseCode; /* Byte 18 */
470 unsigned char AdditionalSenseCodeQualifier; /* Byte 19 */
471 unsigned char Dummy[12]; /* Bytes 20-31 */
473 DAC960_EventLogEntry_T;
477 Define the Physical Device State type.
480 typedef enum
482 DAC960_Device_Dead = 0x00,
483 DAC960_Device_WriteOnly = 0x02,
484 DAC960_Device_Online = 0x03,
485 DAC960_Device_Standby = 0x10
487 __attribute__ ((packed))
488 DAC960_PhysicalDeviceState_T;
492 Define the Get Device State reply structure.
495 typedef struct DAC960_DeviceState
497 boolean Present:1; /* Byte 0 Bit 0 */
498 unsigned char :7; /* Byte 0 Bits 1-7 */
499 enum {
500 DAC960_OtherType = 0x00,
501 DAC960_DiskType = 0x01,
502 DAC960_SequentialType = 0x02,
503 DAC960_CDROM_or_WORM_Type = 0x03
504 } __attribute__ ((packed)) DeviceType:2; /* Byte 1 Bits 0-1 */
505 boolean :1; /* Byte 1 Bit 2 */
506 boolean Fast20:1; /* Byte 1 Bit 3 */
507 boolean Sync:1; /* Byte 1 Bit 4 */
508 boolean Fast:1; /* Byte 1 Bit 5 */
509 boolean Wide:1; /* Byte 1 Bit 6 */
510 boolean TaggedQueuingSupported:1; /* Byte 1 Bit 7 */
511 DAC960_PhysicalDeviceState_T DeviceState; /* Byte 2 */
512 unsigned char :8; /* Byte 3 */
513 unsigned char SynchronousMultiplier; /* Byte 4 */
514 unsigned char SynchronousOffset:5; /* Byte 5 Bits 0-4 */
515 unsigned char :3; /* Byte 5 Bits 5-7 */
516 unsigned long DiskSize __attribute__ ((packed)); /* Bytes 6-9 */
518 DAC960_DeviceState_T;
522 Define the Get Rebuild Progress reply structure.
525 typedef struct DAC960_RebuildProgress
527 unsigned int LogicalDriveNumber; /* Bytes 0-3 */
528 unsigned int LogicalDriveSize; /* Bytes 4-7 */
529 unsigned int RemainingBlocks; /* Bytes 8-11 */
531 DAC960_RebuildProgress_T;
535 Define the Error Table Entry and Get Error Table reply structure.
538 typedef struct DAC960_ErrorTableEntry
540 unsigned char ParityErrorCount; /* Byte 0 */
541 unsigned char SoftErrorCount; /* Byte 1 */
542 unsigned char HardErrorCount; /* Byte 2 */
543 unsigned char MiscErrorCount; /* Byte 3 */
545 DAC960_ErrorTableEntry_T;
549 Define the Get Error Table reply structure.
552 typedef struct DAC960_ErrorTable
554 DAC960_ErrorTableEntry_T
555 ErrorTableEntries[DAC960_MaxChannels][DAC960_MaxTargets];
557 DAC960_ErrorTable_T;
561 Define the Config2 reply structure.
564 typedef struct DAC960_Config2
566 unsigned char :1; /* Byte 0 Bit 0 */
567 boolean ActiveNegationEnabled:1; /* Byte 0 Bit 1 */
568 unsigned char :5; /* Byte 0 Bits 2-6 */
569 boolean NoRescanIfResetReceivedDuringScan:1; /* Byte 0 Bit 7 */
570 boolean StorageWorksSupportEnabled:1; /* Byte 1 Bit 0 */
571 boolean HewlettPackardSupportEnabled:1; /* Byte 1 Bit 1 */
572 boolean NoDisconnectOnFirstCommand:1; /* Byte 1 Bit 2 */
573 unsigned char :2; /* Byte 1 Bits 3-4 */
574 boolean AEMI_ARM:1; /* Byte 1 Bit 5 */
575 boolean AEMI_OFM:1; /* Byte 1 Bit 6 */
576 unsigned char :1; /* Byte 1 Bit 7 */
577 enum {
578 DAC960_OEMID_Mylex = 0x00,
579 DAC960_OEMID_IBM = 0x08,
580 DAC960_OEMID_HP = 0x0A,
581 DAC960_OEMID_DEC = 0x0C,
582 DAC960_OEMID_Siemens = 0x10,
583 DAC960_OEMID_Intel = 0x12
584 } __attribute__ ((packed)) OEMID; /* Byte 2 */
585 unsigned char OEMModelNumber; /* Byte 3 */
586 unsigned char PhysicalSector; /* Byte 4 */
587 unsigned char LogicalSector; /* Byte 5 */
588 unsigned char BlockFactor; /* Byte 6 */
589 boolean ReadAheadEnabled:1; /* Byte 7 Bit 0 */
590 boolean LowBIOSDelay:1; /* Byte 7 Bit 1 */
591 unsigned char :2; /* Byte 7 Bits 2-3 */
592 boolean ReassignRestrictedToOneSector:1; /* Byte 7 Bit 4 */
593 unsigned char :1; /* Byte 7 Bit 5 */
594 boolean ForceUnitAccessDuringWriteRecovery:1; /* Byte 7 Bit 6 */
595 boolean EnableLeftSymmetricRAID5Algorithm:1; /* Byte 7 Bit 7 */
596 unsigned char DefaultRebuildRate; /* Byte 8 */
597 unsigned char :8; /* Byte 9 */
598 unsigned char BlocksPerCacheLine; /* Byte 10 */
599 unsigned char BlocksPerStripe; /* Byte 11 */
600 struct {
601 enum {
602 DAC960_Async = 0x00,
603 DAC960_Sync_8MHz = 0x01,
604 DAC960_Sync_5MHz = 0x02,
605 DAC960_Sync_10or20MHz = 0x03 /* Bits 0-1 */
606 } __attribute__ ((packed)) Speed:2;
607 boolean Force8Bit:1; /* Bit 2 */
608 boolean DisableFast20:1; /* Bit 3 */
609 unsigned char :3; /* Bits 4-6 */
610 boolean EnableTaggedQueuing:1; /* Bit 7 */
611 } __attribute__ ((packed)) ChannelParameters[6]; /* Bytes 12-17 */
612 unsigned char SCSIInitiatorID; /* Byte 18 */
613 unsigned char :8; /* Byte 19 */
614 enum {
615 DAC960_StartupMode_ControllerSpinUp = 0x00,
616 DAC960_StartupMode_PowerOnSpinUp = 0x01
617 } __attribute__ ((packed)) StartupMode; /* Byte 20 */
618 unsigned char SimultaneousDeviceSpinUpCount; /* Byte 21 */
619 unsigned char SecondsDelayBetweenSpinUps; /* Byte 22 */
620 unsigned char Reserved1[29]; /* Bytes 23-51 */
621 boolean BIOSDisabled:1; /* Byte 52 Bit 0 */
622 boolean CDROMBootEnabled:1; /* Byte 52 Bit 1 */
623 unsigned char :3; /* Byte 52 Bits 2-4 */
624 enum {
625 DAC960_Geometry_128_32 = 0x00,
626 DAC960_Geometry_255_63 = 0x01,
627 DAC960_Geometry_Reserved1 = 0x02,
628 DAC960_Geometry_Reserved2 = 0x03
629 } __attribute__ ((packed)) DriveGeometry:2; /* Byte 52 Bits 5-6 */
630 unsigned char :1; /* Byte 52 Bit 7 */
631 unsigned char Reserved2[9]; /* Bytes 53-61 */
632 unsigned short Checksum; /* Bytes 62-63 */
634 DAC960_Config2_T;
638 Define the DCDB request structure.
641 typedef struct DAC960_DCDB
643 unsigned char TargetID:4; /* Byte 0 Bits 0-3 */
644 unsigned char Channel:4; /* Byte 0 Bits 4-7 */
645 enum {
646 DAC960_DCDB_NoDataTransfer = 0,
647 DAC960_DCDB_DataTransferDeviceToSystem = 1,
648 DAC960_DCDB_DataTransferSystemToDevice = 2,
649 DAC960_DCDB_IllegalDataTransfer = 3
650 } __attribute__ ((packed)) Direction:2; /* Byte 1 Bits 0-1 */
651 boolean EarlyStatus:1; /* Byte 1 Bit 2 */
652 unsigned char :1; /* Byte 1 Bit 3 */
653 enum {
654 DAC960_DCDB_Timeout_24_hours = 0,
655 DAC960_DCDB_Timeout_10_seconds = 1,
656 DAC960_DCDB_Timeout_60_seconds = 2,
657 DAC960_DCDB_Timeout_10_minutes = 3
658 } __attribute__ ((packed)) Timeout:2; /* Byte 1 Bits 4-5 */
659 boolean NoAutomaticRequestSense:1; /* Byte 1 Bit 6 */
660 boolean DisconnectPermitted:1; /* Byte 1 Bit 7 */
661 unsigned short TransferLength; /* Bytes 2-3 */
662 DAC960_BusAddress_T BusAddress; /* Bytes 4-7 */
663 unsigned char CDBLength:4; /* Byte 8 Bits 0-3 */
664 unsigned char TransferLengthHigh4:4; /* Byte 8 Bits 4-7 */
665 unsigned char SenseLength; /* Byte 9 */
666 unsigned char CDB[12]; /* Bytes 10-21 */
667 unsigned char SenseData[64]; /* Bytes 22-85 */
668 unsigned char Status; /* Byte 86 */
669 unsigned char :8; /* Byte 87 */
671 DAC960_DCDB_T;
675 Define the SCSI INQUIRY Standard Data reply structure.
678 typedef struct DAC960_SCSI_Inquiry
680 unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */
681 unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */
682 unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */
683 boolean RMB:1; /* Byte 1 Bit 7 */
684 unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */
685 unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */
686 unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */
687 unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */
688 unsigned char :2; /* Byte 3 Bits 4-5 */
689 boolean TrmIOP:1; /* Byte 3 Bit 6 */
690 boolean AENC:1; /* Byte 3 Bit 7 */
691 unsigned char AdditionalLength; /* Byte 4 */
692 unsigned char :8; /* Byte 5 */
693 unsigned char :8; /* Byte 6 */
694 boolean SftRe:1; /* Byte 7 Bit 0 */
695 boolean CmdQue:1; /* Byte 7 Bit 1 */
696 boolean :1; /* Byte 7 Bit 2 */
697 boolean Linked:1; /* Byte 7 Bit 3 */
698 boolean Sync:1; /* Byte 7 Bit 4 */
699 boolean WBus16:1; /* Byte 7 Bit 5 */
700 boolean WBus32:1; /* Byte 7 Bit 6 */
701 boolean RelAdr:1; /* Byte 7 Bit 7 */
702 unsigned char VendorIdentification[8]; /* Bytes 8-15 */
703 unsigned char ProductIdentification[16]; /* Bytes 16-31 */
704 unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */
706 DAC960_SCSI_Inquiry_T;
710 Define the SCSI INQUIRY Unit Serial Number reply structure.
713 typedef struct DAC960_SCSI_Inquiry_UnitSerialNumber
715 unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */
716 unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */
717 unsigned char PageCode; /* Byte 1 */
718 unsigned char :8; /* Byte 2 */
719 unsigned char PageLength; /* Byte 3 */
720 unsigned char ProductSerialNumber[28]; /* Bytes 4 - 31 */
722 DAC960_SCSI_Inquiry_UnitSerialNumber_T;
726 Define the Scatter/Gather List Type 1 32 Bit Address 32 Bit Byte Count
727 structure.
730 typedef struct DAC960_ScatterGatherSegment
732 DAC960_BusAddress_T SegmentDataPointer; /* Bytes 0-3 */
733 DAC960_ByteCount_T SegmentByteCount; /* Bytes 4-7 */
735 DAC960_ScatterGatherSegment_T;
739 Define the 13 Byte DAC960 Command Mailbox structure. Bytes 13-15 are
740 not used. The Command Mailbox structure is padded to 16 bytes for
741 efficient access.
744 typedef union DAC960_CommandMailbox
746 unsigned int Words[4]; /* Words 0-3 */
747 unsigned char Bytes[16]; /* Bytes 0-15 */
748 struct {
749 DAC960_CommandOpcode_T CommandOpcode; /* Byte 0 */
750 DAC960_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
751 unsigned char Dummy[14]; /* Bytes 2-15 */
752 } __attribute__ ((packed)) Common;
753 struct {
754 DAC960_CommandOpcode_T CommandOpcode; /* Byte 0 */
755 DAC960_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
756 unsigned char Dummy1[6]; /* Bytes 2-7 */
757 DAC960_BusAddress_T BusAddress; /* Bytes 8-11 */
758 unsigned char Dummy2[4]; /* Bytes 12-15 */
759 } __attribute__ ((packed)) Type3;
760 struct {
761 DAC960_CommandOpcode_T CommandOpcode; /* Byte 0 */
762 DAC960_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
763 unsigned char Dummy1[5]; /* Bytes 2-6 */
764 unsigned char LogicalDriveNumber:6; /* Byte 7 Bits 0-6 */
765 boolean AutoRestore:1; /* Byte 7 Bit 7 */
766 unsigned char Dummy2[8]; /* Bytes 8-15 */
767 } __attribute__ ((packed)) Type3C;
768 struct {
769 DAC960_CommandOpcode_T CommandOpcode; /* Byte 0 */
770 DAC960_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
771 unsigned char Channel; /* Byte 2 */
772 unsigned char TargetID; /* Byte 3 */
773 DAC960_PhysicalDeviceState_T DeviceState:5; /* Byte 4 Bits 0-4 */
774 unsigned char Modifier:3; /* Byte 4 Bits 5-7 */
775 unsigned char Dummy1[3]; /* Bytes 5-7 */
776 DAC960_BusAddress_T BusAddress; /* Bytes 8-11 */
777 unsigned char Dummy2[4]; /* Bytes 12-15 */
778 } __attribute__ ((packed)) Type3D;
779 struct {
780 DAC960_CommandOpcode_T CommandOpcode; /* Byte 0 */
781 DAC960_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
782 DAC960_PerformEventLogOpType_T OperationType; /* Byte 2 */
783 unsigned char OperationQualifier; /* Byte 3 */
784 unsigned short SequenceNumber; /* Bytes 4-5 */
785 unsigned char Dummy1[2]; /* Bytes 6-7 */
786 DAC960_BusAddress_T BusAddress; /* Bytes 8-11 */
787 unsigned char Dummy2[4]; /* Bytes 12-15 */
788 } __attribute__ ((packed)) Type3E;
789 struct {
790 DAC960_CommandOpcode_T CommandOpcode; /* Byte 0 */
791 DAC960_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
792 unsigned char Dummy1[2]; /* Bytes 2-3 */
793 unsigned char RebuildRateConstant; /* Byte 4 */
794 unsigned char Dummy2[3]; /* Bytes 5-7 */
795 DAC960_BusAddress_T BusAddress; /* Bytes 8-11 */
796 unsigned char Dummy3[4]; /* Bytes 12-15 */
797 } __attribute__ ((packed)) Type3R;
798 struct {
799 DAC960_CommandOpcode_T CommandOpcode; /* Byte 0 */
800 DAC960_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
801 unsigned short TransferLength; /* Bytes 2-3 */
802 unsigned int LogicalBlockAddress; /* Bytes 4-7 */
803 DAC960_BusAddress_T BusAddress; /* Bytes 8-11 */
804 unsigned char LogicalDriveNumber; /* Byte 12 */
805 unsigned char Dummy[3]; /* Bytes 13-15 */
806 } __attribute__ ((packed)) Type4;
807 struct {
808 DAC960_CommandOpcode_T CommandOpcode; /* Byte 0 */
809 DAC960_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
810 struct {
811 unsigned short TransferLength:11; /* Bytes 2-3 */
812 unsigned char LogicalDriveNumber:5; /* Byte 3 Bits 3-7 */
813 } __attribute__ ((packed)) LD;
814 unsigned int LogicalBlockAddress; /* Bytes 4-7 */
815 DAC960_BusAddress_T BusAddress; /* Bytes 8-11 */
816 unsigned char ScatterGatherCount:6; /* Byte 12 Bits 0-5 */
817 enum {
818 DAC960_ScatterGather_32BitAddress_32BitByteCount = 0x0,
819 DAC960_ScatterGather_32BitAddress_16BitByteCount = 0x1,
820 DAC960_ScatterGather_32BitByteCount_32BitAddress = 0x2,
821 DAC960_ScatterGather_16BitByteCount_32BitAddress = 0x3
822 } __attribute__ ((packed)) ScatterGatherType:2; /* Byte 12 Bits 6-7 */
823 unsigned char Dummy[3]; /* Bytes 13-15 */
824 } __attribute__ ((packed)) Type5;
825 struct {
826 DAC960_CommandOpcode_T CommandOpcode; /* Byte 0 */
827 DAC960_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
828 unsigned char CommandOpcode2; /* Byte 2 */
829 unsigned char :8; /* Byte 3 */
830 DAC960_BusAddress_T CommandMailboxesBusAddress; /* Bytes 4-7 */
831 DAC960_BusAddress_T StatusMailboxesBusAddress; /* Bytes 8-11 */
832 unsigned char Dummy[4]; /* Bytes 12-15 */
833 } __attribute__ ((packed)) TypeX;
835 DAC960_CommandMailbox_T;
839 Define the DAC960 Driver IOCTL requests.
842 #define DAC960_IOCTL_GET_CONTROLLER_COUNT 0xDAC001
843 #define DAC960_IOCTL_GET_CONTROLLER_INFO 0xDAC002
844 #define DAC960_IOCTL_EXECUTE_COMMAND 0xDAC003
848 Define the DAC960_IOCTL_GET_CONTROLLER_INFO reply structure.
851 typedef struct DAC960_ControllerInfo
853 unsigned char ControllerNumber;
854 unsigned char PCI_Bus;
855 unsigned char PCI_Device;
856 unsigned char PCI_Function;
857 unsigned char IRQ_Channel;
858 unsigned char Channels;
859 DAC960_PCI_Address_T PCI_Address;
860 unsigned char ModelName[16];
861 unsigned char FirmwareVersion[16];
863 DAC960_ControllerInfo_T;
867 Define the User Mode DAC960_IOCTL_EXECUTE_COMMAND request structure.
870 typedef struct DAC960_UserCommand
872 unsigned char ControllerNumber;
873 DAC960_CommandMailbox_T CommandMailbox;
874 int DataTransferLength;
875 void *DataTransferBuffer;
876 DAC960_DCDB_T *DCDB;
878 DAC960_UserCommand_T;
882 Define the Kernel Mode DAC960_IOCTL_EXECUTE_COMMAND request structure.
885 typedef struct DAC960_KernelCommand
887 unsigned char ControllerNumber;
888 DAC960_CommandMailbox_T CommandMailbox;
889 int DataTransferLength;
890 void *DataTransferBuffer;
891 DAC960_DCDB_T *DCDB;
892 DAC960_CommandStatus_T CommandStatus;
893 void (*CompletionFunction)(struct DAC960_KernelCommand *);
894 void *CompletionData;
896 DAC960_KernelCommand_T;
900 Import the Kernel Mode IOCTL interface.
903 extern int DAC960_KernelIOCTL(unsigned int Request, void *Argument);
907 Virtual_to_Bus maps from Kernel Virtual Addresses to PCI Bus Addresses.
910 static inline DAC960_BusAddress_T Virtual_to_Bus(void *VirtualAddress)
912 return (DAC960_BusAddress_T) virt_to_bus(VirtualAddress);
917 Bus_to_Virtual maps from PCI Bus Addresses to Kernel Virtual Addresses.
920 static inline void *Bus_to_Virtual(DAC960_BusAddress_T BusAddress)
922 return (void *) bus_to_virt(BusAddress);
927 DAC960_DriverVersion protects the private portion of this file.
930 #ifdef DAC960_DriverVersion
934 Define the maximum Driver Queue Depth and Controller Queue Depth supported
935 by any DAC960 model.
938 #define DAC960_MaxDriverQueueDepth 127
939 #define DAC960_MaxControllerQueueDepth 128
943 Define the maximum number of Scatter/Gather Segments supported by any
944 DAC960 model.
947 #define DAC960_MaxScatterGatherSegments 33
951 Define the number of Command Mailboxes and Status Mailboxes used by the
952 Memory Mailbox Interface.
955 #define DAC960_CommandMailboxCount 256
956 #define DAC960_StatusMailboxCount 1024
960 Define the DAC960 Controller Monitoring Timer Interval.
963 #define DAC960_MonitoringTimerInterval (10 * HZ)
967 Define the DAC960 Controller Secondary Monitoring Interval.
970 #define DAC960_SecondaryMonitoringInterval (60 * HZ)
974 Define the DAC960 Controller Progress Reporting Interval.
977 #define DAC960_ProgressReportingInterval (60 * HZ)
981 Define the maximum number of Partitions allowed for each Logical Drive.
984 #define DAC960_MaxPartitions 8
985 #define DAC960_MaxPartitionsBits 3
989 Define macros to extract the Controller Number, Logical Drive Number, and
990 Partition Number from a Kernel Device, and to construct a Major Number, Minor
991 Number, and Kernel Device from the Controller Number, Logical Drive Number,
992 and Partition Number. There is one Major Number assigned to each Controller.
993 The associated Minor Number is divided into the Logical Drive Number and
994 Partition Number.
997 #define DAC960_ControllerNumber(Device) \
998 (MAJOR(Device) - DAC960_MAJOR)
1000 #define DAC960_LogicalDriveNumber(Device) \
1001 (MINOR(Device) >> DAC960_MaxPartitionsBits)
1003 #define DAC960_PartitionNumber(Device) \
1004 (MINOR(Device) & (DAC960_MaxPartitions - 1))
1006 #define DAC960_MajorNumber(ControllerNumber) \
1007 (DAC960_MAJOR + (ControllerNumber))
1009 #define DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber) \
1010 (((LogicalDriveNumber) << DAC960_MaxPartitionsBits) | (PartitionNumber))
1012 #define DAC960_MinorCount (DAC960_MaxLogicalDrives \
1013 * DAC960_MaxPartitions)
1015 #define DAC960_KernelDevice(ControllerNumber, \
1016 LogicalDriveNumber, \
1017 PartitionNumber) \
1018 MKDEV(DAC960_MajorNumber(ControllerNumber), \
1019 DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber))
1023 Define the DAC960 Controller fixed Block Size and Block Size Bits.
1026 #define DAC960_BlockSize 512
1027 #define DAC960_BlockSizeBits 9
1031 Define the Controller Line Buffer, Status Buffer, Rebuild Progress,
1032 and User Message Sizes.
1035 #define DAC960_LineBufferSize 100
1036 #define DAC960_StatusBufferSize 16384
1037 #define DAC960_RebuildProgressSize 200
1038 #define DAC960_UserMessageSize 200
1042 Define the types of DAC960 Controllers that are supported.
1045 typedef enum
1047 DAC960_V5_Controller = 1, /* DAC1164P */
1048 DAC960_V4_Controller = 2, /* DAC960PTL/PJ/PG */
1049 DAC960_V3_Controller = 3 /* DAC960PU/PD/PL */
1051 DAC960_ControllerType_T;
1055 Define the Driver Message Levels.
1058 typedef enum DAC960_MessageLevel
1060 DAC960_AnnounceLevel = 0,
1061 DAC960_InfoLevel = 1,
1062 DAC960_NoticeLevel = 2,
1063 DAC960_WarningLevel = 3,
1064 DAC960_ErrorLevel = 4,
1065 DAC960_ProgressLevel = 5,
1066 DAC960_CriticalLevel = 6,
1067 DAC960_UserCriticalLevel = 7
1069 DAC960_MessageLevel_T;
1071 static char
1072 *DAC960_MessageLevelMap[] =
1073 { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING,
1074 KERN_ERR, KERN_CRIT, KERN_CRIT, KERN_CRIT };
1078 Define Driver Message macros.
1081 #define DAC960_Announce(Format, Arguments...) \
1082 DAC960_Message(DAC960_AnnounceLevel, Format, ##Arguments)
1084 #define DAC960_Info(Format, Arguments...) \
1085 DAC960_Message(DAC960_InfoLevel, Format, ##Arguments)
1087 #define DAC960_Notice(Format, Arguments...) \
1088 DAC960_Message(DAC960_NoticeLevel, Format, ##Arguments)
1090 #define DAC960_Warning(Format, Arguments...) \
1091 DAC960_Message(DAC960_WarningLevel, Format, ##Arguments)
1093 #define DAC960_Error(Format, Arguments...) \
1094 DAC960_Message(DAC960_ErrorLevel, Format, ##Arguments)
1096 #define DAC960_Progress(Format, Arguments...) \
1097 DAC960_Message(DAC960_ProgressLevel, Format, ##Arguments)
1099 #define DAC960_Critical(Format, Arguments...) \
1100 DAC960_Message(DAC960_CriticalLevel, Format, ##Arguments)
1102 #define DAC960_UserCritical(Format, Arguments...) \
1103 DAC960_Message(DAC960_UserCriticalLevel, Format, ##Arguments)
1107 Define types for some of the structures that interface with the rest
1108 of the Linux Kernel and I/O Subsystem.
1111 typedef struct buffer_head BufferHeader_T;
1112 typedef struct file File_T;
1113 typedef struct file_operations FileOperations_T;
1114 typedef struct gendisk GenericDiskInfo_T;
1115 typedef struct hd_geometry DiskGeometry_T;
1116 typedef struct hd_struct DiskPartition_T;
1117 typedef struct inode Inode_T;
1118 typedef struct inode_operations InodeOperations_T;
1119 typedef kdev_t KernelDevice_T;
1120 typedef struct notifier_block NotifierBlock_T;
1121 typedef struct pci_dev PCI_Device_T;
1122 typedef struct proc_dir_entry PROC_DirectoryEntry_T;
1123 typedef unsigned long ProcessorFlags_T;
1124 typedef struct pt_regs Registers_T;
1125 typedef struct request IO_Request_T;
1126 typedef struct semaphore Semaphore_T;
1127 typedef struct super_block SuperBlock_T;
1128 typedef struct timer_list Timer_T;
1129 typedef wait_queue_head_t WaitQueue_T;
1133 Define the DAC960 Controller Status Mailbox structure.
1136 typedef union DAC960_StatusMailbox
1138 unsigned int Word; /* Bytes 0-3 */
1139 struct {
1140 DAC960_CommandIdentifier_T CommandIdentifier; /* Byte 0 */
1141 unsigned char :7; /* Byte 1 Bits 0-6 */
1142 boolean Valid:1; /* Byte 1 Bit 7 */
1143 DAC960_CommandStatus_T CommandStatus; /* Bytes 2-3 */
1144 } Fields;
1146 DAC960_StatusMailbox_T;
1150 Define the DAC960 Driver Command Types.
1153 typedef enum
1155 DAC960_ReadCommand = 1,
1156 DAC960_WriteCommand = 2,
1157 DAC960_ReadRetryCommand = 3,
1158 DAC960_WriteRetryCommand = 4,
1159 DAC960_MonitoringCommand = 5,
1160 DAC960_ImmediateCommand = 6,
1161 DAC960_QueuedCommand = 7
1163 DAC960_CommandType_T;
1167 Define the DAC960 Driver Command structure.
1170 typedef struct DAC960_Command
1172 DAC960_CommandType_T CommandType;
1173 DAC960_CommandMailbox_T CommandMailbox;
1174 DAC960_CommandStatus_T CommandStatus;
1175 struct DAC960_Controller *Controller;
1176 struct DAC960_Command *Next;
1177 Semaphore_T *Semaphore;
1178 unsigned int LogicalDriveNumber;
1179 unsigned int BlockNumber;
1180 unsigned int BlockCount;
1181 unsigned int SegmentCount;
1182 BufferHeader_T *BufferHeader;
1183 DAC960_KernelCommand_T *KernelCommand;
1184 DAC960_ScatterGatherSegment_T
1185 ScatterGatherList[DAC960_MaxScatterGatherSegments];
1187 DAC960_Command_T;
1191 Define the DAC960 Driver Controller structure.
1194 typedef struct DAC960_Controller
1196 void *BaseAddress;
1197 void *MemoryMappedAddress;
1198 DAC960_ControllerType_T ControllerType;
1199 DAC960_IO_Address_T IO_Address;
1200 DAC960_PCI_Address_T PCI_Address;
1201 unsigned char ControllerNumber;
1202 unsigned char ControllerName[4];
1203 unsigned char ModelName[12];
1204 unsigned char FullModelName[18];
1205 unsigned char FirmwareVersion[14];
1206 unsigned char Bus;
1207 unsigned char Device;
1208 unsigned char Function;
1209 unsigned char IRQ_Channel;
1210 unsigned char Channels;
1211 unsigned char MemorySize;
1212 unsigned char LogicalDriveCount;
1213 unsigned char GeometryTranslationHeads;
1214 unsigned char GeometryTranslationSectors;
1215 unsigned short ControllerQueueDepth;
1216 unsigned short DriverQueueDepth;
1217 unsigned short MaxBlocksPerCommand;
1218 unsigned short MaxScatterGatherSegments;
1219 unsigned short StripeSize;
1220 unsigned short SegmentSize;
1221 unsigned short NewEventLogSequenceNumber;
1222 unsigned short OldEventLogSequenceNumber;
1223 unsigned short InitialStatusLength;
1224 unsigned short CurrentStatusLength;
1225 unsigned short UserStatusLength;
1226 unsigned short RebuildProgressLength;
1227 unsigned int ControllerUsageCount;
1228 unsigned int EnquiryIndex;
1229 unsigned int LogicalDriveInformationIndex;
1230 unsigned int ErrorTableIndex;
1231 unsigned int DeviceStateIndex;
1232 unsigned int DeviceStateChannel;
1233 unsigned int DeviceStateTargetID;
1234 unsigned long MonitoringTimerCount;
1235 unsigned long SecondaryMonitoringTime;
1236 unsigned long LastProgressReportTime;
1237 unsigned long LastCurrentStatusTime;
1238 boolean DualModeMemoryMailboxInterface;
1239 boolean SAFTE_EnclosureManagementEnabled;
1240 boolean ControllerInitialized;
1241 boolean MonitoringCommandDeferred;
1242 boolean NeedLogicalDriveInformation;
1243 boolean NeedErrorTableInformation;
1244 boolean NeedDeviceStateInformation;
1245 boolean NeedDeviceInquiryInformation;
1246 boolean NeedDeviceSerialNumberInformation;
1247 boolean NeedRebuildProgress;
1248 boolean NeedConsistencyCheckProgress;
1249 boolean EphemeralProgressMessage;
1250 Timer_T MonitoringTimer;
1251 GenericDiskInfo_T GenericDiskInfo;
1252 DAC960_Command_T *FreeCommands;
1253 DAC960_CommandMailbox_T *FirstCommandMailbox;
1254 DAC960_CommandMailbox_T *LastCommandMailbox;
1255 DAC960_CommandMailbox_T *NextCommandMailbox;
1256 DAC960_CommandMailbox_T *PreviousCommandMailbox1;
1257 DAC960_CommandMailbox_T *PreviousCommandMailbox2;
1258 DAC960_StatusMailbox_T *FirstStatusMailbox;
1259 DAC960_StatusMailbox_T *LastStatusMailbox;
1260 DAC960_StatusMailbox_T *NextStatusMailbox;
1261 PROC_DirectoryEntry_T ControllerProcEntry;
1262 PROC_DirectoryEntry_T InitialStatusProcEntry;
1263 PROC_DirectoryEntry_T CurrentStatusProcEntry;
1264 PROC_DirectoryEntry_T UserCommandProcEntry;
1265 WaitQueue_T CommandWaitQueue;
1266 DAC960_DCDB_T MonitoringDCDB;
1267 DAC960_Enquiry_T Enquiry[2];
1268 DAC960_ErrorTable_T ErrorTable[2];
1269 DAC960_EventLogEntry_T EventLogEntry;
1270 DAC960_RebuildProgress_T RebuildProgress;
1271 DAC960_CommandStatus_T LastRebuildStatus;
1272 DAC960_LogicalDriveInformation_T
1273 LogicalDriveInformation[2][DAC960_MaxLogicalDrives];
1274 DAC960_LogicalDriveState_T LogicalDriveInitialState[DAC960_MaxLogicalDrives];
1275 DAC960_DeviceState_T DeviceState[2][DAC960_MaxChannels][DAC960_MaxTargets];
1276 DAC960_Command_T Commands[DAC960_MaxDriverQueueDepth];
1277 DAC960_SCSI_Inquiry_T
1278 InquiryStandardData[DAC960_MaxChannels][DAC960_MaxTargets];
1279 DAC960_SCSI_Inquiry_UnitSerialNumber_T
1280 InquiryUnitSerialNumber[DAC960_MaxChannels][DAC960_MaxTargets];
1281 DiskPartition_T DiskPartitions[DAC960_MinorCount];
1282 int LogicalDriveUsageCount[DAC960_MaxLogicalDrives];
1283 int PartitionSizes[DAC960_MinorCount];
1284 int BlockSizes[DAC960_MinorCount];
1285 int MaxSectorsPerRequest[DAC960_MinorCount];
1286 int MaxSegmentsPerRequest[DAC960_MinorCount];
1287 int DeviceResetCount[DAC960_MaxChannels][DAC960_MaxTargets];
1288 boolean DirectCommandActive[DAC960_MaxChannels][DAC960_MaxTargets];
1289 char InitialStatusBuffer[DAC960_StatusBufferSize];
1290 char CurrentStatusBuffer[DAC960_StatusBufferSize];
1291 char UserStatusBuffer[DAC960_UserMessageSize];
1292 char RebuildProgressBuffer[DAC960_RebuildProgressSize];
1294 DAC960_Controller_T;
1298 DAC960_AcquireControllerLock acquires exclusive access to Controller.
1301 static inline
1302 void DAC960_AcquireControllerLock(DAC960_Controller_T *Controller,
1303 ProcessorFlags_T *ProcessorFlags)
1305 spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
1310 DAC960_ReleaseControllerLock releases exclusive access to Controller.
1313 static inline
1314 void DAC960_ReleaseControllerLock(DAC960_Controller_T *Controller,
1315 ProcessorFlags_T *ProcessorFlags)
1317 spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
1322 DAC960_AcquireControllerLockRF acquires exclusive access to Controller,
1323 but is only called from the request function with the io_request_lock held.
1326 static inline
1327 void DAC960_AcquireControllerLockRF(DAC960_Controller_T *Controller,
1328 ProcessorFlags_T *ProcessorFlags)
1334 DAC960_ReleaseControllerLockRF releases exclusive access to Controller,
1335 but is only called from the request function with the io_request_lock held.
1338 static inline
1339 void DAC960_ReleaseControllerLockRF(DAC960_Controller_T *Controller,
1340 ProcessorFlags_T *ProcessorFlags)
1346 DAC960_AcquireControllerLockIH acquires exclusive access to Controller,
1347 but is only called from the interrupt handler.
1350 static inline
1351 void DAC960_AcquireControllerLockIH(DAC960_Controller_T *Controller,
1352 ProcessorFlags_T *ProcessorFlags)
1354 spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
1359 DAC960_ReleaseControllerLockIH releases exclusive access to Controller,
1360 but is only called from the interrupt handler.
1363 static inline
1364 void DAC960_ReleaseControllerLockIH(DAC960_Controller_T *Controller,
1365 ProcessorFlags_T *ProcessorFlags)
1367 spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
1372 Define the DAC960 V5 Controller Interface Register Offsets.
1375 #define DAC960_V5_RegisterWindowSize 0x80
1377 typedef enum
1379 DAC960_V5_InboundDoorBellRegisterOffset = 0x60,
1380 DAC960_V5_OutboundDoorBellRegisterOffset = 0x61,
1381 DAC960_V5_InterruptMaskRegisterOffset = 0x34,
1382 DAC960_V5_CommandOpcodeRegisterOffset = 0x50,
1383 DAC960_V5_CommandIdentifierRegisterOffset = 0x51,
1384 DAC960_V5_MailboxRegister2Offset = 0x52,
1385 DAC960_V5_MailboxRegister3Offset = 0x53,
1386 DAC960_V5_MailboxRegister4Offset = 0x54,
1387 DAC960_V5_MailboxRegister5Offset = 0x55,
1388 DAC960_V5_MailboxRegister6Offset = 0x56,
1389 DAC960_V5_MailboxRegister7Offset = 0x57,
1390 DAC960_V5_MailboxRegister8Offset = 0x58,
1391 DAC960_V5_MailboxRegister9Offset = 0x59,
1392 DAC960_V5_MailboxRegister10Offset = 0x5A,
1393 DAC960_V5_MailboxRegister11Offset = 0x5B,
1394 DAC960_V5_MailboxRegister12Offset = 0x5C,
1395 DAC960_V5_StatusCommandIdentifierRegOffset = 0x5D,
1396 DAC960_V5_StatusRegisterOffset = 0x5E
1398 DAC960_V5_RegisterOffsets_T;
1402 Define the structure of the DAC960 V5 Inbound Door Bell Register.
1405 typedef union DAC960_V5_InboundDoorBellRegister
1407 unsigned char All;
1408 struct {
1409 boolean HardwareMailboxNewCommand:1; /* Bit 0 */
1410 boolean AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */
1411 boolean GenerateInterrupt:1; /* Bit 2 */
1412 boolean ControllerReset:1; /* Bit 3 */
1413 boolean MemoryMailboxNewCommand:1; /* Bit 4 */
1414 unsigned char :3; /* Bits 5-7 */
1415 } Write;
1416 struct {
1417 boolean HardwareMailboxEmpty:1; /* Bit 0 */
1418 unsigned char :7; /* Bits 1-7 */
1419 } Read;
1421 DAC960_V5_InboundDoorBellRegister_T;
1425 Define the structure of the DAC960 V5 Outbound Door Bell Register.
1428 typedef union DAC960_V5_OutboundDoorBellRegister
1430 unsigned char All;
1431 struct {
1432 boolean AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */
1433 boolean AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */
1434 unsigned char :6; /* Bits 2-7 */
1435 } Write;
1436 struct {
1437 boolean HardwareMailboxStatusAvailable:1; /* Bit 0 */
1438 boolean MemoryMailboxStatusAvailable:1; /* Bit 1 */
1439 unsigned char :6; /* Bits 2-7 */
1440 } Read;
1442 DAC960_V5_OutboundDoorBellRegister_T;
1446 Define the structure of the DAC960 V5 Interrupt Mask Register.
1449 typedef union DAC960_V5_InterruptMaskRegister
1451 unsigned char All;
1452 struct {
1453 unsigned char :2; /* Bits 0-1 */
1454 boolean DisableInterrupts:1; /* Bit 2 */
1455 unsigned char :5; /* Bits 3-7 */
1456 } Bits;
1458 DAC960_V5_InterruptMaskRegister_T;
1462 Define inline functions to provide an abstraction for reading and writing the
1463 DAC960 V5 Controller Interface Registers.
1466 static inline
1467 void DAC960_V5_HardwareMailboxNewCommand(void *ControllerBaseAddress)
1469 DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
1470 InboundDoorBellRegister.All = 0;
1471 InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
1472 writeb(InboundDoorBellRegister.All,
1473 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
1476 static inline
1477 void DAC960_V5_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
1479 DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
1480 InboundDoorBellRegister.All = 0;
1481 InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
1482 writeb(InboundDoorBellRegister.All,
1483 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
1486 static inline
1487 void DAC960_V5_GenerateInterrupt(void *ControllerBaseAddress)
1489 DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
1490 InboundDoorBellRegister.All = 0;
1491 InboundDoorBellRegister.Write.GenerateInterrupt = true;
1492 writeb(InboundDoorBellRegister.All,
1493 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
1496 static inline
1497 void DAC960_V5_ControllerReset(void *ControllerBaseAddress)
1499 DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
1500 InboundDoorBellRegister.All = 0;
1501 InboundDoorBellRegister.Write.ControllerReset = true;
1502 writeb(InboundDoorBellRegister.All,
1503 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
1506 static inline
1507 void DAC960_V5_MemoryMailboxNewCommand(void *ControllerBaseAddress)
1509 DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
1510 InboundDoorBellRegister.All = 0;
1511 InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
1512 writeb(InboundDoorBellRegister.All,
1513 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
1516 static inline
1517 boolean DAC960_V5_HardwareMailboxEmptyP(void *ControllerBaseAddress)
1519 DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
1520 InboundDoorBellRegister.All =
1521 readb(ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
1522 return InboundDoorBellRegister.Read.HardwareMailboxEmpty;
1525 static inline
1526 void DAC960_V5_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
1528 DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
1529 OutboundDoorBellRegister.All = 0;
1530 OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
1531 writeb(OutboundDoorBellRegister.All,
1532 ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
1535 static inline
1536 void DAC960_V5_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
1538 DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
1539 OutboundDoorBellRegister.All = 0;
1540 OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
1541 writeb(OutboundDoorBellRegister.All,
1542 ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
1545 static inline
1546 void DAC960_V5_AcknowledgeInterrupt(void *ControllerBaseAddress)
1548 DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
1549 OutboundDoorBellRegister.All = 0;
1550 OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
1551 OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
1552 writeb(OutboundDoorBellRegister.All,
1553 ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
1556 static inline
1557 boolean DAC960_V5_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
1559 DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
1560 OutboundDoorBellRegister.All =
1561 readb(ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
1562 return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
1565 static inline
1566 boolean DAC960_V5_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
1568 DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
1569 OutboundDoorBellRegister.All =
1570 readb(ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
1571 return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
1574 static inline
1575 void DAC960_V5_EnableInterrupts(void *ControllerBaseAddress)
1577 DAC960_V5_InterruptMaskRegister_T InterruptMaskRegister;
1578 InterruptMaskRegister.All = 0;
1579 InterruptMaskRegister.Bits.DisableInterrupts = false;
1580 writeb(InterruptMaskRegister.All,
1581 ControllerBaseAddress + DAC960_V5_InterruptMaskRegisterOffset);
1584 static inline
1585 void DAC960_V5_DisableInterrupts(void *ControllerBaseAddress)
1587 DAC960_V5_InterruptMaskRegister_T InterruptMaskRegister;
1588 InterruptMaskRegister.All = 0;
1589 InterruptMaskRegister.Bits.DisableInterrupts = true;
1590 writeb(InterruptMaskRegister.All,
1591 ControllerBaseAddress + DAC960_V5_InterruptMaskRegisterOffset);
1594 static inline
1595 boolean DAC960_V5_InterruptsEnabledP(void *ControllerBaseAddress)
1597 DAC960_V5_InterruptMaskRegister_T InterruptMaskRegister;
1598 InterruptMaskRegister.All =
1599 readb(ControllerBaseAddress + DAC960_V5_InterruptMaskRegisterOffset);
1600 return !InterruptMaskRegister.Bits.DisableInterrupts;
1603 static inline
1604 void DAC960_V5_WriteCommandMailbox(DAC960_CommandMailbox_T *NextCommandMailbox,
1605 DAC960_CommandMailbox_T *CommandMailbox)
1607 NextCommandMailbox->Words[1] = CommandMailbox->Words[1];
1608 NextCommandMailbox->Words[2] = CommandMailbox->Words[2];
1609 NextCommandMailbox->Words[3] = CommandMailbox->Words[3];
1610 NextCommandMailbox->Words[0] = CommandMailbox->Words[0];
1613 static inline
1614 void DAC960_V5_WriteHardwareMailbox(void *ControllerBaseAddress,
1615 DAC960_CommandMailbox_T *CommandMailbox)
1617 writel(CommandMailbox->Words[0],
1618 ControllerBaseAddress + DAC960_V5_CommandOpcodeRegisterOffset);
1619 writel(CommandMailbox->Words[1],
1620 ControllerBaseAddress + DAC960_V5_MailboxRegister4Offset);
1621 writel(CommandMailbox->Words[2],
1622 ControllerBaseAddress + DAC960_V5_MailboxRegister8Offset);
1623 writeb(CommandMailbox->Bytes[12],
1624 ControllerBaseAddress + DAC960_V5_MailboxRegister12Offset);
1627 static inline DAC960_CommandIdentifier_T
1628 DAC960_V5_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
1630 return readb(ControllerBaseAddress
1631 + DAC960_V5_StatusCommandIdentifierRegOffset);
1634 static inline DAC960_CommandStatus_T
1635 DAC960_V5_ReadStatusRegister(void *ControllerBaseAddress)
1637 return readw(ControllerBaseAddress + DAC960_V5_StatusRegisterOffset);
1640 static inline
1641 void DAC960_V5_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
1643 void *ControllerBaseAddress = Controller->BaseAddress;
1644 writel(0x743C485E,
1645 ControllerBaseAddress + DAC960_V5_CommandOpcodeRegisterOffset);
1646 writel((unsigned long) Controller->FirstCommandMailbox,
1647 ControllerBaseAddress + DAC960_V5_MailboxRegister4Offset);
1648 writew(Controller->NextCommandMailbox - Controller->FirstCommandMailbox,
1649 ControllerBaseAddress + DAC960_V5_MailboxRegister8Offset);
1650 writew(Controller->NextStatusMailbox - Controller->FirstStatusMailbox,
1651 ControllerBaseAddress + DAC960_V5_MailboxRegister10Offset);
1654 static inline
1655 void DAC960_V5_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
1656 void **MemoryMailboxAddress,
1657 short *NextCommandMailboxIndex,
1658 short *NextStatusMailboxIndex)
1660 void *ControllerBaseAddress = Controller->BaseAddress;
1661 if (readl(ControllerBaseAddress
1662 + DAC960_V5_CommandOpcodeRegisterOffset) != 0x743C485E)
1663 return;
1664 *MemoryMailboxAddress =
1665 (void *) readl(ControllerBaseAddress + DAC960_V5_MailboxRegister4Offset);
1666 *NextCommandMailboxIndex =
1667 readw(ControllerBaseAddress + DAC960_V5_MailboxRegister8Offset);
1668 *NextStatusMailboxIndex =
1669 readw(ControllerBaseAddress + DAC960_V5_MailboxRegister10Offset);
1674 Define the DAC960 V4 Controller Interface Register Offsets.
1677 #define DAC960_V4_RegisterWindowSize 0x2000
1679 typedef enum
1681 DAC960_V4_InboundDoorBellRegisterOffset = 0x0020,
1682 DAC960_V4_OutboundDoorBellRegisterOffset = 0x002C,
1683 DAC960_V4_InterruptMaskRegisterOffset = 0x0034,
1684 DAC960_V4_CommandOpcodeRegisterOffset = 0x1000,
1685 DAC960_V4_CommandIdentifierRegisterOffset = 0x1001,
1686 DAC960_V4_MailboxRegister2Offset = 0x1002,
1687 DAC960_V4_MailboxRegister3Offset = 0x1003,
1688 DAC960_V4_MailboxRegister4Offset = 0x1004,
1689 DAC960_V4_MailboxRegister5Offset = 0x1005,
1690 DAC960_V4_MailboxRegister6Offset = 0x1006,
1691 DAC960_V4_MailboxRegister7Offset = 0x1007,
1692 DAC960_V4_MailboxRegister8Offset = 0x1008,
1693 DAC960_V4_MailboxRegister9Offset = 0x1009,
1694 DAC960_V4_MailboxRegister10Offset = 0x100A,
1695 DAC960_V4_MailboxRegister11Offset = 0x100B,
1696 DAC960_V4_MailboxRegister12Offset = 0x100C,
1697 DAC960_V4_StatusCommandIdentifierRegOffset = 0x1018,
1698 DAC960_V4_StatusRegisterOffset = 0x101A
1700 DAC960_V4_RegisterOffsets_T;
1704 Define the structure of the DAC960 V4 Inbound Door Bell Register.
1707 typedef union DAC960_V4_InboundDoorBellRegister
1709 unsigned int All;
1710 struct {
1711 boolean HardwareMailboxNewCommand:1; /* Bit 0 */
1712 boolean AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */
1713 boolean GenerateInterrupt:1; /* Bit 2 */
1714 boolean ControllerReset:1; /* Bit 3 */
1715 boolean MemoryMailboxNewCommand:1; /* Bit 4 */
1716 unsigned int :27; /* Bits 5-31 */
1717 } Write;
1718 struct {
1719 boolean HardwareMailboxFull:1; /* Bit 0 */
1720 unsigned int :31; /* Bits 1-31 */
1721 } Read;
1723 DAC960_V4_InboundDoorBellRegister_T;
1727 Define the structure of the DAC960 V4 Outbound Door Bell Register.
1730 typedef union DAC960_V4_OutboundDoorBellRegister
1732 unsigned int All;
1733 struct {
1734 boolean AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */
1735 boolean AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */
1736 unsigned int :30; /* Bits 2-31 */
1737 } Write;
1738 struct {
1739 boolean HardwareMailboxStatusAvailable:1; /* Bit 0 */
1740 boolean MemoryMailboxStatusAvailable:1; /* Bit 1 */
1741 unsigned int :30; /* Bits 2-31 */
1742 } Read;
1744 DAC960_V4_OutboundDoorBellRegister_T;
1748 Define the structure of the DAC960 V4 Interrupt Mask Register.
1751 typedef union DAC960_V4_InterruptMaskRegister
1753 unsigned int All;
1754 struct {
1755 unsigned int MessageUnitInterruptMask1:2; /* Bits 0-1 */
1756 boolean DisableInterrupts:1; /* Bit 2 */
1757 unsigned int MessageUnitInterruptMask2:5; /* Bits 3-7 */
1758 unsigned int Reserved0:24; /* Bits 8-31 */
1759 } Bits;
1761 DAC960_V4_InterruptMaskRegister_T;
1765 Define inline functions to provide an abstraction for reading and writing the
1766 DAC960 V4 Controller Interface Registers.
1769 static inline
1770 void DAC960_V4_HardwareMailboxNewCommand(void *ControllerBaseAddress)
1772 DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
1773 InboundDoorBellRegister.All = 0;
1774 InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
1775 writel(InboundDoorBellRegister.All,
1776 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
1779 static inline
1780 void DAC960_V4_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
1782 DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
1783 InboundDoorBellRegister.All = 0;
1784 InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
1785 writel(InboundDoorBellRegister.All,
1786 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
1789 static inline
1790 void DAC960_V4_GenerateInterrupt(void *ControllerBaseAddress)
1792 DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
1793 InboundDoorBellRegister.All = 0;
1794 InboundDoorBellRegister.Write.GenerateInterrupt = true;
1795 writel(InboundDoorBellRegister.All,
1796 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
1799 static inline
1800 void DAC960_V4_ControllerReset(void *ControllerBaseAddress)
1802 DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
1803 InboundDoorBellRegister.All = 0;
1804 InboundDoorBellRegister.Write.ControllerReset = true;
1805 writel(InboundDoorBellRegister.All,
1806 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
1809 static inline
1810 void DAC960_V4_MemoryMailboxNewCommand(void *ControllerBaseAddress)
1812 DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
1813 InboundDoorBellRegister.All = 0;
1814 InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
1815 writel(InboundDoorBellRegister.All,
1816 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
1819 static inline
1820 boolean DAC960_V4_HardwareMailboxFullP(void *ControllerBaseAddress)
1822 DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
1823 InboundDoorBellRegister.All =
1824 readl(ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
1825 return InboundDoorBellRegister.Read.HardwareMailboxFull;
1828 static inline
1829 void DAC960_V4_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
1831 DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
1832 OutboundDoorBellRegister.All = 0;
1833 OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
1834 writel(OutboundDoorBellRegister.All,
1835 ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
1838 static inline
1839 void DAC960_V4_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
1841 DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
1842 OutboundDoorBellRegister.All = 0;
1843 OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
1844 writel(OutboundDoorBellRegister.All,
1845 ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
1848 static inline
1849 void DAC960_V4_AcknowledgeInterrupt(void *ControllerBaseAddress)
1851 DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
1852 OutboundDoorBellRegister.All = 0;
1853 OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
1854 OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
1855 writel(OutboundDoorBellRegister.All,
1856 ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
1859 static inline
1860 boolean DAC960_V4_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
1862 DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
1863 OutboundDoorBellRegister.All =
1864 readl(ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
1865 return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
1868 static inline
1869 boolean DAC960_V4_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
1871 DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
1872 OutboundDoorBellRegister.All =
1873 readl(ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
1874 return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
1877 static inline
1878 void DAC960_V4_EnableInterrupts(void *ControllerBaseAddress)
1880 DAC960_V4_InterruptMaskRegister_T InterruptMaskRegister;
1881 InterruptMaskRegister.All = 0;
1882 InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3;
1883 InterruptMaskRegister.Bits.DisableInterrupts = false;
1884 InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F;
1885 writel(InterruptMaskRegister.All,
1886 ControllerBaseAddress + DAC960_V4_InterruptMaskRegisterOffset);
1889 static inline
1890 void DAC960_V4_DisableInterrupts(void *ControllerBaseAddress)
1892 DAC960_V4_InterruptMaskRegister_T InterruptMaskRegister;
1893 InterruptMaskRegister.All = 0;
1894 InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3;
1895 InterruptMaskRegister.Bits.DisableInterrupts = true;
1896 InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F;
1897 writel(InterruptMaskRegister.All,
1898 ControllerBaseAddress + DAC960_V4_InterruptMaskRegisterOffset);
1901 static inline
1902 boolean DAC960_V4_InterruptsEnabledP(void *ControllerBaseAddress)
1904 DAC960_V4_InterruptMaskRegister_T InterruptMaskRegister;
1905 InterruptMaskRegister.All =
1906 readl(ControllerBaseAddress + DAC960_V4_InterruptMaskRegisterOffset);
1907 return !InterruptMaskRegister.Bits.DisableInterrupts;
1910 static inline
1911 void DAC960_V4_WriteCommandMailbox(DAC960_CommandMailbox_T *NextCommandMailbox,
1912 DAC960_CommandMailbox_T *CommandMailbox)
1914 NextCommandMailbox->Words[1] = CommandMailbox->Words[1];
1915 NextCommandMailbox->Words[2] = CommandMailbox->Words[2];
1916 NextCommandMailbox->Words[3] = CommandMailbox->Words[3];
1917 NextCommandMailbox->Words[0] = CommandMailbox->Words[0];
1920 static inline
1921 void DAC960_V4_WriteHardwareMailbox(void *ControllerBaseAddress,
1922 DAC960_CommandMailbox_T *CommandMailbox)
1924 writel(CommandMailbox->Words[0],
1925 ControllerBaseAddress + DAC960_V4_CommandOpcodeRegisterOffset);
1926 writel(CommandMailbox->Words[1],
1927 ControllerBaseAddress + DAC960_V4_MailboxRegister4Offset);
1928 writel(CommandMailbox->Words[2],
1929 ControllerBaseAddress + DAC960_V4_MailboxRegister8Offset);
1930 writeb(CommandMailbox->Bytes[12],
1931 ControllerBaseAddress + DAC960_V4_MailboxRegister12Offset);
1934 static inline DAC960_CommandIdentifier_T
1935 DAC960_V4_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
1937 return readb(ControllerBaseAddress
1938 + DAC960_V4_StatusCommandIdentifierRegOffset);
1941 static inline DAC960_CommandStatus_T
1942 DAC960_V4_ReadStatusRegister(void *ControllerBaseAddress)
1944 return readw(ControllerBaseAddress + DAC960_V4_StatusRegisterOffset);
1947 static inline
1948 void DAC960_V4_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
1950 void *ControllerBaseAddress = Controller->BaseAddress;
1951 writel(0xAABBFFFF,
1952 ControllerBaseAddress + DAC960_V4_CommandOpcodeRegisterOffset);
1953 writel((unsigned long) Controller->FirstCommandMailbox,
1954 ControllerBaseAddress + DAC960_V4_MailboxRegister4Offset);
1955 writew(Controller->NextCommandMailbox - Controller->FirstCommandMailbox,
1956 ControllerBaseAddress + DAC960_V4_MailboxRegister8Offset);
1957 writew(Controller->NextStatusMailbox - Controller->FirstStatusMailbox,
1958 ControllerBaseAddress + DAC960_V4_MailboxRegister10Offset);
1961 static inline
1962 void DAC960_V4_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
1963 void **MemoryMailboxAddress,
1964 short *NextCommandMailboxIndex,
1965 short *NextStatusMailboxIndex)
1967 void *ControllerBaseAddress = Controller->BaseAddress;
1968 if (readl(ControllerBaseAddress
1969 + DAC960_V4_CommandOpcodeRegisterOffset) != 0xAABBFFFF)
1970 return;
1971 *MemoryMailboxAddress =
1972 (void *) readl(ControllerBaseAddress + DAC960_V4_MailboxRegister4Offset);
1973 *NextCommandMailboxIndex =
1974 readw(ControllerBaseAddress + DAC960_V4_MailboxRegister8Offset);
1975 *NextStatusMailboxIndex =
1976 readw(ControllerBaseAddress + DAC960_V4_MailboxRegister10Offset);
1981 Define the DAC960 V3 Controller Interface Register Offsets.
1984 #define DAC960_V3_RegisterWindowSize 0x80
1986 typedef enum
1988 DAC960_V3_CommandOpcodeRegisterOffset = 0x00,
1989 DAC960_V3_CommandIdentifierRegisterOffset = 0x01,
1990 DAC960_V3_MailboxRegister2Offset = 0x02,
1991 DAC960_V3_MailboxRegister3Offset = 0x03,
1992 DAC960_V3_MailboxRegister4Offset = 0x04,
1993 DAC960_V3_MailboxRegister5Offset = 0x05,
1994 DAC960_V3_MailboxRegister6Offset = 0x06,
1995 DAC960_V3_MailboxRegister7Offset = 0x07,
1996 DAC960_V3_MailboxRegister8Offset = 0x08,
1997 DAC960_V3_MailboxRegister9Offset = 0x09,
1998 DAC960_V3_MailboxRegister10Offset = 0x0A,
1999 DAC960_V3_MailboxRegister11Offset = 0x0B,
2000 DAC960_V3_MailboxRegister12Offset = 0x0C,
2001 DAC960_V3_StatusCommandIdentifierRegOffset = 0x0D,
2002 DAC960_V3_StatusRegisterOffset = 0x0E,
2003 DAC960_V3_InboundDoorBellRegisterOffset = 0x40,
2004 DAC960_V3_OutboundDoorBellRegisterOffset = 0x41,
2005 DAC960_V3_InterruptEnableRegisterOffset = 0x43
2007 DAC960_V3_RegisterOffsets_T;
2011 Define the structure of the DAC960 V3 Inbound Door Bell Register.
2014 typedef union DAC960_V3_InboundDoorBellRegister
2016 unsigned char All;
2017 struct {
2018 boolean NewCommand:1; /* Bit 0 */
2019 boolean AcknowledgeStatus:1; /* Bit 1 */
2020 boolean GenerateInterrupt:1; /* Bit 2 */
2021 boolean ControllerReset:1; /* Bit 3 */
2022 unsigned char :4; /* Bits 4-7 */
2023 } Write;
2024 struct {
2025 boolean MailboxFull:1; /* Bit 0 */
2026 unsigned char :7; /* Bits 1-7 */
2027 } Read;
2029 DAC960_V3_InboundDoorBellRegister_T;
2033 Define the structure of the DAC960 V3 Outbound Door Bell Register.
2036 typedef union DAC960_V3_OutboundDoorBellRegister
2038 unsigned char All;
2039 struct {
2040 boolean AcknowledgeInterrupt:1; /* Bit 0 */
2041 unsigned char :7; /* Bits 1-7 */
2042 } Write;
2043 struct {
2044 boolean StatusAvailable:1; /* Bit 0 */
2045 unsigned char :7; /* Bits 1-7 */
2046 } Read;
2048 DAC960_V3_OutboundDoorBellRegister_T;
2052 Define the structure of the DAC960 V3 Interrupt Enable Register.
2055 typedef union DAC960_V3_InterruptEnableRegister
2057 unsigned char All;
2058 struct {
2059 boolean EnableInterrupts:1; /* Bit 0 */
2060 unsigned char :7; /* Bits 1-7 */
2061 } Bits;
2063 DAC960_V3_InterruptEnableRegister_T;
2067 Define inline functions to provide an abstraction for reading and writing the
2068 DAC960 V3 Controller Interface Registers.
2071 static inline
2072 void DAC960_V3_NewCommand(void *ControllerBaseAddress)
2074 DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
2075 InboundDoorBellRegister.All = 0;
2076 InboundDoorBellRegister.Write.NewCommand = true;
2077 writeb(InboundDoorBellRegister.All,
2078 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
2081 static inline
2082 void DAC960_V3_AcknowledgeStatus(void *ControllerBaseAddress)
2084 DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
2085 InboundDoorBellRegister.All = 0;
2086 InboundDoorBellRegister.Write.AcknowledgeStatus = true;
2087 writeb(InboundDoorBellRegister.All,
2088 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
2091 static inline
2092 void DAC960_V3_GenerateInterrupt(void *ControllerBaseAddress)
2094 DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
2095 InboundDoorBellRegister.All = 0;
2096 InboundDoorBellRegister.Write.GenerateInterrupt = true;
2097 writeb(InboundDoorBellRegister.All,
2098 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
2101 static inline
2102 void DAC960_V3_ControllerReset(void *ControllerBaseAddress)
2104 DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
2105 InboundDoorBellRegister.All = 0;
2106 InboundDoorBellRegister.Write.ControllerReset = true;
2107 writeb(InboundDoorBellRegister.All,
2108 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
2111 static inline
2112 boolean DAC960_V3_MailboxFullP(void *ControllerBaseAddress)
2114 DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
2115 InboundDoorBellRegister.All =
2116 readb(ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
2117 return InboundDoorBellRegister.Read.MailboxFull;
2120 static inline
2121 void DAC960_V3_AcknowledgeInterrupt(void *ControllerBaseAddress)
2123 DAC960_V3_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2124 OutboundDoorBellRegister.All = 0;
2125 OutboundDoorBellRegister.Write.AcknowledgeInterrupt = true;
2126 writeb(OutboundDoorBellRegister.All,
2127 ControllerBaseAddress + DAC960_V3_OutboundDoorBellRegisterOffset);
2130 static inline
2131 boolean DAC960_V3_StatusAvailableP(void *ControllerBaseAddress)
2133 DAC960_V3_OutboundDoorBellRegister_T OutboundDoorBellRegister;
2134 OutboundDoorBellRegister.All =
2135 readb(ControllerBaseAddress + DAC960_V3_OutboundDoorBellRegisterOffset);
2136 return OutboundDoorBellRegister.Read.StatusAvailable;
2139 static inline
2140 void DAC960_V3_EnableInterrupts(void *ControllerBaseAddress)
2142 DAC960_V3_InterruptEnableRegister_T InterruptEnableRegister;
2143 InterruptEnableRegister.All = 0;
2144 InterruptEnableRegister.Bits.EnableInterrupts = true;
2145 writeb(InterruptEnableRegister.All,
2146 ControllerBaseAddress + DAC960_V3_InterruptEnableRegisterOffset);
2149 static inline
2150 void DAC960_V3_DisableInterrupts(void *ControllerBaseAddress)
2152 DAC960_V3_InterruptEnableRegister_T InterruptEnableRegister;
2153 InterruptEnableRegister.All = 0;
2154 InterruptEnableRegister.Bits.EnableInterrupts = false;
2155 writeb(InterruptEnableRegister.All,
2156 ControllerBaseAddress + DAC960_V3_InterruptEnableRegisterOffset);
2159 static inline
2160 boolean DAC960_V3_InterruptsEnabledP(void *ControllerBaseAddress)
2162 DAC960_V3_InterruptEnableRegister_T InterruptEnableRegister;
2163 InterruptEnableRegister.All =
2164 readb(ControllerBaseAddress + DAC960_V3_InterruptEnableRegisterOffset);
2165 return InterruptEnableRegister.Bits.EnableInterrupts;
2168 static inline
2169 void DAC960_V3_WriteCommandMailbox(void *ControllerBaseAddress,
2170 DAC960_CommandMailbox_T *CommandMailbox)
2172 writel(CommandMailbox->Words[0],
2173 ControllerBaseAddress + DAC960_V3_CommandOpcodeRegisterOffset);
2174 writel(CommandMailbox->Words[1],
2175 ControllerBaseAddress + DAC960_V3_MailboxRegister4Offset);
2176 writel(CommandMailbox->Words[2],
2177 ControllerBaseAddress + DAC960_V3_MailboxRegister8Offset);
2178 writeb(CommandMailbox->Bytes[12],
2179 ControllerBaseAddress + DAC960_V3_MailboxRegister12Offset);
2182 static inline DAC960_CommandIdentifier_T
2183 DAC960_V3_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
2185 return readb(ControllerBaseAddress
2186 + DAC960_V3_StatusCommandIdentifierRegOffset);
2189 static inline DAC960_CommandStatus_T
2190 DAC960_V3_ReadStatusRegister(void *ControllerBaseAddress)
2192 return readw(ControllerBaseAddress + DAC960_V3_StatusRegisterOffset);
2197 Define compatibility macros between Linux 2.0 and Linux 2.1.
2200 #if LINUX_VERSION_CODE < 0x20100
2202 #define MODULE_PARM(Variable, Type)
2203 #define ioremap_nocache(Offset, Size) vremap(Offset, Size)
2204 #define iounmap(Address) vfree(Address)
2206 #endif
2210 Define prototypes for the forward referenced DAC960 Driver Internal Functions.
2213 static void DAC960_FinalizeController(DAC960_Controller_T *);
2214 static int DAC960_Finalize(NotifierBlock_T *, unsigned long, void *);
2215 static void DAC960_RequestFunction0(void);
2216 static void DAC960_RequestFunction1(void);
2217 static void DAC960_RequestFunction2(void);
2218 static void DAC960_RequestFunction3(void);
2219 static void DAC960_RequestFunction4(void);
2220 static void DAC960_RequestFunction5(void);
2221 static void DAC960_RequestFunction6(void);
2222 static void DAC960_RequestFunction7(void);
2223 static void DAC960_InterruptHandler(int, void *, Registers_T *);
2224 static void DAC960_QueueMonitoringCommand(DAC960_Command_T *);
2225 static void DAC960_MonitoringTimerFunction(unsigned long);
2226 static int DAC960_Open(Inode_T *, File_T *);
2227 static int DAC960_Release(Inode_T *, File_T *);
2228 static int DAC960_IOCTL(Inode_T *, File_T *, unsigned int, unsigned long);
2229 static int DAC960_UserIOCTL(Inode_T *, File_T *, unsigned int, unsigned long);
2230 static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T *);
2231 static void DAC960_Message(DAC960_MessageLevel_T, char *,
2232 DAC960_Controller_T *, ...);
2233 static void DAC960_CreateProcEntries(void);
2234 static void DAC960_DestroyProcEntries(void);
2238 Export the Kernel Mode IOCTL interface.
2241 EXPORT_SYMBOL(DAC960_KernelIOCTL);
2244 #endif /* DAC960_DriverVersion */