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
16 The author respectfully requests that any modifications to this software be
17 sent directly to him for evaluation and testing.
22 #define DAC960_DriverVersion "2.3.4"
23 #define DAC960_DriverDate "23 September 1999"
26 #include <linux/version.h>
27 #include <linux/module.h>
28 #include <linux/types.h>
29 #include <linux/blk.h>
30 #include <linux/blkdev.h>
31 #include <linux/delay.h>
32 #include <linux/hdreg.h>
33 #include <linux/interrupt.h>
34 #include <linux/ioport.h>
35 #include <linux/locks.h>
37 #include <linux/malloc.h>
38 #include <linux/proc_fs.h>
39 #include <linux/reboot.h>
40 #include <linux/timer.h>
41 #include <linux/pci.h>
43 #include <asm/segment.h>
44 #include <linux/spinlock.h>
45 #include <asm/uaccess.h>
50 DAC960_ControllerCount is the number of DAC960 Controllers detected.
54 DAC960_ControllerCount
= 0;
58 DAC960_ActiveControllerCount is the number of Active DAC960 Controllers
63 DAC960_ActiveControllerCount
= 0;
67 DAC960_Controllers is an array of pointers to the DAC960 Controller
71 static DAC960_Controller_T
72 *DAC960_Controllers
[DAC960_MaxControllers
] = { NULL
};
76 DAC960_FileOperations is the File Operations structure for DAC960 Logical
78 Leonard, no offence, but _where_ did this C dialect come from?
81 static struct block_device_operations DAC960_FileOperations
= {
83 release
: DAC960_Release
,
88 DAC960_ProcDirectoryEntry is the DAC960 /proc/driver/rd directory entry.
91 static PROC_DirectoryEntry_T
*
92 DAC960_ProcDirectoryEntry
= NULL
;
96 DAC960_NotifierBlock is the Notifier Block structure for DAC960 Driver.
99 static NotifierBlock_T
100 DAC960_NotifierBlock
= { DAC960_Finalize
, NULL
, 0 };
104 DAC960_AnnounceDriver announces the Driver Version and Date, Author's Name,
105 Copyright Notice, and Electronic Mail Address.
108 static void DAC960_AnnounceDriver(DAC960_Controller_T
*Controller
)
110 DAC960_Announce("***** DAC960 RAID Driver Version "
111 DAC960_DriverVersion
" of "
112 DAC960_DriverDate
" *****\n", Controller
);
113 DAC960_Announce("Copyright 1998-1999 by Leonard N. Zubkoff "
114 "<lnz@dandelion.com>\n", Controller
);
119 DAC960_Failure prints a standardized error message, and then returns false.
122 static boolean
DAC960_Failure(DAC960_Controller_T
*Controller
,
125 DAC960_Error("While configuring DAC960 PCI RAID Controller at\n",
127 if (Controller
->IO_Address
== 0)
128 DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
129 "PCI Address 0x%X\n", Controller
,
130 Controller
->Bus
, Controller
->Device
,
131 Controller
->Function
, Controller
->PCI_Address
);
132 else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
133 "0x%X PCI Address 0x%X\n", Controller
,
134 Controller
->Bus
, Controller
->Device
,
135 Controller
->Function
, Controller
->IO_Address
,
136 Controller
->PCI_Address
);
137 DAC960_Error("%s FAILED - DETACHING\n", Controller
, ErrorMessage
);
143 DAC960_ClearCommand clears critical fields of Command.
146 static inline void DAC960_ClearCommand(DAC960_Command_T
*Command
)
148 DAC960_CommandMailbox_T
*CommandMailbox
= &Command
->CommandMailbox
;
149 CommandMailbox
->Words
[0] = 0;
150 CommandMailbox
->Words
[1] = 0;
151 CommandMailbox
->Words
[2] = 0;
152 CommandMailbox
->Words
[3] = 0;
153 Command
->CommandStatus
= 0;
158 DAC960_AllocateCommand allocates a Command structure from Controller's
162 static inline DAC960_Command_T
*DAC960_AllocateCommand(DAC960_Controller_T
165 DAC960_Command_T
*Command
= Controller
->FreeCommands
;
166 if (Command
== NULL
) return NULL
;
167 Controller
->FreeCommands
= Command
->Next
;
168 Command
->Next
= NULL
;
174 DAC960_DeallocateCommand deallocates Command, returning it to Controller's
178 static inline void DAC960_DeallocateCommand(DAC960_Command_T
*Command
)
180 DAC960_Controller_T
*Controller
= Command
->Controller
;
181 Command
->Next
= Controller
->FreeCommands
;
182 Controller
->FreeCommands
= Command
;
187 DAC960_QueueCommand queues Command.
190 static void DAC960_QueueCommand(DAC960_Command_T
*Command
)
192 DAC960_Controller_T
*Controller
= Command
->Controller
;
193 void *ControllerBaseAddress
= Controller
->BaseAddress
;
194 DAC960_CommandMailbox_T
*CommandMailbox
= &Command
->CommandMailbox
;
195 DAC960_CommandMailbox_T
*NextCommandMailbox
;
196 CommandMailbox
->Common
.CommandIdentifier
= Command
- Controller
->Commands
;
197 switch (Controller
->ControllerType
)
199 case DAC960_V5_Controller
:
200 NextCommandMailbox
= Controller
->NextCommandMailbox
;
201 DAC960_V5_WriteCommandMailbox(NextCommandMailbox
, CommandMailbox
);
202 if (Controller
->PreviousCommandMailbox1
->Words
[0] == 0 ||
203 Controller
->PreviousCommandMailbox2
->Words
[0] == 0)
205 if (Controller
->DualModeMemoryMailboxInterface
)
206 DAC960_V5_MemoryMailboxNewCommand(ControllerBaseAddress
);
207 else DAC960_V5_HardwareMailboxNewCommand(ControllerBaseAddress
);
209 Controller
->PreviousCommandMailbox2
= Controller
->PreviousCommandMailbox1
;
210 Controller
->PreviousCommandMailbox1
= NextCommandMailbox
;
211 if (++NextCommandMailbox
> Controller
->LastCommandMailbox
)
212 NextCommandMailbox
= Controller
->FirstCommandMailbox
;
213 Controller
->NextCommandMailbox
= NextCommandMailbox
;
215 case DAC960_V4_Controller
:
216 NextCommandMailbox
= Controller
->NextCommandMailbox
;
217 DAC960_V4_WriteCommandMailbox(NextCommandMailbox
, CommandMailbox
);
218 if (Controller
->PreviousCommandMailbox1
->Words
[0] == 0 ||
219 Controller
->PreviousCommandMailbox2
->Words
[0] == 0)
221 if (Controller
->DualModeMemoryMailboxInterface
)
222 DAC960_V4_MemoryMailboxNewCommand(ControllerBaseAddress
);
223 else DAC960_V4_HardwareMailboxNewCommand(ControllerBaseAddress
);
225 Controller
->PreviousCommandMailbox2
= Controller
->PreviousCommandMailbox1
;
226 Controller
->PreviousCommandMailbox1
= NextCommandMailbox
;
227 if (++NextCommandMailbox
> Controller
->LastCommandMailbox
)
228 NextCommandMailbox
= Controller
->FirstCommandMailbox
;
229 Controller
->NextCommandMailbox
= NextCommandMailbox
;
231 case DAC960_V3_Controller
:
232 while (DAC960_V3_MailboxFullP(ControllerBaseAddress
))
234 DAC960_V3_WriteCommandMailbox(ControllerBaseAddress
, CommandMailbox
);
235 DAC960_V3_NewCommand(ControllerBaseAddress
);
242 DAC960_ExecuteCommand executes Command and waits for completion. It
243 returns true on success and false on failure.
246 static boolean
DAC960_ExecuteCommand(DAC960_Command_T
*Command
)
248 DAC960_Controller_T
*Controller
= Command
->Controller
;
249 DECLARE_MUTEX_LOCKED(Semaphore
);
250 unsigned long ProcessorFlags
;
251 Command
->Semaphore
= &Semaphore
;
252 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
253 DAC960_QueueCommand(Command
);
254 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
257 return Command
->CommandStatus
== DAC960_NormalCompletion
;
262 DAC960_ExecuteType3 executes a DAC960 Type 3 Command and waits for
263 completion. It returns true on success and false on failure.
266 static boolean
DAC960_ExecuteType3(DAC960_Controller_T
*Controller
,
267 DAC960_CommandOpcode_T CommandOpcode
,
270 DAC960_Command_T
*Command
= DAC960_AllocateCommand(Controller
);
271 DAC960_CommandMailbox_T
*CommandMailbox
= &Command
->CommandMailbox
;
273 DAC960_ClearCommand(Command
);
274 Command
->CommandType
= DAC960_ImmediateCommand
;
275 CommandMailbox
->Type3
.CommandOpcode
= CommandOpcode
;
276 CommandMailbox
->Type3
.BusAddress
= Virtual_to_Bus(DataPointer
);
277 Result
= DAC960_ExecuteCommand(Command
);
278 DAC960_DeallocateCommand(Command
);
284 DAC960_ExecuteType3D executes a DAC960 Type 3D Command and waits for
285 completion. It returns true on success and false on failure.
288 static boolean
DAC960_ExecuteType3D(DAC960_Controller_T
*Controller
,
289 DAC960_CommandOpcode_T CommandOpcode
,
290 unsigned char Channel
,
291 unsigned char TargetID
,
294 DAC960_Command_T
*Command
= DAC960_AllocateCommand(Controller
);
295 DAC960_CommandMailbox_T
*CommandMailbox
= &Command
->CommandMailbox
;
297 DAC960_ClearCommand(Command
);
298 Command
->CommandType
= DAC960_ImmediateCommand
;
299 CommandMailbox
->Type3D
.CommandOpcode
= CommandOpcode
;
300 CommandMailbox
->Type3D
.Channel
= Channel
;
301 CommandMailbox
->Type3D
.TargetID
= TargetID
;
302 CommandMailbox
->Type3D
.BusAddress
= Virtual_to_Bus(DataPointer
);
303 Result
= DAC960_ExecuteCommand(Command
);
304 DAC960_DeallocateCommand(Command
);
310 DAC960_EnableMemoryMailboxInterface enables the Memory Mailbox Interface.
313 static boolean
DAC960_EnableMemoryMailboxInterface(DAC960_Controller_T
316 void *ControllerBaseAddress
= Controller
->BaseAddress
;
317 DAC960_CommandMailbox_T
*CommandMailboxesMemory
;
318 DAC960_StatusMailbox_T
*StatusMailboxesMemory
;
319 DAC960_CommandMailbox_T CommandMailbox
;
320 DAC960_CommandStatus_T CommandStatus
;
321 void *SavedMemoryMailboxesAddress
= NULL
;
322 short NextCommandMailboxIndex
= 0;
323 short NextStatusMailboxIndex
= 0;
324 int TimeoutCounter
= 1000000, i
;
325 if (Controller
->ControllerType
== DAC960_V5_Controller
)
326 DAC960_V5_RestoreMemoryMailboxInfo(Controller
,
327 &SavedMemoryMailboxesAddress
,
328 &NextCommandMailboxIndex
,
329 &NextStatusMailboxIndex
);
330 else DAC960_V4_RestoreMemoryMailboxInfo(Controller
,
331 &SavedMemoryMailboxesAddress
,
332 &NextCommandMailboxIndex
,
333 &NextStatusMailboxIndex
);
334 if (SavedMemoryMailboxesAddress
== NULL
)
335 CommandMailboxesMemory
=
336 (DAC960_CommandMailbox_T
*) __get_free_pages(GFP_KERNEL
, 1);
337 else CommandMailboxesMemory
= SavedMemoryMailboxesAddress
;
338 memset(CommandMailboxesMemory
, 0, PAGE_SIZE
<< 1);
339 Controller
->FirstCommandMailbox
= CommandMailboxesMemory
;
340 CommandMailboxesMemory
+= DAC960_CommandMailboxCount
- 1;
341 Controller
->LastCommandMailbox
= CommandMailboxesMemory
;
342 Controller
->NextCommandMailbox
=
343 &Controller
->FirstCommandMailbox
[NextCommandMailboxIndex
];
344 if (--NextCommandMailboxIndex
< 0)
345 NextCommandMailboxIndex
= DAC960_CommandMailboxCount
- 1;
346 Controller
->PreviousCommandMailbox1
=
347 &Controller
->FirstCommandMailbox
[NextCommandMailboxIndex
];
348 if (--NextCommandMailboxIndex
< 0)
349 NextCommandMailboxIndex
= DAC960_CommandMailboxCount
- 1;
350 Controller
->PreviousCommandMailbox2
=
351 &Controller
->FirstCommandMailbox
[NextCommandMailboxIndex
];
352 StatusMailboxesMemory
=
353 (DAC960_StatusMailbox_T
*) (CommandMailboxesMemory
+ 1);
354 Controller
->FirstStatusMailbox
= StatusMailboxesMemory
;
355 StatusMailboxesMemory
+= DAC960_StatusMailboxCount
- 1;
356 Controller
->LastStatusMailbox
= StatusMailboxesMemory
;
357 Controller
->NextStatusMailbox
=
358 &Controller
->FirstStatusMailbox
[NextStatusMailboxIndex
];
359 if (SavedMemoryMailboxesAddress
!= NULL
) return true;
360 /* Enable the Memory Mailbox Interface. */
361 Controller
->DualModeMemoryMailboxInterface
= true;
362 CommandMailbox
.TypeX
.CommandOpcode
= 0x2B;
363 CommandMailbox
.TypeX
.CommandIdentifier
= 0;
364 CommandMailbox
.TypeX
.CommandOpcode2
= 0x14;
365 CommandMailbox
.TypeX
.CommandMailboxesBusAddress
=
366 Virtual_to_Bus(Controller
->FirstCommandMailbox
);
367 CommandMailbox
.TypeX
.StatusMailboxesBusAddress
=
368 Virtual_to_Bus(Controller
->FirstStatusMailbox
);
369 for (i
= 0; i
< 2; i
++)
370 switch (Controller
->ControllerType
)
372 case DAC960_V5_Controller
:
373 while (--TimeoutCounter
>= 0)
375 if (DAC960_V5_HardwareMailboxEmptyP(ControllerBaseAddress
))
379 if (TimeoutCounter
< 0) return false;
380 DAC960_V5_WriteHardwareMailbox(ControllerBaseAddress
, &CommandMailbox
);
381 DAC960_V5_HardwareMailboxNewCommand(ControllerBaseAddress
);
382 while (--TimeoutCounter
>= 0)
384 if (DAC960_V5_HardwareMailboxStatusAvailableP(
385 ControllerBaseAddress
))
389 if (TimeoutCounter
< 0) return false;
390 CommandStatus
= DAC960_V5_ReadStatusRegister(ControllerBaseAddress
);
391 DAC960_V5_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress
);
392 DAC960_V5_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress
);
393 if (CommandStatus
== DAC960_NormalCompletion
) return true;
394 Controller
->DualModeMemoryMailboxInterface
= false;
395 CommandMailbox
.TypeX
.CommandOpcode2
= 0x10;
397 case DAC960_V4_Controller
:
398 while (--TimeoutCounter
>= 0)
400 if (!DAC960_V4_HardwareMailboxFullP(ControllerBaseAddress
))
404 if (TimeoutCounter
< 0) return false;
405 DAC960_V4_WriteHardwareMailbox(ControllerBaseAddress
, &CommandMailbox
);
406 DAC960_V4_HardwareMailboxNewCommand(ControllerBaseAddress
);
407 while (--TimeoutCounter
>= 0)
409 if (DAC960_V4_HardwareMailboxStatusAvailableP(
410 ControllerBaseAddress
))
414 if (TimeoutCounter
< 0) return false;
415 CommandStatus
= DAC960_V4_ReadStatusRegister(ControllerBaseAddress
);
416 DAC960_V4_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress
);
417 DAC960_V4_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress
);
418 if (CommandStatus
== DAC960_NormalCompletion
) return true;
419 Controller
->DualModeMemoryMailboxInterface
= false;
420 CommandMailbox
.TypeX
.CommandOpcode2
= 0x10;
430 DAC960_DetectControllers detects DAC960 PCI RAID Controllers by interrogating
431 the PCI Configuration Space for Controller Type.
434 static void DAC960_DetectControllers(DAC960_ControllerType_T ControllerType
)
436 unsigned short VendorID
= 0, DeviceID
= 0;
437 unsigned int MemoryWindowSize
= 0;
438 PCI_Device_T
*PCI_Device
= NULL
;
439 switch (ControllerType
)
441 case DAC960_V5_Controller
:
442 VendorID
= PCI_VENDOR_ID_DEC
;
443 DeviceID
= PCI_DEVICE_ID_DEC_21285
;
444 MemoryWindowSize
= DAC960_V5_RegisterWindowSize
;
446 case DAC960_V4_Controller
:
447 VendorID
= PCI_VENDOR_ID_MYLEX
;
448 DeviceID
= PCI_DEVICE_ID_MYLEX_DAC960P_V4
;
449 MemoryWindowSize
= DAC960_V4_RegisterWindowSize
;
451 case DAC960_V3_Controller
:
452 VendorID
= PCI_VENDOR_ID_MYLEX
;
453 DeviceID
= PCI_DEVICE_ID_MYLEX_DAC960P_V3
;
454 MemoryWindowSize
= DAC960_V3_RegisterWindowSize
;
457 while ((PCI_Device
= pci_find_device(VendorID
, DeviceID
, PCI_Device
)) != NULL
)
459 DAC960_Controller_T
*Controller
= (DAC960_Controller_T
*)
460 kmalloc(sizeof(DAC960_Controller_T
), GFP_ATOMIC
);
461 DAC960_IO_Address_T IO_Address
= 0;
462 DAC960_PCI_Address_T PCI_Address
= 0;
463 unsigned char Bus
= PCI_Device
->bus
->number
;
464 unsigned char DeviceFunction
= PCI_Device
->devfn
;
465 unsigned char Device
= DeviceFunction
>> 3;
466 unsigned char Function
= DeviceFunction
& 0x7;
467 unsigned int IRQ_Channel
= PCI_Device
->irq
;
468 unsigned long BaseAddress0
= PCI_Device
->resource
[0].start
;
469 unsigned long BaseAddress1
= PCI_Device
->resource
[1].start
;
470 unsigned short SubsystemVendorID
, SubsystemDeviceID
;
471 int CommandIdentifier
;
472 pci_read_config_word(PCI_Device
, PCI_SUBSYSTEM_VENDOR_ID
,
474 pci_read_config_word(PCI_Device
, PCI_SUBSYSTEM_ID
,
476 switch (ControllerType
)
478 case DAC960_V5_Controller
:
479 if (!(SubsystemVendorID
== PCI_VENDOR_ID_MYLEX
&&
480 SubsystemDeviceID
== PCI_DEVICE_ID_MYLEX_DAC960P_V5
))
482 PCI_Address
= BaseAddress0
& PCI_BASE_ADDRESS_MEM_MASK
;
484 case DAC960_V4_Controller
:
485 PCI_Address
= BaseAddress0
& PCI_BASE_ADDRESS_MEM_MASK
;
487 case DAC960_V3_Controller
:
488 IO_Address
= BaseAddress0
& PCI_BASE_ADDRESS_IO_MASK
;
489 PCI_Address
= BaseAddress1
& PCI_BASE_ADDRESS_MEM_MASK
;
492 if (DAC960_ControllerCount
== DAC960_MaxControllers
)
494 DAC960_Error("More than %d DAC960 Controllers detected - "
495 "ignoring from Controller at\n",
496 NULL
, DAC960_MaxControllers
);
499 if (Controller
== NULL
)
501 DAC960_Error("Unable to allocate Controller structure for "
502 "Controller at\n", NULL
);
505 memset(Controller
, 0, sizeof(DAC960_Controller_T
));
506 init_waitqueue_head(&Controller
->CommandWaitQueue
);
507 Controller
->ControllerNumber
= DAC960_ControllerCount
;
508 DAC960_Controllers
[DAC960_ControllerCount
++] = Controller
;
509 DAC960_AnnounceDriver(Controller
);
510 Controller
->ControllerType
= ControllerType
;
511 Controller
->IO_Address
= IO_Address
;
512 Controller
->PCI_Address
= PCI_Address
;
513 Controller
->Bus
= Bus
;
514 Controller
->Device
= Device
;
515 Controller
->Function
= Function
;
516 sprintf(Controller
->ControllerName
, "c%d", Controller
->ControllerNumber
);
518 Acquire shared access to the IRQ Channel.
520 if (IRQ_Channel
== 0)
522 DAC960_Error("IRQ Channel %d illegal for Controller at\n",
523 Controller
, IRQ_Channel
);
526 strcpy(Controller
->FullModelName
, "DAC960");
527 if (request_irq(IRQ_Channel
, DAC960_InterruptHandler
,
528 SA_SHIRQ
, Controller
->FullModelName
, Controller
) < 0)
530 DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
531 Controller
, IRQ_Channel
);
534 Controller
->IRQ_Channel
= IRQ_Channel
;
536 Map the Controller Register Window.
538 if (MemoryWindowSize
< PAGE_SIZE
)
539 MemoryWindowSize
= PAGE_SIZE
;
540 Controller
->MemoryMappedAddress
=
541 ioremap_nocache(PCI_Address
& PAGE_MASK
, MemoryWindowSize
);
542 Controller
->BaseAddress
=
543 Controller
->MemoryMappedAddress
+ (PCI_Address
& ~PAGE_MASK
);
544 if (Controller
->MemoryMappedAddress
== NULL
)
546 DAC960_Error("Unable to map Controller Register Window for "
547 "Controller at\n", Controller
);
550 switch (ControllerType
)
552 case DAC960_V5_Controller
:
553 DAC960_V5_DisableInterrupts(Controller
->BaseAddress
);
554 if (!DAC960_EnableMemoryMailboxInterface(Controller
))
556 DAC960_Error("Unable to Enable Memory Mailbox Interface "
557 "for Controller at\n", Controller
);
560 DAC960_V5_EnableInterrupts(Controller
->BaseAddress
);
562 case DAC960_V4_Controller
:
563 DAC960_V4_DisableInterrupts(Controller
->BaseAddress
);
564 if (!DAC960_EnableMemoryMailboxInterface(Controller
))
566 DAC960_Error("Unable to Enable Memory Mailbox Interface "
567 "for Controller at\n", Controller
);
570 DAC960_V4_EnableInterrupts(Controller
->BaseAddress
);
572 case DAC960_V3_Controller
:
573 request_region(Controller
->IO_Address
, 0x80,
574 Controller
->FullModelName
);
575 DAC960_V3_EnableInterrupts(Controller
->BaseAddress
);
578 DAC960_ActiveControllerCount
++;
579 for (CommandIdentifier
= 0;
580 CommandIdentifier
< DAC960_MaxChannels
;
583 Controller
->Commands
[CommandIdentifier
].Controller
= Controller
;
584 Controller
->Commands
[CommandIdentifier
].Next
=
585 Controller
->FreeCommands
;
586 Controller
->FreeCommands
= &Controller
->Commands
[CommandIdentifier
];
591 DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
592 "PCI Address 0x%X\n", Controller
,
593 Bus
, Device
, Function
, PCI_Address
);
594 else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
595 "0x%X PCI Address 0x%X\n", Controller
,
596 Bus
, Device
, Function
, IO_Address
, PCI_Address
);
597 if (Controller
== NULL
) break;
598 if (Controller
->IRQ_Channel
> 0)
599 free_irq(IRQ_Channel
, Controller
);
600 if (Controller
->MemoryMappedAddress
!= NULL
)
601 iounmap(Controller
->MemoryMappedAddress
);
602 DAC960_Controllers
[Controller
->ControllerNumber
] = NULL
;
610 DAC960_ReadControllerConfiguration reads the Configuration Information
611 from Controller and initializes the Controller structure.
614 static boolean
DAC960_ReadControllerConfiguration(DAC960_Controller_T
617 DAC960_Enquiry2_T Enquiry2
;
618 DAC960_Config2_T Config2
;
619 int LogicalDriveNumber
, Channel
, TargetID
;
620 if (!DAC960_ExecuteType3(Controller
, DAC960_Enquiry
,
621 &Controller
->Enquiry
[0]))
622 return DAC960_Failure(Controller
, "ENQUIRY");
623 if (!DAC960_ExecuteType3(Controller
, DAC960_Enquiry2
, &Enquiry2
))
624 return DAC960_Failure(Controller
, "ENQUIRY2");
625 if (!DAC960_ExecuteType3(Controller
, DAC960_ReadConfig2
, &Config2
))
626 return DAC960_Failure(Controller
, "READ CONFIG2");
627 if (!DAC960_ExecuteType3(Controller
, DAC960_GetLogicalDriveInformation
,
628 &Controller
->LogicalDriveInformation
[0]))
629 return DAC960_Failure(Controller
, "GET LOGICAL DRIVE INFORMATION");
630 for (Channel
= 0; Channel
< Enquiry2
.ActualChannels
; Channel
++)
631 for (TargetID
= 0; TargetID
< DAC960_MaxTargets
; TargetID
++)
632 if (!DAC960_ExecuteType3D(Controller
, DAC960_GetDeviceState
,
634 &Controller
->DeviceState
[0][Channel
][TargetID
]))
635 return DAC960_Failure(Controller
, "GET DEVICE STATE");
637 Initialize the Controller Model Name and Full Model Name fields.
639 switch (Enquiry2
.HardwareID
.SubModel
)
642 if (Enquiry2
.SCSICapability
.BusSpeed
== DAC960_Ultra
)
643 strcpy(Controller
->ModelName
, "DAC960PU");
644 else strcpy(Controller
->ModelName
, "DAC960PD");
647 strcpy(Controller
->ModelName
, "DAC960PL");
650 strcpy(Controller
->ModelName
, "DAC960PG");
653 strcpy(Controller
->ModelName
, "DAC960PJ");
656 strcpy(Controller
->ModelName
, "DAC960PR");
659 strcpy(Controller
->ModelName
, "DAC960PT");
662 strcpy(Controller
->ModelName
, "DAC960PTL0");
665 strcpy(Controller
->ModelName
, "DAC960PRL");
668 strcpy(Controller
->ModelName
, "DAC960PTL1");
671 strcpy(Controller
->ModelName
, "DAC1164P");
674 return DAC960_Failure(Controller
, "MODEL VERIFICATION");
676 strcpy(Controller
->FullModelName
, "Mylex ");
677 strcat(Controller
->FullModelName
, Controller
->ModelName
);
679 Initialize the Controller Firmware Version field and verify that it
680 is a supported firmware version. The supported firmware versions are:
682 DAC1164P 5.06 and above
683 DAC960PTL/PRL/PJ/PG 4.06 and above
684 DAC960PU/PD/PL 3.51 and above
686 sprintf(Controller
->FirmwareVersion
, "%d.%02d-%c-%02d",
687 Enquiry2
.FirmwareID
.MajorVersion
, Enquiry2
.FirmwareID
.MinorVersion
,
688 Enquiry2
.FirmwareID
.FirmwareType
, Enquiry2
.FirmwareID
.TurnID
);
689 if (!((Controller
->FirmwareVersion
[0] == '5' &&
690 strcmp(Controller
->FirmwareVersion
, "5.06") >= 0) ||
691 (Controller
->FirmwareVersion
[0] == '4' &&
692 strcmp(Controller
->FirmwareVersion
, "4.06") >= 0) ||
693 (Controller
->FirmwareVersion
[0] == '3' &&
694 strcmp(Controller
->FirmwareVersion
, "3.51") >= 0)))
696 DAC960_Failure(Controller
, "FIRMWARE VERSION VERIFICATION");
697 DAC960_Error("Firmware Version = '%s'\n", Controller
,
698 Controller
->FirmwareVersion
);
702 Initialize the Controller Channels, Memory Size, and SAF-TE Enclosure
703 Management Enabled fields.
705 Controller
->Channels
= Enquiry2
.ActualChannels
;
706 Controller
->MemorySize
= Enquiry2
.MemorySize
>> 20;
707 Controller
->SAFTE_EnclosureManagementEnabled
=
708 Enquiry2
.FaultManagementType
== DAC960_SAFTE
;
710 Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
711 Count, Maximum Blocks per Command, and Maximum Scatter/Gather Segments.
712 The Driver Queue Depth must be at most one less than the Controller Queue
713 Depth to allow for an automatic drive rebuild operation.
715 Controller
->ControllerQueueDepth
= Controller
->Enquiry
[0].MaxCommands
;
716 Controller
->DriverQueueDepth
= Controller
->ControllerQueueDepth
- 1;
717 Controller
->LogicalDriveCount
= Controller
->Enquiry
[0].NumberOfLogicalDrives
;
718 Controller
->MaxBlocksPerCommand
= Enquiry2
.MaxBlocksPerCommand
;
719 Controller
->MaxScatterGatherSegments
= Enquiry2
.MaxScatterGatherEntries
;
721 Initialize the Stripe Size, Segment Size, and Geometry Translation.
723 Controller
->StripeSize
= Config2
.BlocksPerStripe
* Config2
.BlockFactor
724 >> (10 - DAC960_BlockSizeBits
);
725 Controller
->SegmentSize
= Config2
.BlocksPerCacheLine
* Config2
.BlockFactor
726 >> (10 - DAC960_BlockSizeBits
);
727 switch (Config2
.DriveGeometry
)
729 case DAC960_Geometry_128_32
:
730 Controller
->GeometryTranslationHeads
= 128;
731 Controller
->GeometryTranslationSectors
= 32;
733 case DAC960_Geometry_255_63
:
734 Controller
->GeometryTranslationHeads
= 255;
735 Controller
->GeometryTranslationSectors
= 63;
738 return DAC960_Failure(Controller
, "CONFIG2 DRIVE GEOMETRY");
741 Initialize the Logical Drive Initial State.
743 for (LogicalDriveNumber
= 0;
744 LogicalDriveNumber
< Controller
->LogicalDriveCount
;
745 LogicalDriveNumber
++)
746 Controller
->LogicalDriveInitialState
[LogicalDriveNumber
] =
747 Controller
->LogicalDriveInformation
[0]
748 [LogicalDriveNumber
].LogicalDriveState
;
749 Controller
->LastRebuildStatus
= DAC960_NoRebuildOrCheckInProgress
;
755 DAC960_ReportControllerConfiguration reports the Configuration Information of
759 static boolean
DAC960_ReportControllerConfiguration(DAC960_Controller_T
762 DAC960_Info("Configuring Mylex %s PCI RAID Controller\n",
763 Controller
, Controller
->ModelName
);
764 DAC960_Info(" Firmware Version: %s, Channels: %d, Memory Size: %dMB\n",
765 Controller
, Controller
->FirmwareVersion
,
766 Controller
->Channels
, Controller
->MemorySize
);
767 DAC960_Info(" PCI Bus: %d, Device: %d, Function: %d, I/O Address: ",
768 Controller
, Controller
->Bus
,
769 Controller
->Device
, Controller
->Function
);
770 if (Controller
->IO_Address
== 0)
771 DAC960_Info("Unassigned\n", Controller
);
772 else DAC960_Info("0x%X\n", Controller
, Controller
->IO_Address
);
773 DAC960_Info(" PCI Address: 0x%X mapped at 0x%lX, IRQ Channel: %d\n",
774 Controller
, Controller
->PCI_Address
,
775 (unsigned long) Controller
->BaseAddress
,
776 Controller
->IRQ_Channel
);
777 DAC960_Info(" Controller Queue Depth: %d, "
778 "Maximum Blocks per Command: %d\n",
779 Controller
, Controller
->ControllerQueueDepth
,
780 Controller
->MaxBlocksPerCommand
);
781 DAC960_Info(" Driver Queue Depth: %d, "
782 "Maximum Scatter/Gather Segments: %d\n",
783 Controller
, Controller
->DriverQueueDepth
,
784 Controller
->MaxScatterGatherSegments
);
785 DAC960_Info(" Stripe Size: %dKB, Segment Size: %dKB, "
786 "BIOS Geometry: %d/%d\n", Controller
,
787 Controller
->StripeSize
,
788 Controller
->SegmentSize
,
789 Controller
->GeometryTranslationHeads
,
790 Controller
->GeometryTranslationSectors
);
791 if (Controller
->SAFTE_EnclosureManagementEnabled
)
792 DAC960_Info(" SAF-TE Enclosure Management Enabled\n", Controller
);
798 DAC960_ReadDeviceConfiguration reads the Device Configuration Information by
799 requesting the SCSI Inquiry and SCSI Inquiry Unit Serial Number information
800 for each device connected to Controller.
803 static boolean
DAC960_ReadDeviceConfiguration(DAC960_Controller_T
*Controller
)
805 DAC960_DCDB_T DCDBs
[DAC960_MaxChannels
], *DCDB
;
806 Semaphore_T Semaphores
[DAC960_MaxChannels
], *Semaphore
;
807 unsigned long ProcessorFlags
;
808 int Channel
, TargetID
;
809 for (TargetID
= 0; TargetID
< DAC960_MaxTargets
; TargetID
++)
811 for (Channel
= 0; Channel
< Controller
->Channels
; Channel
++)
813 DAC960_Command_T
*Command
= &Controller
->Commands
[Channel
];
814 DAC960_SCSI_Inquiry_T
*InquiryStandardData
=
815 &Controller
->InquiryStandardData
[Channel
][TargetID
];
816 InquiryStandardData
->PeripheralDeviceType
= 0x1F;
817 Semaphore
= &Semaphores
[Channel
];
818 init_MUTEX_LOCKED(Semaphore
);
819 DCDB
= &DCDBs
[Channel
];
820 DAC960_ClearCommand(Command
);
821 Command
->CommandType
= DAC960_ImmediateCommand
;
822 Command
->Semaphore
= Semaphore
;
823 Command
->CommandMailbox
.Type3
.CommandOpcode
= DAC960_DCDB
;
824 Command
->CommandMailbox
.Type3
.BusAddress
= Virtual_to_Bus(DCDB
);
825 DCDB
->Channel
= Channel
;
826 DCDB
->TargetID
= TargetID
;
827 DCDB
->Direction
= DAC960_DCDB_DataTransferDeviceToSystem
;
828 DCDB
->EarlyStatus
= false;
829 DCDB
->Timeout
= DAC960_DCDB_Timeout_10_seconds
;
830 DCDB
->NoAutomaticRequestSense
= false;
831 DCDB
->DisconnectPermitted
= true;
832 DCDB
->TransferLength
= sizeof(DAC960_SCSI_Inquiry_T
);
833 DCDB
->BusAddress
= Virtual_to_Bus(InquiryStandardData
);
835 DCDB
->TransferLengthHigh4
= 0;
836 DCDB
->SenseLength
= sizeof(DCDB
->SenseData
);
837 DCDB
->CDB
[0] = 0x12; /* INQUIRY */
838 DCDB
->CDB
[1] = 0; /* EVPD = 0 */
839 DCDB
->CDB
[2] = 0; /* Page Code */
840 DCDB
->CDB
[3] = 0; /* Reserved */
841 DCDB
->CDB
[4] = sizeof(DAC960_SCSI_Inquiry_T
);
842 DCDB
->CDB
[5] = 0; /* Control */
843 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
844 DAC960_QueueCommand(Command
);
845 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
847 for (Channel
= 0; Channel
< Controller
->Channels
; Channel
++)
849 DAC960_Command_T
*Command
= &Controller
->Commands
[Channel
];
850 DAC960_SCSI_Inquiry_UnitSerialNumber_T
*InquiryUnitSerialNumber
=
851 &Controller
->InquiryUnitSerialNumber
[Channel
][TargetID
];
852 InquiryUnitSerialNumber
->PeripheralDeviceType
= 0x1F;
853 Semaphore
= &Semaphores
[Channel
];
855 if (Command
->CommandStatus
!= DAC960_NormalCompletion
) continue;
856 Command
->Semaphore
= Semaphore
;
857 DCDB
= &DCDBs
[Channel
];
858 DCDB
->TransferLength
= sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T
);
859 DCDB
->BusAddress
= Virtual_to_Bus(InquiryUnitSerialNumber
);
860 DCDB
->SenseLength
= sizeof(DCDB
->SenseData
);
861 DCDB
->CDB
[0] = 0x12; /* INQUIRY */
862 DCDB
->CDB
[1] = 1; /* EVPD = 1 */
863 DCDB
->CDB
[2] = 0x80; /* Page Code */
864 DCDB
->CDB
[3] = 0; /* Reserved */
865 DCDB
->CDB
[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T
);
866 DCDB
->CDB
[5] = 0; /* Control */
867 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
868 DAC960_QueueCommand(Command
);
869 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
878 DAC960_ReportDeviceConfiguration reports the Device Configuration Information
882 static boolean
DAC960_ReportDeviceConfiguration(DAC960_Controller_T
*Controller
)
884 int LogicalDriveNumber
, Channel
, TargetID
;
885 DAC960_Info(" Physical Devices:\n", Controller
);
886 for (Channel
= 0; Channel
< Controller
->Channels
; Channel
++)
887 for (TargetID
= 0; TargetID
< DAC960_MaxTargets
; TargetID
++)
889 DAC960_SCSI_Inquiry_T
*InquiryStandardData
=
890 &Controller
->InquiryStandardData
[Channel
][TargetID
];
891 DAC960_SCSI_Inquiry_UnitSerialNumber_T
*InquiryUnitSerialNumber
=
892 &Controller
->InquiryUnitSerialNumber
[Channel
][TargetID
];
893 DAC960_DeviceState_T
*DeviceState
=
894 &Controller
->DeviceState
[Controller
->DeviceStateIndex
]
896 DAC960_ErrorTable_T
*ErrorTable
=
897 &Controller
->ErrorTable
[Controller
->ErrorTableIndex
];
898 DAC960_ErrorTableEntry_T
*ErrorEntry
=
899 &ErrorTable
->ErrorTableEntries
[Channel
][TargetID
];
900 char Vendor
[1+sizeof(InquiryStandardData
->VendorIdentification
)];
901 char Model
[1+sizeof(InquiryStandardData
->ProductIdentification
)];
902 char Revision
[1+sizeof(InquiryStandardData
->ProductRevisionLevel
)];
903 char SerialNumber
[1+sizeof(InquiryUnitSerialNumber
904 ->ProductSerialNumber
)];
906 if (InquiryStandardData
->PeripheralDeviceType
== 0x1F) continue;
907 for (i
= 0; i
< sizeof(Vendor
)-1; i
++)
909 unsigned char VendorCharacter
=
910 InquiryStandardData
->VendorIdentification
[i
];
911 Vendor
[i
] = (VendorCharacter
>= ' ' && VendorCharacter
<= '~'
912 ? VendorCharacter
: ' ');
914 Vendor
[sizeof(Vendor
)-1] = '\0';
915 for (i
= 0; i
< sizeof(Model
)-1; i
++)
917 unsigned char ModelCharacter
=
918 InquiryStandardData
->ProductIdentification
[i
];
919 Model
[i
] = (ModelCharacter
>= ' ' && ModelCharacter
<= '~'
920 ? ModelCharacter
: ' ');
922 Model
[sizeof(Model
)-1] = '\0';
923 for (i
= 0; i
< sizeof(Revision
)-1; i
++)
925 unsigned char RevisionCharacter
=
926 InquiryStandardData
->ProductRevisionLevel
[i
];
927 Revision
[i
] = (RevisionCharacter
>= ' ' && RevisionCharacter
<= '~'
928 ? RevisionCharacter
: ' ');
930 Revision
[sizeof(Revision
)-1] = '\0';
931 DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %s\n",
932 Controller
, Channel
, TargetID
, (TargetID
< 10 ? " " : ""),
933 Vendor
, Model
, Revision
);
934 if (InquiryUnitSerialNumber
->PeripheralDeviceType
!= 0x1F)
936 int SerialNumberLength
= InquiryUnitSerialNumber
->PageLength
;
937 if (SerialNumberLength
>
938 sizeof(InquiryUnitSerialNumber
->ProductSerialNumber
))
940 sizeof(InquiryUnitSerialNumber
->ProductSerialNumber
);
941 for (i
= 0; i
< SerialNumberLength
; i
++)
943 unsigned char SerialNumberCharacter
=
944 InquiryUnitSerialNumber
->ProductSerialNumber
[i
];
946 (SerialNumberCharacter
>= ' ' && SerialNumberCharacter
<= '~'
947 ? SerialNumberCharacter
: ' ');
949 SerialNumber
[SerialNumberLength
] = '\0';
950 DAC960_Info(" Serial Number: %s\n",
951 Controller
, SerialNumber
);
953 if (DeviceState
->Present
&& DeviceState
->DeviceType
== DAC960_DiskType
)
955 if (Controller
->DeviceResetCount
[Channel
][TargetID
] > 0)
956 DAC960_Info(" Disk Status: %s, %d blocks, %d resets\n",
958 (DeviceState
->DeviceState
== DAC960_Device_Dead
960 : DeviceState
->DeviceState
== DAC960_Device_WriteOnly
962 : DeviceState
->DeviceState
== DAC960_Device_Online
963 ? "Online" : "Standby"),
964 DeviceState
->DiskSize
,
965 Controller
->DeviceResetCount
[Channel
][TargetID
]);
967 DAC960_Info(" Disk Status: %s, %d blocks\n", Controller
,
968 (DeviceState
->DeviceState
== DAC960_Device_Dead
970 : DeviceState
->DeviceState
== DAC960_Device_WriteOnly
972 : DeviceState
->DeviceState
== DAC960_Device_Online
973 ? "Online" : "Standby"),
974 DeviceState
->DiskSize
);
976 if (ErrorEntry
->ParityErrorCount
> 0 ||
977 ErrorEntry
->SoftErrorCount
> 0 ||
978 ErrorEntry
->HardErrorCount
> 0 ||
979 ErrorEntry
->MiscErrorCount
> 0)
980 DAC960_Info(" Errors - Parity: %d, Soft: %d, "
981 "Hard: %d, Misc: %d\n", Controller
,
982 ErrorEntry
->ParityErrorCount
,
983 ErrorEntry
->SoftErrorCount
,
984 ErrorEntry
->HardErrorCount
,
985 ErrorEntry
->MiscErrorCount
);
987 DAC960_Info(" Logical Drives:\n", Controller
);
988 for (LogicalDriveNumber
= 0;
989 LogicalDriveNumber
< Controller
->LogicalDriveCount
;
990 LogicalDriveNumber
++)
992 DAC960_LogicalDriveInformation_T
*LogicalDriveInformation
=
993 &Controller
->LogicalDriveInformation
994 [Controller
->LogicalDriveInformationIndex
][LogicalDriveNumber
];
995 DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %d blocks, %s\n",
996 Controller
, Controller
->ControllerNumber
, LogicalDriveNumber
,
997 LogicalDriveInformation
->RAIDLevel
,
998 (LogicalDriveInformation
->LogicalDriveState
==
999 DAC960_LogicalDrive_Online
1001 : LogicalDriveInformation
->LogicalDriveState
==
1002 DAC960_LogicalDrive_Critical
1003 ? "Critical" : "Offline"),
1004 LogicalDriveInformation
->LogicalDriveSize
,
1005 (LogicalDriveInformation
->WriteBack
1006 ? "Write Back" : "Write Thru"));
1013 DAC960_RegisterBlockDevice registers the Block Device structures
1014 associated with Controller.
1017 static boolean
DAC960_RegisterBlockDevice(DAC960_Controller_T
*Controller
)
1019 static void (*RequestFunctions
[DAC960_MaxControllers
])(request_queue_t
*) =
1020 { DAC960_RequestFunction0
, DAC960_RequestFunction1
,
1021 DAC960_RequestFunction2
, DAC960_RequestFunction3
,
1022 DAC960_RequestFunction4
, DAC960_RequestFunction5
,
1023 DAC960_RequestFunction6
, DAC960_RequestFunction7
};
1024 int MajorNumber
= DAC960_MAJOR
+ Controller
->ControllerNumber
;
1025 GenericDiskInfo_T
*GenericDiskInfo
;
1028 Register the Block Device Major Number for this DAC960 Controller.
1030 if (register_blkdev(MajorNumber
, "rd", &DAC960_FileOperations
) < 0)
1032 DAC960_Error("UNABLE TO ACQUIRE MAJOR NUMBER %d - DETACHING\n",
1033 Controller
, MajorNumber
);
1037 Initialize the I/O Request Function.
1039 blk_init_queue(BLK_DEFAULT_QUEUE(MajorNumber
),
1040 RequestFunctions
[Controller
->ControllerNumber
]);
1042 Initialize the Disk Partitions array, Partition Sizes array, Block Sizes
1043 array, Max Sectors per Request array, and Max Segments per Request array.
1045 for (MinorNumber
= 0; MinorNumber
< DAC960_MinorCount
; MinorNumber
++)
1047 Controller
->BlockSizes
[MinorNumber
] = BLOCK_SIZE
;
1048 Controller
->MaxSectorsPerRequest
[MinorNumber
] =
1049 Controller
->MaxBlocksPerCommand
;
1050 Controller
->MaxSegmentsPerRequest
[MinorNumber
] =
1051 Controller
->MaxScatterGatherSegments
;
1053 Controller
->GenericDiskInfo
.part
= Controller
->DiskPartitions
;
1054 Controller
->GenericDiskInfo
.sizes
= Controller
->PartitionSizes
;
1055 blksize_size
[MajorNumber
] = Controller
->BlockSizes
;
1056 max_sectors
[MajorNumber
] = Controller
->MaxSectorsPerRequest
;
1057 max_segments
[MajorNumber
] = Controller
->MaxSegmentsPerRequest
;
1059 Initialize Read Ahead to 128 sectors.
1061 read_ahead
[MajorNumber
] = 128;
1063 Complete initialization of the Generic Disk Information structure.
1065 Controller
->GenericDiskInfo
.major
= MajorNumber
;
1066 Controller
->GenericDiskInfo
.major_name
= "rd";
1067 Controller
->GenericDiskInfo
.minor_shift
= DAC960_MaxPartitionsBits
;
1068 Controller
->GenericDiskInfo
.max_p
= DAC960_MaxPartitions
;
1069 Controller
->GenericDiskInfo
.max_nr
= DAC960_MaxLogicalDrives
;
1070 Controller
->GenericDiskInfo
.init
= DAC960_InitializeGenericDiskInfo
;
1071 Controller
->GenericDiskInfo
.nr_real
= Controller
->LogicalDriveCount
;
1072 Controller
->GenericDiskInfo
.real_devices
= Controller
;
1073 Controller
->GenericDiskInfo
.next
= NULL
;
1075 Install the Generic Disk Information structure at the end of the list.
1077 if ((GenericDiskInfo
= gendisk_head
) != NULL
)
1079 while (GenericDiskInfo
->next
!= NULL
)
1080 GenericDiskInfo
= GenericDiskInfo
->next
;
1081 GenericDiskInfo
->next
= &Controller
->GenericDiskInfo
;
1083 else gendisk_head
= &Controller
->GenericDiskInfo
;
1085 Indicate the Block Device Registration completed successfully,
1092 DAC960_UnregisterBlockDevice unregisters the Block Device structures
1093 associated with Controller.
1096 static void DAC960_UnregisterBlockDevice(DAC960_Controller_T
*Controller
)
1098 int MajorNumber
= DAC960_MAJOR
+ Controller
->ControllerNumber
;
1100 Unregister the Block Device Major Number for this DAC960 Controller.
1102 unregister_blkdev(MajorNumber
, "rd");
1104 Remove the I/O Request Function.
1106 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MajorNumber
));
1108 Remove the Disk Partitions array, Partition Sizes array, Block Sizes
1109 array, Max Sectors per Request array, and Max Segments per Request array.
1111 Controller
->GenericDiskInfo
.part
= NULL
;
1112 Controller
->GenericDiskInfo
.sizes
= NULL
;
1113 blk_size
[MajorNumber
] = NULL
;
1114 blksize_size
[MajorNumber
] = NULL
;
1115 max_sectors
[MajorNumber
] = NULL
;
1116 max_segments
[MajorNumber
] = NULL
;
1118 Remove the Generic Disk Information structure from the list.
1120 if (gendisk_head
!= &Controller
->GenericDiskInfo
)
1122 GenericDiskInfo_T
*GenericDiskInfo
= gendisk_head
;
1123 while (GenericDiskInfo
!= NULL
&&
1124 GenericDiskInfo
->next
!= &Controller
->GenericDiskInfo
)
1125 GenericDiskInfo
= GenericDiskInfo
->next
;
1126 if (GenericDiskInfo
!= NULL
)
1127 GenericDiskInfo
->next
= GenericDiskInfo
->next
->next
;
1129 else gendisk_head
= Controller
->GenericDiskInfo
.next
;
1134 DAC960_InitializeController initializes Controller.
1137 static void DAC960_InitializeController(DAC960_Controller_T
*Controller
)
1139 if (DAC960_ReadControllerConfiguration(Controller
) &&
1140 DAC960_ReportControllerConfiguration(Controller
) &&
1141 DAC960_ReadDeviceConfiguration(Controller
) &&
1142 DAC960_ReportDeviceConfiguration(Controller
) &&
1143 DAC960_RegisterBlockDevice(Controller
))
1146 Initialize the Command structures.
1148 DAC960_Command_T
*Commands
= Controller
->Commands
;
1149 int CommandIdentifier
;
1150 Controller
->FreeCommands
= NULL
;
1151 for (CommandIdentifier
= 0;
1152 CommandIdentifier
< Controller
->DriverQueueDepth
;
1153 CommandIdentifier
++)
1155 Commands
[CommandIdentifier
].Controller
= Controller
;
1156 Commands
[CommandIdentifier
].Next
= Controller
->FreeCommands
;
1157 Controller
->FreeCommands
= &Commands
[CommandIdentifier
];
1160 Initialize the Monitoring Timer.
1162 init_timer(&Controller
->MonitoringTimer
);
1163 Controller
->MonitoringTimer
.expires
=
1164 jiffies
+ DAC960_MonitoringTimerInterval
;
1165 Controller
->MonitoringTimer
.data
= (unsigned long) Controller
;
1166 Controller
->MonitoringTimer
.function
= DAC960_MonitoringTimerFunction
;
1167 add_timer(&Controller
->MonitoringTimer
);
1168 Controller
->ControllerInitialized
= true;
1170 else DAC960_FinalizeController(Controller
);
1175 DAC960_FinalizeController finalizes Controller.
1178 static void DAC960_FinalizeController(DAC960_Controller_T
*Controller
)
1180 if (Controller
->ControllerInitialized
)
1182 del_timer(&Controller
->MonitoringTimer
);
1183 DAC960_Notice("Flushing Cache...", Controller
);
1184 DAC960_ExecuteType3(Controller
, DAC960_Flush
, NULL
);
1185 DAC960_Notice("done\n", Controller
);
1186 switch (Controller
->ControllerType
)
1188 case DAC960_V5_Controller
:
1189 if (!Controller
->DualModeMemoryMailboxInterface
)
1190 DAC960_V5_SaveMemoryMailboxInfo(Controller
);
1192 case DAC960_V4_Controller
:
1193 if (!Controller
->DualModeMemoryMailboxInterface
)
1194 DAC960_V4_SaveMemoryMailboxInfo(Controller
);
1196 case DAC960_V3_Controller
:
1200 free_irq(Controller
->IRQ_Channel
, Controller
);
1201 iounmap(Controller
->MemoryMappedAddress
);
1202 if (Controller
->IO_Address
> 0)
1203 release_region(Controller
->IO_Address
, 0x80);
1204 DAC960_UnregisterBlockDevice(Controller
);
1205 DAC960_Controllers
[Controller
->ControllerNumber
] = NULL
;
1211 DAC960_Initialize initializes the DAC960 Driver.
1214 void DAC960_Initialize(void)
1216 int ControllerNumber
;
1217 DAC960_DetectControllers(DAC960_V5_Controller
);
1218 DAC960_DetectControllers(DAC960_V4_Controller
);
1219 DAC960_DetectControllers(DAC960_V3_Controller
);
1220 if (DAC960_ActiveControllerCount
== 0) return;
1221 for (ControllerNumber
= 0;
1222 ControllerNumber
< DAC960_ControllerCount
;
1224 if (DAC960_Controllers
[ControllerNumber
] != NULL
)
1225 DAC960_InitializeController(DAC960_Controllers
[ControllerNumber
]);
1226 DAC960_CreateProcEntries();
1227 register_reboot_notifier(&DAC960_NotifierBlock
);
1232 DAC960_Finalize finalizes the DAC960 Driver.
1235 static int DAC960_Finalize(NotifierBlock_T
*NotifierBlock
,
1236 unsigned long Event
,
1239 int ControllerNumber
;
1240 if (!(Event
== SYS_RESTART
|| Event
== SYS_HALT
|| Event
== SYS_POWER_OFF
))
1242 if (DAC960_ActiveControllerCount
== 0) return NOTIFY_OK
;
1243 for (ControllerNumber
= 0;
1244 ControllerNumber
< DAC960_ControllerCount
;
1246 if (DAC960_Controllers
[ControllerNumber
] != NULL
)
1247 DAC960_FinalizeController(DAC960_Controllers
[ControllerNumber
]);
1248 DAC960_DestroyProcEntries();
1249 unregister_reboot_notifier(&DAC960_NotifierBlock
);
1255 DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
1256 I/O Request Queue and queues it to the Controller. WaitForCommand is true if
1257 this function should wait for a Command to become available if necessary.
1258 This function returns true if an I/O Request was queued and false otherwise.
1261 static boolean
DAC960_ProcessRequest(DAC960_Controller_T
*Controller
,
1262 boolean WaitForCommand
)
1264 IO_Request_T
**RequestQueuePointer
=
1265 &blk_dev
[DAC960_MAJOR
+ Controller
->ControllerNumber
].request_queue
.current_request
;
1266 IO_Request_T
*Request
;
1267 DAC960_Command_T
*Command
;
1268 char *RequestBuffer
;
1271 Request
= *RequestQueuePointer
;
1272 if (Request
== NULL
|| Request
->rq_status
== RQ_INACTIVE
) return false;
1273 Command
= DAC960_AllocateCommand(Controller
);
1274 if (Command
!= NULL
) break;
1275 if (!WaitForCommand
) return false;
1276 spin_unlock(&io_request_lock
);
1277 sleep_on(&Controller
->CommandWaitQueue
);
1278 spin_lock_irq(&io_request_lock
);
1280 DAC960_ClearCommand(Command
);
1281 if (Request
->cmd
== READ
)
1282 Command
->CommandType
= DAC960_ReadCommand
;
1283 else Command
->CommandType
= DAC960_WriteCommand
;
1284 Command
->Semaphore
= Request
->sem
;
1285 Command
->LogicalDriveNumber
= DAC960_LogicalDriveNumber(Request
->rq_dev
);
1286 Command
->BlockNumber
=
1288 + Controller
->GenericDiskInfo
.part
[MINOR(Request
->rq_dev
)].start_sect
;
1289 Command
->BlockCount
= Request
->nr_sectors
;
1290 Command
->SegmentCount
= Request
->nr_segments
;
1291 Command
->BufferHeader
= Request
->bh
;
1292 RequestBuffer
= Request
->buffer
;
1293 Request
->rq_status
= RQ_INACTIVE
;
1294 *RequestQueuePointer
= Request
->next
;
1295 wake_up(&wait_for_request
);
1296 if (Command
->SegmentCount
== 1)
1298 DAC960_CommandMailbox_T
*CommandMailbox
= &Command
->CommandMailbox
;
1299 if (Command
->CommandType
== DAC960_ReadCommand
)
1300 CommandMailbox
->Type5
.CommandOpcode
= DAC960_Read
;
1301 else CommandMailbox
->Type5
.CommandOpcode
= DAC960_Write
;
1302 CommandMailbox
->Type5
.LD
.TransferLength
= Command
->BlockCount
;
1303 CommandMailbox
->Type5
.LD
.LogicalDriveNumber
= Command
->LogicalDriveNumber
;
1304 CommandMailbox
->Type5
.LogicalBlockAddress
= Command
->BlockNumber
;
1305 CommandMailbox
->Type5
.BusAddress
= Virtual_to_Bus(RequestBuffer
);
1309 DAC960_CommandMailbox_T
*CommandMailbox
= &Command
->CommandMailbox
;
1310 DAC960_ScatterGatherSegment_T
1311 *ScatterGatherList
= Command
->ScatterGatherList
;
1312 BufferHeader_T
*BufferHeader
= Command
->BufferHeader
;
1313 char *LastDataEndPointer
= NULL
;
1314 int SegmentNumber
= 0;
1315 if (Command
->CommandType
== DAC960_ReadCommand
)
1316 CommandMailbox
->Type5
.CommandOpcode
= DAC960_ReadWithOldScatterGather
;
1318 CommandMailbox
->Type5
.CommandOpcode
= DAC960_WriteWithOldScatterGather
;
1319 CommandMailbox
->Type5
.LD
.TransferLength
= Command
->BlockCount
;
1320 CommandMailbox
->Type5
.LD
.LogicalDriveNumber
= Command
->LogicalDriveNumber
;
1321 CommandMailbox
->Type5
.LogicalBlockAddress
= Command
->BlockNumber
;
1322 CommandMailbox
->Type5
.BusAddress
= Virtual_to_Bus(ScatterGatherList
);
1323 CommandMailbox
->Type5
.ScatterGatherCount
= Command
->SegmentCount
;
1324 while (BufferHeader
!= NULL
)
1326 if (BufferHeader
->b_data
== LastDataEndPointer
)
1328 ScatterGatherList
[SegmentNumber
-1].SegmentByteCount
+=
1329 BufferHeader
->b_size
;
1330 LastDataEndPointer
+= BufferHeader
->b_size
;
1334 ScatterGatherList
[SegmentNumber
].SegmentDataPointer
=
1335 Virtual_to_Bus(BufferHeader
->b_data
);
1336 ScatterGatherList
[SegmentNumber
].SegmentByteCount
=
1337 BufferHeader
->b_size
;
1338 LastDataEndPointer
= BufferHeader
->b_data
+ BufferHeader
->b_size
;
1339 if (SegmentNumber
++ > Controller
->MaxScatterGatherSegments
)
1340 panic("DAC960: Scatter/Gather Segment Overflow\n");
1342 BufferHeader
= BufferHeader
->b_reqnext
;
1344 if (SegmentNumber
!= Command
->SegmentCount
)
1345 panic("DAC960: SegmentNumber != SegmentCount\n");
1347 DAC960_QueueCommand(Command
);
1353 DAC960_ProcessRequests attempts to remove as many I/O Requests as possible
1354 from Controller's I/O Request Queue and queue them to the Controller.
1357 static inline void DAC960_ProcessRequests(DAC960_Controller_T
*Controller
)
1360 while (DAC960_ProcessRequest(Controller
, Counter
++ == 0)) ;
1365 DAC960_RequestFunction0 is the I/O Request Function for DAC960 Controller 0.
1368 static void DAC960_RequestFunction0(request_queue_t
* q
)
1370 DAC960_Controller_T
*Controller
= DAC960_Controllers
[0];
1371 ProcessorFlags_T ProcessorFlags
;
1373 Acquire exclusive access to Controller.
1375 DAC960_AcquireControllerLockRF(Controller
, &ProcessorFlags
);
1377 Process I/O Requests for Controller.
1379 DAC960_ProcessRequests(Controller
);
1381 Release exclusive access to Controller.
1383 DAC960_ReleaseControllerLockRF(Controller
, &ProcessorFlags
);
1388 DAC960_RequestFunction1 is the I/O Request Function for DAC960 Controller 1.
1391 static void DAC960_RequestFunction1(request_queue_t
* q
)
1393 DAC960_Controller_T
*Controller
= DAC960_Controllers
[1];
1394 ProcessorFlags_T ProcessorFlags
;
1396 Acquire exclusive access to Controller.
1398 DAC960_AcquireControllerLockRF(Controller
, &ProcessorFlags
);
1400 Process I/O Requests for Controller.
1402 DAC960_ProcessRequests(Controller
);
1404 Release exclusive access to Controller.
1406 DAC960_ReleaseControllerLockRF(Controller
, &ProcessorFlags
);
1411 DAC960_RequestFunction2 is the I/O Request Function for DAC960 Controller 2.
1414 static void DAC960_RequestFunction2(request_queue_t
* q
)
1416 DAC960_Controller_T
*Controller
= DAC960_Controllers
[2];
1417 ProcessorFlags_T ProcessorFlags
;
1419 Acquire exclusive access to Controller.
1421 DAC960_AcquireControllerLockRF(Controller
, &ProcessorFlags
);
1423 Process I/O Requests for Controller.
1425 DAC960_ProcessRequests(Controller
);
1427 Release exclusive access to Controller.
1429 DAC960_ReleaseControllerLockRF(Controller
, &ProcessorFlags
);
1434 DAC960_RequestFunction3 is the I/O Request Function for DAC960 Controller 3.
1437 static void DAC960_RequestFunction3(request_queue_t
* q
)
1439 DAC960_Controller_T
*Controller
= DAC960_Controllers
[3];
1440 ProcessorFlags_T ProcessorFlags
;
1442 Acquire exclusive access to Controller.
1444 DAC960_AcquireControllerLockRF(Controller
, &ProcessorFlags
);
1446 Process I/O Requests for Controller.
1448 DAC960_ProcessRequests(Controller
);
1450 Release exclusive access to Controller.
1452 DAC960_ReleaseControllerLockRF(Controller
, &ProcessorFlags
);
1457 DAC960_RequestFunction4 is the I/O Request Function for DAC960 Controller 4.
1460 static void DAC960_RequestFunction4(request_queue_t
* q
)
1462 DAC960_Controller_T
*Controller
= DAC960_Controllers
[4];
1463 ProcessorFlags_T ProcessorFlags
;
1465 Acquire exclusive access to Controller.
1467 DAC960_AcquireControllerLockRF(Controller
, &ProcessorFlags
);
1469 Process I/O Requests for Controller.
1471 DAC960_ProcessRequests(Controller
);
1473 Release exclusive access to Controller.
1475 DAC960_ReleaseControllerLockRF(Controller
, &ProcessorFlags
);
1480 DAC960_RequestFunction5 is the I/O Request Function for DAC960 Controller 5.
1483 static void DAC960_RequestFunction5(request_queue_t
* q
)
1485 DAC960_Controller_T
*Controller
= DAC960_Controllers
[5];
1486 ProcessorFlags_T ProcessorFlags
;
1488 Acquire exclusive access to Controller.
1490 DAC960_AcquireControllerLockRF(Controller
, &ProcessorFlags
);
1492 Process I/O Requests for Controller.
1494 DAC960_ProcessRequests(Controller
);
1496 Release exclusive access to Controller.
1498 DAC960_ReleaseControllerLockRF(Controller
, &ProcessorFlags
);
1503 DAC960_RequestFunction6 is the I/O Request Function for DAC960 Controller 6.
1506 static void DAC960_RequestFunction6(request_queue_t
* q
)
1508 DAC960_Controller_T
*Controller
= DAC960_Controllers
[6];
1509 ProcessorFlags_T ProcessorFlags
;
1511 Acquire exclusive access to Controller.
1513 DAC960_AcquireControllerLockRF(Controller
, &ProcessorFlags
);
1515 Process I/O Requests for Controller.
1517 DAC960_ProcessRequests(Controller
);
1519 Release exclusive access to Controller.
1521 DAC960_ReleaseControllerLockRF(Controller
, &ProcessorFlags
);
1526 DAC960_RequestFunction7 is the I/O Request Function for DAC960 Controller 7.
1529 static void DAC960_RequestFunction7(request_queue_t
* q
)
1531 DAC960_Controller_T
*Controller
= DAC960_Controllers
[7];
1532 ProcessorFlags_T ProcessorFlags
;
1534 Acquire exclusive access to Controller.
1536 DAC960_AcquireControllerLockRF(Controller
, &ProcessorFlags
);
1538 Process I/O Requests for Controller.
1540 DAC960_ProcessRequests(Controller
);
1542 Release exclusive access to Controller.
1544 DAC960_ReleaseControllerLockRF(Controller
, &ProcessorFlags
);
1549 DAC960_ReadWriteError prints an appropriate error message for Command when
1550 an error occurs on a Read or Write operation.
1553 static void DAC960_ReadWriteError(DAC960_Command_T
*Command
)
1555 DAC960_Controller_T
*Controller
= Command
->Controller
;
1556 char *CommandName
= "UNKNOWN";
1557 switch (Command
->CommandType
)
1559 case DAC960_ReadCommand
:
1560 case DAC960_ReadRetryCommand
:
1561 CommandName
= "READ";
1563 case DAC960_WriteCommand
:
1564 case DAC960_WriteRetryCommand
:
1565 CommandName
= "WRITE";
1567 case DAC960_MonitoringCommand
:
1568 case DAC960_ImmediateCommand
:
1569 case DAC960_QueuedCommand
:
1572 switch (Command
->CommandStatus
)
1574 case DAC960_IrrecoverableDataError
:
1575 DAC960_Error("Irrecoverable Data Error on %s:\n",
1576 Controller
, CommandName
);
1578 case DAC960_LogicalDriveNonexistentOrOffline
:
1579 DAC960_Error("Logical Drive Nonexistent or Offline on %s:\n",
1580 Controller
, CommandName
);
1582 case DAC960_AccessBeyondEndOfLogicalDrive
:
1583 DAC960_Error("Attempt to Access Beyond End of Logical Drive "
1584 "on %s:\n", Controller
, CommandName
);
1586 case DAC960_BadDataEncountered
:
1587 DAC960_Error("Bad Data Encountered on %s:\n", Controller
, CommandName
);
1590 DAC960_Error("Unexpected Error Status %04X on %s:\n",
1591 Controller
, Command
->CommandStatus
, CommandName
);
1594 DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %d..%d\n",
1595 Controller
, Controller
->ControllerNumber
,
1596 Command
->LogicalDriveNumber
, Command
->BlockNumber
,
1597 Command
->BlockNumber
+ Command
->BlockCount
- 1);
1598 if (DAC960_PartitionNumber(Command
->BufferHeader
->b_rdev
) > 0)
1599 DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
1600 Controller
, Controller
->ControllerNumber
,
1601 Command
->LogicalDriveNumber
,
1602 DAC960_PartitionNumber(Command
->BufferHeader
->b_rdev
),
1603 Command
->BufferHeader
->b_rsector
,
1604 Command
->BufferHeader
->b_rsector
+ Command
->BlockCount
- 1);
1609 DAC960_ProcessCompletedBuffer performs completion processing for an
1613 static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T
*BufferHeader
,
1614 boolean SuccessfulIO
)
1616 BufferHeader
->b_end_io(BufferHeader
, SuccessfulIO
);
1621 DAC960_ProcessCompletedCommand performs completion processing for Command.
1624 static void DAC960_ProcessCompletedCommand(DAC960_Command_T
*Command
)
1626 DAC960_Controller_T
*Controller
= Command
->Controller
;
1627 DAC960_CommandType_T CommandType
= Command
->CommandType
;
1628 DAC960_CommandOpcode_T CommandOpcode
=
1629 Command
->CommandMailbox
.Common
.CommandOpcode
;
1630 DAC960_CommandStatus_T CommandStatus
= Command
->CommandStatus
;
1631 BufferHeader_T
*BufferHeader
= Command
->BufferHeader
;
1632 if (CommandType
== DAC960_ReadCommand
||
1633 CommandType
== DAC960_WriteCommand
)
1635 if (CommandStatus
== DAC960_NormalCompletion
)
1638 Perform completion processing for all buffers in this I/O Request.
1640 while (BufferHeader
!= NULL
)
1642 BufferHeader_T
*NextBufferHeader
= BufferHeader
->b_reqnext
;
1643 BufferHeader
->b_reqnext
= NULL
;
1644 DAC960_ProcessCompletedBuffer(BufferHeader
, true);
1645 BufferHeader
= NextBufferHeader
;
1648 Wake up requestor for swap file paging requests.
1650 if (Command
->Semaphore
!= NULL
)
1652 up(Command
->Semaphore
);
1653 Command
->Semaphore
= NULL
;
1655 add_blkdev_randomness(DAC960_MAJOR
+ Controller
->ControllerNumber
);
1657 else if ((CommandStatus
== DAC960_IrrecoverableDataError
||
1658 CommandStatus
== DAC960_BadDataEncountered
) &&
1659 BufferHeader
!= NULL
&&
1660 BufferHeader
->b_reqnext
!= NULL
)
1662 DAC960_CommandMailbox_T
*CommandMailbox
= &Command
->CommandMailbox
;
1663 if (CommandType
== DAC960_ReadCommand
)
1665 Command
->CommandType
= DAC960_ReadRetryCommand
;
1666 CommandMailbox
->Type5
.CommandOpcode
= DAC960_Read
;
1670 Command
->CommandType
= DAC960_WriteRetryCommand
;
1671 CommandMailbox
->Type5
.CommandOpcode
= DAC960_Write
;
1673 Command
->BlockCount
= BufferHeader
->b_size
>> DAC960_BlockSizeBits
;
1674 CommandMailbox
->Type5
.LD
.TransferLength
= Command
->BlockCount
;
1675 CommandMailbox
->Type5
.BusAddress
=
1676 Virtual_to_Bus(BufferHeader
->b_data
);
1677 DAC960_QueueCommand(Command
);
1682 if (CommandStatus
!= DAC960_LogicalDriveNonexistentOrOffline
)
1683 DAC960_ReadWriteError(Command
);
1685 Perform completion processing for all buffers in this I/O Request.
1687 while (BufferHeader
!= NULL
)
1689 BufferHeader_T
*NextBufferHeader
= BufferHeader
->b_reqnext
;
1690 BufferHeader
->b_reqnext
= NULL
;
1691 DAC960_ProcessCompletedBuffer(BufferHeader
, false);
1692 BufferHeader
= NextBufferHeader
;
1695 Wake up requestor for swap file paging requests.
1697 if (Command
->Semaphore
!= NULL
)
1699 up(Command
->Semaphore
);
1700 Command
->Semaphore
= NULL
;
1704 else if (CommandType
== DAC960_ReadRetryCommand
||
1705 CommandType
== DAC960_WriteRetryCommand
)
1707 BufferHeader_T
*NextBufferHeader
= BufferHeader
->b_reqnext
;
1708 BufferHeader
->b_reqnext
= NULL
;
1710 Perform completion processing for this single buffer.
1712 if (CommandStatus
== DAC960_NormalCompletion
)
1713 DAC960_ProcessCompletedBuffer(BufferHeader
, true);
1716 if (CommandStatus
!= DAC960_LogicalDriveNonexistentOrOffline
)
1717 DAC960_ReadWriteError(Command
);
1718 DAC960_ProcessCompletedBuffer(BufferHeader
, false);
1720 if (NextBufferHeader
!= NULL
)
1722 DAC960_CommandMailbox_T
*CommandMailbox
= &Command
->CommandMailbox
;
1723 Command
->BlockNumber
+=
1724 BufferHeader
->b_size
>> DAC960_BlockSizeBits
;
1725 Command
->BlockCount
=
1726 NextBufferHeader
->b_size
>> DAC960_BlockSizeBits
;
1727 Command
->BufferHeader
= NextBufferHeader
;
1728 CommandMailbox
->Type5
.LD
.TransferLength
= Command
->BlockCount
;
1729 CommandMailbox
->Type5
.LogicalBlockAddress
= Command
->BlockNumber
;
1730 CommandMailbox
->Type5
.BusAddress
=
1731 Virtual_to_Bus(NextBufferHeader
->b_data
);
1732 DAC960_QueueCommand(Command
);
1736 else if (CommandType
== DAC960_MonitoringCommand
||
1737 CommandOpcode
== DAC960_Enquiry
||
1738 CommandOpcode
== DAC960_GetRebuildProgress
)
1740 if (CommandType
!= DAC960_MonitoringCommand
)
1742 if (CommandOpcode
== DAC960_Enquiry
)
1743 memcpy(&Controller
->Enquiry
[Controller
->EnquiryIndex
^ 1],
1744 Bus_to_Virtual(Command
->CommandMailbox
.Type3
.BusAddress
),
1745 sizeof(DAC960_Enquiry_T
));
1746 else if (CommandOpcode
== DAC960_GetRebuildProgress
)
1747 memcpy(&Controller
->RebuildProgress
,
1748 Bus_to_Virtual(Command
->CommandMailbox
.Type3
.BusAddress
),
1749 sizeof(DAC960_RebuildProgress_T
));
1751 if (CommandOpcode
== DAC960_Enquiry
)
1753 DAC960_Enquiry_T
*OldEnquiry
=
1754 &Controller
->Enquiry
[Controller
->EnquiryIndex
];
1755 DAC960_Enquiry_T
*NewEnquiry
=
1756 &Controller
->Enquiry
[Controller
->EnquiryIndex
^= 1];
1757 unsigned int OldCriticalLogicalDriveCount
=
1758 OldEnquiry
->CriticalLogicalDriveCount
;
1759 unsigned int NewCriticalLogicalDriveCount
=
1760 NewEnquiry
->CriticalLogicalDriveCount
;
1761 if (NewEnquiry
->StatusFlags
.DeferredWriteError
!=
1762 OldEnquiry
->StatusFlags
.DeferredWriteError
)
1763 DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller
,
1764 (NewEnquiry
->StatusFlags
.DeferredWriteError
1765 ? "TRUE" : "FALSE"));
1766 if ((NewCriticalLogicalDriveCount
> 0 ||
1767 NewCriticalLogicalDriveCount
!= OldCriticalLogicalDriveCount
) ||
1768 (NewEnquiry
->OfflineLogicalDriveCount
> 0 ||
1769 NewEnquiry
->OfflineLogicalDriveCount
!=
1770 OldEnquiry
->OfflineLogicalDriveCount
) ||
1771 (NewEnquiry
->DeadDriveCount
> 0 ||
1772 NewEnquiry
->DeadDriveCount
!=
1773 OldEnquiry
->DeadDriveCount
) ||
1774 (NewEnquiry
->EventLogSequenceNumber
!=
1775 OldEnquiry
->EventLogSequenceNumber
) ||
1776 Controller
->MonitoringTimerCount
== 0 ||
1777 (jiffies
- Controller
->SecondaryMonitoringTime
1778 >= DAC960_SecondaryMonitoringInterval
))
1780 Controller
->NeedLogicalDriveInformation
= true;
1781 Controller
->NewEventLogSequenceNumber
=
1782 NewEnquiry
->EventLogSequenceNumber
;
1783 Controller
->NeedErrorTableInformation
= true;
1784 Controller
->NeedDeviceStateInformation
= true;
1785 Controller
->DeviceStateChannel
= 0;
1786 Controller
->DeviceStateTargetID
= -1;
1787 Controller
->SecondaryMonitoringTime
= jiffies
;
1789 if (NewEnquiry
->RebuildFlag
== DAC960_StandbyRebuildInProgress
||
1790 NewEnquiry
->RebuildFlag
== DAC960_BackgroundRebuildInProgress
||
1791 OldEnquiry
->RebuildFlag
== DAC960_StandbyRebuildInProgress
||
1792 OldEnquiry
->RebuildFlag
== DAC960_BackgroundRebuildInProgress
)
1793 Controller
->NeedRebuildProgress
= true;
1794 if (OldEnquiry
->RebuildFlag
== DAC960_BackgroundCheckInProgress
)
1795 switch (NewEnquiry
->RebuildFlag
)
1797 case DAC960_NoStandbyRebuildOrCheckInProgress
:
1798 DAC960_Progress("Consistency Check Completed Successfully\n",
1801 case DAC960_StandbyRebuildInProgress
:
1802 case DAC960_BackgroundRebuildInProgress
:
1804 case DAC960_BackgroundCheckInProgress
:
1805 Controller
->NeedConsistencyCheckProgress
= true;
1807 case DAC960_StandbyRebuildCompletedWithError
:
1808 DAC960_Progress("Consistency Check Completed with Error\n",
1811 case DAC960_BackgroundRebuildOrCheckFailed_DriveFailed
:
1812 DAC960_Progress("Consistency Check Failed - "
1813 "Physical Drive Failed\n", Controller
);
1815 case DAC960_BackgroundRebuildOrCheckFailed_LogicalDriveFailed
:
1816 DAC960_Progress("Consistency Check Failed - "
1817 "Logical Drive Failed\n", Controller
);
1819 case DAC960_BackgroundRebuildOrCheckFailed_OtherCauses
:
1820 DAC960_Progress("Consistency Check Failed - Other Causes\n",
1823 case DAC960_BackgroundRebuildOrCheckSuccessfullyTerminated
:
1824 DAC960_Progress("Consistency Check Successfully Terminated\n",
1828 else if (NewEnquiry
->RebuildFlag
== DAC960_BackgroundCheckInProgress
)
1829 Controller
->NeedConsistencyCheckProgress
= true;
1831 else if (CommandOpcode
== DAC960_PerformEventLogOperation
)
1834 *DAC960_EventMessages
[] =
1835 { "killed because write recovery failed",
1836 "killed because of SCSI bus reset failure",
1837 "killed because of double check condition",
1838 "killed because it was removed",
1839 "killed because of gross error on SCSI chip",
1840 "killed because of bad tag returned from drive",
1841 "killed because of timeout on SCSI command",
1842 "killed because of reset SCSI command issued from system",
1843 "killed because busy or parity error count exceeded limit",
1844 "killed because of 'kill drive' command from system",
1845 "killed because of selection timeout",
1846 "killed due to SCSI phase sequence error",
1847 "killed due to unknown status" };
1848 DAC960_EventLogEntry_T
*EventLogEntry
= &Controller
->EventLogEntry
;
1849 if (EventLogEntry
->SequenceNumber
==
1850 Controller
->OldEventLogSequenceNumber
)
1852 unsigned char SenseKey
= EventLogEntry
->SenseKey
;
1853 unsigned char AdditionalSenseCode
=
1854 EventLogEntry
->AdditionalSenseCode
;
1855 unsigned char AdditionalSenseCodeQualifier
=
1856 EventLogEntry
->AdditionalSenseCodeQualifier
;
1857 if (SenseKey
== 9 &&
1858 AdditionalSenseCode
== 0x80 &&
1859 AdditionalSenseCodeQualifier
<
1860 sizeof(DAC960_EventMessages
) / sizeof(char *))
1861 DAC960_Critical("Physical Drive %d:%d %s\n", Controller
,
1862 EventLogEntry
->Channel
,
1863 EventLogEntry
->TargetID
,
1864 DAC960_EventMessages
[
1865 AdditionalSenseCodeQualifier
]);
1866 else if (SenseKey
== 6 && AdditionalSenseCode
== 0x29)
1868 if (Controller
->MonitoringTimerCount
> 0)
1869 Controller
->DeviceResetCount
[EventLogEntry
->Channel
]
1870 [EventLogEntry
->TargetID
]++;
1872 else if (!(SenseKey
== 0 ||
1874 AdditionalSenseCode
== 0x04 &&
1875 (AdditionalSenseCodeQualifier
== 0x01 ||
1876 AdditionalSenseCodeQualifier
== 0x02))))
1878 DAC960_Critical("Physical Drive %d:%d Error Log: "
1879 "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
1881 EventLogEntry
->Channel
,
1882 EventLogEntry
->TargetID
,
1884 AdditionalSenseCode
,
1885 AdditionalSenseCodeQualifier
);
1886 DAC960_Critical("Physical Drive %d:%d Error Log: "
1887 "Information = %02X%02X%02X%02X "
1888 "%02X%02X%02X%02X\n",
1890 EventLogEntry
->Channel
,
1891 EventLogEntry
->TargetID
,
1892 EventLogEntry
->Information
[0],
1893 EventLogEntry
->Information
[1],
1894 EventLogEntry
->Information
[2],
1895 EventLogEntry
->Information
[3],
1896 EventLogEntry
->CommandSpecificInformation
[0],
1897 EventLogEntry
->CommandSpecificInformation
[1],
1898 EventLogEntry
->CommandSpecificInformation
[2],
1899 EventLogEntry
->CommandSpecificInformation
[3]);
1902 Controller
->OldEventLogSequenceNumber
++;
1904 else if (CommandOpcode
== DAC960_GetErrorTable
)
1906 DAC960_ErrorTable_T
*OldErrorTable
=
1907 &Controller
->ErrorTable
[Controller
->ErrorTableIndex
];
1908 DAC960_ErrorTable_T
*NewErrorTable
=
1909 &Controller
->ErrorTable
[Controller
->ErrorTableIndex
^= 1];
1910 int Channel
, TargetID
;
1911 for (Channel
= 0; Channel
< Controller
->Channels
; Channel
++)
1912 for (TargetID
= 0; TargetID
< DAC960_MaxTargets
; TargetID
++)
1914 DAC960_ErrorTableEntry_T
*NewErrorEntry
=
1915 &NewErrorTable
->ErrorTableEntries
[Channel
][TargetID
];
1916 DAC960_ErrorTableEntry_T
*OldErrorEntry
=
1917 &OldErrorTable
->ErrorTableEntries
[Channel
][TargetID
];
1918 if ((NewErrorEntry
->ParityErrorCount
!=
1919 OldErrorEntry
->ParityErrorCount
) ||
1920 (NewErrorEntry
->SoftErrorCount
!=
1921 OldErrorEntry
->SoftErrorCount
) ||
1922 (NewErrorEntry
->HardErrorCount
!=
1923 OldErrorEntry
->HardErrorCount
) ||
1924 (NewErrorEntry
->MiscErrorCount
!=
1925 OldErrorEntry
->MiscErrorCount
))
1926 DAC960_Critical("Physical Drive %d:%d Errors: "
1927 "Parity = %d, Soft = %d, "
1928 "Hard = %d, Misc = %d\n",
1929 Controller
, Channel
, TargetID
,
1930 NewErrorEntry
->ParityErrorCount
,
1931 NewErrorEntry
->SoftErrorCount
,
1932 NewErrorEntry
->HardErrorCount
,
1933 NewErrorEntry
->MiscErrorCount
);
1936 else if (CommandOpcode
== DAC960_GetDeviceState
)
1938 DAC960_DeviceState_T
*OldDeviceState
=
1939 &Controller
->DeviceState
[Controller
->DeviceStateIndex
]
1940 [Controller
->DeviceStateChannel
]
1941 [Controller
->DeviceStateTargetID
];
1942 DAC960_DeviceState_T
*NewDeviceState
=
1943 &Controller
->DeviceState
[Controller
->DeviceStateIndex
^ 1]
1944 [Controller
->DeviceStateChannel
]
1945 [Controller
->DeviceStateTargetID
];
1946 if (NewDeviceState
->DeviceState
!= OldDeviceState
->DeviceState
)
1947 DAC960_Critical("Physical Drive %d:%d is now %s\n", Controller
,
1948 Controller
->DeviceStateChannel
,
1949 Controller
->DeviceStateTargetID
,
1950 (NewDeviceState
->DeviceState
== DAC960_Device_Dead
1952 : NewDeviceState
->DeviceState
1953 == DAC960_Device_WriteOnly
1955 : NewDeviceState
->DeviceState
1956 == DAC960_Device_Online
1957 ? "ONLINE" : "STANDBY"));
1958 if (OldDeviceState
->DeviceState
== DAC960_Device_Dead
&&
1959 NewDeviceState
->DeviceState
!= DAC960_Device_Dead
)
1961 Controller
->NeedDeviceInquiryInformation
= true;
1962 Controller
->NeedDeviceSerialNumberInformation
= true;
1965 else if (CommandOpcode
== DAC960_GetLogicalDriveInformation
)
1967 int LogicalDriveNumber
;
1968 for (LogicalDriveNumber
= 0;
1969 LogicalDriveNumber
< Controller
->LogicalDriveCount
;
1970 LogicalDriveNumber
++)
1972 DAC960_LogicalDriveInformation_T
*OldLogicalDriveInformation
=
1973 &Controller
->LogicalDriveInformation
1974 [Controller
->LogicalDriveInformationIndex
]
1975 [LogicalDriveNumber
];
1976 DAC960_LogicalDriveInformation_T
*NewLogicalDriveInformation
=
1977 &Controller
->LogicalDriveInformation
1978 [Controller
->LogicalDriveInformationIndex
^ 1]
1979 [LogicalDriveNumber
];
1980 if (NewLogicalDriveInformation
->LogicalDriveState
!=
1981 OldLogicalDriveInformation
->LogicalDriveState
)
1982 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
1983 "is now %s\n", Controller
,
1985 Controller
->ControllerNumber
,
1987 (NewLogicalDriveInformation
->LogicalDriveState
1988 == DAC960_LogicalDrive_Online
1990 : NewLogicalDriveInformation
->LogicalDriveState
1991 == DAC960_LogicalDrive_Critical
1992 ? "CRITICAL" : "OFFLINE"));
1993 if (NewLogicalDriveInformation
->WriteBack
!=
1994 OldLogicalDriveInformation
->WriteBack
)
1995 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
1996 "is now %s\n", Controller
,
1998 Controller
->ControllerNumber
,
2000 (NewLogicalDriveInformation
->WriteBack
2001 ? "WRITE BACK" : "WRITE THRU"));
2003 Controller
->LogicalDriveInformationIndex
^= 1;
2005 else if (CommandOpcode
== DAC960_GetRebuildProgress
)
2007 unsigned int LogicalDriveNumber
=
2008 Controller
->RebuildProgress
.LogicalDriveNumber
;
2009 unsigned int LogicalDriveSize
=
2010 Controller
->RebuildProgress
.LogicalDriveSize
;
2011 unsigned int BlocksCompleted
=
2012 LogicalDriveSize
- Controller
->RebuildProgress
.RemainingBlocks
;
2013 switch (CommandStatus
)
2015 case DAC960_NormalCompletion
:
2016 Controller
->EphemeralProgressMessage
= true;
2017 DAC960_Progress("Rebuild in Progress: "
2018 "Logical Drive %d (/dev/rd/c%dd%d) "
2020 Controller
, LogicalDriveNumber
,
2021 Controller
->ControllerNumber
,
2023 (100 * (BlocksCompleted
>> 7))
2024 / (LogicalDriveSize
>> 7));
2025 Controller
->EphemeralProgressMessage
= false;
2027 case DAC960_RebuildFailed_LogicalDriveFailure
:
2028 DAC960_Progress("Rebuild Failed due to "
2029 "Logical Drive Failure\n", Controller
);
2031 case DAC960_RebuildFailed_BadBlocksOnOther
:
2032 DAC960_Progress("Rebuild Failed due to "
2033 "Bad Blocks on Other Drives\n", Controller
);
2035 case DAC960_RebuildFailed_NewDriveFailed
:
2036 DAC960_Progress("Rebuild Failed due to "
2037 "Failure of Drive Being Rebuilt\n", Controller
);
2039 case DAC960_NoRebuildOrCheckInProgress
:
2040 if (Controller
->LastRebuildStatus
!= DAC960_NormalCompletion
)
2042 case DAC960_RebuildSuccessful
:
2043 DAC960_Progress("Rebuild Completed Successfully\n", Controller
);
2046 Controller
->LastRebuildStatus
= CommandStatus
;
2048 else if (CommandOpcode
== DAC960_RebuildStat
)
2050 unsigned int LogicalDriveNumber
=
2051 Controller
->RebuildProgress
.LogicalDriveNumber
;
2052 unsigned int LogicalDriveSize
=
2053 Controller
->RebuildProgress
.LogicalDriveSize
;
2054 unsigned int BlocksCompleted
=
2055 LogicalDriveSize
- Controller
->RebuildProgress
.RemainingBlocks
;
2056 if (CommandStatus
== DAC960_NormalCompletion
)
2058 Controller
->EphemeralProgressMessage
= true;
2059 DAC960_Progress("Consistency Check in Progress: "
2060 "Logical Drive %d (/dev/rd/c%dd%d) "
2062 Controller
, LogicalDriveNumber
,
2063 Controller
->ControllerNumber
,
2065 (100 * (BlocksCompleted
>> 7))
2066 / (LogicalDriveSize
>> 7));
2067 Controller
->EphemeralProgressMessage
= false;
2071 if (CommandType
== DAC960_MonitoringCommand
)
2073 if (Controller
->NewEventLogSequenceNumber
2074 - Controller
->OldEventLogSequenceNumber
> 0)
2076 Command
->CommandMailbox
.Type3E
.CommandOpcode
=
2077 DAC960_PerformEventLogOperation
;
2078 Command
->CommandMailbox
.Type3E
.OperationType
=
2079 DAC960_GetEventLogEntry
;
2080 Command
->CommandMailbox
.Type3E
.OperationQualifier
= 1;
2081 Command
->CommandMailbox
.Type3E
.SequenceNumber
=
2082 Controller
->OldEventLogSequenceNumber
;
2083 Command
->CommandMailbox
.Type3E
.BusAddress
=
2084 Virtual_to_Bus(&Controller
->EventLogEntry
);
2085 DAC960_QueueCommand(Command
);
2088 if (Controller
->NeedErrorTableInformation
)
2090 Controller
->NeedErrorTableInformation
= false;
2091 Command
->CommandMailbox
.Type3
.CommandOpcode
= DAC960_GetErrorTable
;
2092 Command
->CommandMailbox
.Type3
.BusAddress
=
2094 &Controller
->ErrorTable
[Controller
->ErrorTableIndex
^ 1]);
2095 DAC960_QueueCommand(Command
);
2098 if (Controller
->NeedRebuildProgress
&&
2099 Controller
->Enquiry
[Controller
->EnquiryIndex
]
2100 .CriticalLogicalDriveCount
<
2101 Controller
->Enquiry
[Controller
->EnquiryIndex
^ 1]
2102 .CriticalLogicalDriveCount
)
2104 Controller
->NeedRebuildProgress
= false;
2105 Command
->CommandMailbox
.Type3
.CommandOpcode
=
2106 DAC960_GetRebuildProgress
;
2107 Command
->CommandMailbox
.Type3
.BusAddress
=
2108 Virtual_to_Bus(&Controller
->RebuildProgress
);
2109 DAC960_QueueCommand(Command
);
2112 if (Controller
->NeedDeviceStateInformation
)
2114 if (Controller
->NeedDeviceInquiryInformation
)
2116 DAC960_DCDB_T
*DCDB
= &Controller
->MonitoringDCDB
;
2117 DAC960_SCSI_Inquiry_T
*InquiryStandardData
=
2118 &Controller
->InquiryStandardData
2119 [Controller
->DeviceStateChannel
]
2120 [Controller
->DeviceStateTargetID
];
2121 InquiryStandardData
->PeripheralDeviceType
= 0x1F;
2122 Command
->CommandMailbox
.Type3
.CommandOpcode
= DAC960_DCDB
;
2123 Command
->CommandMailbox
.Type3
.BusAddress
= Virtual_to_Bus(DCDB
);
2124 DCDB
->Channel
= Controller
->DeviceStateChannel
;
2125 DCDB
->TargetID
= Controller
->DeviceStateTargetID
;
2126 DCDB
->Direction
= DAC960_DCDB_DataTransferDeviceToSystem
;
2127 DCDB
->EarlyStatus
= false;
2128 DCDB
->Timeout
= DAC960_DCDB_Timeout_10_seconds
;
2129 DCDB
->NoAutomaticRequestSense
= false;
2130 DCDB
->DisconnectPermitted
= true;
2131 DCDB
->TransferLength
= sizeof(DAC960_SCSI_Inquiry_T
);
2132 DCDB
->BusAddress
= Virtual_to_Bus(InquiryStandardData
);
2133 DCDB
->CDBLength
= 6;
2134 DCDB
->TransferLengthHigh4
= 0;
2135 DCDB
->SenseLength
= sizeof(DCDB
->SenseData
);
2136 DCDB
->CDB
[0] = 0x12; /* INQUIRY */
2137 DCDB
->CDB
[1] = 0; /* EVPD = 0 */
2138 DCDB
->CDB
[2] = 0; /* Page Code */
2139 DCDB
->CDB
[3] = 0; /* Reserved */
2140 DCDB
->CDB
[4] = sizeof(DAC960_SCSI_Inquiry_T
);
2141 DCDB
->CDB
[5] = 0; /* Control */
2142 DAC960_QueueCommand(Command
);
2143 Controller
->NeedDeviceInquiryInformation
= false;
2146 if (Controller
->NeedDeviceSerialNumberInformation
)
2148 DAC960_DCDB_T
*DCDB
= &Controller
->MonitoringDCDB
;
2149 DAC960_SCSI_Inquiry_UnitSerialNumber_T
*InquiryUnitSerialNumber
=
2150 &Controller
->InquiryUnitSerialNumber
2151 [Controller
->DeviceStateChannel
]
2152 [Controller
->DeviceStateTargetID
];
2153 InquiryUnitSerialNumber
->PeripheralDeviceType
= 0x1F;
2154 Command
->CommandMailbox
.Type3
.CommandOpcode
= DAC960_DCDB
;
2155 Command
->CommandMailbox
.Type3
.BusAddress
= Virtual_to_Bus(DCDB
);
2156 DCDB
->Channel
= Controller
->DeviceStateChannel
;
2157 DCDB
->TargetID
= Controller
->DeviceStateTargetID
;
2158 DCDB
->Direction
= DAC960_DCDB_DataTransferDeviceToSystem
;
2159 DCDB
->EarlyStatus
= false;
2160 DCDB
->Timeout
= DAC960_DCDB_Timeout_10_seconds
;
2161 DCDB
->NoAutomaticRequestSense
= false;
2162 DCDB
->DisconnectPermitted
= true;
2163 DCDB
->TransferLength
=
2164 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T
);
2165 DCDB
->BusAddress
= Virtual_to_Bus(InquiryUnitSerialNumber
);
2166 DCDB
->CDBLength
= 6;
2167 DCDB
->TransferLengthHigh4
= 0;
2168 DCDB
->SenseLength
= sizeof(DCDB
->SenseData
);
2169 DCDB
->CDB
[0] = 0x12; /* INQUIRY */
2170 DCDB
->CDB
[1] = 1; /* EVPD = 1 */
2171 DCDB
->CDB
[2] = 0x80; /* Page Code */
2172 DCDB
->CDB
[3] = 0; /* Reserved */
2173 DCDB
->CDB
[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T
);
2174 DCDB
->CDB
[5] = 0; /* Control */
2175 DAC960_QueueCommand(Command
);
2176 Controller
->NeedDeviceSerialNumberInformation
= false;
2179 if (++Controller
->DeviceStateTargetID
== DAC960_MaxTargets
)
2181 Controller
->DeviceStateChannel
++;
2182 Controller
->DeviceStateTargetID
= 0;
2184 while (Controller
->DeviceStateChannel
< Controller
->Channels
)
2186 DAC960_DeviceState_T
*OldDeviceState
=
2187 &Controller
->DeviceState
[Controller
->DeviceStateIndex
]
2188 [Controller
->DeviceStateChannel
]
2189 [Controller
->DeviceStateTargetID
];
2190 if (OldDeviceState
->Present
&&
2191 OldDeviceState
->DeviceType
== DAC960_DiskType
)
2193 Command
->CommandMailbox
.Type3D
.CommandOpcode
=
2194 DAC960_GetDeviceState
;
2195 Command
->CommandMailbox
.Type3D
.Channel
=
2196 Controller
->DeviceStateChannel
;
2197 Command
->CommandMailbox
.Type3D
.TargetID
=
2198 Controller
->DeviceStateTargetID
;
2199 Command
->CommandMailbox
.Type3D
.BusAddress
=
2200 Virtual_to_Bus(&Controller
->DeviceState
2201 [Controller
->DeviceStateIndex
^ 1]
2202 [Controller
->DeviceStateChannel
]
2203 [Controller
->DeviceStateTargetID
]);
2204 DAC960_QueueCommand(Command
);
2207 if (++Controller
->DeviceStateTargetID
== DAC960_MaxTargets
)
2209 Controller
->DeviceStateChannel
++;
2210 Controller
->DeviceStateTargetID
= 0;
2213 Controller
->NeedDeviceStateInformation
= false;
2214 Controller
->DeviceStateIndex
^= 1;
2216 if (Controller
->NeedLogicalDriveInformation
)
2218 Controller
->NeedLogicalDriveInformation
= false;
2219 Command
->CommandMailbox
.Type3
.CommandOpcode
=
2220 DAC960_GetLogicalDriveInformation
;
2221 Command
->CommandMailbox
.Type3
.BusAddress
=
2223 &Controller
->LogicalDriveInformation
2224 [Controller
->LogicalDriveInformationIndex
^ 1]);
2225 DAC960_QueueCommand(Command
);
2228 if (Controller
->NeedRebuildProgress
)
2230 Controller
->NeedRebuildProgress
= false;
2231 Command
->CommandMailbox
.Type3
.CommandOpcode
=
2232 DAC960_GetRebuildProgress
;
2233 Command
->CommandMailbox
.Type3
.BusAddress
=
2234 Virtual_to_Bus(&Controller
->RebuildProgress
);
2235 DAC960_QueueCommand(Command
);
2238 if (Controller
->NeedConsistencyCheckProgress
)
2240 Controller
->NeedConsistencyCheckProgress
= false;
2241 Command
->CommandMailbox
.Type3
.CommandOpcode
= DAC960_RebuildStat
;
2242 Command
->CommandMailbox
.Type3
.BusAddress
=
2243 Virtual_to_Bus(&Controller
->RebuildProgress
);
2244 DAC960_QueueCommand(Command
);
2247 Controller
->MonitoringTimerCount
++;
2248 Controller
->MonitoringTimer
.expires
=
2249 jiffies
+ DAC960_MonitoringTimerInterval
;
2250 add_timer(&Controller
->MonitoringTimer
);
2252 if (CommandType
== DAC960_ImmediateCommand
)
2254 up(Command
->Semaphore
);
2255 Command
->Semaphore
= NULL
;
2258 if (CommandType
== DAC960_QueuedCommand
)
2260 DAC960_KernelCommand_T
*KernelCommand
= Command
->KernelCommand
;
2261 KernelCommand
->CommandStatus
= CommandStatus
;
2262 Command
->KernelCommand
= NULL
;
2263 if (CommandOpcode
== DAC960_DCDB
)
2264 Controller
->DirectCommandActive
[KernelCommand
->DCDB
->Channel
]
2265 [KernelCommand
->DCDB
->TargetID
] = false;
2266 DAC960_DeallocateCommand(Command
);
2267 KernelCommand
->CompletionFunction(KernelCommand
);
2271 Queue a Status Monitoring Command to the Controller using the just
2272 completed Command if one was deferred previously due to lack of a
2273 free Command when the Monitoring Timer Function was called.
2275 if (Controller
->MonitoringCommandDeferred
)
2277 Controller
->MonitoringCommandDeferred
= false;
2278 DAC960_QueueMonitoringCommand(Command
);
2282 Deallocate the Command, and wake up any processes waiting on a free Command.
2284 DAC960_DeallocateCommand(Command
);
2285 wake_up(&Controller
->CommandWaitQueue
);
2290 DAC960_InterruptHandler handles hardware interrupts from DAC960 Controllers.
2293 static void DAC960_InterruptHandler(int IRQ_Channel
,
2294 void *DeviceIdentifier
,
2295 Registers_T
*InterruptRegisters
)
2297 DAC960_Controller_T
*Controller
= (DAC960_Controller_T
*) DeviceIdentifier
;
2298 void *ControllerBaseAddress
= Controller
->BaseAddress
;
2299 DAC960_StatusMailbox_T
*NextStatusMailbox
;
2300 ProcessorFlags_T ProcessorFlags
;
2302 Acquire exclusive access to Controller.
2304 DAC960_AcquireControllerLockIH(Controller
, &ProcessorFlags
);
2306 Process Hardware Interrupts for Controller.
2308 switch (Controller
->ControllerType
)
2310 case DAC960_V5_Controller
:
2311 DAC960_V5_AcknowledgeInterrupt(ControllerBaseAddress
);
2312 NextStatusMailbox
= Controller
->NextStatusMailbox
;
2313 while (NextStatusMailbox
->Fields
.Valid
)
2315 DAC960_CommandIdentifier_T CommandIdentifier
=
2316 NextStatusMailbox
->Fields
.CommandIdentifier
;
2317 DAC960_Command_T
*Command
= &Controller
->Commands
[CommandIdentifier
];
2318 Command
->CommandStatus
= NextStatusMailbox
->Fields
.CommandStatus
;
2319 NextStatusMailbox
->Word
= 0;
2320 if (++NextStatusMailbox
> Controller
->LastStatusMailbox
)
2321 NextStatusMailbox
= Controller
->FirstStatusMailbox
;
2322 DAC960_ProcessCompletedCommand(Command
);
2324 Controller
->NextStatusMailbox
= NextStatusMailbox
;
2326 case DAC960_V4_Controller
:
2327 DAC960_V4_AcknowledgeInterrupt(ControllerBaseAddress
);
2328 NextStatusMailbox
= Controller
->NextStatusMailbox
;
2329 while (NextStatusMailbox
->Fields
.Valid
)
2331 DAC960_CommandIdentifier_T CommandIdentifier
=
2332 NextStatusMailbox
->Fields
.CommandIdentifier
;
2333 DAC960_Command_T
*Command
= &Controller
->Commands
[CommandIdentifier
];
2334 Command
->CommandStatus
= NextStatusMailbox
->Fields
.CommandStatus
;
2335 NextStatusMailbox
->Word
= 0;
2336 if (++NextStatusMailbox
> Controller
->LastStatusMailbox
)
2337 NextStatusMailbox
= Controller
->FirstStatusMailbox
;
2338 DAC960_ProcessCompletedCommand(Command
);
2340 Controller
->NextStatusMailbox
= NextStatusMailbox
;
2342 case DAC960_V3_Controller
:
2343 while (DAC960_V3_StatusAvailableP(ControllerBaseAddress
))
2345 DAC960_CommandIdentifier_T CommandIdentifier
=
2346 DAC960_V3_ReadStatusCommandIdentifier(ControllerBaseAddress
);
2347 DAC960_Command_T
*Command
= &Controller
->Commands
[CommandIdentifier
];
2348 Command
->CommandStatus
=
2349 DAC960_V3_ReadStatusRegister(ControllerBaseAddress
);
2350 DAC960_V3_AcknowledgeInterrupt(ControllerBaseAddress
);
2351 DAC960_V3_AcknowledgeStatus(ControllerBaseAddress
);
2352 DAC960_ProcessCompletedCommand(Command
);
2357 Attempt to remove additional I/O Requests from the Controller's
2358 I/O Request Queue and queue them to the Controller.
2360 while (DAC960_ProcessRequest(Controller
, false)) ;
2362 Release exclusive access to Controller.
2364 DAC960_ReleaseControllerLockIH(Controller
, &ProcessorFlags
);
2369 DAC960_QueueMonitoringCommand queues a Monitoring Command to Controller.
2372 static void DAC960_QueueMonitoringCommand(DAC960_Command_T
*Command
)
2374 DAC960_Controller_T
*Controller
= Command
->Controller
;
2375 DAC960_CommandMailbox_T
*CommandMailbox
= &Command
->CommandMailbox
;
2376 DAC960_ClearCommand(Command
);
2377 Command
->CommandType
= DAC960_MonitoringCommand
;
2378 CommandMailbox
->Type3
.CommandOpcode
= DAC960_Enquiry
;
2379 CommandMailbox
->Type3
.BusAddress
=
2380 Virtual_to_Bus(&Controller
->Enquiry
[Controller
->EnquiryIndex
^ 1]);
2381 DAC960_QueueCommand(Command
);
2386 DAC960_MonitoringTimerFunction is the timer function for monitoring
2387 the status of DAC960 Controllers.
2390 static void DAC960_MonitoringTimerFunction(unsigned long TimerData
)
2392 DAC960_Controller_T
*Controller
= (DAC960_Controller_T
*) TimerData
;
2393 DAC960_Command_T
*Command
;
2394 ProcessorFlags_T ProcessorFlags
;
2396 Acquire exclusive access to Controller.
2398 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
2400 Queue a Status Monitoring Command to Controller.
2402 Command
= DAC960_AllocateCommand(Controller
);
2403 if (Command
!= NULL
)
2404 DAC960_QueueMonitoringCommand(Command
);
2405 else Controller
->MonitoringCommandDeferred
= true;
2407 Release exclusive access to Controller.
2409 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
2414 DAC960_Open is the Device Open Function for the DAC960 Driver.
2417 static int DAC960_Open(Inode_T
*Inode
, File_T
*File
)
2419 int ControllerNumber
= DAC960_ControllerNumber(Inode
->i_rdev
);
2420 int LogicalDriveNumber
= DAC960_LogicalDriveNumber(Inode
->i_rdev
);
2421 DAC960_Controller_T
*Controller
;
2422 if (ControllerNumber
== 0 && LogicalDriveNumber
== 0 &&
2423 (File
->f_flags
& O_NONBLOCK
))
2425 if (ControllerNumber
< 0 || ControllerNumber
> DAC960_ControllerCount
- 1)
2427 Controller
= DAC960_Controllers
[ControllerNumber
];
2428 if (Controller
== NULL
||
2429 LogicalDriveNumber
> Controller
->LogicalDriveCount
- 1)
2431 if (Controller
->LogicalDriveInformation
2432 [Controller
->LogicalDriveInformationIndex
]
2433 [LogicalDriveNumber
].LogicalDriveState
2434 == DAC960_LogicalDrive_Offline
)
2436 if (Controller
->LogicalDriveInitialState
[LogicalDriveNumber
]
2437 == DAC960_LogicalDrive_Offline
)
2439 Controller
->LogicalDriveInitialState
[LogicalDriveNumber
] =
2440 DAC960_LogicalDrive_Online
;
2441 DAC960_InitializeGenericDiskInfo(&Controller
->GenericDiskInfo
);
2442 resetup_one_dev(&Controller
->GenericDiskInfo
, LogicalDriveNumber
);
2444 if (Controller
->GenericDiskInfo
.sizes
[MINOR(Inode
->i_rdev
)] == 0)
2447 Increment Controller and Logical Drive Usage Counts.
2449 Controller
->ControllerUsageCount
++;
2450 Controller
->LogicalDriveUsageCount
[LogicalDriveNumber
]++;
2458 DAC960_Release is the Device Release Function for the DAC960 Driver.
2461 static int DAC960_Release(Inode_T
*Inode
, File_T
*File
)
2463 int ControllerNumber
= DAC960_ControllerNumber(Inode
->i_rdev
);
2464 int LogicalDriveNumber
= DAC960_LogicalDriveNumber(Inode
->i_rdev
);
2465 DAC960_Controller_T
*Controller
= DAC960_Controllers
[ControllerNumber
];
2466 if (ControllerNumber
== 0 && LogicalDriveNumber
== 0 &&
2467 File
!= NULL
&& (File
->f_flags
& O_NONBLOCK
))
2470 Decrement the Logical Drive and Controller Usage Counts.
2472 Controller
->LogicalDriveUsageCount
[LogicalDriveNumber
]--;
2473 Controller
->ControllerUsageCount
--;
2481 DAC960_IOCTL is the Device IOCTL Function for the DAC960 Driver.
2484 static int DAC960_IOCTL(Inode_T
*Inode
, File_T
*File
,
2485 unsigned int Request
, unsigned long Argument
)
2487 int ControllerNumber
= DAC960_ControllerNumber(Inode
->i_rdev
);
2488 int LogicalDriveNumber
= DAC960_LogicalDriveNumber(Inode
->i_rdev
);
2489 DiskGeometry_T Geometry
, *UserGeometry
;
2490 DAC960_Controller_T
*Controller
;
2491 int PartitionNumber
;
2492 if (File
->f_flags
& O_NONBLOCK
)
2493 return DAC960_UserIOCTL(Inode
, File
, Request
, Argument
);
2494 if (ControllerNumber
< 0 || ControllerNumber
> DAC960_ControllerCount
- 1)
2496 Controller
= DAC960_Controllers
[ControllerNumber
];
2497 if (Controller
== NULL
||
2498 LogicalDriveNumber
> Controller
->LogicalDriveCount
- 1)
2503 /* Get BIOS Disk Geometry. */
2504 UserGeometry
= (DiskGeometry_T
*) Argument
;
2505 if (UserGeometry
== NULL
) return -EINVAL
;
2506 Geometry
.heads
= Controller
->GeometryTranslationHeads
;
2507 Geometry
.sectors
= Controller
->GeometryTranslationSectors
;
2508 Geometry
.cylinders
=
2509 Controller
->LogicalDriveInformation
2510 [Controller
->LogicalDriveInformationIndex
]
2511 [LogicalDriveNumber
].LogicalDriveSize
2512 / (Controller
->GeometryTranslationHeads
*
2513 Controller
->GeometryTranslationSectors
);
2514 Geometry
.start
= Controller
->GenericDiskInfo
.part
[MINOR(Inode
->i_rdev
)]
2516 return copy_to_user(UserGeometry
, &Geometry
, sizeof(DiskGeometry_T
));
2518 /* Get Device Size. */
2519 if ((long *) Argument
== NULL
) return -EINVAL
;
2520 return put_user(Controller
->GenericDiskInfo
.part
[MINOR(Inode
->i_rdev
)]
2524 /* Get Read-Ahead. */
2525 if ((int *) Argument
== NULL
) return -EINVAL
;
2526 return put_user(read_ahead
[MAJOR(Inode
->i_rdev
)], (int *) Argument
);
2528 /* Set Read-Ahead. */
2529 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
2530 if (Argument
> 256) return -EINVAL
;
2531 read_ahead
[MAJOR(Inode
->i_rdev
)] = Argument
;
2534 /* Flush Buffers. */
2535 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
2536 fsync_dev(Inode
->i_rdev
);
2537 invalidate_buffers(Inode
->i_rdev
);
2540 /* Re-Read Partition Table. */
2541 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
2542 if (Controller
->LogicalDriveUsageCount
[LogicalDriveNumber
] > 1)
2544 for (PartitionNumber
= 0;
2545 PartitionNumber
< DAC960_MaxPartitions
;
2548 KernelDevice_T Device
= DAC960_KernelDevice(ControllerNumber
,
2551 int MinorNumber
= DAC960_MinorNumber(LogicalDriveNumber
,
2553 SuperBlock_T
*SuperBlock
= get_super(Device
);
2554 if (Controller
->GenericDiskInfo
.part
[MinorNumber
].nr_sects
== 0)
2557 Flush all changes and invalidate buffered state.
2560 if (SuperBlock
!= NULL
)
2561 invalidate_inodes(SuperBlock
);
2562 invalidate_buffers(Device
);
2564 Clear existing partition sizes.
2566 if (PartitionNumber
> 0)
2568 Controller
->GenericDiskInfo
.part
[MinorNumber
].start_sect
= 0;
2569 Controller
->GenericDiskInfo
.part
[MinorNumber
].nr_sects
= 0;
2572 Reset the Block Size so that the partition table can be read.
2574 set_blocksize(Device
, BLOCK_SIZE
);
2576 resetup_one_dev(&Controller
->GenericDiskInfo
, LogicalDriveNumber
);
2584 DAC960_UserIOCTL is the User IOCTL Function for the DAC960 Driver.
2587 static int DAC960_UserIOCTL(Inode_T
*Inode
, File_T
*File
,
2588 unsigned int Request
, unsigned long Argument
)
2591 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
2594 case DAC960_IOCTL_GET_CONTROLLER_COUNT
:
2595 return DAC960_ControllerCount
;
2596 case DAC960_IOCTL_GET_CONTROLLER_INFO
:
2598 DAC960_ControllerInfo_T
*UserSpaceControllerInfo
=
2599 (DAC960_ControllerInfo_T
*) Argument
;
2600 DAC960_ControllerInfo_T ControllerInfo
;
2601 DAC960_Controller_T
*Controller
;
2602 int ControllerNumber
;
2603 if (UserSpaceControllerInfo
== NULL
) return -EINVAL
;
2604 ErrorCode
= get_user(ControllerNumber
,
2605 &UserSpaceControllerInfo
->ControllerNumber
);
2606 if (ErrorCode
!= 0) return ErrorCode
;
2607 if (ControllerNumber
< 0 ||
2608 ControllerNumber
> DAC960_ControllerCount
- 1)
2610 Controller
= DAC960_Controllers
[ControllerNumber
];
2611 if (Controller
== NULL
)
2613 memset(&ControllerInfo
, 0, sizeof(DAC960_ControllerInfo_T
));
2614 ControllerInfo
.ControllerNumber
= ControllerNumber
;
2615 ControllerInfo
.PCI_Bus
= Controller
->Bus
;
2616 ControllerInfo
.PCI_Device
= Controller
->Device
;
2617 ControllerInfo
.PCI_Function
= Controller
->Function
;
2618 ControllerInfo
.IRQ_Channel
= Controller
->IRQ_Channel
;
2619 ControllerInfo
.Channels
= Controller
->Channels
;
2620 ControllerInfo
.PCI_Address
= Controller
->PCI_Address
;
2621 strcpy(ControllerInfo
.ModelName
, Controller
->ModelName
);
2622 strcpy(ControllerInfo
.FirmwareVersion
, Controller
->FirmwareVersion
);
2623 return copy_to_user(UserSpaceControllerInfo
, &ControllerInfo
,
2624 sizeof(DAC960_ControllerInfo_T
));
2626 case DAC960_IOCTL_EXECUTE_COMMAND
:
2628 DAC960_UserCommand_T
*UserSpaceUserCommand
=
2629 (DAC960_UserCommand_T
*) Argument
;
2630 DAC960_UserCommand_T UserCommand
;
2631 DAC960_Controller_T
*Controller
;
2632 DAC960_Command_T
*Command
= NULL
;
2633 DAC960_CommandOpcode_T CommandOpcode
;
2634 DAC960_CommandStatus_T CommandStatus
;
2636 ProcessorFlags_T ProcessorFlags
;
2637 int ControllerNumber
, DataTransferLength
;
2638 unsigned char *DataTransferBuffer
= NULL
;
2639 if (UserSpaceUserCommand
== NULL
) return -EINVAL
;
2640 ErrorCode
= copy_from_user(&UserCommand
, UserSpaceUserCommand
,
2641 sizeof(DAC960_UserCommand_T
));
2642 if (ErrorCode
!= 0) goto Failure
;
2643 ControllerNumber
= UserCommand
.ControllerNumber
;
2644 if (ControllerNumber
< 0 ||
2645 ControllerNumber
> DAC960_ControllerCount
- 1)
2647 Controller
= DAC960_Controllers
[ControllerNumber
];
2648 if (Controller
== NULL
)
2650 CommandOpcode
= UserCommand
.CommandMailbox
.Common
.CommandOpcode
;
2651 DataTransferLength
= UserCommand
.DataTransferLength
;
2652 if (CommandOpcode
& 0x80) return -EINVAL
;
2653 if (CommandOpcode
== DAC960_DCDB
)
2656 copy_from_user(&DCDB
, UserCommand
.DCDB
, sizeof(DAC960_DCDB_T
));
2657 if (ErrorCode
!= 0) goto Failure
;
2658 if (!((DataTransferLength
== 0 &&
2659 DCDB
.Direction
== DAC960_DCDB_NoDataTransfer
) ||
2660 (DataTransferLength
> 0 &&
2661 DCDB
.Direction
== DAC960_DCDB_DataTransferDeviceToSystem
) ||
2662 (DataTransferLength
< 0 &&
2663 DCDB
.Direction
== DAC960_DCDB_DataTransferSystemToDevice
)))
2665 if (((DCDB
.TransferLengthHigh4
<< 16) | DCDB
.TransferLength
)
2666 != abs(DataTransferLength
))
2669 if (DataTransferLength
> 0)
2671 DataTransferBuffer
= kmalloc(DataTransferLength
, GFP_KERNEL
);
2672 if (DataTransferBuffer
== NULL
) return -ENOMEM
;
2673 memset(DataTransferBuffer
, 0, DataTransferLength
);
2675 else if (DataTransferLength
< 0)
2677 DataTransferBuffer
= kmalloc(-DataTransferLength
, GFP_KERNEL
);
2678 if (DataTransferBuffer
== NULL
) return -ENOMEM
;
2679 ErrorCode
= copy_from_user(DataTransferBuffer
,
2680 UserCommand
.DataTransferBuffer
,
2681 -DataTransferLength
);
2682 if (ErrorCode
!= 0) goto Failure
;
2684 if (CommandOpcode
== DAC960_DCDB
)
2688 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
2689 if (!Controller
->DirectCommandActive
[DCDB
.Channel
]
2691 Command
= DAC960_AllocateCommand(Controller
);
2692 if (Command
!= NULL
)
2693 Controller
->DirectCommandActive
[DCDB
.Channel
]
2694 [DCDB
.TargetID
] = true;
2695 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
2696 if (Command
!= NULL
) break;
2697 sleep_on(&Controller
->CommandWaitQueue
);
2699 DAC960_ClearCommand(Command
);
2700 Command
->CommandType
= DAC960_ImmediateCommand
;
2701 memcpy(&Command
->CommandMailbox
, &UserCommand
.CommandMailbox
,
2702 sizeof(DAC960_CommandMailbox_T
));
2703 Command
->CommandMailbox
.Type3
.BusAddress
= Virtual_to_Bus(&DCDB
);
2704 DCDB
.BusAddress
= Virtual_to_Bus(DataTransferBuffer
);
2710 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
2711 Command
= DAC960_AllocateCommand(Controller
);
2712 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
2713 if (Command
!= NULL
) break;
2714 sleep_on(&Controller
->CommandWaitQueue
);
2716 DAC960_ClearCommand(Command
);
2717 Command
->CommandType
= DAC960_ImmediateCommand
;
2718 memcpy(&Command
->CommandMailbox
, &UserCommand
.CommandMailbox
,
2719 sizeof(DAC960_CommandMailbox_T
));
2720 if (DataTransferBuffer
!= NULL
)
2721 Command
->CommandMailbox
.Type3
.BusAddress
=
2722 Virtual_to_Bus(DataTransferBuffer
);
2724 DAC960_ExecuteCommand(Command
);
2725 CommandStatus
= Command
->CommandStatus
;
2726 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
2727 DAC960_DeallocateCommand(Command
);
2728 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
2729 if (CommandStatus
== DAC960_NormalCompletion
&&
2730 DataTransferLength
> 0)
2732 ErrorCode
= copy_to_user(UserCommand
.DataTransferBuffer
,
2733 DataTransferBuffer
, DataTransferLength
);
2734 if (ErrorCode
!= 0) goto Failure
;
2736 if (CommandOpcode
== DAC960_DCDB
)
2738 Controller
->DirectCommandActive
[DCDB
.Channel
]
2739 [DCDB
.TargetID
] = false;
2741 copy_to_user(UserCommand
.DCDB
, &DCDB
, sizeof(DAC960_DCDB_T
));
2742 if (ErrorCode
!= 0) goto Failure
;
2744 ErrorCode
= CommandStatus
;
2746 if (DataTransferBuffer
!= NULL
)
2747 kfree(DataTransferBuffer
);
2756 DAC960_KernelIOCTL is the Kernel IOCTL Function for the DAC960 Driver.
2759 int DAC960_KernelIOCTL(unsigned int Request
, void *Argument
)
2763 case DAC960_IOCTL_GET_CONTROLLER_COUNT
:
2764 return DAC960_ControllerCount
;
2765 case DAC960_IOCTL_GET_CONTROLLER_INFO
:
2767 DAC960_ControllerInfo_T
*ControllerInfo
=
2768 (DAC960_ControllerInfo_T
*) Argument
;
2769 DAC960_Controller_T
*Controller
;
2770 int ControllerNumber
;
2771 if (ControllerInfo
== NULL
) return -EINVAL
;
2772 ControllerNumber
= ControllerInfo
->ControllerNumber
;
2773 if (ControllerNumber
< 0 ||
2774 ControllerNumber
> DAC960_ControllerCount
- 1)
2776 Controller
= DAC960_Controllers
[ControllerNumber
];
2777 if (Controller
== NULL
)
2779 memset(ControllerInfo
, 0, sizeof(DAC960_ControllerInfo_T
));
2780 ControllerInfo
->ControllerNumber
= ControllerNumber
;
2781 ControllerInfo
->PCI_Bus
= Controller
->Bus
;
2782 ControllerInfo
->PCI_Device
= Controller
->Device
;
2783 ControllerInfo
->PCI_Function
= Controller
->Function
;
2784 ControllerInfo
->IRQ_Channel
= Controller
->IRQ_Channel
;
2785 ControllerInfo
->Channels
= Controller
->Channels
;
2786 ControllerInfo
->PCI_Address
= Controller
->PCI_Address
;
2787 strcpy(ControllerInfo
->ModelName
, Controller
->ModelName
);
2788 strcpy(ControllerInfo
->FirmwareVersion
, Controller
->FirmwareVersion
);
2791 case DAC960_IOCTL_EXECUTE_COMMAND
:
2793 DAC960_KernelCommand_T
*KernelCommand
=
2794 (DAC960_KernelCommand_T
*) Argument
;
2795 DAC960_Controller_T
*Controller
;
2796 DAC960_Command_T
*Command
= NULL
;
2797 DAC960_CommandOpcode_T CommandOpcode
;
2798 DAC960_DCDB_T
*DCDB
= NULL
;
2799 ProcessorFlags_T ProcessorFlags
;
2800 int ControllerNumber
, DataTransferLength
;
2801 unsigned char *DataTransferBuffer
= NULL
;
2802 if (KernelCommand
== NULL
) return -EINVAL
;
2803 ControllerNumber
= KernelCommand
->ControllerNumber
;
2804 if (ControllerNumber
< 0 ||
2805 ControllerNumber
> DAC960_ControllerCount
- 1)
2807 Controller
= DAC960_Controllers
[ControllerNumber
];
2808 if (Controller
== NULL
)
2810 CommandOpcode
= KernelCommand
->CommandMailbox
.Common
.CommandOpcode
;
2811 DataTransferLength
= KernelCommand
->DataTransferLength
;
2812 DataTransferBuffer
= KernelCommand
->DataTransferBuffer
;
2813 if (CommandOpcode
& 0x80) return -EINVAL
;
2814 if (CommandOpcode
== DAC960_DCDB
)
2816 DCDB
= KernelCommand
->DCDB
;
2817 if (!((DataTransferLength
== 0 &&
2818 DCDB
->Direction
== DAC960_DCDB_NoDataTransfer
) ||
2819 (DataTransferLength
> 0 &&
2820 DCDB
->Direction
== DAC960_DCDB_DataTransferDeviceToSystem
) ||
2821 (DataTransferLength
< 0 &&
2822 DCDB
->Direction
== DAC960_DCDB_DataTransferSystemToDevice
)))
2824 if (((DCDB
->TransferLengthHigh4
<< 16) | DCDB
->TransferLength
)
2825 != abs(DataTransferLength
))
2828 if (DataTransferLength
!= 0 && DataTransferBuffer
== NULL
)
2830 if (DataTransferLength
> 0)
2831 memset(DataTransferBuffer
, 0, DataTransferLength
);
2832 if (CommandOpcode
== DAC960_DCDB
)
2834 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
2835 if (!Controller
->DirectCommandActive
[DCDB
->Channel
]
2837 Command
= DAC960_AllocateCommand(Controller
);
2838 if (Command
== NULL
)
2840 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
2843 else Controller
->DirectCommandActive
[DCDB
->Channel
]
2844 [DCDB
->TargetID
] = true;
2845 DAC960_ClearCommand(Command
);
2846 Command
->CommandType
= DAC960_QueuedCommand
;
2847 memcpy(&Command
->CommandMailbox
, &KernelCommand
->CommandMailbox
,
2848 sizeof(DAC960_CommandMailbox_T
));
2849 Command
->CommandMailbox
.Type3
.BusAddress
= Virtual_to_Bus(DCDB
);
2850 Command
->KernelCommand
= KernelCommand
;
2851 DCDB
->BusAddress
= Virtual_to_Bus(DataTransferBuffer
);
2852 DAC960_QueueCommand(Command
);
2853 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
2857 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
2858 Command
= DAC960_AllocateCommand(Controller
);
2859 if (Command
== NULL
)
2861 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
2864 DAC960_ClearCommand(Command
);
2865 Command
->CommandType
= DAC960_QueuedCommand
;
2866 memcpy(&Command
->CommandMailbox
, &KernelCommand
->CommandMailbox
,
2867 sizeof(DAC960_CommandMailbox_T
));
2868 if (DataTransferBuffer
!= NULL
)
2869 Command
->CommandMailbox
.Type3
.BusAddress
=
2870 Virtual_to_Bus(DataTransferBuffer
);
2871 Command
->KernelCommand
= KernelCommand
;
2872 DAC960_QueueCommand(Command
);
2873 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
2883 DAC960_GenericDiskInit is the Generic Disk Information Initialization
2884 Function for the DAC960 Driver.
2887 static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T
*GenericDiskInfo
)
2889 DAC960_Controller_T
*Controller
=
2890 (DAC960_Controller_T
*) GenericDiskInfo
->real_devices
;
2891 DAC960_LogicalDriveInformation_T
*LogicalDriveInformation
=
2892 Controller
->LogicalDriveInformation
2893 [Controller
->LogicalDriveInformationIndex
];
2894 int LogicalDriveNumber
;
2895 for (LogicalDriveNumber
= 0;
2896 LogicalDriveNumber
< Controller
->LogicalDriveCount
;
2897 LogicalDriveNumber
++)
2898 GenericDiskInfo
->part
[DAC960_MinorNumber(LogicalDriveNumber
, 0)].nr_sects
=
2899 LogicalDriveInformation
[LogicalDriveNumber
].LogicalDriveSize
;
2904 DAC960_Message prints Driver Messages.
2907 static void DAC960_Message(DAC960_MessageLevel_T MessageLevel
,
2909 DAC960_Controller_T
*Controller
,
2912 static char Buffer
[DAC960_LineBufferSize
];
2913 static boolean BeginningOfLine
= true;
2916 va_start(Arguments
, Controller
);
2917 Length
= vsprintf(Buffer
, Format
, Arguments
);
2919 if (Controller
== NULL
)
2920 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap
[MessageLevel
],
2921 DAC960_ControllerCount
, Buffer
);
2922 else if (MessageLevel
== DAC960_AnnounceLevel
||
2923 MessageLevel
== DAC960_InfoLevel
)
2925 if (!Controller
->ControllerInitialized
)
2927 strcpy(&Controller
->InitialStatusBuffer
[
2928 Controller
->InitialStatusLength
], Buffer
);
2929 Controller
->InitialStatusLength
+= Length
;
2930 if (MessageLevel
== DAC960_AnnounceLevel
)
2932 static int AnnouncementLines
= 0;
2933 if (++AnnouncementLines
<= 2)
2934 printk("%sDAC960: %s", DAC960_MessageLevelMap
[MessageLevel
],
2939 if (BeginningOfLine
)
2941 if (Buffer
[0] != '\n' || Length
> 1)
2942 printk("%sDAC960#%d: %s",
2943 DAC960_MessageLevelMap
[MessageLevel
],
2944 Controller
->ControllerNumber
, Buffer
);
2946 else printk("%s", Buffer
);
2951 strcpy(&Controller
->CurrentStatusBuffer
[
2952 Controller
->CurrentStatusLength
], Buffer
);
2953 Controller
->CurrentStatusLength
+= Length
;
2956 else if (MessageLevel
== DAC960_ProgressLevel
)
2958 strcpy(Controller
->RebuildProgressBuffer
, Buffer
);
2959 Controller
->RebuildProgressLength
= Length
;
2960 if (Controller
->EphemeralProgressMessage
)
2962 if (jiffies
- Controller
->LastProgressReportTime
2963 >= DAC960_ProgressReportingInterval
)
2965 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap
[MessageLevel
],
2966 Controller
->ControllerNumber
, Buffer
);
2967 Controller
->LastProgressReportTime
= jiffies
;
2970 else printk("%sDAC960#%d: %s", DAC960_MessageLevelMap
[MessageLevel
],
2971 Controller
->ControllerNumber
, Buffer
);
2973 else if (MessageLevel
== DAC960_UserCriticalLevel
)
2975 strcpy(&Controller
->UserStatusBuffer
[Controller
->UserStatusLength
],
2977 Controller
->UserStatusLength
+= Length
;
2978 if (Buffer
[0] != '\n' || Length
> 1)
2979 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap
[MessageLevel
],
2980 Controller
->ControllerNumber
, Buffer
);
2984 if (BeginningOfLine
)
2985 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap
[MessageLevel
],
2986 Controller
->ControllerNumber
, Buffer
);
2987 else printk("%s", Buffer
);
2989 BeginningOfLine
= (Buffer
[Length
-1] == '\n');
2994 DAC960_ParsePhysicalDrive parses spaces followed by a Physical Drive
2995 Channel:TargetID specification from a User Command string. It updates
2996 Channel and TargetID and returns true on success and returns false otherwise.
2999 static boolean
DAC960_ParsePhysicalDrive(DAC960_Controller_T
*Controller
,
3000 char *UserCommandString
,
3001 unsigned char *Channel
,
3002 unsigned char *TargetID
)
3004 char *NewUserCommandString
= UserCommandString
;
3005 unsigned long XChannel
, XTargetID
;
3006 while (*UserCommandString
== ' ') UserCommandString
++;
3007 if (UserCommandString
== NewUserCommandString
)
3009 XChannel
= simple_strtoul(UserCommandString
, &NewUserCommandString
, 10);
3010 if (NewUserCommandString
== UserCommandString
||
3011 *NewUserCommandString
!= ':' ||
3012 XChannel
>= Controller
->Channels
)
3014 UserCommandString
= ++NewUserCommandString
;
3015 XTargetID
= simple_strtoul(UserCommandString
, &NewUserCommandString
, 10);
3016 if (NewUserCommandString
== UserCommandString
||
3017 *NewUserCommandString
!= '\0' ||
3018 XTargetID
>= DAC960_MaxTargets
)
3020 *Channel
= XChannel
;
3021 *TargetID
= XTargetID
;
3027 DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number
3028 specification from a User Command string. It updates LogicalDriveNumber and
3029 returns true on success and returns false otherwise.
3032 static boolean
DAC960_ParseLogicalDrive(DAC960_Controller_T
*Controller
,
3033 char *UserCommandString
,
3034 unsigned char *LogicalDriveNumber
)
3036 char *NewUserCommandString
= UserCommandString
;
3037 unsigned long XLogicalDriveNumber
;
3038 while (*UserCommandString
== ' ') UserCommandString
++;
3039 if (UserCommandString
== NewUserCommandString
)
3041 XLogicalDriveNumber
=
3042 simple_strtoul(UserCommandString
, &NewUserCommandString
, 10);
3043 if (NewUserCommandString
== UserCommandString
||
3044 *NewUserCommandString
!= '\0' ||
3045 XLogicalDriveNumber
>= Controller
->LogicalDriveCount
)
3047 *LogicalDriveNumber
= XLogicalDriveNumber
;
3053 DAC960_SetDeviceState sets the Device State for a Physical Drive.
3056 static void DAC960_SetDeviceState(DAC960_Controller_T
*Controller
,
3057 DAC960_Command_T
*Command
,
3058 unsigned char Channel
,
3059 unsigned char TargetID
,
3060 DAC960_PhysicalDeviceState_T DeviceState
,
3061 const char *DeviceStateString
)
3063 DAC960_CommandMailbox_T
*CommandMailbox
= &Command
->CommandMailbox
;
3064 CommandMailbox
->Type3D
.CommandOpcode
= DAC960_StartDevice
;
3065 CommandMailbox
->Type3D
.Channel
= Channel
;
3066 CommandMailbox
->Type3D
.TargetID
= TargetID
;
3067 CommandMailbox
->Type3D
.DeviceState
= DeviceState
;
3068 CommandMailbox
->Type3D
.Modifier
= 0;
3069 DAC960_ExecuteCommand(Command
);
3070 switch (Command
->CommandStatus
)
3072 case DAC960_NormalCompletion
:
3073 DAC960_UserCritical("%s of Physical Drive %d:%d Succeeded\n", Controller
,
3074 DeviceStateString
, Channel
, TargetID
);
3076 case DAC960_UnableToStartDevice
:
3077 DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
3078 "Unable to Start Device\n", Controller
,
3079 DeviceStateString
, Channel
, TargetID
);
3081 case DAC960_NoDeviceAtAddress
:
3082 DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
3083 "No Device at Address\n", Controller
,
3084 DeviceStateString
, Channel
, TargetID
);
3086 case DAC960_InvalidChannelOrTargetOrModifier
:
3087 DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
3088 "Invalid Channel or Target or Modifier\n",
3089 Controller
, DeviceStateString
, Channel
, TargetID
);
3091 case DAC960_ChannelBusy
:
3092 DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
3093 "Channel Busy\n", Controller
,
3094 DeviceStateString
, Channel
, TargetID
);
3097 DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
3098 "Unexpected Status %04X\n", Controller
,
3099 DeviceStateString
, Channel
, TargetID
,
3100 Command
->CommandStatus
);
3107 DAC960_ExecuteUserCommand executes a User Command.
3110 static boolean
DAC960_ExecuteUserCommand(DAC960_Controller_T
*Controller
,
3113 DAC960_Command_T
*Command
;
3114 DAC960_CommandMailbox_T
*CommandMailbox
;
3115 ProcessorFlags_T ProcessorFlags
;
3116 unsigned char Channel
, TargetID
, LogicalDriveNumber
;
3119 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
3120 Command
= DAC960_AllocateCommand(Controller
);
3121 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
3122 if (Command
!= NULL
) break;
3123 sleep_on(&Controller
->CommandWaitQueue
);
3125 Controller
->UserStatusLength
= 0;
3126 DAC960_ClearCommand(Command
);
3127 Command
->CommandType
= DAC960_ImmediateCommand
;
3128 CommandMailbox
= &Command
->CommandMailbox
;
3129 if (strcmp(UserCommand
, "flush-cache") == 0)
3131 CommandMailbox
->Type3
.CommandOpcode
= DAC960_Flush
;
3132 DAC960_ExecuteCommand(Command
);
3133 DAC960_UserCritical("Cache Flush Completed\n", Controller
);
3135 else if (strncmp(UserCommand
, "kill", 4) == 0 &&
3136 DAC960_ParsePhysicalDrive(Controller
, &UserCommand
[4],
3137 &Channel
, &TargetID
))
3139 DAC960_DeviceState_T
*DeviceState
=
3140 &Controller
->DeviceState
[Controller
->DeviceStateIndex
]
3141 [Channel
][TargetID
];
3142 if (DeviceState
->Present
&&
3143 DeviceState
->DeviceType
== DAC960_DiskType
&&
3144 DeviceState
->DeviceState
!= DAC960_Device_Dead
)
3145 DAC960_SetDeviceState(Controller
, Command
, Channel
, TargetID
,
3146 DAC960_Device_Dead
, "Kill");
3147 else DAC960_UserCritical("Kill of Physical Drive %d:%d Illegal\n",
3148 Controller
, Channel
, TargetID
);
3150 else if (strncmp(UserCommand
, "make-online", 11) == 0 &&
3151 DAC960_ParsePhysicalDrive(Controller
, &UserCommand
[11],
3152 &Channel
, &TargetID
))
3154 DAC960_DeviceState_T
*DeviceState
=
3155 &Controller
->DeviceState
[Controller
->DeviceStateIndex
]
3156 [Channel
][TargetID
];
3157 if (DeviceState
->Present
&&
3158 DeviceState
->DeviceType
== DAC960_DiskType
&&
3159 DeviceState
->DeviceState
== DAC960_Device_Dead
)
3160 DAC960_SetDeviceState(Controller
, Command
, Channel
, TargetID
,
3161 DAC960_Device_Online
, "Make Online");
3162 else DAC960_UserCritical("Make Online of Physical Drive %d:%d Illegal\n",
3163 Controller
, Channel
, TargetID
);
3166 else if (strncmp(UserCommand
, "make-standby", 12) == 0 &&
3167 DAC960_ParsePhysicalDrive(Controller
, &UserCommand
[12],
3168 &Channel
, &TargetID
))
3170 DAC960_DeviceState_T
*DeviceState
=
3171 &Controller
->DeviceState
[Controller
->DeviceStateIndex
]
3172 [Channel
][TargetID
];
3173 if (DeviceState
->Present
&&
3174 DeviceState
->DeviceType
== DAC960_DiskType
&&
3175 DeviceState
->DeviceState
== DAC960_Device_Dead
)
3176 DAC960_SetDeviceState(Controller
, Command
, Channel
, TargetID
,
3177 DAC960_Device_Standby
, "Make Standby");
3178 else DAC960_UserCritical("Make Standby of Physical Drive %d:%d Illegal\n",
3179 Controller
, Channel
, TargetID
);
3181 else if (strncmp(UserCommand
, "rebuild", 7) == 0 &&
3182 DAC960_ParsePhysicalDrive(Controller
, &UserCommand
[7],
3183 &Channel
, &TargetID
))
3185 CommandMailbox
->Type3D
.CommandOpcode
= DAC960_RebuildAsync
;
3186 CommandMailbox
->Type3D
.Channel
= Channel
;
3187 CommandMailbox
->Type3D
.TargetID
= TargetID
;
3188 DAC960_ExecuteCommand(Command
);
3189 switch (Command
->CommandStatus
)
3191 case DAC960_NormalCompletion
:
3192 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Initiated\n",
3193 Controller
, Channel
, TargetID
);
3195 case DAC960_AttemptToRebuildOnlineDrive
:
3196 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
3197 "Attempt to Rebuild Online or "
3198 "Unresponsive Drive\n",
3199 Controller
, Channel
, TargetID
);
3201 case DAC960_NewDiskFailedDuringRebuild
:
3202 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
3203 "New Disk Failed During Rebuild\n",
3204 Controller
, Channel
, TargetID
);
3206 case DAC960_InvalidDeviceAddress
:
3207 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
3208 "Invalid Device Address\n",
3209 Controller
, Channel
, TargetID
);
3211 case DAC960_RebuildOrCheckAlreadyInProgress
:
3212 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
3213 "Rebuild or Consistency Check Already "
3214 "in Progress\n", Controller
, Channel
, TargetID
);
3217 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
3218 "Unexpected Status %04X\n", Controller
,
3219 Channel
, TargetID
, Command
->CommandStatus
);
3223 else if (strncmp(UserCommand
, "check-consistency", 17) == 0 &&
3224 DAC960_ParseLogicalDrive(Controller
, &UserCommand
[17],
3225 &LogicalDriveNumber
))
3227 CommandMailbox
->Type3C
.CommandOpcode
= DAC960_CheckConsistencyAsync
;
3228 CommandMailbox
->Type3C
.LogicalDriveNumber
= LogicalDriveNumber
;
3229 CommandMailbox
->Type3C
.AutoRestore
= true;
3230 DAC960_ExecuteCommand(Command
);
3231 switch (Command
->CommandStatus
)
3233 case DAC960_NormalCompletion
:
3234 DAC960_UserCritical("Consistency Check of Logical Drive %d "
3235 "(/dev/rd/c%dd%d) Initiated\n",
3236 Controller
, LogicalDriveNumber
,
3237 Controller
->ControllerNumber
,
3238 LogicalDriveNumber
);
3240 case DAC960_DependentDiskIsDead
:
3241 DAC960_UserCritical("Consistency Check of Logical Drive %d "
3242 "(/dev/rd/c%dd%d) Failed - "
3243 "Dependent Physical Drive is DEAD\n",
3244 Controller
, LogicalDriveNumber
,
3245 Controller
->ControllerNumber
,
3246 LogicalDriveNumber
);
3248 case DAC960_InvalidOrNonredundantLogicalDrive
:
3249 DAC960_UserCritical("Consistency Check of Logical Drive %d "
3250 "(/dev/rd/c%dd%d) Failed - "
3251 "Invalid or Nonredundant Logical Drive\n",
3252 Controller
, LogicalDriveNumber
,
3253 Controller
->ControllerNumber
,
3254 LogicalDriveNumber
);
3256 case DAC960_RebuildOrCheckAlreadyInProgress
:
3257 DAC960_UserCritical("Consistency Check of Logical Drive %d "
3258 "(/dev/rd/c%dd%d) Failed - Rebuild or "
3259 "Consistency Check Already in Progress\n",
3260 Controller
, LogicalDriveNumber
,
3261 Controller
->ControllerNumber
,
3262 LogicalDriveNumber
);
3265 DAC960_UserCritical("Consistency Check of Logical Drive %d "
3266 "(/dev/rd/c%dd%d) Failed - "
3267 "Unexpected Status %04X\n",
3268 Controller
, LogicalDriveNumber
,
3269 Controller
->ControllerNumber
,
3270 LogicalDriveNumber
, Command
->CommandStatus
);
3274 else if (strcmp(UserCommand
, "cancel-rebuild") == 0 ||
3275 strcmp(UserCommand
, "cancel-consistency-check") == 0)
3277 unsigned char OldRebuildRateConstant
;
3278 CommandMailbox
->Type3R
.CommandOpcode
= DAC960_RebuildControl
;
3279 CommandMailbox
->Type3R
.RebuildRateConstant
= 0xFF;
3280 CommandMailbox
->Type3R
.BusAddress
=
3281 Virtual_to_Bus(&OldRebuildRateConstant
);
3282 DAC960_ExecuteCommand(Command
);
3283 switch (Command
->CommandStatus
)
3285 case DAC960_NormalCompletion
:
3286 DAC960_UserCritical("Rebuild or Consistency Check Cancelled\n",
3290 DAC960_UserCritical("Cancellation of Rebuild or "
3291 "Consistency Check Failed - "
3292 "Unexpected Status %04X\n",
3293 Controller
, Command
->CommandStatus
);
3297 else DAC960_UserCritical("Illegal User Command: '%s'\n",
3298 Controller
, UserCommand
);
3299 DAC960_AcquireControllerLock(Controller
, &ProcessorFlags
);
3300 DAC960_DeallocateCommand(Command
);
3301 DAC960_ReleaseControllerLock(Controller
, &ProcessorFlags
);
3307 DAC960_ProcReadStatus implements reading /proc/rd/status.
3310 static int DAC960_ProcReadStatus(char *Page
, char **Start
, off_t Offset
,
3311 int Count
, int *EOF
, void *Data
)
3313 char *StatusMessage
= "OK\n";
3314 int ControllerNumber
, BytesAvailable
;
3315 for (ControllerNumber
= 0;
3316 ControllerNumber
< DAC960_ControllerCount
;
3319 DAC960_Controller_T
*Controller
= DAC960_Controllers
[ControllerNumber
];
3320 DAC960_Enquiry_T
*Enquiry
;
3321 if (Controller
== NULL
) continue;
3322 Enquiry
= &Controller
->Enquiry
[Controller
->EnquiryIndex
];
3323 if (Enquiry
->CriticalLogicalDriveCount
> 0 ||
3324 Enquiry
->OfflineLogicalDriveCount
> 0 ||
3325 Enquiry
->DeadDriveCount
> 0)
3327 StatusMessage
= "ALERT\n";
3331 BytesAvailable
= strlen(StatusMessage
) - Offset
;
3332 if (Count
>= BytesAvailable
)
3334 Count
= BytesAvailable
;
3337 if (Count
<= 0) return 0;
3339 memcpy(Page
, &StatusMessage
[Offset
], Count
);
3345 DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status.
3348 static int DAC960_ProcReadInitialStatus(char *Page
, char **Start
, off_t Offset
,
3349 int Count
, int *EOF
, void *Data
)
3351 DAC960_Controller_T
*Controller
= (DAC960_Controller_T
*) Data
;
3352 int BytesAvailable
= Controller
->InitialStatusLength
- Offset
;
3353 if (Count
>= BytesAvailable
)
3355 Count
= BytesAvailable
;
3358 if (Count
<= 0) return 0;
3360 memcpy(Page
, &Controller
->InitialStatusBuffer
[Offset
], Count
);
3366 DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status.
3369 static int DAC960_ProcReadCurrentStatus(char *Page
, char **Start
, off_t Offset
,
3370 int Count
, int *EOF
, void *Data
)
3372 DAC960_Controller_T
*Controller
= (DAC960_Controller_T
*) Data
;
3374 if (jiffies
!= Controller
->LastCurrentStatusTime
)
3376 Controller
->CurrentStatusLength
= 0;
3377 DAC960_AnnounceDriver(Controller
);
3378 DAC960_ReportControllerConfiguration(Controller
);
3379 DAC960_ReportDeviceConfiguration(Controller
);
3380 Controller
->CurrentStatusBuffer
[Controller
->CurrentStatusLength
++] = ' ';
3381 Controller
->CurrentStatusBuffer
[Controller
->CurrentStatusLength
++] = ' ';
3382 if (Controller
->RebuildProgressLength
> 0)
3384 strcpy(&Controller
->CurrentStatusBuffer
3385 [Controller
->CurrentStatusLength
],
3386 Controller
->RebuildProgressBuffer
);
3387 Controller
->CurrentStatusLength
+= Controller
->RebuildProgressLength
;
3391 char *StatusMessage
= "No Rebuild or Consistency Check in Progress\n";
3392 strcpy(&Controller
->CurrentStatusBuffer
3393 [Controller
->CurrentStatusLength
],
3395 Controller
->CurrentStatusLength
+= strlen(StatusMessage
);
3397 Controller
->LastCurrentStatusTime
= jiffies
;
3399 BytesAvailable
= Controller
->CurrentStatusLength
- Offset
;
3400 if (Count
>= BytesAvailable
)
3402 Count
= BytesAvailable
;
3405 if (Count
<= 0) return 0;
3407 memcpy(Page
, &Controller
->CurrentStatusBuffer
[Offset
], Count
);
3413 DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command.
3416 static int DAC960_ProcReadUserCommand(char *Page
, char **Start
, off_t Offset
,
3417 int Count
, int *EOF
, void *Data
)
3419 DAC960_Controller_T
*Controller
= (DAC960_Controller_T
*) Data
;
3420 int BytesAvailable
= Controller
->UserStatusLength
- Offset
;
3421 if (Count
>= BytesAvailable
)
3423 Count
= BytesAvailable
;
3426 if (Count
<= 0) return 0;
3428 memcpy(Page
, &Controller
->UserStatusBuffer
[Offset
], Count
);
3434 DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
3437 static int DAC960_ProcWriteUserCommand(File_T
*File
, const char *Buffer
,
3438 unsigned long Count
, void *Data
)
3440 DAC960_Controller_T
*Controller
= (DAC960_Controller_T
*) Data
;
3441 char CommandBuffer
[80];
3443 if (Count
> sizeof(CommandBuffer
)-1) return -EINVAL
;
3444 copy_from_user(CommandBuffer
, Buffer
, Count
);
3445 CommandBuffer
[Count
] = '\0';
3446 Length
= strlen(CommandBuffer
);
3447 if (CommandBuffer
[Length
-1] == '\n')
3448 CommandBuffer
[--Length
] = '\0';
3449 return (DAC960_ExecuteUserCommand(Controller
, CommandBuffer
)
3455 DAC960_CreateProcEntries creates the /proc/driver/rd/... entries
3456 for the DAC960 Driver.
3459 static void DAC960_CreateProcEntries(void)
3461 static PROC_DirectoryEntry_T
*StatusProcEntry
;
3462 int ControllerNumber
;
3463 DAC960_ProcDirectoryEntry
= proc_mkdir("driver/rd", NULL
);
3464 StatusProcEntry
= create_proc_read_entry("status", 0,
3465 DAC960_ProcDirectoryEntry
,
3466 DAC960_ProcReadStatus
, NULL
);
3467 for (ControllerNumber
= 0;
3468 ControllerNumber
< DAC960_ControllerCount
;
3471 DAC960_Controller_T
*Controller
= DAC960_Controllers
[ControllerNumber
];
3472 PROC_DirectoryEntry_T
*ControllerProcEntry
;
3473 PROC_DirectoryEntry_T
*UserCommandProcEntry
;
3474 if (Controller
== NULL
) continue;
3475 ControllerProcEntry
= proc_mkdir(Controller
->ControllerName
,
3476 DAC960_ProcDirectoryEntry
);
3477 create_proc_read_entry("initial_status",0,ControllerProcEntry
,
3478 DAC960_ProcReadInitialStatus
, Controller
);
3479 create_proc_read_entry("current_status",0,ControllerProcEntry
,
3480 DAC960_ProcReadCurrentStatus
, Controller
);
3481 UserCommandProcEntry
=
3482 create_proc_read_entry("user_command", S_IWUSR
|S_IRUSR
,
3483 ControllerProcEntry
,
3484 DAC960_ProcReadUserCommand
, Controller
);
3485 UserCommandProcEntry
->write_proc
= DAC960_ProcWriteUserCommand
;
3491 DAC960_DestroyProcEntries destroys the /proc/rd/... entries for the DAC960
3495 static void DAC960_DestroyProcEntries(void)
3498 remove_proc_entry("driver/rd", NULL
);
3503 Include Module support if requested.
3509 int init_module(void)
3511 int ControllerNumber
, LogicalDriveNumber
;
3512 DAC960_Initialize();
3513 if (DAC960_ActiveControllerCount
== 0) return -1;
3514 for (ControllerNumber
= 0;
3515 ControllerNumber
< DAC960_ControllerCount
;
3518 DAC960_Controller_T
*Controller
= DAC960_Controllers
[ControllerNumber
];
3519 if (Controller
== NULL
) continue;
3520 DAC960_InitializeGenericDiskInfo(&Controller
->GenericDiskInfo
);
3521 for (LogicalDriveNumber
= 0;
3522 LogicalDriveNumber
< Controller
->LogicalDriveCount
;
3523 LogicalDriveNumber
++)
3524 resetup_one_dev(&Controller
->GenericDiskInfo
, LogicalDriveNumber
);
3530 void cleanup_module(void)
3532 DAC960_Finalize(&DAC960_NotifierBlock
, SYS_RESTART
, NULL
);