Import 2.4.0-test6pre3
[davej-history.git] / drivers / block / DAC960.c
blob749b0d3da70d45715da86e43b9e72f91275d16f3
1 /*
3 Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
5 Copyright 1998-2000 by Leonard N. Zubkoff <lnz@dandelion.com>
7 This program is free software; you may redistribute and/or modify it under
8 the terms of the GNU General Public License Version 2 as published by the
9 Free Software Foundation.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for complete details.
16 The author respectfully requests that any modifications to this software be
17 sent directly to him for evaluation and testing.
22 #define DAC960_DriverVersion "2.4.7"
23 #define DAC960_DriverDate "1 August 2000"
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>
36 #include <linux/mm.h>
37 #include <linux/malloc.h>
38 #include <linux/proc_fs.h>
39 #include <linux/reboot.h>
40 #include <linux/spinlock.h>
41 #include <linux/timer.h>
42 #include <linux/pci.h>
43 #include <asm/io.h>
44 #include <asm/segment.h>
45 #include <asm/uaccess.h>
46 #include "DAC960.h"
50 DAC960_ControllerCount is the number of DAC960 Controllers detected.
53 static int
54 DAC960_ControllerCount = 0;
58 DAC960_ActiveControllerCount is the number of active DAC960 Controllers
59 detected.
62 static int
63 DAC960_ActiveControllerCount = 0;
67 DAC960_Controllers is an array of pointers to the DAC960 Controller
68 structures.
71 static DAC960_Controller_T
72 *DAC960_Controllers[DAC960_MaxControllers] = { NULL };
76 DAC960_BlockDeviceOperations is the Block Device Operations structure for
77 DAC960 Logical Disk Devices.
80 static BlockDeviceOperations_T
81 DAC960_BlockDeviceOperations =
82 { open: DAC960_Open,
83 release: DAC960_Release,
84 ioctl: DAC960_IOCTL };
88 DAC960_ProcDirectoryEntry is the DAC960 /proc/rd directory entry.
91 static PROC_DirectoryEntry_T
92 *DAC960_ProcDirectoryEntry;
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-2000 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,
123 unsigned char *ErrorMessage)
125 DAC960_Error("While configuring DAC960 PCI RAID Controller at\n",
126 Controller);
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);
138 return false;
143 DAC960_CreateAuxiliaryStructures allocates and initializes the auxiliary
144 data structures for Controller. It returns true on success and false on
145 failure.
148 static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
150 int CommandAllocationLength, CommandAllocationGroupSize;
151 int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount;
152 void *AllocationPointer = NULL;
153 if (Controller->FirmwareType == DAC960_V1_Controller)
155 CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker);
156 CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize;
158 else
160 CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker);
161 CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize;
163 Controller->CommandAllocationGroupSize = CommandAllocationGroupSize;
164 Controller->FreeCommands = NULL;
165 for (CommandIdentifier = 1;
166 CommandIdentifier <= Controller->DriverQueueDepth;
167 CommandIdentifier++)
169 DAC960_Command_T *Command;
170 if (--CommandsRemaining <= 0)
172 CommandsRemaining =
173 Controller->DriverQueueDepth - CommandIdentifier + 1;
174 if (CommandsRemaining > CommandAllocationGroupSize)
175 CommandsRemaining = CommandAllocationGroupSize;
176 CommandGroupByteCount =
177 CommandsRemaining * CommandAllocationLength;
178 AllocationPointer = kmalloc(CommandGroupByteCount, GFP_ATOMIC);
179 if (AllocationPointer == NULL)
180 return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
181 memset(AllocationPointer, 0, CommandGroupByteCount);
183 Command = (DAC960_Command_T *) AllocationPointer;
184 AllocationPointer += CommandAllocationLength;
185 Command->CommandIdentifier = CommandIdentifier;
186 Command->Controller = Controller;
187 Command->Next = Controller->FreeCommands;
188 Controller->FreeCommands = Command;
189 Controller->Commands[CommandIdentifier-1] = Command;
191 return true;
196 DAC960_DestroyAuxiliaryStructures deallocates the auxiliary data
197 structures for Controller.
200 static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
202 int i;
203 Controller->FreeCommands = NULL;
204 for (i = 0; i < Controller->DriverQueueDepth; i++)
206 DAC960_Command_T *Command = Controller->Commands[i];
207 if (Command != NULL &&
208 (Command->CommandIdentifier
209 % Controller->CommandAllocationGroupSize) == 1)
210 kfree(Command);
211 Controller->Commands[i] = NULL;
213 if (Controller->CombinedStatusBuffer != NULL)
215 kfree(Controller->CombinedStatusBuffer);
216 Controller->CombinedStatusBuffer = NULL;
217 Controller->CurrentStatusBuffer = NULL;
219 if (Controller->FirmwareType == DAC960_V1_Controller) return;
220 for (i = 0; i < DAC960_MaxLogicalDrives; i++)
221 if (Controller->V2.LogicalDeviceInformation[i] != NULL)
223 kfree(Controller->V2.LogicalDeviceInformation[i]);
224 Controller->V2.LogicalDeviceInformation[i] = NULL;
226 for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)
228 if (Controller->V2.PhysicalDeviceInformation[i] != NULL)
230 kfree(Controller->V2.PhysicalDeviceInformation[i]);
231 Controller->V2.PhysicalDeviceInformation[i] = NULL;
233 if (Controller->V2.InquiryUnitSerialNumber[i] != NULL)
235 kfree(Controller->V2.InquiryUnitSerialNumber[i]);
236 Controller->V2.InquiryUnitSerialNumber[i] = NULL;
243 DAC960_V1_ClearCommand clears critical fields of Command for DAC960 V1
244 Firmware Controllers.
247 static inline void DAC960_V1_ClearCommand(DAC960_Command_T *Command)
249 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
250 memset(CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T));
251 Command->V1.CommandStatus = 0;
256 DAC960_V2_ClearCommand clears critical fields of Command for DAC960 V2
257 Firmware Controllers.
260 static inline void DAC960_V2_ClearCommand(DAC960_Command_T *Command)
262 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
263 memset(CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
264 Command->V2.CommandStatus = 0;
269 DAC960_AllocateCommand allocates a Command structure from Controller's
270 free list.
273 static inline DAC960_Command_T *DAC960_AllocateCommand(DAC960_Controller_T
274 *Controller)
276 DAC960_Command_T *Command = Controller->FreeCommands;
277 if (Command == NULL) return NULL;
278 Controller->FreeCommands = Command->Next;
279 Command->Next = NULL;
280 return Command;
285 DAC960_DeallocateCommand deallocates Command, returning it to Controller's
286 free list.
289 static inline void DAC960_DeallocateCommand(DAC960_Command_T *Command)
291 DAC960_Controller_T *Controller = Command->Controller;
292 Command->Next = Controller->FreeCommands;
293 Controller->FreeCommands = Command;
298 DAC960_WaitForCommand waits for a wake_up on Controller's Command Wait Queue.
301 static void DAC960_WaitForCommand(DAC960_Controller_T *Controller)
303 DECLARE_WAITQUEUE(WaitQueueEntry, current);
304 add_wait_queue(&Controller->CommandWaitQueue, &WaitQueueEntry);
305 current->state = TASK_UNINTERRUPTIBLE;
306 spin_unlock(&io_request_lock);
307 schedule();
308 current->state = TASK_RUNNING;
309 remove_wait_queue(&Controller->CommandWaitQueue, &WaitQueueEntry);
310 spin_lock_irq(&io_request_lock);
315 DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers.
318 static void DAC960_BA_QueueCommand(DAC960_Command_T *Command)
320 DAC960_Controller_T *Controller = Command->Controller;
321 void *ControllerBaseAddress = Controller->BaseAddress;
322 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
323 DAC960_V2_CommandMailbox_T *NextCommandMailbox =
324 Controller->V2.NextCommandMailbox;
325 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
326 DAC960_BA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
327 if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
328 Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
329 DAC960_BA_MemoryMailboxNewCommand(ControllerBaseAddress);
330 Controller->V2.PreviousCommandMailbox2 =
331 Controller->V2.PreviousCommandMailbox1;
332 Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
333 if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
334 NextCommandMailbox = Controller->V2.FirstCommandMailbox;
335 Controller->V2.NextCommandMailbox = NextCommandMailbox;
340 DAC960_LP_QueueCommand queues Command for DAC960 LP Series Controllers.
343 static void DAC960_LP_QueueCommand(DAC960_Command_T *Command)
345 DAC960_Controller_T *Controller = Command->Controller;
346 void *ControllerBaseAddress = Controller->BaseAddress;
347 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
348 DAC960_V2_CommandMailbox_T *NextCommandMailbox =
349 Controller->V2.NextCommandMailbox;
350 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
351 DAC960_LP_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
352 if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
353 Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
354 DAC960_LP_MemoryMailboxNewCommand(ControllerBaseAddress);
355 Controller->V2.PreviousCommandMailbox2 =
356 Controller->V2.PreviousCommandMailbox1;
357 Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
358 if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
359 NextCommandMailbox = Controller->V2.FirstCommandMailbox;
360 Controller->V2.NextCommandMailbox = NextCommandMailbox;
365 DAC960_LA_QueueCommandDualMode queues Command for DAC960 LA Series
366 Controllers with Dual Mode Firmware.
369 static void DAC960_LA_QueueCommandDualMode(DAC960_Command_T *Command)
371 DAC960_Controller_T *Controller = Command->Controller;
372 void *ControllerBaseAddress = Controller->BaseAddress;
373 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
374 DAC960_V1_CommandMailbox_T *NextCommandMailbox =
375 Controller->V1.NextCommandMailbox;
376 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
377 DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
378 if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
379 Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
380 DAC960_LA_MemoryMailboxNewCommand(ControllerBaseAddress);
381 Controller->V1.PreviousCommandMailbox2 =
382 Controller->V1.PreviousCommandMailbox1;
383 Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
384 if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
385 NextCommandMailbox = Controller->V1.FirstCommandMailbox;
386 Controller->V1.NextCommandMailbox = NextCommandMailbox;
391 DAC960_LA_QueueCommandSingleMode queues Command for DAC960 LA Series
392 Controllers with Single Mode Firmware.
395 static void DAC960_LA_QueueCommandSingleMode(DAC960_Command_T *Command)
397 DAC960_Controller_T *Controller = Command->Controller;
398 void *ControllerBaseAddress = Controller->BaseAddress;
399 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
400 DAC960_V1_CommandMailbox_T *NextCommandMailbox =
401 Controller->V1.NextCommandMailbox;
402 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
403 DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
404 if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
405 Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
406 DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
407 Controller->V1.PreviousCommandMailbox2 =
408 Controller->V1.PreviousCommandMailbox1;
409 Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
410 if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
411 NextCommandMailbox = Controller->V1.FirstCommandMailbox;
412 Controller->V1.NextCommandMailbox = NextCommandMailbox;
417 DAC960_PG_QueueCommandDualMode queues Command for DAC960 PG Series
418 Controllers with Dual Mode Firmware.
421 static void DAC960_PG_QueueCommandDualMode(DAC960_Command_T *Command)
423 DAC960_Controller_T *Controller = Command->Controller;
424 void *ControllerBaseAddress = Controller->BaseAddress;
425 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
426 DAC960_V1_CommandMailbox_T *NextCommandMailbox =
427 Controller->V1.NextCommandMailbox;
428 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
429 DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
430 if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
431 Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
432 DAC960_PG_MemoryMailboxNewCommand(ControllerBaseAddress);
433 Controller->V1.PreviousCommandMailbox2 =
434 Controller->V1.PreviousCommandMailbox1;
435 Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
436 if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
437 NextCommandMailbox = Controller->V1.FirstCommandMailbox;
438 Controller->V1.NextCommandMailbox = NextCommandMailbox;
443 DAC960_PG_QueueCommandSingleMode queues Command for DAC960 PG Series
444 Controllers with Single Mode Firmware.
447 static void DAC960_PG_QueueCommandSingleMode(DAC960_Command_T *Command)
449 DAC960_Controller_T *Controller = Command->Controller;
450 void *ControllerBaseAddress = Controller->BaseAddress;
451 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
452 DAC960_V1_CommandMailbox_T *NextCommandMailbox =
453 Controller->V1.NextCommandMailbox;
454 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
455 DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
456 if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
457 Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
458 DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
459 Controller->V1.PreviousCommandMailbox2 =
460 Controller->V1.PreviousCommandMailbox1;
461 Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
462 if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
463 NextCommandMailbox = Controller->V1.FirstCommandMailbox;
464 Controller->V1.NextCommandMailbox = NextCommandMailbox;
469 DAC960_PD_QueueCommand queues Command for DAC960 PD Series Controllers.
472 static void DAC960_PD_QueueCommand(DAC960_Command_T *Command)
474 DAC960_Controller_T *Controller = Command->Controller;
475 void *ControllerBaseAddress = Controller->BaseAddress;
476 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
477 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
478 while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
479 udelay(1);
480 DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
481 DAC960_PD_NewCommand(ControllerBaseAddress);
486 DAC960_ExecuteCommand executes Command and waits for completion.
489 static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
491 DAC960_Controller_T *Controller = Command->Controller;
492 DECLARE_MUTEX_LOCKED(Semaphore);
493 unsigned long ProcessorFlags;
494 Command->Semaphore = &Semaphore;
495 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
496 DAC960_QueueCommand(Command);
497 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
498 if (in_interrupt()) return;
499 down(&Semaphore);
504 DAC960_V1_ExecuteType3 executes a DAC960 V1 Firmware Controller Type 3
505 Command and waits for completion. It returns true on success and false
506 on failure.
509 static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
510 DAC960_V1_CommandOpcode_T CommandOpcode,
511 void *DataPointer)
513 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
514 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
515 DAC960_V1_CommandStatus_T CommandStatus;
516 DAC960_V1_ClearCommand(Command);
517 Command->CommandType = DAC960_ImmediateCommand;
518 CommandMailbox->Type3.CommandOpcode = CommandOpcode;
519 CommandMailbox->Type3.BusAddress = Virtual_to_Bus(DataPointer);
520 DAC960_ExecuteCommand(Command);
521 CommandStatus = Command->V1.CommandStatus;
522 DAC960_DeallocateCommand(Command);
523 return (CommandStatus == DAC960_V1_NormalCompletion);
528 DAC960_V1_ExecuteType3D executes a DAC960 V1 Firmware Controller Type 3D
529 Command and waits for completion. It returns true on success and false
530 on failure.
533 static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
534 DAC960_V1_CommandOpcode_T CommandOpcode,
535 unsigned char Channel,
536 unsigned char TargetID,
537 void *DataPointer)
539 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
540 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
541 DAC960_V1_CommandStatus_T CommandStatus;
542 DAC960_V1_ClearCommand(Command);
543 Command->CommandType = DAC960_ImmediateCommand;
544 CommandMailbox->Type3D.CommandOpcode = CommandOpcode;
545 CommandMailbox->Type3D.Channel = Channel;
546 CommandMailbox->Type3D.TargetID = TargetID;
547 CommandMailbox->Type3D.BusAddress = Virtual_to_Bus(DataPointer);
548 DAC960_ExecuteCommand(Command);
549 CommandStatus = Command->V1.CommandStatus;
550 DAC960_DeallocateCommand(Command);
551 return (CommandStatus == DAC960_V1_NormalCompletion);
556 DAC960_V2_GeneralInfo executes a DAC960 V2 Firmware General Information
557 Reading IOCTL Command and waits for completion. It returns true on success
558 and false on failure.
561 static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller,
562 DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
563 void *DataPointer,
564 unsigned int DataByteCount)
566 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
567 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
568 DAC960_V2_CommandStatus_T CommandStatus;
569 DAC960_V2_ClearCommand(Command);
570 Command->CommandType = DAC960_ImmediateCommand;
571 CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
572 CommandMailbox->Common.CommandControlBits
573 .DataTransferControllerToHost = true;
574 CommandMailbox->Common.CommandControlBits
575 .NoAutoRequestSense = true;
576 CommandMailbox->Common.DataTransferSize = DataByteCount;
577 CommandMailbox->Common.IOCTL_Opcode = IOCTL_Opcode;
578 CommandMailbox->Common.DataTransferMemoryAddress
579 .ScatterGatherSegments[0]
580 .SegmentDataPointer =
581 Virtual_to_Bus(DataPointer);
582 CommandMailbox->Common.DataTransferMemoryAddress
583 .ScatterGatherSegments[0]
584 .SegmentByteCount =
585 CommandMailbox->Common.DataTransferSize;
586 DAC960_ExecuteCommand(Command);
587 CommandStatus = Command->V2.CommandStatus;
588 DAC960_DeallocateCommand(Command);
589 return (CommandStatus == DAC960_V2_NormalCompletion);
594 DAC960_V2_ControllerInfo executes a DAC960 V2 Firmware Controller
595 Information Reading IOCTL Command and waits for completion. It returns
596 true on success and false on failure.
599 static boolean DAC960_V2_ControllerInfo(DAC960_Controller_T *Controller,
600 DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
601 void *DataPointer,
602 unsigned int DataByteCount)
604 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
605 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
606 DAC960_V2_CommandStatus_T CommandStatus;
607 DAC960_V2_ClearCommand(Command);
608 Command->CommandType = DAC960_ImmediateCommand;
609 CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
610 CommandMailbox->ControllerInfo.CommandControlBits
611 .DataTransferControllerToHost = true;
612 CommandMailbox->ControllerInfo.CommandControlBits
613 .NoAutoRequestSense = true;
614 CommandMailbox->ControllerInfo.DataTransferSize = DataByteCount;
615 CommandMailbox->ControllerInfo.ControllerNumber = 0;
616 CommandMailbox->ControllerInfo.IOCTL_Opcode = IOCTL_Opcode;
617 CommandMailbox->ControllerInfo.DataTransferMemoryAddress
618 .ScatterGatherSegments[0]
619 .SegmentDataPointer =
620 Virtual_to_Bus(DataPointer);
621 CommandMailbox->ControllerInfo.DataTransferMemoryAddress
622 .ScatterGatherSegments[0]
623 .SegmentByteCount =
624 CommandMailbox->ControllerInfo.DataTransferSize;
625 DAC960_ExecuteCommand(Command);
626 CommandStatus = Command->V2.CommandStatus;
627 DAC960_DeallocateCommand(Command);
628 return (CommandStatus == DAC960_V2_NormalCompletion);
633 DAC960_V2_LogicalDeviceInfo executes a DAC960 V2 Firmware Controller Logical
634 Device Information Reading IOCTL Command and waits for completion. It
635 returns true on success and false on failure.
638 static boolean DAC960_V2_LogicalDeviceInfo(DAC960_Controller_T *Controller,
639 DAC960_V2_IOCTL_Opcode_T
640 IOCTL_Opcode,
641 unsigned short
642 LogicalDeviceNumber,
643 void *DataPointer,
644 unsigned int DataByteCount)
646 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
647 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
648 DAC960_V2_CommandStatus_T CommandStatus;
649 DAC960_V2_ClearCommand(Command);
650 Command->CommandType = DAC960_ImmediateCommand;
651 CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
652 CommandMailbox->LogicalDeviceInfo.CommandControlBits
653 .DataTransferControllerToHost = true;
654 CommandMailbox->LogicalDeviceInfo.CommandControlBits
655 .NoAutoRequestSense = true;
656 CommandMailbox->LogicalDeviceInfo.DataTransferSize = DataByteCount;
657 CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
658 LogicalDeviceNumber;
659 CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
660 CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
661 .ScatterGatherSegments[0]
662 .SegmentDataPointer =
663 Virtual_to_Bus(DataPointer);
664 CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
665 .ScatterGatherSegments[0]
666 .SegmentByteCount =
667 CommandMailbox->LogicalDeviceInfo.DataTransferSize;
668 DAC960_ExecuteCommand(Command);
669 CommandStatus = Command->V2.CommandStatus;
670 DAC960_DeallocateCommand(Command);
671 return (CommandStatus == DAC960_V2_NormalCompletion);
676 DAC960_V2_PhysicalDeviceInfo executes a DAC960 V2 Firmware Controller Physical
677 Device Information Reading IOCTL Command and waits for completion. It
678 returns true on success and false on failure.
681 static boolean DAC960_V2_PhysicalDeviceInfo(DAC960_Controller_T *Controller,
682 DAC960_V2_IOCTL_Opcode_T
683 IOCTL_Opcode,
684 unsigned char Channel,
685 unsigned char TargetID,
686 unsigned char LogicalUnit,
687 void *DataPointer,
688 unsigned int DataByteCount)
690 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
691 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
692 DAC960_V2_CommandStatus_T CommandStatus;
693 DAC960_V2_ClearCommand(Command);
694 Command->CommandType = DAC960_ImmediateCommand;
695 CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
696 CommandMailbox->PhysicalDeviceInfo.CommandControlBits
697 .DataTransferControllerToHost = true;
698 CommandMailbox->PhysicalDeviceInfo.CommandControlBits
699 .NoAutoRequestSense = true;
700 CommandMailbox->PhysicalDeviceInfo.DataTransferSize = DataByteCount;
701 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit = LogicalUnit;
702 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
703 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
704 CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
705 CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
706 .ScatterGatherSegments[0]
707 .SegmentDataPointer =
708 Virtual_to_Bus(DataPointer);
709 CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
710 .ScatterGatherSegments[0]
711 .SegmentByteCount =
712 CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
713 DAC960_ExecuteCommand(Command);
714 CommandStatus = Command->V2.CommandStatus;
715 DAC960_DeallocateCommand(Command);
716 return (CommandStatus == DAC960_V2_NormalCompletion);
721 DAC960_V2_DeviceOperation executes a DAC960 V2 Firmware Controller Device
722 Operation IOCTL Command and waits for completion. It returns true on
723 success and false on failure.
726 static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
727 DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
728 DAC960_V2_OperationDevice_T
729 OperationDevice)
731 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
732 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
733 DAC960_V2_CommandStatus_T CommandStatus;
734 DAC960_V2_ClearCommand(Command);
735 Command->CommandType = DAC960_ImmediateCommand;
736 CommandMailbox->DeviceOperation.CommandOpcode = DAC960_V2_IOCTL;
737 CommandMailbox->DeviceOperation.CommandControlBits
738 .DataTransferControllerToHost = true;
739 CommandMailbox->DeviceOperation.CommandControlBits
740 .NoAutoRequestSense = true;
741 CommandMailbox->DeviceOperation.IOCTL_Opcode = IOCTL_Opcode;
742 CommandMailbox->DeviceOperation.OperationDevice = OperationDevice;
743 DAC960_ExecuteCommand(Command);
744 CommandStatus = Command->V2.CommandStatus;
745 DAC960_DeallocateCommand(Command);
746 return (CommandStatus == DAC960_V2_NormalCompletion);
751 DAC960_V1_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
752 for DAC960 V1 Firmware Controllers.
755 static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
756 *Controller)
758 void *ControllerBaseAddress = Controller->BaseAddress;
759 DAC960_V1_CommandMailbox_T *CommandMailboxesMemory;
760 DAC960_V1_StatusMailbox_T *StatusMailboxesMemory;
761 DAC960_V1_CommandMailbox_T CommandMailbox;
762 DAC960_V1_CommandStatus_T CommandStatus;
763 unsigned long MemoryMailboxPagesAddress;
764 unsigned long MemoryMailboxPagesOrder;
765 unsigned long MemoryMailboxPagesSize;
766 void *SavedMemoryMailboxesAddress = NULL;
767 short NextCommandMailboxIndex = 0;
768 short NextStatusMailboxIndex = 0;
769 int TimeoutCounter = 1000000, i;
770 MemoryMailboxPagesOrder = 0;
771 MemoryMailboxPagesSize =
772 DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T) +
773 DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T);
774 while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
775 MemoryMailboxPagesOrder++;
776 if (Controller->HardwareType == DAC960_LA_Controller)
777 DAC960_LA_RestoreMemoryMailboxInfo(Controller,
778 &SavedMemoryMailboxesAddress,
779 &NextCommandMailboxIndex,
780 &NextStatusMailboxIndex);
781 else DAC960_PG_RestoreMemoryMailboxInfo(Controller,
782 &SavedMemoryMailboxesAddress,
783 &NextCommandMailboxIndex,
784 &NextStatusMailboxIndex);
785 if (SavedMemoryMailboxesAddress == NULL)
787 MemoryMailboxPagesAddress =
788 __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
789 Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
790 CommandMailboxesMemory =
791 (DAC960_V1_CommandMailbox_T *) MemoryMailboxPagesAddress;
793 else CommandMailboxesMemory = SavedMemoryMailboxesAddress;
794 if (CommandMailboxesMemory == NULL) return false;
795 Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
796 memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
797 Controller->V1.FirstCommandMailbox = CommandMailboxesMemory;
798 CommandMailboxesMemory += DAC960_V1_CommandMailboxCount - 1;
799 Controller->V1.LastCommandMailbox = CommandMailboxesMemory;
800 Controller->V1.NextCommandMailbox =
801 &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
802 if (--NextCommandMailboxIndex < 0)
803 NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
804 Controller->V1.PreviousCommandMailbox1 =
805 &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
806 if (--NextCommandMailboxIndex < 0)
807 NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
808 Controller->V1.PreviousCommandMailbox2 =
809 &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
810 StatusMailboxesMemory =
811 (DAC960_V1_StatusMailbox_T *) (CommandMailboxesMemory + 1);
812 Controller->V1.FirstStatusMailbox = StatusMailboxesMemory;
813 StatusMailboxesMemory += DAC960_V1_StatusMailboxCount - 1;
814 Controller->V1.LastStatusMailbox = StatusMailboxesMemory;
815 Controller->V1.NextStatusMailbox =
816 &Controller->V1.FirstStatusMailbox[NextStatusMailboxIndex];
817 if (SavedMemoryMailboxesAddress != NULL) return true;
818 /* Enable the Memory Mailbox Interface. */
819 Controller->V1.DualModeMemoryMailboxInterface = true;
820 CommandMailbox.TypeX.CommandOpcode = 0x2B;
821 CommandMailbox.TypeX.CommandIdentifier = 0;
822 CommandMailbox.TypeX.CommandOpcode2 = 0x14;
823 CommandMailbox.TypeX.CommandMailboxesBusAddress =
824 Virtual_to_Bus(Controller->V1.FirstCommandMailbox);
825 CommandMailbox.TypeX.StatusMailboxesBusAddress =
826 Virtual_to_Bus(Controller->V1.FirstStatusMailbox);
827 for (i = 0; i < 2; i++)
828 switch (Controller->HardwareType)
830 case DAC960_LA_Controller:
831 while (--TimeoutCounter >= 0)
833 if (!DAC960_LA_HardwareMailboxFullP(ControllerBaseAddress))
834 break;
835 udelay(10);
837 if (TimeoutCounter < 0) return false;
838 DAC960_LA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
839 DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
840 while (--TimeoutCounter >= 0)
842 if (DAC960_LA_HardwareMailboxStatusAvailableP(
843 ControllerBaseAddress))
844 break;
845 udelay(10);
847 if (TimeoutCounter < 0) return false;
848 CommandStatus = DAC960_LA_ReadStatusRegister(ControllerBaseAddress);
849 DAC960_LA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
850 DAC960_LA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
851 if (CommandStatus == DAC960_V1_NormalCompletion) return true;
852 Controller->V1.DualModeMemoryMailboxInterface = false;
853 CommandMailbox.TypeX.CommandOpcode2 = 0x10;
854 break;
855 case DAC960_PG_Controller:
856 while (--TimeoutCounter >= 0)
858 if (!DAC960_PG_HardwareMailboxFullP(ControllerBaseAddress))
859 break;
860 udelay(10);
862 if (TimeoutCounter < 0) return false;
863 DAC960_PG_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
864 DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
865 while (--TimeoutCounter >= 0)
867 if (DAC960_PG_HardwareMailboxStatusAvailableP(
868 ControllerBaseAddress))
869 break;
870 udelay(10);
872 if (TimeoutCounter < 0) return false;
873 CommandStatus = DAC960_PG_ReadStatusRegister(ControllerBaseAddress);
874 DAC960_PG_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
875 DAC960_PG_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
876 if (CommandStatus == DAC960_V1_NormalCompletion) return true;
877 Controller->V1.DualModeMemoryMailboxInterface = false;
878 CommandMailbox.TypeX.CommandOpcode2 = 0x10;
879 break;
880 default:
881 break;
883 return false;
888 DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
889 for DAC960 V2 Firmware Controllers.
892 static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
893 *Controller)
895 void *ControllerBaseAddress = Controller->BaseAddress;
896 DAC960_V2_CommandMailbox_T *CommandMailboxesMemory;
897 DAC960_V2_StatusMailbox_T *StatusMailboxesMemory;
898 DAC960_V2_CommandMailbox_T CommandMailbox;
899 DAC960_V2_CommandStatus_T CommandStatus = 0;
900 unsigned long MemoryMailboxPagesAddress;
901 unsigned long MemoryMailboxPagesOrder;
902 unsigned long MemoryMailboxPagesSize;
903 MemoryMailboxPagesOrder = 0;
904 MemoryMailboxPagesSize =
905 DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T) +
906 DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T) +
907 sizeof(DAC960_V2_HealthStatusBuffer_T);
908 while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
909 MemoryMailboxPagesOrder++;
910 MemoryMailboxPagesAddress =
911 __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
912 Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
913 CommandMailboxesMemory =
914 (DAC960_V2_CommandMailbox_T *) MemoryMailboxPagesAddress;
915 if (CommandMailboxesMemory == NULL) return false;
916 Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
917 memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
918 Controller->V2.FirstCommandMailbox = CommandMailboxesMemory;
919 CommandMailboxesMemory += DAC960_V2_CommandMailboxCount - 1;
920 Controller->V2.LastCommandMailbox = CommandMailboxesMemory;
921 Controller->V2.NextCommandMailbox = Controller->V2.FirstCommandMailbox;
922 Controller->V2.PreviousCommandMailbox1 = Controller->V2.LastCommandMailbox;
923 Controller->V2.PreviousCommandMailbox2 =
924 Controller->V2.LastCommandMailbox - 1;
925 StatusMailboxesMemory =
926 (DAC960_V2_StatusMailbox_T *) (CommandMailboxesMemory + 1);
927 Controller->V2.FirstStatusMailbox = StatusMailboxesMemory;
928 StatusMailboxesMemory += DAC960_V2_StatusMailboxCount - 1;
929 Controller->V2.LastStatusMailbox = StatusMailboxesMemory;
930 Controller->V2.NextStatusMailbox = Controller->V2.FirstStatusMailbox;
931 Controller->V2.HealthStatusBuffer =
932 (DAC960_V2_HealthStatusBuffer_T *) (StatusMailboxesMemory + 1);
933 /* Enable the Memory Mailbox Interface. */
934 memset(&CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
935 CommandMailbox.SetMemoryMailbox.CommandIdentifier = 1;
936 CommandMailbox.SetMemoryMailbox.CommandOpcode = DAC960_V2_IOCTL;
937 CommandMailbox.SetMemoryMailbox.CommandControlBits.NoAutoRequestSense = true;
938 CommandMailbox.SetMemoryMailbox.FirstCommandMailboxSizeKB =
939 (DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T)) >> 10;
940 CommandMailbox.SetMemoryMailbox.FirstStatusMailboxSizeKB =
941 (DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T)) >> 10;
942 CommandMailbox.SetMemoryMailbox.SecondCommandMailboxSizeKB = 0;
943 CommandMailbox.SetMemoryMailbox.SecondStatusMailboxSizeKB = 0;
944 CommandMailbox.SetMemoryMailbox.RequestSenseSize = 0;
945 CommandMailbox.SetMemoryMailbox.IOCTL_Opcode = DAC960_V2_SetMemoryMailbox;
946 CommandMailbox.SetMemoryMailbox.HealthStatusBufferSizeKB = 1;
947 CommandMailbox.SetMemoryMailbox.HealthStatusBufferBusAddress =
948 Virtual_to_Bus(Controller->V2.HealthStatusBuffer);
949 CommandMailbox.SetMemoryMailbox.FirstCommandMailboxBusAddress =
950 Virtual_to_Bus(Controller->V2.FirstCommandMailbox);
951 CommandMailbox.SetMemoryMailbox.FirstStatusMailboxBusAddress =
952 Virtual_to_Bus(Controller->V2.FirstStatusMailbox);
953 switch (Controller->HardwareType)
955 case DAC960_BA_Controller:
956 while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress))
957 udelay(1);
958 DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
959 DAC960_BA_HardwareMailboxNewCommand(ControllerBaseAddress);
960 while (!DAC960_BA_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
961 udelay(1);
962 CommandStatus = DAC960_BA_ReadCommandStatus(ControllerBaseAddress);
963 DAC960_BA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
964 DAC960_BA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
965 break;
966 case DAC960_LP_Controller:
967 while (DAC960_LP_HardwareMailboxFullP(ControllerBaseAddress))
968 udelay(1);
969 DAC960_LP_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
970 DAC960_LP_HardwareMailboxNewCommand(ControllerBaseAddress);
971 while (!DAC960_LP_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
972 udelay(1);
973 CommandStatus = DAC960_LP_ReadCommandStatus(ControllerBaseAddress);
974 DAC960_LP_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
975 DAC960_LP_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
976 break;
977 default:
978 break;
980 return (CommandStatus == DAC960_V2_NormalCompletion);
985 DAC960_V1_ReadControllerConfiguration reads the Configuration Information
986 from DAC960 V1 Firmware Controllers and initializes the Controller structure.
989 static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
990 *Controller)
992 DAC960_V1_Enquiry2_T Enquiry2;
993 DAC960_V1_Config2_T Config2;
994 int LogicalDriveNumber, Channel, TargetID;
995 if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry,
996 &Controller->V1.Enquiry))
997 return DAC960_Failure(Controller, "ENQUIRY");
998 if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, &Enquiry2))
999 return DAC960_Failure(Controller, "ENQUIRY2");
1000 if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, &Config2))
1001 return DAC960_Failure(Controller, "READ CONFIG2");
1002 if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_GetLogicalDriveInformation,
1003 &Controller->V1.LogicalDriveInformation))
1004 return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION");
1005 for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++)
1006 for (TargetID = 0; TargetID < Enquiry2.MaxTargets; TargetID++)
1007 if (!DAC960_V1_ExecuteType3D(Controller, DAC960_V1_GetDeviceState,
1008 Channel, TargetID,
1009 &Controller->V1.DeviceState
1010 [Channel][TargetID]))
1011 return DAC960_Failure(Controller, "GET DEVICE STATE");
1013 Initialize the Controller Model Name and Full Model Name fields.
1015 switch (Enquiry2.HardwareID.SubModel)
1017 case DAC960_V1_P_PD_PU:
1018 if (Enquiry2.SCSICapability.BusSpeed == DAC960_V1_Ultra)
1019 strcpy(Controller->ModelName, "DAC960PU");
1020 else strcpy(Controller->ModelName, "DAC960PD");
1021 break;
1022 case DAC960_V1_PL:
1023 strcpy(Controller->ModelName, "DAC960PL");
1024 break;
1025 case DAC960_V1_PG:
1026 strcpy(Controller->ModelName, "DAC960PG");
1027 break;
1028 case DAC960_V1_PJ:
1029 strcpy(Controller->ModelName, "DAC960PJ");
1030 break;
1031 case DAC960_V1_PR:
1032 strcpy(Controller->ModelName, "DAC960PR");
1033 break;
1034 case DAC960_V1_PT:
1035 strcpy(Controller->ModelName, "DAC960PT");
1036 break;
1037 case DAC960_V1_PTL0:
1038 strcpy(Controller->ModelName, "DAC960PTL0");
1039 break;
1040 case DAC960_V1_PRL:
1041 strcpy(Controller->ModelName, "DAC960PRL");
1042 break;
1043 case DAC960_V1_PTL1:
1044 strcpy(Controller->ModelName, "DAC960PTL1");
1045 break;
1046 case DAC960_V1_1164P:
1047 strcpy(Controller->ModelName, "DAC1164P");
1048 break;
1049 default:
1050 return DAC960_Failure(Controller, "MODEL VERIFICATION");
1052 strcpy(Controller->FullModelName, "Mylex ");
1053 strcat(Controller->FullModelName, Controller->ModelName);
1055 Initialize the Controller Firmware Version field and verify that it
1056 is a supported firmware version. The supported firmware versions are:
1058 DAC1164P 5.06 and above
1059 DAC960PTL/PRL/PJ/PG 4.06 and above
1060 DAC960PU/PD/PL 3.51 and above
1062 sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
1063 Enquiry2.FirmwareID.MajorVersion, Enquiry2.FirmwareID.MinorVersion,
1064 Enquiry2.FirmwareID.FirmwareType, Enquiry2.FirmwareID.TurnID);
1065 if (!((Controller->FirmwareVersion[0] == '5' &&
1066 strcmp(Controller->FirmwareVersion, "5.06") >= 0) ||
1067 (Controller->FirmwareVersion[0] == '4' &&
1068 strcmp(Controller->FirmwareVersion, "4.06") >= 0) ||
1069 (Controller->FirmwareVersion[0] == '3' &&
1070 strcmp(Controller->FirmwareVersion, "3.51") >= 0)))
1072 DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
1073 DAC960_Error("Firmware Version = '%s'\n", Controller,
1074 Controller->FirmwareVersion);
1075 return false;
1078 Initialize the Controller Channels, Targets, Memory Size, and SAF-TE
1079 Enclosure Management Enabled fields.
1081 Controller->Channels = Enquiry2.ActualChannels;
1082 Controller->Targets = Enquiry2.MaxTargets;
1083 Controller->MemorySize = Enquiry2.MemorySize >> 20;
1084 Controller->V1.SAFTE_EnclosureManagementEnabled =
1085 (Enquiry2.FaultManagementType == DAC960_V1_SAFTE);
1087 Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
1088 Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
1089 Driver Scatter/Gather Limit. The Driver Queue Depth must be at most one
1090 less than the Controller Queue Depth to allow for an automatic drive
1091 rebuild operation.
1093 Controller->ControllerQueueDepth = Controller->V1.Enquiry.MaxCommands;
1094 Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
1095 if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
1096 Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
1097 Controller->LogicalDriveCount =
1098 Controller->V1.Enquiry.NumberOfLogicalDrives;
1099 Controller->MaxBlocksPerCommand = Enquiry2.MaxBlocksPerCommand;
1100 Controller->ControllerScatterGatherLimit = Enquiry2.MaxScatterGatherEntries;
1101 Controller->DriverScatterGatherLimit =
1102 Controller->ControllerScatterGatherLimit;
1103 if (Controller->DriverScatterGatherLimit > DAC960_V1_ScatterGatherLimit)
1104 Controller->DriverScatterGatherLimit = DAC960_V1_ScatterGatherLimit;
1106 Initialize the Stripe Size, Segment Size, and Geometry Translation.
1108 Controller->V1.StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
1109 >> (10 - DAC960_BlockSizeBits);
1110 Controller->V1.SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
1111 >> (10 - DAC960_BlockSizeBits);
1112 switch (Config2.DriveGeometry)
1114 case DAC960_V1_Geometry_128_32:
1115 Controller->V1.GeometryTranslationHeads = 128;
1116 Controller->V1.GeometryTranslationSectors = 32;
1117 break;
1118 case DAC960_V1_Geometry_255_63:
1119 Controller->V1.GeometryTranslationHeads = 255;
1120 Controller->V1.GeometryTranslationSectors = 63;
1121 break;
1122 default:
1123 return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
1126 Initialize the Logical Drive Initially Accessible flag.
1128 for (LogicalDriveNumber = 0;
1129 LogicalDriveNumber < Controller->LogicalDriveCount;
1130 LogicalDriveNumber++)
1131 if (Controller->V1.LogicalDriveInformation
1132 [LogicalDriveNumber].LogicalDriveState !=
1133 DAC960_V1_LogicalDrive_Offline)
1134 Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
1135 Controller->V1.LastRebuildStatus = DAC960_V1_NoRebuildOrCheckInProgress;
1136 return true;
1141 DAC960_V2_ReadControllerConfiguration reads the Configuration Information
1142 from DAC960 V2 Firmware Controllers and initializes the Controller structure.
1145 static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
1146 *Controller)
1148 DAC960_V2_ControllerInfo_T *ControllerInfo =
1149 &Controller->V2.ControllerInformation;
1150 unsigned short LogicalDeviceNumber = 0;
1151 int ModelNameLength;
1152 if (!DAC960_V2_ControllerInfo(Controller, DAC960_V2_GetControllerInfo,
1153 ControllerInfo,
1154 sizeof(DAC960_V2_ControllerInfo_T)))
1155 return DAC960_Failure(Controller, "GET CONTROLLER INFO");
1156 if (!DAC960_V2_GeneralInfo(Controller, DAC960_V2_GetHealthStatus,
1157 Controller->V2.HealthStatusBuffer,
1158 sizeof(DAC960_V2_HealthStatusBuffer_T)))
1159 return DAC960_Failure(Controller, "GET HEALTH STATUS");
1161 Initialize the Controller Model Name and Full Model Name fields.
1163 ModelNameLength = sizeof(ControllerInfo->ControllerName);
1164 if (ModelNameLength > sizeof(Controller->ModelName)-1)
1165 ModelNameLength = sizeof(Controller->ModelName)-1;
1166 memcpy(Controller->ModelName, ControllerInfo->ControllerName,
1167 ModelNameLength);
1168 ModelNameLength--;
1169 while (Controller->ModelName[ModelNameLength] == ' ' ||
1170 Controller->ModelName[ModelNameLength] == '\0')
1171 ModelNameLength--;
1172 Controller->ModelName[++ModelNameLength] = '\0';
1173 strcpy(Controller->FullModelName, "Mylex ");
1174 strcat(Controller->FullModelName, Controller->ModelName);
1176 Initialize the Controller Firmware Version field.
1178 sprintf(Controller->FirmwareVersion, "%d.%02d-%02d",
1179 ControllerInfo->FirmwareMajorVersion,
1180 ControllerInfo->FirmwareMinorVersion,
1181 ControllerInfo->FirmwareTurnNumber);
1182 if (ControllerInfo->FirmwareMajorVersion == 6 &&
1183 ControllerInfo->FirmwareMinorVersion == 0 &&
1184 ControllerInfo->FirmwareTurnNumber < 1)
1186 DAC960_Info("FIRMWARE VERSION %s DOES NOT PROVIDE THE CONTROLLER\n",
1187 Controller, Controller->FirmwareVersion);
1188 DAC960_Info("STATUS MONITORING FUNCTIONALITY NEEDED BY THIS DRIVER.\n",
1189 Controller);
1190 DAC960_Info("PLEASE UPGRADE TO VERSION 6.00-01 OR ABOVE.\n",
1191 Controller);
1194 Initialize the Controller Channels, Targets, and Memory Size.
1196 Controller->Channels = ControllerInfo->NumberOfPhysicalChannelsPresent;
1197 Controller->Targets =
1198 ControllerInfo->MaximumTargetsPerChannel
1199 [ControllerInfo->NumberOfPhysicalChannelsPresent-1];
1200 Controller->MemorySize = ControllerInfo->MemorySizeMB;
1202 Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
1203 Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
1204 Driver Scatter/Gather Limit. The Driver Queue Depth must be at most one
1205 less than the Controller Queue Depth to allow for an automatic drive
1206 rebuild operation.
1208 Controller->ControllerQueueDepth = ControllerInfo->MaximumParallelCommands;
1209 Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
1210 if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
1211 Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
1212 Controller->LogicalDriveCount = ControllerInfo->LogicalDevicesPresent;
1213 Controller->MaxBlocksPerCommand =
1214 ControllerInfo->MaximumDataTransferSizeInBlocks;
1215 Controller->ControllerScatterGatherLimit =
1216 ControllerInfo->MaximumScatterGatherEntries;
1217 Controller->DriverScatterGatherLimit =
1218 Controller->ControllerScatterGatherLimit;
1219 if (Controller->DriverScatterGatherLimit > DAC960_V2_ScatterGatherLimit)
1220 Controller->DriverScatterGatherLimit = DAC960_V2_ScatterGatherLimit;
1222 Initialize the Logical Device Information.
1224 while (true)
1226 DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
1227 &Controller->V2.NewLogicalDeviceInformation;
1228 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo;
1229 DAC960_V2_PhysicalDevice_T PhysicalDevice;
1230 if (!DAC960_V2_LogicalDeviceInfo(Controller,
1231 DAC960_V2_GetLogicalDeviceInfoValid,
1232 LogicalDeviceNumber,
1233 NewLogicalDeviceInfo,
1234 sizeof(DAC960_V2_LogicalDeviceInfo_T)))
1235 break;
1236 LogicalDeviceNumber = NewLogicalDeviceInfo->LogicalDeviceNumber;
1237 if (LogicalDeviceNumber > DAC960_MaxLogicalDrives)
1238 panic("DAC960: Logical Drive Number %d not supported\n",
1239 LogicalDeviceNumber);
1240 if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize)
1241 panic("DAC960: Logical Drive Block Size %d not supported\n",
1242 NewLogicalDeviceInfo->DeviceBlockSizeInBytes);
1243 PhysicalDevice.Controller = 0;
1244 PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
1245 PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
1246 PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
1247 Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
1248 PhysicalDevice;
1249 if (NewLogicalDeviceInfo->LogicalDeviceState !=
1250 DAC960_V2_LogicalDevice_Offline)
1251 Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true;
1252 LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
1253 kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
1254 if (LogicalDeviceInfo == NULL)
1255 return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION");
1256 Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
1257 LogicalDeviceInfo;
1258 memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
1259 sizeof(DAC960_V2_LogicalDeviceInfo_T));
1260 LogicalDeviceNumber++;
1262 return true;
1267 DAC960_ReportControllerConfiguration reports the Configuration Information
1268 for Controller.
1271 static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
1272 *Controller)
1274 DAC960_Info("Configuring Mylex %s PCI RAID Controller\n",
1275 Controller, Controller->ModelName);
1276 DAC960_Info(" Firmware Version: %s, Channels: %d, Memory Size: %dMB\n",
1277 Controller, Controller->FirmwareVersion,
1278 Controller->Channels, Controller->MemorySize);
1279 DAC960_Info(" PCI Bus: %d, Device: %d, Function: %d, I/O Address: ",
1280 Controller, Controller->Bus,
1281 Controller->Device, Controller->Function);
1282 if (Controller->IO_Address == 0)
1283 DAC960_Info("Unassigned\n", Controller);
1284 else DAC960_Info("0x%X\n", Controller, Controller->IO_Address);
1285 DAC960_Info(" PCI Address: 0x%X mapped at 0x%lX, IRQ Channel: %d\n",
1286 Controller, Controller->PCI_Address,
1287 (unsigned long) Controller->BaseAddress,
1288 Controller->IRQ_Channel);
1289 DAC960_Info(" Controller Queue Depth: %d, "
1290 "Maximum Blocks per Command: %d\n",
1291 Controller, Controller->ControllerQueueDepth,
1292 Controller->MaxBlocksPerCommand);
1293 DAC960_Info(" Driver Queue Depth: %d, "
1294 "Scatter/Gather Limit: %d of %d Segments\n",
1295 Controller, Controller->DriverQueueDepth,
1296 Controller->DriverScatterGatherLimit,
1297 Controller->ControllerScatterGatherLimit);
1298 if (Controller->FirmwareType == DAC960_V1_Controller)
1300 DAC960_Info(" Stripe Size: %dKB, Segment Size: %dKB, "
1301 "BIOS Geometry: %d/%d\n", Controller,
1302 Controller->V1.StripeSize,
1303 Controller->V1.SegmentSize,
1304 Controller->V1.GeometryTranslationHeads,
1305 Controller->V1.GeometryTranslationSectors);
1306 if (Controller->V1.SAFTE_EnclosureManagementEnabled)
1307 DAC960_Info(" SAF-TE Enclosure Management Enabled\n", Controller);
1309 return true;
1314 DAC960_V1_ReadDeviceConfiguration reads the Device Configuration Information
1315 for DAC960 V1 Firmware Controllers by requesting the SCSI Inquiry and SCSI
1316 Inquiry Unit Serial Number information for each device connected to
1317 Controller.
1320 static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
1321 *Controller)
1323 DAC960_V1_DCDB_T DCDBs[DAC960_V1_MaxChannels], *DCDB;
1324 Semaphore_T Semaphores[DAC960_V1_MaxChannels], *Semaphore;
1325 unsigned long ProcessorFlags;
1326 int Channel, TargetID;
1327 for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
1329 for (Channel = 0; Channel < Controller->Channels; Channel++)
1331 DAC960_Command_T *Command = Controller->Commands[Channel];
1332 DAC960_SCSI_Inquiry_T *InquiryStandardData =
1333 &Controller->V1.InquiryStandardData[Channel][TargetID];
1334 InquiryStandardData->PeripheralDeviceType = 0x1F;
1335 Semaphore = &Semaphores[Channel];
1336 init_MUTEX_LOCKED(Semaphore);
1337 DCDB = &DCDBs[Channel];
1338 DAC960_V1_ClearCommand(Command);
1339 Command->CommandType = DAC960_ImmediateCommand;
1340 Command->Semaphore = Semaphore;
1341 Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
1342 Command->V1.CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
1343 DCDB->Channel = Channel;
1344 DCDB->TargetID = TargetID;
1345 DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
1346 DCDB->EarlyStatus = false;
1347 DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
1348 DCDB->NoAutomaticRequestSense = false;
1349 DCDB->DisconnectPermitted = true;
1350 DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
1351 DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
1352 DCDB->CDBLength = 6;
1353 DCDB->TransferLengthHigh4 = 0;
1354 DCDB->SenseLength = sizeof(DCDB->SenseData);
1355 DCDB->CDB[0] = 0x12; /* INQUIRY */
1356 DCDB->CDB[1] = 0; /* EVPD = 0 */
1357 DCDB->CDB[2] = 0; /* Page Code */
1358 DCDB->CDB[3] = 0; /* Reserved */
1359 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
1360 DCDB->CDB[5] = 0; /* Control */
1361 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
1362 DAC960_QueueCommand(Command);
1363 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
1365 for (Channel = 0; Channel < Controller->Channels; Channel++)
1367 DAC960_Command_T *Command = Controller->Commands[Channel];
1368 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
1369 &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
1370 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
1371 Semaphore = &Semaphores[Channel];
1372 down(Semaphore);
1373 if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion)
1374 continue;
1375 Command->Semaphore = Semaphore;
1376 DCDB = &DCDBs[Channel];
1377 DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1378 DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
1379 DCDB->SenseLength = sizeof(DCDB->SenseData);
1380 DCDB->CDB[0] = 0x12; /* INQUIRY */
1381 DCDB->CDB[1] = 1; /* EVPD = 1 */
1382 DCDB->CDB[2] = 0x80; /* Page Code */
1383 DCDB->CDB[3] = 0; /* Reserved */
1384 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1385 DCDB->CDB[5] = 0; /* Control */
1386 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
1387 DAC960_QueueCommand(Command);
1388 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
1389 down(Semaphore);
1392 return true;
1397 DAC960_V2_ReadDeviceConfiguration reads the Device Configuration Information
1398 for DAC960 V2 Firmware Controllers by requesting the Physical Device
1399 Information and SCSI Inquiry Unit Serial Number information for each
1400 device connected to Controller.
1403 static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
1404 *Controller)
1406 unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0;
1407 unsigned short PhysicalDeviceIndex = 0;
1408 while (true)
1410 DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
1411 &Controller->V2.NewPhysicalDeviceInformation;
1412 DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo;
1413 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
1414 DAC960_Command_T *Command;
1415 DAC960_V2_CommandMailbox_T *CommandMailbox;
1416 if (!DAC960_V2_PhysicalDeviceInfo(Controller,
1417 DAC960_V2_GetPhysicalDeviceInfoValid,
1418 Channel,
1419 TargetID,
1420 LogicalUnit,
1421 NewPhysicalDeviceInfo,
1422 sizeof(DAC960_V2_PhysicalDeviceInfo_T)))
1423 break;
1424 Channel = NewPhysicalDeviceInfo->Channel;
1425 TargetID = NewPhysicalDeviceInfo->TargetID;
1426 LogicalUnit = NewPhysicalDeviceInfo->LogicalUnit;
1427 PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
1428 kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
1429 if (PhysicalDeviceInfo == NULL)
1430 return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION");
1431 Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] =
1432 PhysicalDeviceInfo;
1433 memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
1434 sizeof(DAC960_V2_PhysicalDeviceInfo_T));
1435 InquiryUnitSerialNumber = (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
1436 kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
1437 if (InquiryUnitSerialNumber == NULL)
1438 return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION");
1439 Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex] =
1440 InquiryUnitSerialNumber;
1441 memset(InquiryUnitSerialNumber, 0,
1442 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
1443 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
1444 Command = DAC960_AllocateCommand(Controller);
1445 CommandMailbox = &Command->V2.CommandMailbox;
1446 DAC960_V2_ClearCommand(Command);
1447 Command->CommandType = DAC960_ImmediateCommand;
1448 CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10_Passthru;
1449 CommandMailbox->SCSI_10.CommandControlBits
1450 .DataTransferControllerToHost = true;
1451 CommandMailbox->SCSI_10.CommandControlBits
1452 .NoAutoRequestSense = true;
1453 CommandMailbox->SCSI_10.DataTransferSize =
1454 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1455 CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit = LogicalUnit;
1456 CommandMailbox->SCSI_10.PhysicalDevice.TargetID = TargetID;
1457 CommandMailbox->SCSI_10.PhysicalDevice.Channel = Channel;
1458 CommandMailbox->SCSI_10.CDBLength = 6;
1459 CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
1460 CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
1461 CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
1462 CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
1463 CommandMailbox->SCSI_10.SCSI_CDB[4] =
1464 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1465 CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
1466 CommandMailbox->SCSI_10.DataTransferMemoryAddress
1467 .ScatterGatherSegments[0]
1468 .SegmentDataPointer =
1469 Virtual_to_Bus(InquiryUnitSerialNumber);
1470 CommandMailbox->SCSI_10.DataTransferMemoryAddress
1471 .ScatterGatherSegments[0]
1472 .SegmentByteCount =
1473 CommandMailbox->SCSI_10.DataTransferSize;
1474 DAC960_ExecuteCommand(Command);
1475 DAC960_DeallocateCommand(Command);
1476 PhysicalDeviceIndex++;
1477 LogicalUnit++;
1479 return true;
1484 DAC960_SanitizeInquiryData sanitizes the Vendor, Model, Revision, and
1485 Product Serial Number fields of the Inquiry Standard Data and Inquiry
1486 Unit Serial Number structures.
1489 static void DAC960_SanitizeInquiryData(DAC960_SCSI_Inquiry_T
1490 *InquiryStandardData,
1491 DAC960_SCSI_Inquiry_UnitSerialNumber_T
1492 *InquiryUnitSerialNumber,
1493 unsigned char *Vendor,
1494 unsigned char *Model,
1495 unsigned char *Revision,
1496 unsigned char *SerialNumber)
1498 int SerialNumberLength, i;
1499 if (InquiryStandardData->PeripheralDeviceType == 0x1F) return;
1500 for (i = 0; i < sizeof(InquiryStandardData->VendorIdentification); i++)
1502 unsigned char VendorCharacter =
1503 InquiryStandardData->VendorIdentification[i];
1504 Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~'
1505 ? VendorCharacter : ' ');
1507 Vendor[sizeof(InquiryStandardData->VendorIdentification)] = '\0';
1508 for (i = 0; i < sizeof(InquiryStandardData->ProductIdentification); i++)
1510 unsigned char ModelCharacter =
1511 InquiryStandardData->ProductIdentification[i];
1512 Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
1513 ? ModelCharacter : ' ');
1515 Model[sizeof(InquiryStandardData->ProductIdentification)] = '\0';
1516 for (i = 0; i < sizeof(InquiryStandardData->ProductRevisionLevel); i++)
1518 unsigned char RevisionCharacter =
1519 InquiryStandardData->ProductRevisionLevel[i];
1520 Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
1521 ? RevisionCharacter : ' ');
1523 Revision[sizeof(InquiryStandardData->ProductRevisionLevel)] = '\0';
1524 if (InquiryUnitSerialNumber->PeripheralDeviceType == 0x1F) return;
1525 SerialNumberLength = InquiryUnitSerialNumber->PageLength;
1526 if (SerialNumberLength >
1527 sizeof(InquiryUnitSerialNumber->ProductSerialNumber))
1528 SerialNumberLength = sizeof(InquiryUnitSerialNumber->ProductSerialNumber);
1529 for (i = 0; i < SerialNumberLength; i++)
1531 unsigned char SerialNumberCharacter =
1532 InquiryUnitSerialNumber->ProductSerialNumber[i];
1533 SerialNumber[i] =
1534 (SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~'
1535 ? SerialNumberCharacter : ' ');
1537 SerialNumber[SerialNumberLength] = '\0';
1542 DAC960_V1_ReportDeviceConfiguration reports the Device Configuration
1543 Information for DAC960 V1 Firmware Controllers.
1546 static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
1547 *Controller)
1549 int LogicalDriveNumber, Channel, TargetID;
1550 DAC960_Info(" Physical Devices:\n", Controller);
1551 for (Channel = 0; Channel < Controller->Channels; Channel++)
1552 for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
1554 DAC960_SCSI_Inquiry_T *InquiryStandardData =
1555 &Controller->V1.InquiryStandardData[Channel][TargetID];
1556 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
1557 &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
1558 DAC960_V1_DeviceState_T *DeviceState =
1559 &Controller->V1.DeviceState[Channel][TargetID];
1560 DAC960_V1_ErrorTableEntry_T *ErrorEntry =
1561 &Controller->V1.ErrorTable.ErrorTableEntries[Channel][TargetID];
1562 char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
1563 char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
1564 char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
1565 char SerialNumber[1+sizeof(InquiryUnitSerialNumber
1566 ->ProductSerialNumber)];
1567 if (InquiryStandardData->PeripheralDeviceType == 0x1F) continue;
1568 DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
1569 Vendor, Model, Revision, SerialNumber);
1570 DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %s\n",
1571 Controller, Channel, TargetID, (TargetID < 10 ? " " : ""),
1572 Vendor, Model, Revision);
1573 if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
1574 DAC960_Info(" Serial Number: %s\n", Controller, SerialNumber);
1575 if (DeviceState->Present &&
1576 DeviceState->DeviceType == DAC960_V1_DiskType)
1578 if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0)
1579 DAC960_Info(" Disk Status: %s, %d blocks, %d resets\n",
1580 Controller,
1581 (DeviceState->DeviceState == DAC960_V1_Device_Dead
1582 ? "Dead"
1583 : DeviceState->DeviceState
1584 == DAC960_V1_Device_WriteOnly
1585 ? "Write-Only"
1586 : DeviceState->DeviceState
1587 == DAC960_V1_Device_Online
1588 ? "Online" : "Standby"),
1589 DeviceState->DiskSize,
1590 Controller->V1.DeviceResetCount[Channel][TargetID]);
1591 else
1592 DAC960_Info(" Disk Status: %s, %d blocks\n", Controller,
1593 (DeviceState->DeviceState == DAC960_V1_Device_Dead
1594 ? "Dead"
1595 : DeviceState->DeviceState
1596 == DAC960_V1_Device_WriteOnly
1597 ? "Write-Only"
1598 : DeviceState->DeviceState
1599 == DAC960_V1_Device_Online
1600 ? "Online" : "Standby"),
1601 DeviceState->DiskSize);
1603 if (ErrorEntry->ParityErrorCount > 0 ||
1604 ErrorEntry->SoftErrorCount > 0 ||
1605 ErrorEntry->HardErrorCount > 0 ||
1606 ErrorEntry->MiscErrorCount > 0)
1607 DAC960_Info(" Errors - Parity: %d, Soft: %d, "
1608 "Hard: %d, Misc: %d\n", Controller,
1609 ErrorEntry->ParityErrorCount,
1610 ErrorEntry->SoftErrorCount,
1611 ErrorEntry->HardErrorCount,
1612 ErrorEntry->MiscErrorCount);
1614 DAC960_Info(" Logical Drives:\n", Controller);
1615 for (LogicalDriveNumber = 0;
1616 LogicalDriveNumber < Controller->LogicalDriveCount;
1617 LogicalDriveNumber++)
1619 DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation =
1620 &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
1621 DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %d blocks, %s\n",
1622 Controller, Controller->ControllerNumber, LogicalDriveNumber,
1623 LogicalDriveInformation->RAIDLevel,
1624 (LogicalDriveInformation->LogicalDriveState
1625 == DAC960_V1_LogicalDrive_Online
1626 ? "Online"
1627 : LogicalDriveInformation->LogicalDriveState
1628 == DAC960_V1_LogicalDrive_Critical
1629 ? "Critical" : "Offline"),
1630 LogicalDriveInformation->LogicalDriveSize,
1631 (LogicalDriveInformation->WriteBack
1632 ? "Write Back" : "Write Thru"));
1634 return true;
1639 DAC960_V2_ReportDeviceConfiguration reports the Device Configuration
1640 Information for DAC960 V2 Firmware Controllers.
1643 static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
1644 *Controller)
1646 int PhysicalDeviceIndex, LogicalDriveNumber;
1647 DAC960_Info(" Physical Devices:\n", Controller);
1648 for (PhysicalDeviceIndex = 0;
1649 PhysicalDeviceIndex < DAC960_V2_MaxPhysicalDevices;
1650 PhysicalDeviceIndex++)
1652 DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
1653 Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
1654 DAC960_SCSI_Inquiry_T *InquiryStandardData =
1655 (DAC960_SCSI_Inquiry_T *) &PhysicalDeviceInfo->SCSI_InquiryData;
1656 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
1657 Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
1658 char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
1659 char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
1660 char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
1661 char SerialNumber[1+sizeof(InquiryUnitSerialNumber->ProductSerialNumber)];
1662 if (PhysicalDeviceInfo == NULL) break;
1663 DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
1664 Vendor, Model, Revision, SerialNumber);
1665 DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %s\n",
1666 Controller,
1667 PhysicalDeviceInfo->Channel,
1668 PhysicalDeviceInfo->TargetID,
1669 (PhysicalDeviceInfo->TargetID < 10 ? " " : ""),
1670 Vendor, Model, Revision);
1671 if (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers == 0)
1672 DAC960_Info(" %sAsynchronous\n", Controller,
1673 (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
1674 ? "Wide " :""));
1675 else
1676 DAC960_Info(" %sSynchronous at %d MB/sec\n", Controller,
1677 (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
1678 ? "Wide " :""),
1679 (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers
1680 * (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
1681 ? 2 : 1)));
1682 if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
1683 DAC960_Info(" Serial Number: %s\n", Controller, SerialNumber);
1684 if (PhysicalDeviceInfo->PhysicalDeviceState ==
1685 DAC960_V2_Device_Unconfigured)
1686 continue;
1687 DAC960_Info(" Disk Status: %s, %d blocks\n", Controller,
1688 (PhysicalDeviceInfo->PhysicalDeviceState
1689 == DAC960_V2_Device_Online
1690 ? "Online"
1691 : PhysicalDeviceInfo->PhysicalDeviceState
1692 == DAC960_V2_Device_WriteOnly
1693 ? "Write-Only"
1694 : PhysicalDeviceInfo->PhysicalDeviceState
1695 == DAC960_V2_Device_Dead
1696 ? "Dead" : "Standby"),
1697 PhysicalDeviceInfo
1698 ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
1699 if (PhysicalDeviceInfo->ParityErrors == 0 &&
1700 PhysicalDeviceInfo->SoftErrors == 0 &&
1701 PhysicalDeviceInfo->HardErrors == 0 &&
1702 PhysicalDeviceInfo->MiscellaneousErrors == 0 &&
1703 PhysicalDeviceInfo->CommandTimeouts == 0 &&
1704 PhysicalDeviceInfo->Retries == 0 &&
1705 PhysicalDeviceInfo->Aborts == 0 &&
1706 PhysicalDeviceInfo->PredictedFailuresDetected == 0)
1707 continue;
1708 DAC960_Info(" Errors - Parity: %d, Soft: %d, "
1709 "Hard: %d, Misc: %d\n", Controller,
1710 PhysicalDeviceInfo->ParityErrors,
1711 PhysicalDeviceInfo->SoftErrors,
1712 PhysicalDeviceInfo->HardErrors,
1713 PhysicalDeviceInfo->MiscellaneousErrors);
1714 DAC960_Info(" Timeouts: %d, Retries: %d, "
1715 "Aborts: %d, Predicted: %d\n", Controller,
1716 PhysicalDeviceInfo->CommandTimeouts,
1717 PhysicalDeviceInfo->Retries,
1718 PhysicalDeviceInfo->Aborts,
1719 PhysicalDeviceInfo->PredictedFailuresDetected);
1721 DAC960_Info(" Logical Drives:\n", Controller);
1722 for (LogicalDriveNumber = 0;
1723 LogicalDriveNumber < DAC960_MaxLogicalDrives;
1724 LogicalDriveNumber++)
1726 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
1727 Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
1728 unsigned char *ReadCacheStatus[] = { "Read Cache Disabled",
1729 "Read Cache Enabled",
1730 "Read Ahead Enabled",
1731 "Intelligent Read Ahead Enabled",
1732 "-", "-", "-", "-" };
1733 unsigned char *WriteCacheStatus[] = { "Write Cache Disabled",
1734 "Logical Device Read Only",
1735 "Write Cache Enabled",
1736 "Intelligent Write Cache Enabled",
1737 "-", "-", "-", "-" };
1738 unsigned char *GeometryTranslation;
1739 if (LogicalDeviceInfo == NULL) continue;
1740 switch(LogicalDeviceInfo->DriveGeometry)
1742 case DAC960_V2_Geometry_128_32:
1743 GeometryTranslation = "128/32";
1744 break;
1745 case DAC960_V2_Geometry_255_63:
1746 GeometryTranslation = "255/63";
1747 break;
1748 default:
1749 GeometryTranslation = "Invalid";
1750 DAC960_Error("Illegal Logical Device Geometry %d\n",
1751 Controller, LogicalDeviceInfo->DriveGeometry);
1752 break;
1754 DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %d blocks\n",
1755 Controller, Controller->ControllerNumber, LogicalDriveNumber,
1756 LogicalDeviceInfo->RAIDLevel,
1757 (LogicalDeviceInfo->LogicalDeviceState
1758 == DAC960_V2_LogicalDevice_Online
1759 ? "Online"
1760 : LogicalDeviceInfo->LogicalDeviceState
1761 == DAC960_V2_LogicalDevice_Critical
1762 ? "Critical" : "Offline"),
1763 LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
1764 DAC960_Info(" Logical Device %s, BIOS Geometry: %s\n",
1765 Controller,
1766 (LogicalDeviceInfo->LogicalDeviceControl
1767 .LogicalDeviceInitialized
1768 ? "Initialized" : "Uninitialized"),
1769 GeometryTranslation);
1770 if (LogicalDeviceInfo->StripeSize == 0)
1772 if (LogicalDeviceInfo->CacheLineSize == 0)
1773 DAC960_Info(" Stripe Size: N/A, "
1774 "Segment Size: N/A\n", Controller);
1775 else
1776 DAC960_Info(" Stripe Size: N/A, "
1777 "Segment Size: %dKB\n", Controller,
1778 1 << (LogicalDeviceInfo->CacheLineSize - 2));
1780 else
1782 if (LogicalDeviceInfo->CacheLineSize == 0)
1783 DAC960_Info(" Stripe Size: %dKB, "
1784 "Segment Size: N/A\n", Controller,
1785 1 << (LogicalDeviceInfo->StripeSize - 2));
1786 else
1787 DAC960_Info(" Stripe Size: %dKB, "
1788 "Segment Size: %dKB\n", Controller,
1789 1 << (LogicalDeviceInfo->StripeSize - 2),
1790 1 << (LogicalDeviceInfo->CacheLineSize - 2));
1792 DAC960_Info(" %s, %s\n", Controller,
1793 ReadCacheStatus[
1794 LogicalDeviceInfo->LogicalDeviceControl.ReadCache],
1795 WriteCacheStatus[
1796 LogicalDeviceInfo->LogicalDeviceControl.WriteCache]);
1797 if (LogicalDeviceInfo->SoftErrors > 0 ||
1798 LogicalDeviceInfo->CommandsFailed > 0 ||
1799 LogicalDeviceInfo->DeferredWriteErrors)
1800 DAC960_Info(" Errors - Soft: %d, Failed: %d, "
1801 "Deferred Write: %d\n", Controller,
1802 LogicalDeviceInfo->SoftErrors,
1803 LogicalDeviceInfo->CommandsFailed,
1804 LogicalDeviceInfo->DeferredWriteErrors);
1807 return true;
1812 DAC960_BackMergeFunction is the Back Merge Function for the DAC960 driver.
1815 static int DAC960_BackMergeFunction(RequestQueue_T *RequestQueue,
1816 IO_Request_T *Request,
1817 BufferHeader_T *BufferHeader,
1818 int MaxSegments)
1820 DAC960_Controller_T *Controller =
1821 (DAC960_Controller_T *) RequestQueue->queuedata;
1822 if (Request->bhtail->b_data + Request->bhtail->b_size == BufferHeader->b_data)
1823 return true;
1824 if (Request->nr_segments < MaxSegments &&
1825 Request->nr_segments < Controller->DriverScatterGatherLimit)
1827 Request->nr_segments++;
1828 RequestQueue->elevator.nr_segments++;
1829 return true;
1831 return false;
1836 DAC960_FrontMergeFunction is the Front Merge Function for the DAC960 driver.
1839 static int DAC960_FrontMergeFunction(RequestQueue_T *RequestQueue,
1840 IO_Request_T *Request,
1841 BufferHeader_T *BufferHeader,
1842 int MaxSegments)
1844 DAC960_Controller_T *Controller =
1845 (DAC960_Controller_T *) RequestQueue->queuedata;
1846 if (BufferHeader->b_data + BufferHeader->b_size == Request->bh->b_data)
1847 return true;
1848 if (Request->nr_segments < MaxSegments &&
1849 Request->nr_segments < Controller->DriverScatterGatherLimit)
1851 Request->nr_segments++;
1852 RequestQueue->elevator.nr_segments++;
1853 return true;
1855 return false;
1860 DAC960_MergeRequestsFunction is the Merge Requests Function for the
1861 DAC960 driver.
1864 static int DAC960_MergeRequestsFunction(RequestQueue_T *RequestQueue,
1865 IO_Request_T *Request,
1866 IO_Request_T *NextRequest,
1867 int MaxSegments)
1869 DAC960_Controller_T *Controller =
1870 (DAC960_Controller_T *) RequestQueue->queuedata;
1871 int TotalSegments = Request->nr_segments + NextRequest->nr_segments;
1872 int SameSegment = 0;
1873 if (Request->bhtail->b_data + Request->bhtail->b_size
1874 == NextRequest->bh->b_data)
1876 TotalSegments--;
1877 SameSegment = 1;
1879 if (TotalSegments > MaxSegments ||
1880 TotalSegments > Controller->DriverScatterGatherLimit)
1881 return false;
1882 RequestQueue->elevator.nr_segments -= SameSegment;
1883 Request->nr_segments = TotalSegments;
1884 return true;
1889 DAC960_RegisterBlockDevice registers the Block Device structures
1890 associated with Controller.
1893 static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
1895 int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
1896 GenericDiskInfo_T *GenericDiskInfo;
1897 RequestQueue_T *RequestQueue;
1898 int MinorNumber;
1900 Register the Block Device Major Number for this DAC960 Controller.
1902 if (devfs_register_blkdev(MajorNumber, "dac960",
1903 &DAC960_BlockDeviceOperations) < 0)
1905 DAC960_Error("UNABLE TO ACQUIRE MAJOR NUMBER %d - DETACHING\n",
1906 Controller, MajorNumber);
1907 return false;
1910 Initialize the I/O Request Queue.
1912 RequestQueue = BLK_DEFAULT_QUEUE(MajorNumber);
1913 blk_init_queue(RequestQueue, DAC960_RequestFunction);
1914 blk_queue_headactive(RequestQueue, 0);
1915 RequestQueue->back_merge_fn = DAC960_BackMergeFunction;
1916 RequestQueue->front_merge_fn = DAC960_FrontMergeFunction;
1917 RequestQueue->merge_requests_fn = DAC960_MergeRequestsFunction;
1918 RequestQueue->queuedata = Controller;
1919 Controller->RequestQueue = RequestQueue;
1921 Initialize the Disk Partitions array, Partition Sizes array, Block Sizes
1922 array, and Max Sectors per Request array.
1924 for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++)
1926 Controller->BlockSizes[MinorNumber] = BLOCK_SIZE;
1927 Controller->MaxSectorsPerRequest[MinorNumber] =
1928 Controller->MaxBlocksPerCommand;
1930 Controller->GenericDiskInfo.part = Controller->DiskPartitions;
1931 Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
1932 blksize_size[MajorNumber] = Controller->BlockSizes;
1933 max_sectors[MajorNumber] = Controller->MaxSectorsPerRequest;
1935 Initialize Read Ahead to 128 sectors.
1937 read_ahead[MajorNumber] = 128;
1939 Complete initialization of the Generic Disk Information structure.
1941 Controller->GenericDiskInfo.major = MajorNumber;
1942 Controller->GenericDiskInfo.major_name = "rd";
1943 Controller->GenericDiskInfo.minor_shift = DAC960_MaxPartitionsBits;
1944 Controller->GenericDiskInfo.max_p = DAC960_MaxPartitions;
1945 Controller->GenericDiskInfo.nr_real = Controller->LogicalDriveCount;
1946 Controller->GenericDiskInfo.next = NULL;
1947 Controller->GenericDiskInfo.fops = &DAC960_BlockDeviceOperations;
1949 Install the Generic Disk Information structure at the end of the list.
1951 if ((GenericDiskInfo = gendisk_head) != NULL)
1953 while (GenericDiskInfo->next != NULL)
1954 GenericDiskInfo = GenericDiskInfo->next;
1955 GenericDiskInfo->next = &Controller->GenericDiskInfo;
1957 else gendisk_head = &Controller->GenericDiskInfo;
1959 Indicate the Block Device Registration completed successfully,
1961 return true;
1966 DAC960_UnregisterBlockDevice unregisters the Block Device structures
1967 associated with Controller.
1970 static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller)
1972 int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
1974 Unregister the Block Device Major Number for this DAC960 Controller.
1976 devfs_unregister_blkdev(MajorNumber, "dac960");
1978 Remove the I/O Request Queue.
1980 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MajorNumber));
1982 Remove the Disk Partitions array, Partition Sizes array, Block Sizes
1983 array, Max Sectors per Request array, and Max Segments per Request array.
1985 Controller->GenericDiskInfo.part = NULL;
1986 Controller->GenericDiskInfo.sizes = NULL;
1987 blk_size[MajorNumber] = NULL;
1988 blksize_size[MajorNumber] = NULL;
1989 max_sectors[MajorNumber] = NULL;
1991 Remove the Generic Disk Information structure from the list.
1993 if (gendisk_head != &Controller->GenericDiskInfo)
1995 GenericDiskInfo_T *GenericDiskInfo = gendisk_head;
1996 while (GenericDiskInfo != NULL &&
1997 GenericDiskInfo->next != &Controller->GenericDiskInfo)
1998 GenericDiskInfo = GenericDiskInfo->next;
1999 if (GenericDiskInfo != NULL)
2000 GenericDiskInfo->next = GenericDiskInfo->next->next;
2002 else gendisk_head = Controller->GenericDiskInfo.next;
2007 DAC960_RegisterDisk registers the DAC960 Logical Disk Device for Logical
2008 Drive Number if it exists.
2011 static void DAC960_RegisterDisk(DAC960_Controller_T *Controller,
2012 int LogicalDriveNumber)
2014 if (Controller->FirmwareType == DAC960_V1_Controller)
2016 if (LogicalDriveNumber > Controller->LogicalDriveCount - 1) return;
2017 register_disk(&Controller->GenericDiskInfo,
2018 DAC960_KernelDevice(Controller->ControllerNumber,
2019 LogicalDriveNumber, 0),
2020 DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
2021 Controller->V1.LogicalDriveInformation
2022 [LogicalDriveNumber].LogicalDriveSize);
2024 else
2026 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
2027 Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
2028 if (LogicalDeviceInfo == NULL) return;
2029 register_disk(&Controller->GenericDiskInfo,
2030 DAC960_KernelDevice(Controller->ControllerNumber,
2031 LogicalDriveNumber, 0),
2032 DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
2033 LogicalDeviceInfo
2034 ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
2040 DAC960_ReportErrorStatus reports Controller BIOS Messages passed through
2041 the Error Status Register when the driver performs the BIOS handshaking.
2042 It returns true for fatal errors and false otherwise.
2045 static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
2046 unsigned char ErrorStatus,
2047 unsigned char Parameter0,
2048 unsigned char Parameter1)
2050 switch (ErrorStatus)
2052 case 0x00:
2053 DAC960_Notice("Physical Device %d:%d Not Responding\n",
2054 Controller, Parameter1, Parameter0);
2055 break;
2056 case 0x08:
2057 if (Controller->DriveSpinUpMessageDisplayed) break;
2058 DAC960_Notice("Spinning Up Drives\n", Controller);
2059 Controller->DriveSpinUpMessageDisplayed = true;
2060 break;
2061 case 0x30:
2062 DAC960_Notice("Configuration Checksum Error\n", Controller);
2063 break;
2064 case 0x60:
2065 DAC960_Notice("Mirror Race Recovery Failed\n", Controller);
2066 break;
2067 case 0x70:
2068 DAC960_Notice("Mirror Race Recovery In Progress\n", Controller);
2069 break;
2070 case 0x90:
2071 DAC960_Notice("Physical Device %d:%d COD Mismatch\n",
2072 Controller, Parameter1, Parameter0);
2073 break;
2074 case 0xA0:
2075 DAC960_Notice("Logical Drive Installation Aborted\n", Controller);
2076 break;
2077 case 0xB0:
2078 DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller);
2079 break;
2080 case 0xD0:
2081 DAC960_Notice("New Controller Configuration Found\n", Controller);
2082 break;
2083 case 0xF0:
2084 DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller);
2085 return true;
2086 default:
2087 DAC960_Error("Unknown Initialization Error %02X for Controller at\n",
2088 Controller, ErrorStatus);
2089 return true;
2091 return false;
2096 DAC960_DetectControllers detects Mylex DAC960/AcceleRAID/eXtremeRAID
2097 PCI RAID Controllers by interrogating the PCI Configuration Space for
2098 Controller Type.
2101 static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
2103 void (*InterruptHandler)(int, void *, Registers_T *) = NULL;
2104 DAC960_FirmwareType_T FirmwareType = 0;
2105 unsigned short VendorID = 0, DeviceID = 0;
2106 unsigned int MemoryWindowSize = 0;
2107 PCI_Device_T *PCI_Device = NULL;
2108 switch (HardwareType)
2110 case DAC960_BA_Controller:
2111 VendorID = PCI_VENDOR_ID_MYLEX;
2112 DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_BA;
2113 FirmwareType = DAC960_V2_Controller;
2114 InterruptHandler = DAC960_BA_InterruptHandler;
2115 MemoryWindowSize = DAC960_BA_RegisterWindowSize;
2116 break;
2117 case DAC960_LP_Controller:
2118 VendorID = PCI_VENDOR_ID_MYLEX;
2119 DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_LP;
2120 FirmwareType = DAC960_LP_Controller;
2121 InterruptHandler = DAC960_LP_InterruptHandler;
2122 MemoryWindowSize = DAC960_LP_RegisterWindowSize;
2123 break;
2124 case DAC960_LA_Controller:
2125 VendorID = PCI_VENDOR_ID_DEC;
2126 DeviceID = PCI_DEVICE_ID_DEC_21285;
2127 FirmwareType = DAC960_V1_Controller;
2128 InterruptHandler = DAC960_LA_InterruptHandler;
2129 MemoryWindowSize = DAC960_LA_RegisterWindowSize;
2130 break;
2131 case DAC960_PG_Controller:
2132 VendorID = PCI_VENDOR_ID_MYLEX;
2133 DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PG;
2134 FirmwareType = DAC960_V1_Controller;
2135 InterruptHandler = DAC960_PG_InterruptHandler;
2136 MemoryWindowSize = DAC960_PG_RegisterWindowSize;
2137 break;
2138 case DAC960_PD_Controller:
2139 VendorID = PCI_VENDOR_ID_MYLEX;
2140 DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PD;
2141 FirmwareType = DAC960_V1_Controller;
2142 InterruptHandler = DAC960_PD_InterruptHandler;
2143 MemoryWindowSize = DAC960_PD_RegisterWindowSize;
2144 break;
2146 while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
2148 DAC960_Controller_T *Controller = NULL;
2149 DAC960_IO_Address_T IO_Address = 0;
2150 DAC960_PCI_Address_T PCI_Address = 0;
2151 unsigned char Bus = PCI_Device->bus->number;
2152 unsigned char DeviceFunction = PCI_Device->devfn;
2153 unsigned char Device = DeviceFunction >> 3;
2154 unsigned char Function = DeviceFunction & 0x7;
2155 unsigned char ErrorStatus, Parameter0, Parameter1;
2156 unsigned int IRQ_Channel = PCI_Device->irq;
2157 void *BaseAddress;
2158 if (pci_enable_device(PCI_Device) != 0) continue;
2159 switch (HardwareType)
2161 case DAC960_BA_Controller:
2162 PCI_Address = pci_resource_start(PCI_Device, 0);
2163 break;
2164 case DAC960_LP_Controller:
2165 PCI_Address = pci_resource_start(PCI_Device, 0);
2166 break;
2167 case DAC960_LA_Controller:
2168 if (!(PCI_Device->subsystem_vendor == PCI_VENDOR_ID_MYLEX &&
2169 PCI_Device->subsystem_device == PCI_DEVICE_ID_MYLEX_DAC960_LA))
2170 continue;
2171 PCI_Address = pci_resource_start(PCI_Device, 0);
2172 break;
2173 case DAC960_PG_Controller:
2174 PCI_Address = pci_resource_start(PCI_Device, 0);
2175 break;
2176 case DAC960_PD_Controller:
2177 IO_Address = pci_resource_start(PCI_Device, 0);
2178 PCI_Address = pci_resource_start(PCI_Device, 1);
2179 break;
2181 if (DAC960_ControllerCount == DAC960_MaxControllers)
2183 DAC960_Error("More than %d DAC960 Controllers detected - "
2184 "ignoring from Controller at\n",
2185 NULL, DAC960_MaxControllers);
2186 goto Failure;
2188 Controller = (DAC960_Controller_T *)
2189 kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
2190 if (Controller == NULL)
2192 DAC960_Error("Unable to allocate Controller structure for "
2193 "Controller at\n", NULL);
2194 goto Failure;
2196 memset(Controller, 0, sizeof(DAC960_Controller_T));
2197 Controller->ControllerNumber = DAC960_ControllerCount;
2198 init_waitqueue_head(&Controller->CommandWaitQueue);
2199 init_waitqueue_head(&Controller->HealthStatusWaitQueue);
2200 DAC960_Controllers[DAC960_ControllerCount++] = Controller;
2201 DAC960_AnnounceDriver(Controller);
2202 Controller->FirmwareType = FirmwareType;
2203 Controller->HardwareType = HardwareType;
2204 Controller->IO_Address = IO_Address;
2205 Controller->PCI_Address = PCI_Address;
2206 Controller->Bus = Bus;
2207 Controller->Device = Device;
2208 Controller->Function = Function;
2209 sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
2211 Map the Controller Register Window.
2213 if (MemoryWindowSize < PAGE_SIZE)
2214 MemoryWindowSize = PAGE_SIZE;
2215 Controller->MemoryMappedAddress =
2216 ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
2217 Controller->BaseAddress =
2218 Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
2219 if (Controller->MemoryMappedAddress == NULL)
2221 DAC960_Error("Unable to map Controller Register Window for "
2222 "Controller at\n", Controller);
2223 goto Failure;
2225 BaseAddress = Controller->BaseAddress;
2226 switch (HardwareType)
2228 case DAC960_BA_Controller:
2229 DAC960_BA_DisableInterrupts(Controller->BaseAddress);
2230 DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
2231 udelay(1000);
2232 while (DAC960_BA_InitializationInProgressP(BaseAddress))
2234 if (DAC960_BA_ReadErrorStatus(BaseAddress, &ErrorStatus,
2235 &Parameter0, &Parameter1) &&
2236 DAC960_ReportErrorStatus(Controller, ErrorStatus,
2237 Parameter0, Parameter1))
2238 goto Failure;
2239 udelay(10);
2241 if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
2243 DAC960_Error("Unable to Enable Memory Mailbox Interface "
2244 "for Controller at\n", Controller);
2245 goto Failure;
2247 DAC960_BA_EnableInterrupts(Controller->BaseAddress);
2248 Controller->QueueCommand = DAC960_BA_QueueCommand;
2249 Controller->ReadControllerConfiguration =
2250 DAC960_V2_ReadControllerConfiguration;
2251 Controller->ReadDeviceConfiguration =
2252 DAC960_V2_ReadDeviceConfiguration;
2253 Controller->ReportDeviceConfiguration =
2254 DAC960_V2_ReportDeviceConfiguration;
2255 Controller->QueueReadWriteCommand =
2256 DAC960_V2_QueueReadWriteCommand;
2257 break;
2258 case DAC960_LP_Controller:
2259 DAC960_LP_DisableInterrupts(Controller->BaseAddress);
2260 DAC960_LP_AcknowledgeHardwareMailboxStatus(BaseAddress);
2261 udelay(1000);
2262 while (DAC960_LP_InitializationInProgressP(BaseAddress))
2264 if (DAC960_LP_ReadErrorStatus(BaseAddress, &ErrorStatus,
2265 &Parameter0, &Parameter1) &&
2266 DAC960_ReportErrorStatus(Controller, ErrorStatus,
2267 Parameter0, Parameter1))
2268 goto Failure;
2269 udelay(10);
2271 if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
2273 DAC960_Error("Unable to Enable Memory Mailbox Interface "
2274 "for Controller at\n", Controller);
2275 goto Failure;
2277 DAC960_LP_EnableInterrupts(Controller->BaseAddress);
2278 Controller->QueueCommand = DAC960_LP_QueueCommand;
2279 Controller->ReadControllerConfiguration =
2280 DAC960_V2_ReadControllerConfiguration;
2281 Controller->ReadDeviceConfiguration =
2282 DAC960_V2_ReadDeviceConfiguration;
2283 Controller->ReportDeviceConfiguration =
2284 DAC960_V2_ReportDeviceConfiguration;
2285 Controller->QueueReadWriteCommand =
2286 DAC960_V2_QueueReadWriteCommand;
2287 break;
2288 case DAC960_LA_Controller:
2289 DAC960_LA_DisableInterrupts(Controller->BaseAddress);
2290 DAC960_LA_AcknowledgeHardwareMailboxStatus(BaseAddress);
2291 udelay(1000);
2292 while (DAC960_LA_InitializationInProgressP(BaseAddress))
2294 if (DAC960_LA_ReadErrorStatus(BaseAddress, &ErrorStatus,
2295 &Parameter0, &Parameter1) &&
2296 DAC960_ReportErrorStatus(Controller, ErrorStatus,
2297 Parameter0, Parameter1))
2298 goto Failure;
2299 udelay(10);
2301 if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
2303 DAC960_Error("Unable to Enable Memory Mailbox Interface "
2304 "for Controller at\n", Controller);
2305 goto Failure;
2307 DAC960_LA_EnableInterrupts(Controller->BaseAddress);
2308 if (Controller->V1.DualModeMemoryMailboxInterface)
2309 Controller->QueueCommand = DAC960_LA_QueueCommandDualMode;
2310 else Controller->QueueCommand = DAC960_LA_QueueCommandSingleMode;
2311 Controller->ReadControllerConfiguration =
2312 DAC960_V1_ReadControllerConfiguration;
2313 Controller->ReadDeviceConfiguration =
2314 DAC960_V1_ReadDeviceConfiguration;
2315 Controller->ReportDeviceConfiguration =
2316 DAC960_V1_ReportDeviceConfiguration;
2317 Controller->QueueReadWriteCommand =
2318 DAC960_V1_QueueReadWriteCommand;
2319 break;
2320 case DAC960_PG_Controller:
2321 DAC960_PG_DisableInterrupts(Controller->BaseAddress);
2322 DAC960_PG_AcknowledgeHardwareMailboxStatus(BaseAddress);
2323 udelay(1000);
2324 while (DAC960_PG_InitializationInProgressP(BaseAddress))
2326 if (DAC960_PG_ReadErrorStatus(BaseAddress, &ErrorStatus,
2327 &Parameter0, &Parameter1) &&
2328 DAC960_ReportErrorStatus(Controller, ErrorStatus,
2329 Parameter0, Parameter1))
2330 goto Failure;
2331 udelay(10);
2333 if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
2335 DAC960_Error("Unable to Enable Memory Mailbox Interface "
2336 "for Controller at\n", Controller);
2337 goto Failure;
2339 DAC960_PG_EnableInterrupts(Controller->BaseAddress);
2340 if (Controller->V1.DualModeMemoryMailboxInterface)
2341 Controller->QueueCommand = DAC960_PG_QueueCommandDualMode;
2342 else Controller->QueueCommand = DAC960_PG_QueueCommandSingleMode;
2343 Controller->ReadControllerConfiguration =
2344 DAC960_V1_ReadControllerConfiguration;
2345 Controller->ReadDeviceConfiguration =
2346 DAC960_V1_ReadDeviceConfiguration;
2347 Controller->ReportDeviceConfiguration =
2348 DAC960_V1_ReportDeviceConfiguration;
2349 Controller->QueueReadWriteCommand =
2350 DAC960_V1_QueueReadWriteCommand;
2351 break;
2352 case DAC960_PD_Controller:
2353 request_region(Controller->IO_Address, 0x80,
2354 Controller->FullModelName);
2355 DAC960_PD_DisableInterrupts(BaseAddress);
2356 DAC960_PD_AcknowledgeStatus(BaseAddress);
2357 udelay(1000);
2358 while (DAC960_PD_InitializationInProgressP(BaseAddress))
2360 if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
2361 &Parameter0, &Parameter1) &&
2362 DAC960_ReportErrorStatus(Controller, ErrorStatus,
2363 Parameter0, Parameter1))
2364 goto Failure;
2365 udelay(10);
2367 DAC960_PD_EnableInterrupts(Controller->BaseAddress);
2368 Controller->QueueCommand = DAC960_PD_QueueCommand;
2369 Controller->ReadControllerConfiguration =
2370 DAC960_V1_ReadControllerConfiguration;
2371 Controller->ReadDeviceConfiguration =
2372 DAC960_V1_ReadDeviceConfiguration;
2373 Controller->ReportDeviceConfiguration =
2374 DAC960_V1_ReportDeviceConfiguration;
2375 Controller->QueueReadWriteCommand =
2376 DAC960_V1_QueueReadWriteCommand;
2377 break;
2380 Acquire shared access to the IRQ Channel.
2382 if (IRQ_Channel == 0)
2384 DAC960_Error("IRQ Channel %d illegal for Controller at\n",
2385 Controller, IRQ_Channel);
2386 goto Failure;
2388 strcpy(Controller->FullModelName, "DAC960");
2389 if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
2390 Controller->FullModelName, Controller) < 0)
2392 DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
2393 Controller, IRQ_Channel);
2394 goto Failure;
2396 Controller->IRQ_Channel = IRQ_Channel;
2397 DAC960_ActiveControllerCount++;
2398 Controller->InitialCommand.CommandIdentifier = 1;
2399 Controller->InitialCommand.Controller = Controller;
2400 Controller->Commands[0] = &Controller->InitialCommand;
2401 Controller->FreeCommands = &Controller->InitialCommand;
2402 Controller->ControllerDetectionSuccessful = true;
2403 continue;
2404 Failure:
2405 if (IO_Address == 0)
2406 DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
2407 "PCI Address 0x%X\n", Controller,
2408 Bus, Device, Function, PCI_Address);
2409 else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
2410 "0x%X PCI Address 0x%X\n", Controller,
2411 Bus, Device, Function, IO_Address, PCI_Address);
2412 if (Controller == NULL) break;
2413 if (Controller->MemoryMappedAddress != NULL)
2414 iounmap(Controller->MemoryMappedAddress);
2415 if (Controller->IRQ_Channel > 0)
2416 free_irq(IRQ_Channel, Controller);
2422 DAC960_SortControllers sorts the Controllers by PCI Bus and Device Number.
2425 static void DAC960_SortControllers(void)
2427 int ControllerNumber, LastInterchange, Bound, j;
2428 LastInterchange = DAC960_ControllerCount-1;
2429 while (LastInterchange > 0)
2431 Bound = LastInterchange;
2432 LastInterchange = 0;
2433 for (j = 0; j < Bound; j++)
2435 DAC960_Controller_T *Controller1 = DAC960_Controllers[j];
2436 DAC960_Controller_T *Controller2 = DAC960_Controllers[j+1];
2437 if (Controller1->Bus > Controller2->Bus ||
2438 (Controller1->Bus == Controller2->Bus &&
2439 (Controller1->Device > Controller2->Device)))
2441 Controller2->ControllerNumber = j;
2442 DAC960_Controllers[j] = Controller2;
2443 Controller1->ControllerNumber = j+1;
2444 DAC960_Controllers[j+1] = Controller1;
2445 LastInterchange = j;
2449 for (ControllerNumber = 0;
2450 ControllerNumber < DAC960_ControllerCount;
2451 ControllerNumber++)
2453 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
2454 if (!Controller->ControllerDetectionSuccessful)
2456 DAC960_Controllers[ControllerNumber] = NULL;
2457 kfree(Controller);
2464 DAC960_InitializeController initializes Controller.
2467 static void DAC960_InitializeController(DAC960_Controller_T *Controller)
2469 if (DAC960_ReadControllerConfiguration(Controller) &&
2470 DAC960_ReportControllerConfiguration(Controller) &&
2471 DAC960_CreateAuxiliaryStructures(Controller) &&
2472 DAC960_ReadDeviceConfiguration(Controller) &&
2473 DAC960_ReportDeviceConfiguration(Controller) &&
2474 DAC960_RegisterBlockDevice(Controller))
2477 Initialize the Monitoring Timer.
2479 init_timer(&Controller->MonitoringTimer);
2480 Controller->MonitoringTimer.expires =
2481 jiffies + DAC960_MonitoringTimerInterval;
2482 Controller->MonitoringTimer.data = (unsigned long) Controller;
2483 Controller->MonitoringTimer.function = DAC960_MonitoringTimerFunction;
2484 add_timer(&Controller->MonitoringTimer);
2485 Controller->ControllerInitialized = true;
2487 else DAC960_FinalizeController(Controller);
2492 DAC960_FinalizeController finalizes Controller.
2495 static void DAC960_FinalizeController(DAC960_Controller_T *Controller)
2497 if (Controller->ControllerInitialized)
2499 del_timer(&Controller->MonitoringTimer);
2500 if (Controller->FirmwareType == DAC960_V1_Controller)
2502 DAC960_Notice("Flushing Cache...", Controller);
2503 DAC960_V1_ExecuteType3(Controller, DAC960_V1_Flush, NULL);
2504 DAC960_Notice("done\n", Controller);
2505 switch (Controller->HardwareType)
2507 case DAC960_LA_Controller:
2508 if (Controller->V1.DualModeMemoryMailboxInterface)
2509 free_pages(Controller->MemoryMailboxPagesAddress,
2510 Controller->MemoryMailboxPagesOrder);
2511 else DAC960_LA_SaveMemoryMailboxInfo(Controller);
2512 break;
2513 case DAC960_PG_Controller:
2514 if (Controller->V1.DualModeMemoryMailboxInterface)
2515 free_pages(Controller->MemoryMailboxPagesAddress,
2516 Controller->MemoryMailboxPagesOrder);
2517 else DAC960_PG_SaveMemoryMailboxInfo(Controller);
2518 break;
2519 case DAC960_PD_Controller:
2520 release_region(Controller->IO_Address, 0x80);
2521 break;
2522 default:
2523 break;
2526 else
2528 DAC960_Notice("Flushing Cache...", Controller);
2529 DAC960_V2_DeviceOperation(Controller, DAC960_V2_PauseDevice,
2530 DAC960_V2_RAID_Controller);
2531 DAC960_Notice("done\n", Controller);
2532 free_pages(Controller->MemoryMailboxPagesAddress,
2533 Controller->MemoryMailboxPagesOrder);
2536 free_irq(Controller->IRQ_Channel, Controller);
2537 iounmap(Controller->MemoryMappedAddress);
2538 DAC960_UnregisterBlockDevice(Controller);
2539 DAC960_DestroyAuxiliaryStructures(Controller);
2540 DAC960_Controllers[Controller->ControllerNumber] = NULL;
2541 kfree(Controller);
2546 DAC960_Initialize initializes the DAC960 Driver.
2549 void DAC960_Initialize(void)
2551 int ControllerNumber;
2552 DAC960_DetectControllers(DAC960_BA_Controller);
2553 DAC960_DetectControllers(DAC960_LP_Controller);
2554 DAC960_DetectControllers(DAC960_LA_Controller);
2555 DAC960_DetectControllers(DAC960_PG_Controller);
2556 DAC960_DetectControllers(DAC960_PD_Controller);
2557 DAC960_SortControllers();
2558 if (DAC960_ActiveControllerCount == 0) return;
2559 for (ControllerNumber = 0;
2560 ControllerNumber < DAC960_ControllerCount;
2561 ControllerNumber++)
2563 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
2564 int LogicalDriveNumber;
2565 if (Controller == NULL) continue;
2566 DAC960_InitializeController(Controller);
2567 for (LogicalDriveNumber = 0;
2568 LogicalDriveNumber < DAC960_MaxLogicalDrives;
2569 LogicalDriveNumber++)
2570 DAC960_RegisterDisk(Controller, LogicalDriveNumber);
2572 DAC960_CreateProcEntries();
2573 register_reboot_notifier(&DAC960_NotifierBlock);
2578 DAC960_Finalize finalizes the DAC960 Driver.
2581 static int DAC960_Finalize(NotifierBlock_T *NotifierBlock,
2582 unsigned long Event,
2583 void *Buffer)
2585 int ControllerNumber;
2586 if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
2587 return NOTIFY_DONE;
2588 if (DAC960_ActiveControllerCount == 0) return NOTIFY_OK;
2589 for (ControllerNumber = 0;
2590 ControllerNumber < DAC960_ControllerCount;
2591 ControllerNumber++)
2592 if (DAC960_Controllers[ControllerNumber] != NULL)
2593 DAC960_FinalizeController(DAC960_Controllers[ControllerNumber]);
2594 DAC960_DestroyProcEntries();
2595 unregister_reboot_notifier(&DAC960_NotifierBlock);
2596 return NOTIFY_OK;
2601 DAC960_V1_QueueReadWriteCommand prepares and queues a Read/Write Command for
2602 DAC960 V1 Firmware Controllers.
2605 static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command)
2607 DAC960_Controller_T *Controller = Command->Controller;
2608 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
2609 DAC960_V1_ClearCommand(Command);
2610 if (Command->SegmentCount == 1)
2612 if (Command->CommandType == DAC960_ReadCommand)
2613 CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
2614 else CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
2615 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
2616 CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
2617 CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
2618 CommandMailbox->Type5.BusAddress = Virtual_to_Bus(Command->RequestBuffer);
2620 else
2622 DAC960_V1_ScatterGatherSegment_T
2623 *ScatterGatherList = Command->V1.ScatterGatherList;
2624 BufferHeader_T *BufferHeader = Command->BufferHeader;
2625 char *LastDataEndPointer = NULL;
2626 int SegmentNumber = 0;
2627 if (Command->CommandType == DAC960_ReadCommand)
2628 CommandMailbox->Type5.CommandOpcode =
2629 DAC960_V1_ReadWithOldScatterGather;
2630 else
2631 CommandMailbox->Type5.CommandOpcode =
2632 DAC960_V1_WriteWithOldScatterGather;
2633 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
2634 CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
2635 CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
2636 CommandMailbox->Type5.BusAddress = Virtual_to_Bus(ScatterGatherList);
2637 CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount;
2638 while (BufferHeader != NULL)
2640 if (BufferHeader->b_data == LastDataEndPointer)
2642 ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
2643 BufferHeader->b_size;
2644 LastDataEndPointer += BufferHeader->b_size;
2646 else
2648 ScatterGatherList[SegmentNumber].SegmentDataPointer =
2649 Virtual_to_Bus(BufferHeader->b_data);
2650 ScatterGatherList[SegmentNumber].SegmentByteCount =
2651 BufferHeader->b_size;
2652 LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
2653 if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
2654 panic("DAC960: Scatter/Gather Segment Overflow\n");
2656 BufferHeader = BufferHeader->b_reqnext;
2658 if (SegmentNumber != Command->SegmentCount)
2659 panic("DAC960: SegmentNumber != SegmentCount\n");
2661 DAC960_QueueCommand(Command);
2666 DAC960_V2_QueueReadWriteCommand prepares and queues a Read/Write Command for
2667 DAC960 V2 Firmware Controllers.
2670 static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
2672 DAC960_Controller_T *Controller = Command->Controller;
2673 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
2674 DAC960_V2_ClearCommand(Command);
2675 CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10;
2676 CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost =
2677 (Command->CommandType == DAC960_ReadCommand);
2678 CommandMailbox->SCSI_10.DataTransferSize =
2679 Command->BlockCount << DAC960_BlockSizeBits;
2680 CommandMailbox->SCSI_10.RequestSenseBusAddress =
2681 Virtual_to_Bus(&Command->V2.RequestSense);
2682 CommandMailbox->SCSI_10.PhysicalDevice =
2683 Controller->V2.LogicalDriveToVirtualDevice[Command->LogicalDriveNumber];
2684 CommandMailbox->SCSI_10.RequestSenseSize =
2685 sizeof(DAC960_SCSI_RequestSense_T);
2686 CommandMailbox->SCSI_10.CDBLength = 10;
2687 CommandMailbox->SCSI_10.SCSI_CDB[0] =
2688 (Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A);
2689 CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
2690 CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
2691 CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
2692 CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
2693 CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
2694 CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
2695 if (Command->SegmentCount == 1)
2697 CommandMailbox->SCSI_10.DataTransferMemoryAddress
2698 .ScatterGatherSegments[0]
2699 .SegmentDataPointer =
2700 Virtual_to_Bus(Command->RequestBuffer);
2701 CommandMailbox->SCSI_10.DataTransferMemoryAddress
2702 .ScatterGatherSegments[0]
2703 .SegmentByteCount =
2704 CommandMailbox->SCSI_10.DataTransferSize;
2706 else
2708 DAC960_V2_ScatterGatherSegment_T
2709 *ScatterGatherList = Command->V2.ScatterGatherList;
2710 BufferHeader_T *BufferHeader = Command->BufferHeader;
2711 char *LastDataEndPointer = NULL;
2712 int SegmentNumber = 0;
2713 if (Command->SegmentCount > 2)
2715 CommandMailbox->SCSI_10.CommandControlBits
2716 .AdditionalScatterGatherListMemory = true;
2717 CommandMailbox->SCSI_10.DataTransferMemoryAddress
2718 .ExtendedScatterGather.ScatterGatherList0Length =
2719 Command->SegmentCount;
2720 CommandMailbox->SCSI_10.DataTransferMemoryAddress
2721 .ExtendedScatterGather.ScatterGatherList0Address =
2722 Virtual_to_Bus(ScatterGatherList);
2724 else
2725 ScatterGatherList =
2726 CommandMailbox->SCSI_10.DataTransferMemoryAddress
2727 .ScatterGatherSegments;
2728 while (BufferHeader != NULL)
2730 if (BufferHeader->b_data == LastDataEndPointer)
2732 ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
2733 BufferHeader->b_size;
2734 LastDataEndPointer += BufferHeader->b_size;
2736 else
2738 ScatterGatherList[SegmentNumber].SegmentDataPointer =
2739 Virtual_to_Bus(BufferHeader->b_data);
2740 ScatterGatherList[SegmentNumber].SegmentByteCount =
2741 BufferHeader->b_size;
2742 LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
2743 if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
2744 panic("DAC960: Scatter/Gather Segment Overflow\n");
2746 BufferHeader = BufferHeader->b_reqnext;
2748 if (SegmentNumber != Command->SegmentCount)
2749 panic("DAC960: SegmentNumber != SegmentCount\n");
2751 DAC960_QueueCommand(Command);
2756 DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
2757 I/O Request Queue and queues it to the Controller. WaitForCommand is true if
2758 this function should wait for a Command to become available if necessary.
2759 This function returns true if an I/O Request was queued and false otherwise.
2762 static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
2763 boolean WaitForCommand)
2765 RequestQueue_T *RequestQueue = Controller->RequestQueue;
2766 ListHead_T *RequestQueueHead;
2767 IO_Request_T *Request;
2768 DAC960_Command_T *Command;
2769 if (RequestQueue == NULL) return false;
2770 RequestQueueHead = &RequestQueue->queue_head;
2771 while (true)
2773 if (list_empty(RequestQueueHead)) return false;
2774 Request = blkdev_entry_next_request(RequestQueueHead);
2775 Command = DAC960_AllocateCommand(Controller);
2776 if (Command != NULL) break;
2777 if (!WaitForCommand) return false;
2778 DAC960_WaitForCommand(Controller);
2780 if (Request->cmd == READ)
2781 Command->CommandType = DAC960_ReadCommand;
2782 else Command->CommandType = DAC960_WriteCommand;
2783 Command->Semaphore = Request->sem;
2784 Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
2785 Command->BlockNumber =
2786 Request->sector
2787 + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
2788 Command->BlockCount = Request->nr_sectors;
2789 Command->SegmentCount = Request->nr_segments;
2790 Command->BufferHeader = Request->bh;
2791 Command->RequestBuffer = Request->buffer;
2792 blkdev_dequeue_request(Request);
2793 blkdev_release_request(Request);
2794 DAC960_QueueReadWriteCommand(Command);
2795 return true;
2800 DAC960_ProcessRequests attempts to remove as many I/O Requests as possible
2801 from Controller's I/O Request Queue and queue them to the Controller.
2804 static inline void DAC960_ProcessRequests(DAC960_Controller_T *Controller)
2806 int Counter = 0;
2807 while (DAC960_ProcessRequest(Controller, Counter++ == 0)) ;
2812 DAC960_RequestFunction is the I/O Request Function for DAC960 Controllers.
2815 static void DAC960_RequestFunction(RequestQueue_T *RequestQueue)
2817 DAC960_Controller_T *Controller =
2818 (DAC960_Controller_T *) RequestQueue->queuedata;
2819 ProcessorFlags_T ProcessorFlags;
2821 Acquire exclusive access to Controller.
2823 DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
2825 Process I/O Requests for Controller.
2827 DAC960_ProcessRequests(Controller);
2829 Release exclusive access to Controller.
2831 DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
2836 DAC960_ProcessCompletedBuffer performs completion processing for an
2837 individual Buffer.
2840 static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
2841 boolean SuccessfulIO)
2843 BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
2848 DAC960_V1_ReadWriteError prints an appropriate error message for Command
2849 when an error occurs on a Read or Write operation.
2852 static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command)
2854 DAC960_Controller_T *Controller = Command->Controller;
2855 unsigned char *CommandName = "UNKNOWN";
2856 switch (Command->CommandType)
2858 case DAC960_ReadCommand:
2859 case DAC960_ReadRetryCommand:
2860 CommandName = "READ";
2861 break;
2862 case DAC960_WriteCommand:
2863 case DAC960_WriteRetryCommand:
2864 CommandName = "WRITE";
2865 break;
2866 case DAC960_MonitoringCommand:
2867 case DAC960_ImmediateCommand:
2868 case DAC960_QueuedCommand:
2869 break;
2871 switch (Command->V1.CommandStatus)
2873 case DAC960_V1_IrrecoverableDataError:
2874 DAC960_Error("Irrecoverable Data Error on %s:\n",
2875 Controller, CommandName);
2876 break;
2877 case DAC960_V1_LogicalDriveNonexistentOrOffline:
2878 DAC960_Error("Logical Drive Nonexistent or Offline on %s:\n",
2879 Controller, CommandName);
2880 break;
2881 case DAC960_V1_AccessBeyondEndOfLogicalDrive:
2882 DAC960_Error("Attempt to Access Beyond End of Logical Drive "
2883 "on %s:\n", Controller, CommandName);
2884 break;
2885 case DAC960_V1_BadDataEncountered:
2886 DAC960_Error("Bad Data Encountered on %s:\n", Controller, CommandName);
2887 break;
2888 default:
2889 DAC960_Error("Unexpected Error Status %04X on %s:\n",
2890 Controller, Command->V1.CommandStatus, CommandName);
2891 break;
2893 DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %d..%d\n",
2894 Controller, Controller->ControllerNumber,
2895 Command->LogicalDriveNumber, Command->BlockNumber,
2896 Command->BlockNumber + Command->BlockCount - 1);
2897 if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
2898 DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
2899 Controller, Controller->ControllerNumber,
2900 Command->LogicalDriveNumber,
2901 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
2902 Command->BufferHeader->b_rsector,
2903 Command->BufferHeader->b_rsector + Command->BlockCount - 1);
2908 DAC960_V1_ProcessCompletedCommand performs completion processing for Command
2909 for DAC960 V1 Firmware Controllers.
2912 static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
2914 DAC960_Controller_T *Controller = Command->Controller;
2915 DAC960_CommandType_T CommandType = Command->CommandType;
2916 DAC960_V1_CommandOpcode_T CommandOpcode =
2917 Command->V1.CommandMailbox.Common.CommandOpcode;
2918 DAC960_V1_CommandStatus_T CommandStatus = Command->V1.CommandStatus;
2919 BufferHeader_T *BufferHeader = Command->BufferHeader;
2920 if (CommandType == DAC960_ReadCommand ||
2921 CommandType == DAC960_WriteCommand)
2923 if (CommandStatus == DAC960_V1_NormalCompletion)
2926 Perform completion processing for all buffers in this I/O Request.
2928 while (BufferHeader != NULL)
2930 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
2931 BufferHeader->b_reqnext = NULL;
2932 DAC960_ProcessCompletedBuffer(BufferHeader, true);
2933 BufferHeader = NextBufferHeader;
2936 Wake up requestor for swap file paging requests.
2938 if (Command->Semaphore != NULL)
2940 up(Command->Semaphore);
2941 Command->Semaphore = NULL;
2943 add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
2945 else if ((CommandStatus == DAC960_V1_IrrecoverableDataError ||
2946 CommandStatus == DAC960_V1_BadDataEncountered) &&
2947 BufferHeader != NULL &&
2948 BufferHeader->b_reqnext != NULL)
2950 DAC960_V1_CommandMailbox_T *CommandMailbox =
2951 &Command->V1.CommandMailbox;
2952 if (CommandType == DAC960_ReadCommand)
2954 Command->CommandType = DAC960_ReadRetryCommand;
2955 CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
2957 else
2959 Command->CommandType = DAC960_WriteRetryCommand;
2960 CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
2962 Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
2963 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
2964 CommandMailbox->Type5.BusAddress =
2965 Virtual_to_Bus(BufferHeader->b_data);
2966 DAC960_QueueCommand(Command);
2967 return;
2969 else
2971 if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
2972 DAC960_V1_ReadWriteError(Command);
2974 Perform completion processing for all buffers in this I/O Request.
2976 while (BufferHeader != NULL)
2978 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
2979 BufferHeader->b_reqnext = NULL;
2980 DAC960_ProcessCompletedBuffer(BufferHeader, false);
2981 BufferHeader = NextBufferHeader;
2984 Wake up requestor for swap file paging requests.
2986 if (Command->Semaphore != NULL)
2988 up(Command->Semaphore);
2989 Command->Semaphore = NULL;
2993 else if (CommandType == DAC960_ReadRetryCommand ||
2994 CommandType == DAC960_WriteRetryCommand)
2996 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
2997 BufferHeader->b_reqnext = NULL;
2999 Perform completion processing for this single buffer.
3001 if (CommandStatus == DAC960_V1_NormalCompletion)
3002 DAC960_ProcessCompletedBuffer(BufferHeader, true);
3003 else
3005 if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
3006 DAC960_V1_ReadWriteError(Command);
3007 DAC960_ProcessCompletedBuffer(BufferHeader, false);
3009 if (NextBufferHeader != NULL)
3011 DAC960_V1_CommandMailbox_T *CommandMailbox =
3012 &Command->V1.CommandMailbox;
3013 Command->BlockNumber +=
3014 BufferHeader->b_size >> DAC960_BlockSizeBits;
3015 Command->BlockCount =
3016 NextBufferHeader->b_size >> DAC960_BlockSizeBits;
3017 Command->BufferHeader = NextBufferHeader;
3018 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
3019 CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
3020 CommandMailbox->Type5.BusAddress =
3021 Virtual_to_Bus(NextBufferHeader->b_data);
3022 DAC960_QueueCommand(Command);
3023 return;
3026 else if (CommandType == DAC960_MonitoringCommand ||
3027 CommandOpcode == DAC960_V1_Enquiry ||
3028 CommandOpcode == DAC960_V1_GetRebuildProgress)
3030 if (CommandType != DAC960_MonitoringCommand)
3032 if (CommandOpcode == DAC960_V1_Enquiry)
3033 memcpy(&Controller->V1.NewEnquiry,
3034 Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress),
3035 sizeof(DAC960_V1_Enquiry_T));
3036 else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
3037 memcpy(&Controller->V1.RebuildProgress,
3038 Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress),
3039 sizeof(DAC960_V1_RebuildProgress_T));
3041 if (CommandOpcode == DAC960_V1_Enquiry &&
3042 Controller->ControllerInitialized)
3044 DAC960_V1_Enquiry_T *OldEnquiry = &Controller->V1.Enquiry;
3045 DAC960_V1_Enquiry_T *NewEnquiry = &Controller->V1.NewEnquiry;
3046 unsigned int OldCriticalLogicalDriveCount =
3047 OldEnquiry->CriticalLogicalDriveCount;
3048 unsigned int NewCriticalLogicalDriveCount =
3049 NewEnquiry->CriticalLogicalDriveCount;
3050 if (NewEnquiry->NumberOfLogicalDrives > Controller->LogicalDriveCount)
3052 int LogicalDriveNumber = Controller->LogicalDriveCount;
3053 while (LogicalDriveNumber < NewEnquiry->NumberOfLogicalDrives)
3055 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
3056 "Now Exists\n", Controller,
3057 LogicalDriveNumber,
3058 Controller->ControllerNumber,
3059 LogicalDriveNumber);
3060 LogicalDriveNumber++;
3062 Controller->LogicalDriveCount = LogicalDriveNumber;
3064 if (NewEnquiry->StatusFlags.DeferredWriteError !=
3065 OldEnquiry->StatusFlags.DeferredWriteError)
3066 DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
3067 (NewEnquiry->StatusFlags.DeferredWriteError
3068 ? "TRUE" : "FALSE"));
3069 if ((NewCriticalLogicalDriveCount > 0 ||
3070 NewCriticalLogicalDriveCount != OldCriticalLogicalDriveCount) ||
3071 (NewEnquiry->OfflineLogicalDriveCount > 0 ||
3072 NewEnquiry->OfflineLogicalDriveCount !=
3073 OldEnquiry->OfflineLogicalDriveCount) ||
3074 (NewEnquiry->DeadDriveCount > 0 ||
3075 NewEnquiry->DeadDriveCount !=
3076 OldEnquiry->DeadDriveCount) ||
3077 (NewEnquiry->EventLogSequenceNumber !=
3078 OldEnquiry->EventLogSequenceNumber) ||
3079 Controller->MonitoringTimerCount == 0 ||
3080 (jiffies - Controller->SecondaryMonitoringTime
3081 >= DAC960_SecondaryMonitoringInterval))
3083 Controller->V1.NeedLogicalDriveInformation = true;
3084 Controller->V1.NewEventLogSequenceNumber =
3085 NewEnquiry->EventLogSequenceNumber;
3086 Controller->V1.NeedErrorTableInformation = true;
3087 Controller->V1.NeedDeviceStateInformation = true;
3088 Controller->V1.DeviceStateChannel = 0;
3089 Controller->V1.DeviceStateTargetID = -1;
3090 Controller->SecondaryMonitoringTime = jiffies;
3092 if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
3093 NewEnquiry->RebuildFlag
3094 == DAC960_V1_BackgroundRebuildInProgress ||
3095 OldEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
3096 OldEnquiry->RebuildFlag == DAC960_V1_BackgroundRebuildInProgress)
3098 Controller->V1.NeedRebuildProgress = true;
3099 Controller->V1.RebuildProgressFirst =
3100 (NewEnquiry->CriticalLogicalDriveCount <
3101 OldEnquiry->CriticalLogicalDriveCount);
3103 if (OldEnquiry->RebuildFlag == DAC960_V1_BackgroundCheckInProgress)
3104 switch (NewEnquiry->RebuildFlag)
3106 case DAC960_V1_NoStandbyRebuildOrCheckInProgress:
3107 DAC960_Progress("Consistency Check Completed Successfully\n",
3108 Controller);
3109 break;
3110 case DAC960_V1_StandbyRebuildInProgress:
3111 case DAC960_V1_BackgroundRebuildInProgress:
3112 break;
3113 case DAC960_V1_BackgroundCheckInProgress:
3114 Controller->V1.NeedConsistencyCheckProgress = true;
3115 break;
3116 case DAC960_V1_StandbyRebuildCompletedWithError:
3117 DAC960_Progress("Consistency Check Completed with Error\n",
3118 Controller);
3119 break;
3120 case DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed:
3121 DAC960_Progress("Consistency Check Failed - "
3122 "Physical Device Failed\n", Controller);
3123 break;
3124 case DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
3125 DAC960_Progress("Consistency Check Failed - "
3126 "Logical Drive Failed\n", Controller);
3127 break;
3128 case DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses:
3129 DAC960_Progress("Consistency Check Failed - Other Causes\n",
3130 Controller);
3131 break;
3132 case DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated:
3133 DAC960_Progress("Consistency Check Successfully Terminated\n",
3134 Controller);
3135 break;
3137 else if (NewEnquiry->RebuildFlag
3138 == DAC960_V1_BackgroundCheckInProgress)
3139 Controller->V1.NeedConsistencyCheckProgress = true;
3140 Controller->MonitoringAlertMode =
3141 (NewEnquiry->CriticalLogicalDriveCount > 0 ||
3142 NewEnquiry->OfflineLogicalDriveCount > 0 ||
3143 NewEnquiry->DeadDriveCount > 0);
3144 if (CommandType != DAC960_MonitoringCommand &&
3145 Controller->V1.RebuildFlagPending)
3147 DAC960_V1_Enquiry_T *Enquiry = (DAC960_V1_Enquiry_T *)
3148 Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress);
3149 Enquiry->RebuildFlag = Controller->V1.PendingRebuildFlag;
3150 Controller->V1.RebuildFlagPending = false;
3152 else if (CommandType == DAC960_MonitoringCommand &&
3153 NewEnquiry->RebuildFlag >
3154 DAC960_V1_BackgroundCheckInProgress)
3156 Controller->V1.PendingRebuildFlag = NewEnquiry->RebuildFlag;
3157 Controller->V1.RebuildFlagPending = true;
3159 memcpy(&Controller->V1.Enquiry, &Controller->V1.NewEnquiry,
3160 sizeof(DAC960_V1_Enquiry_T));
3162 else if (CommandOpcode == DAC960_V1_PerformEventLogOperation)
3164 static char
3165 *DAC960_EventMessages[] =
3166 { "killed because write recovery failed",
3167 "killed because of SCSI bus reset failure",
3168 "killed because of double check condition",
3169 "killed because it was removed",
3170 "killed because of gross error on SCSI chip",
3171 "killed because of bad tag returned from drive",
3172 "killed because of timeout on SCSI command",
3173 "killed because of reset SCSI command issued from system",
3174 "killed because busy or parity error count exceeded limit",
3175 "killed because of 'kill drive' command from system",
3176 "killed because of selection timeout",
3177 "killed due to SCSI phase sequence error",
3178 "killed due to unknown status" };
3179 DAC960_V1_EventLogEntry_T *EventLogEntry =
3180 &Controller->V1.EventLogEntry;
3181 if (EventLogEntry->SequenceNumber ==
3182 Controller->V1.OldEventLogSequenceNumber)
3184 unsigned char SenseKey = EventLogEntry->SenseKey;
3185 unsigned char AdditionalSenseCode =
3186 EventLogEntry->AdditionalSenseCode;
3187 unsigned char AdditionalSenseCodeQualifier =
3188 EventLogEntry->AdditionalSenseCodeQualifier;
3189 if (SenseKey == DAC960_SenseKey_VendorSpecific &&
3190 AdditionalSenseCode == 0x80 &&
3191 AdditionalSenseCodeQualifier <
3192 sizeof(DAC960_EventMessages) / sizeof(char *))
3193 DAC960_Critical("Physical Device %d:%d %s\n", Controller,
3194 EventLogEntry->Channel,
3195 EventLogEntry->TargetID,
3196 DAC960_EventMessages[
3197 AdditionalSenseCodeQualifier]);
3198 else if (SenseKey == DAC960_SenseKey_UnitAttention &&
3199 AdditionalSenseCode == 0x29)
3201 if (Controller->MonitoringTimerCount > 0)
3202 Controller->V1.DeviceResetCount[EventLogEntry->Channel]
3203 [EventLogEntry->TargetID]++;
3205 else if (!(SenseKey == DAC960_SenseKey_NoSense ||
3206 (SenseKey == DAC960_SenseKey_NotReady &&
3207 AdditionalSenseCode == 0x04 &&
3208 (AdditionalSenseCodeQualifier == 0x01 ||
3209 AdditionalSenseCodeQualifier == 0x02))))
3211 DAC960_Critical("Physical Device %d:%d Error Log: "
3212 "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
3213 Controller,
3214 EventLogEntry->Channel,
3215 EventLogEntry->TargetID,
3216 SenseKey,
3217 AdditionalSenseCode,
3218 AdditionalSenseCodeQualifier);
3219 DAC960_Critical("Physical Device %d:%d Error Log: "
3220 "Information = %02X%02X%02X%02X "
3221 "%02X%02X%02X%02X\n",
3222 Controller,
3223 EventLogEntry->Channel,
3224 EventLogEntry->TargetID,
3225 EventLogEntry->Information[0],
3226 EventLogEntry->Information[1],
3227 EventLogEntry->Information[2],
3228 EventLogEntry->Information[3],
3229 EventLogEntry->CommandSpecificInformation[0],
3230 EventLogEntry->CommandSpecificInformation[1],
3231 EventLogEntry->CommandSpecificInformation[2],
3232 EventLogEntry->CommandSpecificInformation[3]);
3235 Controller->V1.OldEventLogSequenceNumber++;
3237 else if (CommandOpcode == DAC960_V1_GetErrorTable)
3239 DAC960_V1_ErrorTable_T *OldErrorTable = &Controller->V1.ErrorTable;
3240 DAC960_V1_ErrorTable_T *NewErrorTable = &Controller->V1.NewErrorTable;
3241 int Channel, TargetID;
3242 for (Channel = 0; Channel < Controller->Channels; Channel++)
3243 for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
3245 DAC960_V1_ErrorTableEntry_T *NewErrorEntry =
3246 &NewErrorTable->ErrorTableEntries[Channel][TargetID];
3247 DAC960_V1_ErrorTableEntry_T *OldErrorEntry =
3248 &OldErrorTable->ErrorTableEntries[Channel][TargetID];
3249 if ((NewErrorEntry->ParityErrorCount !=
3250 OldErrorEntry->ParityErrorCount) ||
3251 (NewErrorEntry->SoftErrorCount !=
3252 OldErrorEntry->SoftErrorCount) ||
3253 (NewErrorEntry->HardErrorCount !=
3254 OldErrorEntry->HardErrorCount) ||
3255 (NewErrorEntry->MiscErrorCount !=
3256 OldErrorEntry->MiscErrorCount))
3257 DAC960_Critical("Physical Device %d:%d Errors: "
3258 "Parity = %d, Soft = %d, "
3259 "Hard = %d, Misc = %d\n",
3260 Controller, Channel, TargetID,
3261 NewErrorEntry->ParityErrorCount,
3262 NewErrorEntry->SoftErrorCount,
3263 NewErrorEntry->HardErrorCount,
3264 NewErrorEntry->MiscErrorCount);
3266 memcpy(&Controller->V1.ErrorTable, &Controller->V1.NewErrorTable,
3267 sizeof(DAC960_V1_ErrorTable_T));
3269 else if (CommandOpcode == DAC960_V1_GetDeviceState)
3271 DAC960_V1_DeviceState_T *OldDeviceState =
3272 &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
3273 [Controller->V1.DeviceStateTargetID];
3274 DAC960_V1_DeviceState_T *NewDeviceState =
3275 &Controller->V1.NewDeviceState;
3276 if (NewDeviceState->DeviceState != OldDeviceState->DeviceState)
3277 DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
3278 Controller->V1.DeviceStateChannel,
3279 Controller->V1.DeviceStateTargetID,
3280 (NewDeviceState->DeviceState
3281 == DAC960_V1_Device_Dead
3282 ? "DEAD"
3283 : NewDeviceState->DeviceState
3284 == DAC960_V1_Device_WriteOnly
3285 ? "WRITE-ONLY"
3286 : NewDeviceState->DeviceState
3287 == DAC960_V1_Device_Online
3288 ? "ONLINE" : "STANDBY"));
3289 if (OldDeviceState->DeviceState == DAC960_V1_Device_Dead &&
3290 NewDeviceState->DeviceState != DAC960_V1_Device_Dead)
3292 Controller->V1.NeedDeviceInquiryInformation = true;
3293 Controller->V1.NeedDeviceSerialNumberInformation = true;
3295 memcpy(OldDeviceState, NewDeviceState,
3296 sizeof(DAC960_V1_DeviceState_T));
3298 else if (CommandOpcode == DAC960_V1_GetLogicalDriveInformation)
3300 int LogicalDriveNumber;
3301 for (LogicalDriveNumber = 0;
3302 LogicalDriveNumber < Controller->LogicalDriveCount;
3303 LogicalDriveNumber++)
3305 DAC960_V1_LogicalDriveInformation_T *OldLogicalDriveInformation =
3306 &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
3307 DAC960_V1_LogicalDriveInformation_T *NewLogicalDriveInformation =
3308 &Controller->V1.NewLogicalDriveInformation[LogicalDriveNumber];
3309 if (NewLogicalDriveInformation->LogicalDriveState !=
3310 OldLogicalDriveInformation->LogicalDriveState)
3311 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
3312 "is now %s\n", Controller,
3313 LogicalDriveNumber,
3314 Controller->ControllerNumber,
3315 LogicalDriveNumber,
3316 (NewLogicalDriveInformation->LogicalDriveState
3317 == DAC960_V1_LogicalDrive_Online
3318 ? "ONLINE"
3319 : NewLogicalDriveInformation->LogicalDriveState
3320 == DAC960_V1_LogicalDrive_Critical
3321 ? "CRITICAL" : "OFFLINE"));
3322 if (NewLogicalDriveInformation->WriteBack !=
3323 OldLogicalDriveInformation->WriteBack)
3324 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
3325 "is now %s\n", Controller,
3326 LogicalDriveNumber,
3327 Controller->ControllerNumber,
3328 LogicalDriveNumber,
3329 (NewLogicalDriveInformation->WriteBack
3330 ? "WRITE BACK" : "WRITE THRU"));
3332 memcpy(&Controller->V1.LogicalDriveInformation,
3333 &Controller->V1.NewLogicalDriveInformation,
3334 sizeof(DAC960_V1_LogicalDriveInformationArray_T));
3336 else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
3338 unsigned int LogicalDriveNumber =
3339 Controller->V1.RebuildProgress.LogicalDriveNumber;
3340 unsigned int LogicalDriveSize =
3341 Controller->V1.RebuildProgress.LogicalDriveSize;
3342 unsigned int BlocksCompleted =
3343 LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
3344 if (CommandStatus == DAC960_V1_NoRebuildOrCheckInProgress &&
3345 Controller->V1.LastRebuildStatus == DAC960_V1_NormalCompletion)
3346 CommandStatus = DAC960_V1_RebuildSuccessful;
3347 switch (CommandStatus)
3349 case DAC960_V1_NormalCompletion:
3350 Controller->EphemeralProgressMessage = true;
3351 DAC960_Progress("Rebuild in Progress: "
3352 "Logical Drive %d (/dev/rd/c%dd%d) "
3353 "%d%% completed\n",
3354 Controller, LogicalDriveNumber,
3355 Controller->ControllerNumber,
3356 LogicalDriveNumber,
3357 (100 * (BlocksCompleted >> 7))
3358 / (LogicalDriveSize >> 7));
3359 Controller->EphemeralProgressMessage = false;
3360 break;
3361 case DAC960_V1_RebuildFailed_LogicalDriveFailure:
3362 DAC960_Progress("Rebuild Failed due to "
3363 "Logical Drive Failure\n", Controller);
3364 break;
3365 case DAC960_V1_RebuildFailed_BadBlocksOnOther:
3366 DAC960_Progress("Rebuild Failed due to "
3367 "Bad Blocks on Other Drives\n", Controller);
3368 break;
3369 case DAC960_V1_RebuildFailed_NewDriveFailed:
3370 DAC960_Progress("Rebuild Failed due to "
3371 "Failure of Drive Being Rebuilt\n", Controller);
3372 break;
3373 case DAC960_V1_NoRebuildOrCheckInProgress:
3374 break;
3375 case DAC960_V1_RebuildSuccessful:
3376 DAC960_Progress("Rebuild Completed Successfully\n", Controller);
3377 break;
3378 case DAC960_V1_RebuildSuccessfullyTerminated:
3379 DAC960_Progress("Rebuild Successfully Terminated\n", Controller);
3380 break;
3382 Controller->V1.LastRebuildStatus = CommandStatus;
3383 if (CommandType != DAC960_MonitoringCommand &&
3384 Controller->V1.RebuildStatusPending)
3386 Command->V1.CommandStatus = Controller->V1.PendingRebuildStatus;
3387 Controller->V1.RebuildStatusPending = false;
3389 else if (CommandType == DAC960_MonitoringCommand &&
3390 CommandStatus != DAC960_V1_NormalCompletion &&
3391 CommandStatus != DAC960_V1_NoRebuildOrCheckInProgress)
3393 Controller->V1.PendingRebuildStatus = CommandStatus;
3394 Controller->V1.RebuildStatusPending = true;
3397 else if (CommandOpcode == DAC960_V1_RebuildStat)
3399 unsigned int LogicalDriveNumber =
3400 Controller->V1.RebuildProgress.LogicalDriveNumber;
3401 unsigned int LogicalDriveSize =
3402 Controller->V1.RebuildProgress.LogicalDriveSize;
3403 unsigned int BlocksCompleted =
3404 LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
3405 if (CommandStatus == DAC960_V1_NormalCompletion)
3407 Controller->EphemeralProgressMessage = true;
3408 DAC960_Progress("Consistency Check in Progress: "
3409 "Logical Drive %d (/dev/rd/c%dd%d) "
3410 "%d%% completed\n",
3411 Controller, LogicalDriveNumber,
3412 Controller->ControllerNumber,
3413 LogicalDriveNumber,
3414 (100 * (BlocksCompleted >> 7))
3415 / (LogicalDriveSize >> 7));
3416 Controller->EphemeralProgressMessage = false;
3420 if (CommandType == DAC960_MonitoringCommand)
3422 if (Controller->V1.NewEventLogSequenceNumber
3423 - Controller->V1.OldEventLogSequenceNumber > 0)
3425 Command->V1.CommandMailbox.Type3E.CommandOpcode =
3426 DAC960_V1_PerformEventLogOperation;
3427 Command->V1.CommandMailbox.Type3E.OperationType =
3428 DAC960_V1_GetEventLogEntry;
3429 Command->V1.CommandMailbox.Type3E.OperationQualifier = 1;
3430 Command->V1.CommandMailbox.Type3E.SequenceNumber =
3431 Controller->V1.OldEventLogSequenceNumber;
3432 Command->V1.CommandMailbox.Type3E.BusAddress =
3433 Virtual_to_Bus(&Controller->V1.EventLogEntry);
3434 DAC960_QueueCommand(Command);
3435 return;
3437 if (Controller->V1.NeedErrorTableInformation)
3439 Controller->V1.NeedErrorTableInformation = false;
3440 Command->V1.CommandMailbox.Type3.CommandOpcode =
3441 DAC960_V1_GetErrorTable;
3442 Command->V1.CommandMailbox.Type3.BusAddress =
3443 Virtual_to_Bus(&Controller->V1.NewErrorTable);
3444 DAC960_QueueCommand(Command);
3445 return;
3447 if (Controller->V1.NeedRebuildProgress &&
3448 Controller->V1.RebuildProgressFirst)
3450 Controller->V1.NeedRebuildProgress = false;
3451 Command->V1.CommandMailbox.Type3.CommandOpcode =
3452 DAC960_V1_GetRebuildProgress;
3453 Command->V1.CommandMailbox.Type3.BusAddress =
3454 Virtual_to_Bus(&Controller->V1.RebuildProgress);
3455 DAC960_QueueCommand(Command);
3456 return;
3458 if (Controller->V1.NeedDeviceStateInformation)
3460 if (Controller->V1.NeedDeviceInquiryInformation)
3462 DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
3463 DAC960_SCSI_Inquiry_T *InquiryStandardData =
3464 &Controller->V1.InquiryStandardData
3465 [Controller->V1.DeviceStateChannel]
3466 [Controller->V1.DeviceStateTargetID];
3467 InquiryStandardData->PeripheralDeviceType = 0x1F;
3468 Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
3469 Command->V1.CommandMailbox.Type3.BusAddress =
3470 Virtual_to_Bus(DCDB);
3471 DCDB->Channel = Controller->V1.DeviceStateChannel;
3472 DCDB->TargetID = Controller->V1.DeviceStateTargetID;
3473 DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
3474 DCDB->EarlyStatus = false;
3475 DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
3476 DCDB->NoAutomaticRequestSense = false;
3477 DCDB->DisconnectPermitted = true;
3478 DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
3479 DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
3480 DCDB->CDBLength = 6;
3481 DCDB->TransferLengthHigh4 = 0;
3482 DCDB->SenseLength = sizeof(DCDB->SenseData);
3483 DCDB->CDB[0] = 0x12; /* INQUIRY */
3484 DCDB->CDB[1] = 0; /* EVPD = 0 */
3485 DCDB->CDB[2] = 0; /* Page Code */
3486 DCDB->CDB[3] = 0; /* Reserved */
3487 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
3488 DCDB->CDB[5] = 0; /* Control */
3489 DAC960_QueueCommand(Command);
3490 Controller->V1.NeedDeviceInquiryInformation = false;
3491 return;
3493 if (Controller->V1.NeedDeviceSerialNumberInformation)
3495 DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
3496 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
3497 &Controller->V1.InquiryUnitSerialNumber
3498 [Controller->V1.DeviceStateChannel]
3499 [Controller->V1.DeviceStateTargetID];
3500 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
3501 Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
3502 Command->V1.CommandMailbox.Type3.BusAddress =
3503 Virtual_to_Bus(DCDB);
3504 DCDB->Channel = Controller->V1.DeviceStateChannel;
3505 DCDB->TargetID = Controller->V1.DeviceStateTargetID;
3506 DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
3507 DCDB->EarlyStatus = false;
3508 DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
3509 DCDB->NoAutomaticRequestSense = false;
3510 DCDB->DisconnectPermitted = true;
3511 DCDB->TransferLength =
3512 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
3513 DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
3514 DCDB->CDBLength = 6;
3515 DCDB->TransferLengthHigh4 = 0;
3516 DCDB->SenseLength = sizeof(DCDB->SenseData);
3517 DCDB->CDB[0] = 0x12; /* INQUIRY */
3518 DCDB->CDB[1] = 1; /* EVPD = 1 */
3519 DCDB->CDB[2] = 0x80; /* Page Code */
3520 DCDB->CDB[3] = 0; /* Reserved */
3521 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
3522 DCDB->CDB[5] = 0; /* Control */
3523 DAC960_QueueCommand(Command);
3524 Controller->V1.NeedDeviceSerialNumberInformation = false;
3525 return;
3527 if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
3529 Controller->V1.DeviceStateChannel++;
3530 Controller->V1.DeviceStateTargetID = 0;
3532 while (Controller->V1.DeviceStateChannel < Controller->Channels)
3534 DAC960_V1_DeviceState_T *OldDeviceState =
3535 &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
3536 [Controller->V1.DeviceStateTargetID];
3537 if (OldDeviceState->Present &&
3538 OldDeviceState->DeviceType == DAC960_V1_DiskType)
3540 Command->V1.CommandMailbox.Type3D.CommandOpcode =
3541 DAC960_V1_GetDeviceState;
3542 Command->V1.CommandMailbox.Type3D.Channel =
3543 Controller->V1.DeviceStateChannel;
3544 Command->V1.CommandMailbox.Type3D.TargetID =
3545 Controller->V1.DeviceStateTargetID;
3546 Command->V1.CommandMailbox.Type3D.BusAddress =
3547 Virtual_to_Bus(&Controller->V1.NewDeviceState);
3548 DAC960_QueueCommand(Command);
3549 return;
3551 if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
3553 Controller->V1.DeviceStateChannel++;
3554 Controller->V1.DeviceStateTargetID = 0;
3557 Controller->V1.NeedDeviceStateInformation = false;
3559 if (Controller->V1.NeedLogicalDriveInformation)
3561 Controller->V1.NeedLogicalDriveInformation = false;
3562 Command->V1.CommandMailbox.Type3.CommandOpcode =
3563 DAC960_V1_GetLogicalDriveInformation;
3564 Command->V1.CommandMailbox.Type3.BusAddress =
3565 Virtual_to_Bus(&Controller->V1.NewLogicalDriveInformation);
3566 DAC960_QueueCommand(Command);
3567 return;
3569 if (Controller->V1.NeedRebuildProgress)
3571 Controller->V1.NeedRebuildProgress = false;
3572 Command->V1.CommandMailbox.Type3.CommandOpcode =
3573 DAC960_V1_GetRebuildProgress;
3574 Command->V1.CommandMailbox.Type3.BusAddress =
3575 Virtual_to_Bus(&Controller->V1.RebuildProgress);
3576 DAC960_QueueCommand(Command);
3577 return;
3579 if (Controller->V1.NeedConsistencyCheckProgress)
3581 Controller->V1.NeedConsistencyCheckProgress = false;
3582 Command->V1.CommandMailbox.Type3.CommandOpcode =
3583 DAC960_V1_RebuildStat;
3584 Command->V1.CommandMailbox.Type3.BusAddress =
3585 Virtual_to_Bus(&Controller->V1.RebuildProgress);
3586 DAC960_QueueCommand(Command);
3587 return;
3589 Controller->MonitoringTimerCount++;
3590 Controller->MonitoringTimer.expires =
3591 jiffies + DAC960_MonitoringTimerInterval;
3592 add_timer(&Controller->MonitoringTimer);
3594 if (CommandType == DAC960_ImmediateCommand)
3596 up(Command->Semaphore);
3597 Command->Semaphore = NULL;
3598 return;
3600 if (CommandType == DAC960_QueuedCommand)
3602 DAC960_V1_KernelCommand_T *KernelCommand = Command->V1.KernelCommand;
3603 KernelCommand->CommandStatus = Command->V1.CommandStatus;
3604 Command->V1.KernelCommand = NULL;
3605 if (CommandOpcode == DAC960_V1_DCDB)
3606 Controller->V1.DirectCommandActive[KernelCommand->DCDB->Channel]
3607 [KernelCommand->DCDB->TargetID] =
3608 false;
3609 DAC960_DeallocateCommand(Command);
3610 KernelCommand->CompletionFunction(KernelCommand);
3611 return;
3614 Queue a Status Monitoring Command to the Controller using the just
3615 completed Command if one was deferred previously due to lack of a
3616 free Command when the Monitoring Timer Function was called.
3618 if (Controller->MonitoringCommandDeferred)
3620 Controller->MonitoringCommandDeferred = false;
3621 DAC960_V1_QueueMonitoringCommand(Command);
3622 return;
3625 Deallocate the Command.
3627 DAC960_DeallocateCommand(Command);
3629 Wake up any processes waiting on a free Command.
3631 wake_up(&Controller->CommandWaitQueue);
3636 DAC960_V2_ReadWriteError prints an appropriate error message for Command
3637 when an error occurs on a Read or Write operation.
3640 static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
3642 DAC960_Controller_T *Controller = Command->Controller;
3643 unsigned char *SenseErrors[] = { "NO SENSE", "RECOVERED ERROR",
3644 "NOT READY", "MEDIUM ERROR",
3645 "HARDWARE ERROR", "ILLEGAL REQUEST",
3646 "UNIT ATTENTION", "DATA PROTECT",
3647 "BLANK CHECK", "VENDOR-SPECIFIC",
3648 "COPY ABORTED", "ABORTED COMMAND",
3649 "EQUAL", "VOLUME OVERFLOW",
3650 "MISCOMPARE", "RESERVED" };
3651 unsigned char *CommandName = "UNKNOWN";
3652 switch (Command->CommandType)
3654 case DAC960_ReadCommand:
3655 case DAC960_ReadRetryCommand:
3656 CommandName = "READ";
3657 break;
3658 case DAC960_WriteCommand:
3659 case DAC960_WriteRetryCommand:
3660 CommandName = "WRITE";
3661 break;
3662 case DAC960_MonitoringCommand:
3663 case DAC960_ImmediateCommand:
3664 case DAC960_QueuedCommand:
3665 break;
3667 DAC960_Error("Error Condition %s on %s:\n", Controller,
3668 SenseErrors[Command->V2.RequestSense.SenseKey], CommandName);
3669 DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %d..%d\n",
3670 Controller, Controller->ControllerNumber,
3671 Command->LogicalDriveNumber, Command->BlockNumber,
3672 Command->BlockNumber + Command->BlockCount - 1);
3673 if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
3674 DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
3675 Controller, Controller->ControllerNumber,
3676 Command->LogicalDriveNumber,
3677 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
3678 Command->BufferHeader->b_rsector,
3679 Command->BufferHeader->b_rsector + Command->BlockCount - 1);
3684 DAC960_V2_ReportEvent prints an appropriate message when a Controller Event
3685 occurs.
3688 static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
3689 DAC960_V2_Event_T *Event)
3691 DAC960_SCSI_RequestSense_T *RequestSense =
3692 (DAC960_SCSI_RequestSense_T *) &Event->RequestSenseData;
3693 unsigned char MessageBuffer[DAC960_LineBufferSize];
3694 static struct { int EventCode; unsigned char *EventMessage; } EventList[] =
3695 { /* Physical Device Events (0x0000 - 0x007F) */
3696 { 0x0001, "P Online" },
3697 { 0x0002, "P Standby" },
3698 { 0x0005, "P Automatic Rebuild Started" },
3699 { 0x0006, "P Manual Rebuild Started" },
3700 { 0x0007, "P Rebuild Completed" },
3701 { 0x0008, "P Rebuild Cancelled" },
3702 { 0x0009, "P Rebuild Failed for Unknown Reasons" },
3703 { 0x000A, "P Rebuild Failed due to New Physical Device" },
3704 { 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
3705 { 0x000C, "S Offline" },
3706 { 0x000D, "P Found" },
3707 { 0x000E, "P Gone" },
3708 { 0x000F, "P Unconfigured" },
3709 { 0x0010, "P Expand Capacity Started" },
3710 { 0x0011, "P Expand Capacity Completed" },
3711 { 0x0012, "P Expand Capacity Failed" },
3712 { 0x0016, "P Parity Error" },
3713 { 0x0017, "P Soft Error" },
3714 { 0x0018, "P Miscellaneous Error" },
3715 { 0x0019, "P Reset" },
3716 { 0x001A, "P Active Spare Found" },
3717 { 0x001B, "P Warm Spare Found" },
3718 { 0x001C, "S Sense Data Received" },
3719 { 0x001D, "P Initialization Started" },
3720 { 0x001E, "P Initialization Completed" },
3721 { 0x001F, "P Initialization Failed" },
3722 { 0x0020, "P Initialization Cancelled" },
3723 { 0x0021, "P Failed because Write Recovery Failed" },
3724 { 0x0022, "P Failed because SCSI Bus Reset Failed" },
3725 { 0x0023, "P Failed because of Double Check Condition" },
3726 { 0x0024, "P Failed because Device Cannot Be Accessed" },
3727 { 0x0025, "P Failed because of Gross Error on SCSI Processor" },
3728 { 0x0026, "P Failed because of Bad Tag from Device" },
3729 { 0x0027, "P Failed because of Command Timeout" },
3730 { 0x0028, "P Failed because of System Reset" },
3731 { 0x0029, "P Failed because of Busy Status or Parity Error" },
3732 { 0x002A, "P Failed because Host Set Device to Failed State" },
3733 { 0x002B, "P Failed because of Selection Timeout" },
3734 { 0x002C, "P Failed because of SCSI Bus Phase Error" },
3735 { 0x002D, "P Failed because Device Returned Unknown Status" },
3736 { 0x002E, "P Failed because Device Not Ready" },
3737 { 0x002F, "P Failed because Device Not Found at Startup" },
3738 { 0x0030, "P Failed because COD Write Operation Failed" },
3739 { 0x0031, "P Failed because BDT Write Operation Failed" },
3740 { 0x0039, "P Missing at Startup" },
3741 { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
3742 /* Logical Device Events (0x0080 - 0x00FF) */
3743 { 0x0080, "M Consistency Check Started" },
3744 { 0x0081, "M Consistency Check Completed" },
3745 { 0x0082, "M Consistency Check Cancelled" },
3746 { 0x0083, "M Consistency Check Completed With Errors" },
3747 { 0x0084, "M Consistency Check Failed due to Logical Drive Failure" },
3748 { 0x0085, "M Consistency Check Failed due to Physical Device Failure" },
3749 { 0x0086, "L Offline" },
3750 { 0x0087, "L Critical" },
3751 { 0x0088, "L Online" },
3752 { 0x0089, "M Automatic Rebuild Started" },
3753 { 0x008A, "M Manual Rebuild Started" },
3754 { 0x008B, "M Rebuild Completed" },
3755 { 0x008C, "M Rebuild Cancelled" },
3756 { 0x008D, "M Rebuild Failed for Unknown Reasons" },
3757 { 0x008E, "M Rebuild Failed due to New Physical Device" },
3758 { 0x008F, "M Rebuild Failed due to Logical Drive Failure" },
3759 { 0x0090, "L Initialization Started" },
3760 { 0x0091, "L Initialization Completed" },
3761 { 0x0092, "L Initialization Cancelled" },
3762 { 0x0093, "L Initialization Failed" },
3763 { 0x0094, "L Found" },
3764 { 0x0095, "L Gone" },
3765 { 0x0096, "L Expand Capacity Started" },
3766 { 0x0097, "L Expand Capacity Completed" },
3767 { 0x0098, "L Expand Capacity Failed" },
3768 { 0x0099, "L Bad Block Found" },
3769 { 0x009A, "L Size Changed" },
3770 { 0x009B, "L Type Changed" },
3771 { 0x009C, "L Bad Data Block Found" },
3772 { 0x009E, "L Read of Data Block in BDT" },
3773 { 0x009F, "L Write Back Data for Disk Block Lost" },
3774 /* Fault Management Events (0x0100 - 0x017F) */
3775 { 0x0140, "E Fan %d Failed" },
3776 { 0x0141, "E Fan %d OK" },
3777 { 0x0142, "E Fan %d Not Present" },
3778 { 0x0143, "E Power Supply %d Failed" },
3779 { 0x0144, "E Power Supply %d OK" },
3780 { 0x0145, "E Power Supply %d Not Present" },
3781 { 0x0146, "E Temperature Sensor %d Failed" },
3782 { 0x0147, "E Temperature Sensor %d Critical" },
3783 { 0x0148, "E Temperature Sensor %d OK" },
3784 { 0x0149, "E Temperature Sensor %d Not Present" },
3785 { 0x014A, "E Unit %d Access Critical" },
3786 { 0x014B, "E Unit %d Access OK" },
3787 { 0x014C, "E Unit %d Access Offline" },
3788 /* Controller Events (0x0180 - 0x01FF) */
3789 { 0x0181, "C Cache Write Back Error" },
3790 { 0x0188, "C Battery Backup Unit Found" },
3791 { 0x0189, "C Battery Backup Unit Charge Level Low" },
3792 { 0x018A, "C Battery Backup Unit Charge Level OK" },
3793 { 0x0193, "C Installation Aborted" },
3794 { 0x0195, "C Mirror Race Recovery In Progress" },
3795 { 0x0196, "C Mirror Race on Critical Drive" },
3796 { 0x019E, "C Memory Soft ECC Error" },
3797 { 0x019F, "C Memory Hard ECC Error" },
3798 { 0x01A2, "C Battery Backup Unit Failed" },
3799 { 0, "" } };
3800 int EventListIndex = 0, EventCode;
3801 unsigned char EventType, *EventMessage;
3802 while (true)
3804 EventCode = EventList[EventListIndex].EventCode;
3805 if (EventCode == Event->EventCode || EventCode == 0) break;
3806 EventListIndex++;
3808 EventType = EventList[EventListIndex].EventMessage[0];
3809 EventMessage = &EventList[EventListIndex].EventMessage[2];
3810 if (EventCode == 0)
3812 DAC960_Critical("Unknown Controller Event Code %04X\n",
3813 Controller, Event->EventCode);
3814 return;
3816 switch (EventType)
3818 case 'P':
3819 DAC960_Critical("Physical Device %d:%d %s\n", Controller,
3820 Event->Channel, Event->TargetID, EventMessage);
3821 break;
3822 case 'L':
3823 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller,
3824 Event->LogicalUnit, Controller->ControllerNumber,
3825 Event->LogicalUnit, EventMessage);
3826 break;
3827 case 'M':
3828 DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller,
3829 Event->LogicalUnit, Controller->ControllerNumber,
3830 Event->LogicalUnit, EventMessage);
3831 break;
3832 case 'S':
3833 if (RequestSense->SenseKey == DAC960_SenseKey_NoSense ||
3834 (RequestSense->SenseKey == DAC960_SenseKey_NotReady &&
3835 RequestSense->AdditionalSenseCode == 0x04 &&
3836 (RequestSense->AdditionalSenseCodeQualifier == 0x01 ||
3837 RequestSense->AdditionalSenseCodeQualifier == 0x02)))
3838 break;
3839 DAC960_Critical("Physical Device %d:%d %s\n", Controller,
3840 Event->Channel, Event->TargetID, EventMessage);
3841 DAC960_Critical("Physical Device %d:%d Request Sense: "
3842 "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
3843 Controller,
3844 Event->Channel,
3845 Event->TargetID,
3846 RequestSense->SenseKey,
3847 RequestSense->AdditionalSenseCode,
3848 RequestSense->AdditionalSenseCodeQualifier);
3849 DAC960_Critical("Physical Device %d:%d Request Sense: "
3850 "Information = %02X%02X%02X%02X "
3851 "%02X%02X%02X%02X\n",
3852 Controller,
3853 Event->Channel,
3854 Event->TargetID,
3855 RequestSense->Information[0],
3856 RequestSense->Information[1],
3857 RequestSense->Information[2],
3858 RequestSense->Information[3],
3859 RequestSense->CommandSpecificInformation[0],
3860 RequestSense->CommandSpecificInformation[1],
3861 RequestSense->CommandSpecificInformation[2],
3862 RequestSense->CommandSpecificInformation[3]);
3863 break;
3864 case 'E':
3865 sprintf(MessageBuffer, EventMessage, Event->LogicalUnit);
3866 DAC960_Critical("Enclosure %d %s\n", Controller,
3867 Event->TargetID, MessageBuffer);
3868 break;
3869 case 'C':
3870 DAC960_Critical("Controller %s\n", Controller, EventMessage);
3871 break;
3872 default:
3873 DAC960_Critical("Unknown Controller Event Code %04X\n",
3874 Controller, Event->EventCode);
3875 break;
3881 DAC960_V2_ReportProgress prints an appropriate progress message for
3882 Logical Device Long Operations.
3885 static void DAC960_V2_ReportProgress(DAC960_Controller_T *Controller,
3886 unsigned char *MessageString,
3887 unsigned int LogicalDeviceNumber,
3888 unsigned long BlocksCompleted,
3889 unsigned long LogicalDeviceSize)
3891 Controller->EphemeralProgressMessage = true;
3892 DAC960_Progress("%s in Progress: Logical Drive %d (/dev/rd/c%dd%d) "
3893 "%d%% completed\n", Controller,
3894 MessageString,
3895 LogicalDeviceNumber,
3896 Controller->ControllerNumber,
3897 LogicalDeviceNumber,
3898 (100 * (BlocksCompleted >> 7)) / (LogicalDeviceSize >> 7));
3899 Controller->EphemeralProgressMessage = false;
3904 DAC960_V2_ProcessCompletedCommand performs completion processing for Command
3905 for DAC960 V2 Firmware Controllers.
3908 static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
3910 DAC960_Controller_T *Controller = Command->Controller;
3911 DAC960_CommandType_T CommandType = Command->CommandType;
3912 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
3913 DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode;
3914 DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus;
3915 BufferHeader_T *BufferHeader = Command->BufferHeader;
3916 if (CommandType == DAC960_ReadCommand ||
3917 CommandType == DAC960_WriteCommand)
3919 if (CommandStatus == DAC960_V2_NormalCompletion)
3922 Perform completion processing for all buffers in this I/O Request.
3924 while (BufferHeader != NULL)
3926 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
3927 BufferHeader->b_reqnext = NULL;
3928 DAC960_ProcessCompletedBuffer(BufferHeader, true);
3929 BufferHeader = NextBufferHeader;
3932 Wake up requestor for swap file paging requests.
3934 if (Command->Semaphore != NULL)
3936 up(Command->Semaphore);
3937 Command->Semaphore = NULL;
3939 add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
3941 else if (Command->V2.RequestSense.SenseKey
3942 == DAC960_SenseKey_MediumError &&
3943 BufferHeader != NULL &&
3944 BufferHeader->b_reqnext != NULL)
3946 if (CommandType == DAC960_ReadCommand)
3947 Command->CommandType = DAC960_ReadRetryCommand;
3948 else Command->CommandType = DAC960_WriteRetryCommand;
3949 Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
3950 CommandMailbox->SCSI_10.CommandControlBits
3951 .AdditionalScatterGatherListMemory = false;
3952 CommandMailbox->SCSI_10.DataTransferSize =
3953 Command->BlockCount << DAC960_BlockSizeBits;
3954 CommandMailbox->SCSI_10.DataTransferMemoryAddress
3955 .ScatterGatherSegments[0].SegmentDataPointer =
3956 Virtual_to_Bus(BufferHeader->b_data);
3957 CommandMailbox->SCSI_10.DataTransferMemoryAddress
3958 .ScatterGatherSegments[0].SegmentByteCount =
3959 CommandMailbox->SCSI_10.DataTransferSize;
3960 CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
3961 CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
3962 DAC960_QueueCommand(Command);
3963 return;
3965 else
3967 if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
3968 DAC960_V2_ReadWriteError(Command);
3970 Perform completion processing for all buffers in this I/O Request.
3972 while (BufferHeader != NULL)
3974 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
3975 BufferHeader->b_reqnext = NULL;
3976 DAC960_ProcessCompletedBuffer(BufferHeader, false);
3977 BufferHeader = NextBufferHeader;
3980 Wake up requestor for swap file paging requests.
3982 if (Command->Semaphore != NULL)
3984 up(Command->Semaphore);
3985 Command->Semaphore = NULL;
3989 else if (CommandType == DAC960_ReadRetryCommand ||
3990 CommandType == DAC960_WriteRetryCommand)
3992 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
3993 BufferHeader->b_reqnext = NULL;
3995 Perform completion processing for this single buffer.
3997 if (CommandStatus == DAC960_V2_NormalCompletion)
3998 DAC960_ProcessCompletedBuffer(BufferHeader, true);
3999 else
4001 if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
4002 DAC960_V2_ReadWriteError(Command);
4003 DAC960_ProcessCompletedBuffer(BufferHeader, false);
4005 if (NextBufferHeader != NULL)
4007 Command->BlockNumber +=
4008 BufferHeader->b_size >> DAC960_BlockSizeBits;
4009 Command->BlockCount =
4010 NextBufferHeader->b_size >> DAC960_BlockSizeBits;
4011 Command->BufferHeader = NextBufferHeader;
4012 CommandMailbox->SCSI_10.DataTransferSize =
4013 Command->BlockCount << DAC960_BlockSizeBits;
4014 CommandMailbox->SCSI_10.DataTransferMemoryAddress
4015 .ScatterGatherSegments[0]
4016 .SegmentDataPointer =
4017 Virtual_to_Bus(NextBufferHeader->b_data);
4018 CommandMailbox->SCSI_10.DataTransferMemoryAddress
4019 .ScatterGatherSegments[0]
4020 .SegmentByteCount =
4021 CommandMailbox->SCSI_10.DataTransferSize;
4022 CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
4023 CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
4024 CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
4025 CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
4026 CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
4027 CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
4028 DAC960_QueueCommand(Command);
4029 return;
4032 else if (CommandType == DAC960_MonitoringCommand)
4034 if (CommandOpcode == DAC960_V2_GetControllerInfo)
4036 DAC960_V2_ControllerInfo_T *NewControllerInfo =
4037 &Controller->V2.NewControllerInformation;
4038 DAC960_V2_ControllerInfo_T *ControllerInfo =
4039 &Controller->V2.ControllerInformation;
4040 Controller->LogicalDriveCount =
4041 NewControllerInfo->LogicalDevicesPresent;
4042 Controller->V2.NeedLogicalDeviceInformation = true;
4043 Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber = 0;
4044 Controller->V2.NeedPhysicalDeviceInformation = true;
4045 Controller->V2.PhysicalDeviceIndex = 0;
4046 Controller->V2.NewPhysicalDeviceInformation.Channel = 0;
4047 Controller->V2.NewPhysicalDeviceInformation.TargetID = 0;
4048 Controller->V2.NewPhysicalDeviceInformation.LogicalUnit = 0;
4049 Controller->MonitoringAlertMode =
4050 (NewControllerInfo->LogicalDevicesCritical > 0 ||
4051 NewControllerInfo->LogicalDevicesOffline > 0 ||
4052 NewControllerInfo->PhysicalDisksCritical > 0 ||
4053 NewControllerInfo->PhysicalDisksOffline > 0);
4054 memcpy(ControllerInfo, NewControllerInfo,
4055 sizeof(DAC960_V2_ControllerInfo_T));
4057 else if (CommandOpcode == DAC960_V2_GetEvent)
4059 if (CommandStatus == DAC960_V2_NormalCompletion)
4060 DAC960_V2_ReportEvent(Controller, &Controller->V2.Event);
4061 Controller->V2.NextEventSequenceNumber++;
4063 else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
4064 CommandStatus == DAC960_V2_NormalCompletion)
4066 DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
4067 &Controller->V2.NewPhysicalDeviceInformation;
4068 unsigned int PhysicalDeviceIndex = Controller->V2.PhysicalDeviceIndex;
4069 DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
4070 Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
4071 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
4072 if (PhysicalDeviceInfo == NULL ||
4073 (NewPhysicalDeviceInfo->Channel !=
4074 PhysicalDeviceInfo->Channel) ||
4075 (NewPhysicalDeviceInfo->TargetID !=
4076 PhysicalDeviceInfo->TargetID) ||
4077 (NewPhysicalDeviceInfo->LogicalUnit !=
4078 PhysicalDeviceInfo->LogicalUnit))
4080 unsigned int DeviceIndex;
4081 PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
4082 kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
4083 InquiryUnitSerialNumber =
4084 (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
4085 kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
4086 GFP_ATOMIC);
4087 if (InquiryUnitSerialNumber == NULL)
4089 kfree(PhysicalDeviceInfo);
4090 PhysicalDeviceInfo = NULL;
4092 DAC960_Critical("Physical Device %d:%d Now Exists%s\n",
4093 Controller,
4094 NewPhysicalDeviceInfo->Channel,
4095 NewPhysicalDeviceInfo->TargetID,
4096 (PhysicalDeviceInfo != NULL
4097 ? "" : " - Allocation Failed"));
4098 if (PhysicalDeviceInfo != NULL)
4100 for (DeviceIndex = PhysicalDeviceIndex;
4101 DeviceIndex < DAC960_V2_MaxPhysicalDevices - 1;
4102 DeviceIndex++)
4104 Controller->V2.PhysicalDeviceInformation[DeviceIndex+1] =
4105 Controller->V2.PhysicalDeviceInformation[DeviceIndex];
4106 Controller->V2.InquiryUnitSerialNumber[DeviceIndex+1] =
4107 Controller->V2.InquiryUnitSerialNumber[DeviceIndex];
4108 Controller->V2.PhysicalDeviceInformation
4109 [PhysicalDeviceIndex] =
4110 PhysicalDeviceInfo;
4111 Controller->V2.InquiryUnitSerialNumber
4112 [PhysicalDeviceIndex] =
4113 InquiryUnitSerialNumber;
4115 memset(PhysicalDeviceInfo, 0,
4116 sizeof(DAC960_V2_PhysicalDeviceInfo_T));
4117 PhysicalDeviceInfo->PhysicalDeviceState =
4118 DAC960_V2_Device_InvalidState;
4119 memset(InquiryUnitSerialNumber, 0,
4120 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
4121 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
4122 Controller->V2.NeedDeviceSerialNumberInformation = true;
4125 if (PhysicalDeviceInfo != NULL)
4127 if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
4128 PhysicalDeviceInfo->PhysicalDeviceState)
4129 DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
4130 NewPhysicalDeviceInfo->Channel,
4131 NewPhysicalDeviceInfo->TargetID,
4132 (NewPhysicalDeviceInfo->PhysicalDeviceState
4133 == DAC960_V2_Device_Unconfigured
4134 ? "UNCONFIGURED"
4135 : NewPhysicalDeviceInfo->PhysicalDeviceState
4136 == DAC960_V2_Device_Online
4137 ? "ONLINE"
4138 : NewPhysicalDeviceInfo->PhysicalDeviceState
4139 == DAC960_V2_Device_WriteOnly
4140 ? "WRITE-ONLY"
4141 : NewPhysicalDeviceInfo
4142 ->PhysicalDeviceState
4143 == DAC960_V2_Device_Dead
4144 ? "DEAD" : "STANDBY"));
4145 if ((NewPhysicalDeviceInfo->ParityErrors !=
4146 PhysicalDeviceInfo->ParityErrors) ||
4147 (NewPhysicalDeviceInfo->SoftErrors !=
4148 PhysicalDeviceInfo->SoftErrors) ||
4149 (NewPhysicalDeviceInfo->HardErrors !=
4150 PhysicalDeviceInfo->HardErrors) ||
4151 (NewPhysicalDeviceInfo->MiscellaneousErrors !=
4152 PhysicalDeviceInfo->MiscellaneousErrors) ||
4153 (NewPhysicalDeviceInfo->CommandTimeouts !=
4154 PhysicalDeviceInfo->CommandTimeouts) ||
4155 (NewPhysicalDeviceInfo->Retries !=
4156 PhysicalDeviceInfo->Retries) ||
4157 (NewPhysicalDeviceInfo->Aborts !=
4158 PhysicalDeviceInfo->Aborts) ||
4159 (NewPhysicalDeviceInfo->PredictedFailuresDetected !=
4160 PhysicalDeviceInfo->PredictedFailuresDetected))
4162 DAC960_Critical("Physical Device %d:%d Errors: "
4163 "Parity = %d, Soft = %d, "
4164 "Hard = %d, Misc = %d\n",
4165 Controller,
4166 NewPhysicalDeviceInfo->Channel,
4167 NewPhysicalDeviceInfo->TargetID,
4168 NewPhysicalDeviceInfo->ParityErrors,
4169 NewPhysicalDeviceInfo->SoftErrors,
4170 NewPhysicalDeviceInfo->HardErrors,
4171 NewPhysicalDeviceInfo->MiscellaneousErrors);
4172 DAC960_Critical("Physical Device %d:%d Errors: "
4173 "Timeouts = %d, Retries = %d, "
4174 "Aborts = %d, Predicted = %d\n",
4175 Controller,
4176 NewPhysicalDeviceInfo->Channel,
4177 NewPhysicalDeviceInfo->TargetID,
4178 NewPhysicalDeviceInfo->CommandTimeouts,
4179 NewPhysicalDeviceInfo->Retries,
4180 NewPhysicalDeviceInfo->Aborts,
4181 NewPhysicalDeviceInfo
4182 ->PredictedFailuresDetected);
4184 if (PhysicalDeviceInfo->PhysicalDeviceState
4185 == DAC960_V2_Device_Dead &&
4186 NewPhysicalDeviceInfo->PhysicalDeviceState
4187 != DAC960_V2_Device_Dead)
4188 Controller->V2.NeedDeviceSerialNumberInformation = true;
4189 memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
4190 sizeof(DAC960_V2_PhysicalDeviceInfo_T));
4192 NewPhysicalDeviceInfo->LogicalUnit++;
4193 Controller->V2.PhysicalDeviceIndex++;
4195 else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
4196 Controller->V2.NeedPhysicalDeviceInformation = false;
4197 else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
4198 CommandStatus == DAC960_V2_NormalCompletion)
4200 DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
4201 &Controller->V2.NewLogicalDeviceInformation;
4202 unsigned short LogicalDeviceNumber =
4203 NewLogicalDeviceInfo->LogicalDeviceNumber;
4204 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
4205 Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber];
4206 if (LogicalDeviceInfo == NULL)
4208 DAC960_V2_PhysicalDevice_T PhysicalDevice;
4209 PhysicalDevice.Controller = 0;
4210 PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
4211 PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
4212 PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
4213 Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
4214 PhysicalDevice;
4215 LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
4216 kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
4217 Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
4218 LogicalDeviceInfo;
4219 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
4220 "Now Exists%s\n", Controller,
4221 LogicalDeviceNumber,
4222 Controller->ControllerNumber,
4223 LogicalDeviceNumber,
4224 (LogicalDeviceInfo != NULL
4225 ? "" : " - Allocation Failed"));
4226 if (LogicalDeviceInfo != NULL)
4227 memset(LogicalDeviceInfo, 0,
4228 sizeof(DAC960_V2_LogicalDeviceInfo_T));
4230 if (LogicalDeviceInfo != NULL)
4232 unsigned long LogicalDeviceSize =
4233 NewLogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB;
4234 if (NewLogicalDeviceInfo->LogicalDeviceState !=
4235 LogicalDeviceInfo->LogicalDeviceState)
4236 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
4237 "is now %s\n", Controller,
4238 LogicalDeviceNumber,
4239 Controller->ControllerNumber,
4240 LogicalDeviceNumber,
4241 (NewLogicalDeviceInfo->LogicalDeviceState
4242 == DAC960_V2_LogicalDevice_Online
4243 ? "ONLINE"
4244 : NewLogicalDeviceInfo->LogicalDeviceState
4245 == DAC960_V2_LogicalDevice_Critical
4246 ? "CRITICAL" : "OFFLINE"));
4247 if ((NewLogicalDeviceInfo->SoftErrors !=
4248 LogicalDeviceInfo->SoftErrors) ||
4249 (NewLogicalDeviceInfo->CommandsFailed !=
4250 LogicalDeviceInfo->CommandsFailed) ||
4251 (NewLogicalDeviceInfo->DeferredWriteErrors !=
4252 LogicalDeviceInfo->DeferredWriteErrors))
4253 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) Errors: "
4254 "Soft = %d, Failed = %d, Deferred Write = %d\n",
4255 Controller, LogicalDeviceNumber,
4256 Controller->ControllerNumber,
4257 LogicalDeviceNumber,
4258 NewLogicalDeviceInfo->SoftErrors,
4259 NewLogicalDeviceInfo->CommandsFailed,
4260 NewLogicalDeviceInfo->DeferredWriteErrors);
4261 if (NewLogicalDeviceInfo->ConsistencyCheckInProgress)
4262 DAC960_V2_ReportProgress(Controller,
4263 "Consistency Check",
4264 LogicalDeviceNumber,
4265 NewLogicalDeviceInfo
4266 ->ConsistencyCheckBlockNumber,
4267 LogicalDeviceSize);
4268 else if (NewLogicalDeviceInfo->RebuildInProgress)
4269 DAC960_V2_ReportProgress(Controller,
4270 "Rebuild",
4271 LogicalDeviceNumber,
4272 NewLogicalDeviceInfo
4273 ->RebuildBlockNumber,
4274 LogicalDeviceSize);
4275 else if (NewLogicalDeviceInfo->BackgroundInitializationInProgress)
4276 DAC960_V2_ReportProgress(Controller,
4277 "BackgroundInitialization",
4278 LogicalDeviceNumber,
4279 NewLogicalDeviceInfo
4280 ->BackgroundInitializationBlockNumber,
4281 LogicalDeviceSize);
4282 else if (NewLogicalDeviceInfo->ForegroundInitializationInProgress)
4283 DAC960_V2_ReportProgress(Controller,
4284 "Foreground Initialization",
4285 LogicalDeviceNumber,
4286 NewLogicalDeviceInfo
4287 ->ForegroundInitializationBlockNumber,
4288 LogicalDeviceSize);
4289 else if (NewLogicalDeviceInfo->DataMigrationInProgress)
4290 DAC960_V2_ReportProgress(Controller,
4291 "Data Migration",
4292 LogicalDeviceNumber,
4293 NewLogicalDeviceInfo
4294 ->DataMigrationBlockNumber,
4295 LogicalDeviceSize);
4296 else if (NewLogicalDeviceInfo->PatrolOperationInProgress)
4297 DAC960_V2_ReportProgress(Controller,
4298 "Patrol Operation",
4299 LogicalDeviceNumber,
4300 NewLogicalDeviceInfo
4301 ->PatrolOperationBlockNumber,
4302 LogicalDeviceSize);
4303 memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
4304 sizeof(DAC960_V2_LogicalDeviceInfo_T));
4306 NewLogicalDeviceInfo->LogicalDeviceNumber++;
4308 else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
4309 Controller->V2.NeedLogicalDeviceInformation = false;
4310 if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
4311 - Controller->V2.NextEventSequenceNumber > 0)
4313 CommandMailbox->GetEvent.CommandOpcode = DAC960_V2_IOCTL;
4314 CommandMailbox->GetEvent.DataTransferSize = sizeof(DAC960_V2_Event_T);
4315 CommandMailbox->GetEvent.EventSequenceNumberHigh16 =
4316 Controller->V2.NextEventSequenceNumber >> 16;
4317 CommandMailbox->GetEvent.ControllerNumber = 0;
4318 CommandMailbox->GetEvent.IOCTL_Opcode =
4319 DAC960_V2_GetEvent;
4320 CommandMailbox->GetEvent.EventSequenceNumberLow16 =
4321 Controller->V2.NextEventSequenceNumber & 0xFFFF;
4322 CommandMailbox->GetEvent.DataTransferMemoryAddress
4323 .ScatterGatherSegments[0]
4324 .SegmentDataPointer =
4325 Virtual_to_Bus(&Controller->V2.Event);
4326 CommandMailbox->GetEvent.DataTransferMemoryAddress
4327 .ScatterGatherSegments[0]
4328 .SegmentByteCount =
4329 CommandMailbox->GetEvent.DataTransferSize;
4330 DAC960_QueueCommand(Command);
4331 return;
4333 if (Controller->V2.NeedPhysicalDeviceInformation)
4335 if (Controller->V2.NeedDeviceSerialNumberInformation)
4337 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
4338 Controller->V2.InquiryUnitSerialNumber
4339 [Controller->V2.PhysicalDeviceIndex - 1];
4340 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
4341 CommandMailbox->SCSI_10.CommandOpcode =
4342 DAC960_V2_SCSI_10_Passthru;
4343 CommandMailbox->SCSI_10.DataTransferSize =
4344 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
4345 CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit =
4346 Controller->V2.NewPhysicalDeviceInformation.LogicalUnit - 1;
4347 CommandMailbox->SCSI_10.PhysicalDevice.TargetID =
4348 Controller->V2.NewPhysicalDeviceInformation.TargetID;
4349 CommandMailbox->SCSI_10.PhysicalDevice.Channel =
4350 Controller->V2.NewPhysicalDeviceInformation.Channel;
4351 CommandMailbox->SCSI_10.CDBLength = 6;
4352 CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
4353 CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
4354 CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
4355 CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
4356 CommandMailbox->SCSI_10.SCSI_CDB[4] =
4357 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
4358 CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
4359 CommandMailbox->SCSI_10.DataTransferMemoryAddress
4360 .ScatterGatherSegments[0]
4361 .SegmentDataPointer =
4362 Virtual_to_Bus(InquiryUnitSerialNumber);
4363 CommandMailbox->SCSI_10.DataTransferMemoryAddress
4364 .ScatterGatherSegments[0]
4365 .SegmentByteCount =
4366 CommandMailbox->SCSI_10.DataTransferSize;
4367 DAC960_QueueCommand(Command);
4368 Controller->V2.NeedDeviceSerialNumberInformation = false;
4369 return;
4371 CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
4372 CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
4373 sizeof(DAC960_V2_PhysicalDeviceInfo_T);
4374 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit =
4375 Controller->V2.NewPhysicalDeviceInformation.LogicalUnit;
4376 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID =
4377 Controller->V2.NewPhysicalDeviceInformation.TargetID;
4378 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel =
4379 Controller->V2.NewPhysicalDeviceInformation.Channel;
4380 CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
4381 DAC960_V2_GetPhysicalDeviceInfoValid;
4382 CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
4383 .ScatterGatherSegments[0]
4384 .SegmentDataPointer =
4385 Virtual_to_Bus(&Controller->V2.NewPhysicalDeviceInformation);
4386 CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
4387 .ScatterGatherSegments[0]
4388 .SegmentByteCount =
4389 CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
4390 DAC960_QueueCommand(Command);
4391 return;
4393 if (Controller->V2.NeedLogicalDeviceInformation)
4395 CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
4396 CommandMailbox->LogicalDeviceInfo.DataTransferSize =
4397 sizeof(DAC960_V2_LogicalDeviceInfo_T);
4398 CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
4399 Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber;
4400 CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
4401 DAC960_V2_GetLogicalDeviceInfoValid;
4402 CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
4403 .ScatterGatherSegments[0]
4404 .SegmentDataPointer =
4405 Virtual_to_Bus(&Controller->V2.NewLogicalDeviceInformation);
4406 CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
4407 .ScatterGatherSegments[0]
4408 .SegmentByteCount =
4409 CommandMailbox->LogicalDeviceInfo.DataTransferSize;
4410 DAC960_QueueCommand(Command);
4411 return;
4413 Controller->MonitoringTimerCount++;
4414 Controller->MonitoringTimer.expires =
4415 jiffies + DAC960_HealthStatusMonitoringInterval;
4416 add_timer(&Controller->MonitoringTimer);
4418 if (CommandType == DAC960_ImmediateCommand)
4420 up(Command->Semaphore);
4421 Command->Semaphore = NULL;
4422 return;
4424 if (CommandType == DAC960_QueuedCommand)
4426 DAC960_V2_KernelCommand_T *KernelCommand = Command->V2.KernelCommand;
4427 KernelCommand->CommandStatus = CommandStatus;
4428 KernelCommand->RequestSenseLength = Command->V2.RequestSenseLength;
4429 KernelCommand->DataTransferLength = Command->V2.DataTransferResidue;
4430 Command->V2.KernelCommand = NULL;
4431 DAC960_DeallocateCommand(Command);
4432 KernelCommand->CompletionFunction(KernelCommand);
4433 return;
4436 Queue a Status Monitoring Command to the Controller using the just
4437 completed Command if one was deferred previously due to lack of a
4438 free Command when the Monitoring Timer Function was called.
4440 if (Controller->MonitoringCommandDeferred)
4442 Controller->MonitoringCommandDeferred = false;
4443 DAC960_V2_QueueMonitoringCommand(Command);
4444 return;
4447 Deallocate the Command.
4449 DAC960_DeallocateCommand(Command);
4451 Wake up any processes waiting on a free Command.
4453 wake_up(&Controller->CommandWaitQueue);
4458 DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
4459 Controllers.
4462 static void DAC960_BA_InterruptHandler(int IRQ_Channel,
4463 void *DeviceIdentifier,
4464 Registers_T *InterruptRegisters)
4466 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4467 void *ControllerBaseAddress = Controller->BaseAddress;
4468 DAC960_V2_StatusMailbox_T *NextStatusMailbox;
4469 ProcessorFlags_T ProcessorFlags;
4471 Acquire exclusive access to Controller.
4473 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4475 Process Hardware Interrupts for Controller.
4477 DAC960_BA_AcknowledgeInterrupt(ControllerBaseAddress);
4478 NextStatusMailbox = Controller->V2.NextStatusMailbox;
4479 while (NextStatusMailbox->Fields.CommandIdentifier > 0)
4481 DAC960_V2_CommandIdentifier_T CommandIdentifier =
4482 NextStatusMailbox->Fields.CommandIdentifier;
4483 DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4484 Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
4485 Command->V2.RequestSenseLength =
4486 NextStatusMailbox->Fields.RequestSenseLength;
4487 Command->V2.DataTransferResidue =
4488 NextStatusMailbox->Fields.DataTransferResidue;
4489 NextStatusMailbox->Words[0] = 0;
4490 if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
4491 NextStatusMailbox = Controller->V2.FirstStatusMailbox;
4492 DAC960_V2_ProcessCompletedCommand(Command);
4494 Controller->V2.NextStatusMailbox = NextStatusMailbox;
4496 Attempt to remove additional I/O Requests from the Controller's
4497 I/O Request Queue and queue them to the Controller.
4499 while (DAC960_ProcessRequest(Controller, false)) ;
4501 Release exclusive access to Controller.
4503 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4508 DAC960_LP_InterruptHandler handles hardware interrupts from DAC960 LP Series
4509 Controllers.
4512 static void DAC960_LP_InterruptHandler(int IRQ_Channel,
4513 void *DeviceIdentifier,
4514 Registers_T *InterruptRegisters)
4516 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4517 void *ControllerBaseAddress = Controller->BaseAddress;
4518 DAC960_V2_StatusMailbox_T *NextStatusMailbox;
4519 ProcessorFlags_T ProcessorFlags;
4521 Acquire exclusive access to Controller.
4523 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4525 Process Hardware Interrupts for Controller.
4527 DAC960_LP_AcknowledgeInterrupt(ControllerBaseAddress);
4528 NextStatusMailbox = Controller->V2.NextStatusMailbox;
4529 while (NextStatusMailbox->Fields.CommandIdentifier > 0)
4531 DAC960_V2_CommandIdentifier_T CommandIdentifier =
4532 NextStatusMailbox->Fields.CommandIdentifier;
4533 DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4534 Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
4535 Command->V2.RequestSenseLength =
4536 NextStatusMailbox->Fields.RequestSenseLength;
4537 Command->V2.DataTransferResidue =
4538 NextStatusMailbox->Fields.DataTransferResidue;
4539 NextStatusMailbox->Words[0] = 0;
4540 if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
4541 NextStatusMailbox = Controller->V2.FirstStatusMailbox;
4542 DAC960_V2_ProcessCompletedCommand(Command);
4544 Controller->V2.NextStatusMailbox = NextStatusMailbox;
4546 Attempt to remove additional I/O Requests from the Controller's
4547 I/O Request Queue and queue them to the Controller.
4549 while (DAC960_ProcessRequest(Controller, false)) ;
4551 Release exclusive access to Controller.
4553 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4558 DAC960_LA_InterruptHandler handles hardware interrupts from DAC960 LA Series
4559 Controllers.
4562 static void DAC960_LA_InterruptHandler(int IRQ_Channel,
4563 void *DeviceIdentifier,
4564 Registers_T *InterruptRegisters)
4566 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4567 void *ControllerBaseAddress = Controller->BaseAddress;
4568 DAC960_V1_StatusMailbox_T *NextStatusMailbox;
4569 ProcessorFlags_T ProcessorFlags;
4571 Acquire exclusive access to Controller.
4573 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4575 Process Hardware Interrupts for Controller.
4577 DAC960_LA_AcknowledgeInterrupt(ControllerBaseAddress);
4578 NextStatusMailbox = Controller->V1.NextStatusMailbox;
4579 while (NextStatusMailbox->Fields.Valid)
4581 DAC960_V1_CommandIdentifier_T CommandIdentifier =
4582 NextStatusMailbox->Fields.CommandIdentifier;
4583 DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4584 Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
4585 NextStatusMailbox->Word = 0;
4586 if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
4587 NextStatusMailbox = Controller->V1.FirstStatusMailbox;
4588 DAC960_V1_ProcessCompletedCommand(Command);
4590 Controller->V1.NextStatusMailbox = NextStatusMailbox;
4592 Attempt to remove additional I/O Requests from the Controller's
4593 I/O Request Queue and queue them to the Controller.
4595 while (DAC960_ProcessRequest(Controller, false)) ;
4597 Release exclusive access to Controller.
4599 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4604 DAC960_PG_InterruptHandler handles hardware interrupts from DAC960 PG Series
4605 Controllers.
4608 static void DAC960_PG_InterruptHandler(int IRQ_Channel,
4609 void *DeviceIdentifier,
4610 Registers_T *InterruptRegisters)
4612 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4613 void *ControllerBaseAddress = Controller->BaseAddress;
4614 DAC960_V1_StatusMailbox_T *NextStatusMailbox;
4615 ProcessorFlags_T ProcessorFlags;
4617 Acquire exclusive access to Controller.
4619 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4621 Process Hardware Interrupts for Controller.
4623 DAC960_PG_AcknowledgeInterrupt(ControllerBaseAddress);
4624 NextStatusMailbox = Controller->V1.NextStatusMailbox;
4625 while (NextStatusMailbox->Fields.Valid)
4627 DAC960_V1_CommandIdentifier_T CommandIdentifier =
4628 NextStatusMailbox->Fields.CommandIdentifier;
4629 DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4630 Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
4631 NextStatusMailbox->Word = 0;
4632 if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
4633 NextStatusMailbox = Controller->V1.FirstStatusMailbox;
4634 DAC960_V1_ProcessCompletedCommand(Command);
4636 Controller->V1.NextStatusMailbox = NextStatusMailbox;
4638 Attempt to remove additional I/O Requests from the Controller's
4639 I/O Request Queue and queue them to the Controller.
4641 while (DAC960_ProcessRequest(Controller, false)) ;
4643 Release exclusive access to Controller.
4645 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4650 DAC960_PD_InterruptHandler handles hardware interrupts from DAC960 PD Series
4651 Controllers.
4654 static void DAC960_PD_InterruptHandler(int IRQ_Channel,
4655 void *DeviceIdentifier,
4656 Registers_T *InterruptRegisters)
4658 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4659 void *ControllerBaseAddress = Controller->BaseAddress;
4660 ProcessorFlags_T ProcessorFlags;
4662 Acquire exclusive access to Controller.
4664 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4666 Process Hardware Interrupts for Controller.
4668 while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
4670 DAC960_V1_CommandIdentifier_T CommandIdentifier =
4671 DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
4672 DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4673 Command->V1.CommandStatus =
4674 DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
4675 DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
4676 DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
4677 DAC960_V1_ProcessCompletedCommand(Command);
4680 Attempt to remove additional I/O Requests from the Controller's
4681 I/O Request Queue and queue them to the Controller.
4683 while (DAC960_ProcessRequest(Controller, false)) ;
4685 Release exclusive access to Controller.
4687 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4692 DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1
4693 Firmware Controllers.
4696 static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *Command)
4698 DAC960_Controller_T *Controller = Command->Controller;
4699 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
4700 DAC960_V1_ClearCommand(Command);
4701 Command->CommandType = DAC960_MonitoringCommand;
4702 CommandMailbox->Type3.CommandOpcode = DAC960_V1_Enquiry;
4703 CommandMailbox->Type3.BusAddress = Virtual_to_Bus(&Controller->V1.NewEnquiry);
4704 DAC960_QueueCommand(Command);
4709 DAC960_V2_QueueMonitoringCommand queues a Monitoring Command to DAC960 V2
4710 Firmware Controllers.
4713 static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *Command)
4715 DAC960_Controller_T *Controller = Command->Controller;
4716 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
4717 DAC960_V2_ClearCommand(Command);
4718 Command->CommandType = DAC960_MonitoringCommand;
4719 CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
4720 CommandMailbox->ControllerInfo.CommandControlBits
4721 .DataTransferControllerToHost = true;
4722 CommandMailbox->ControllerInfo.CommandControlBits
4723 .NoAutoRequestSense = true;
4724 CommandMailbox->ControllerInfo.DataTransferSize =
4725 sizeof(DAC960_V2_ControllerInfo_T);
4726 CommandMailbox->ControllerInfo.ControllerNumber = 0;
4727 CommandMailbox->ControllerInfo.IOCTL_Opcode = DAC960_V2_GetControllerInfo;
4728 CommandMailbox->ControllerInfo.DataTransferMemoryAddress
4729 .ScatterGatherSegments[0]
4730 .SegmentDataPointer =
4731 Virtual_to_Bus(&Controller->V2.NewControllerInformation);
4732 CommandMailbox->ControllerInfo.DataTransferMemoryAddress
4733 .ScatterGatherSegments[0]
4734 .SegmentByteCount =
4735 CommandMailbox->ControllerInfo.DataTransferSize;
4736 DAC960_QueueCommand(Command);
4741 DAC960_MonitoringTimerFunction is the timer function for monitoring
4742 the status of DAC960 Controllers.
4745 static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
4747 DAC960_Controller_T *Controller = (DAC960_Controller_T *) TimerData;
4748 DAC960_Command_T *Command;
4749 ProcessorFlags_T ProcessorFlags;
4750 if (Controller->FirmwareType == DAC960_V1_Controller)
4753 Acquire exclusive access to Controller.
4755 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
4757 Queue a Status Monitoring Command to Controller.
4759 Command = DAC960_AllocateCommand(Controller);
4760 if (Command != NULL)
4761 DAC960_V1_QueueMonitoringCommand(Command);
4762 else Controller->MonitoringCommandDeferred = true;
4764 Release exclusive access to Controller.
4766 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
4768 else
4770 DAC960_V2_ControllerInfo_T *ControllerInfo =
4771 &Controller->V2.ControllerInformation;
4772 unsigned int StatusChangeCounter =
4773 Controller->V2.HealthStatusBuffer->StatusChangeCounter;
4774 if (StatusChangeCounter == Controller->V2.StatusChangeCounter &&
4775 Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
4776 == Controller->V2.NextEventSequenceNumber &&
4777 (ControllerInfo->BackgroundInitializationsActive +
4778 ControllerInfo->LogicalDeviceInitializationsActive +
4779 ControllerInfo->PhysicalDeviceInitializationsActive +
4780 ControllerInfo->ConsistencyChecksActive +
4781 ControllerInfo->RebuildsActive +
4782 ControllerInfo->OnlineExpansionsActive == 0 ||
4783 jiffies - Controller->PrimaryMonitoringTime
4784 < DAC960_MonitoringTimerInterval))
4786 Controller->MonitoringTimer.expires =
4787 jiffies + DAC960_HealthStatusMonitoringInterval;
4788 add_timer(&Controller->MonitoringTimer);
4789 return;
4791 Controller->V2.StatusChangeCounter = StatusChangeCounter;
4792 Controller->PrimaryMonitoringTime = jiffies;
4794 Acquire exclusive access to Controller.
4796 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
4798 Queue a Status Monitoring Command to Controller.
4800 Command = DAC960_AllocateCommand(Controller);
4801 if (Command != NULL)
4802 DAC960_V2_QueueMonitoringCommand(Command);
4803 else Controller->MonitoringCommandDeferred = true;
4805 Release exclusive access to Controller.
4807 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
4809 Wake up any processes waiting on a Health Status Buffer change.
4811 wake_up(&Controller->HealthStatusWaitQueue);
4817 DAC960_Open is the Device Open Function for the DAC960 Driver.
4820 static int DAC960_Open(Inode_T *Inode, File_T *File)
4822 int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
4823 int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
4824 DAC960_Controller_T *Controller;
4825 if (ControllerNumber == 0 && LogicalDriveNumber == 0 &&
4826 (File->f_flags & O_NONBLOCK))
4827 goto ModuleOnly;
4828 if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
4829 return -ENXIO;
4830 Controller = DAC960_Controllers[ControllerNumber];
4831 if (Controller == NULL) return -ENXIO;
4832 if (Controller->FirmwareType == DAC960_V1_Controller)
4834 if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
4835 return -ENXIO;
4836 if (Controller->V1.LogicalDriveInformation
4837 [LogicalDriveNumber].LogicalDriveState
4838 == DAC960_V1_LogicalDrive_Offline)
4839 return -ENXIO;
4841 else
4843 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
4844 Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
4845 if (LogicalDeviceInfo == NULL ||
4846 LogicalDeviceInfo->LogicalDeviceState
4847 == DAC960_V2_LogicalDevice_Offline)
4848 return -ENXIO;
4850 if (!Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber])
4852 Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
4853 DAC960_RegisterDisk(Controller, LogicalDriveNumber);
4855 if (Controller->GenericDiskInfo.sizes[MINOR(Inode->i_rdev)] == 0)
4856 return -ENXIO;
4858 Increment Controller and Logical Drive Usage Counts.
4860 Controller->ControllerUsageCount++;
4861 Controller->LogicalDriveUsageCount[LogicalDriveNumber]++;
4862 ModuleOnly:
4863 MOD_INC_USE_COUNT;
4864 return 0;
4869 DAC960_Release is the Device Release Function for the DAC960 Driver.
4872 static int DAC960_Release(Inode_T *Inode, File_T *File)
4874 int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
4875 int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
4876 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
4877 if (ControllerNumber == 0 && LogicalDriveNumber == 0 &&
4878 File != NULL && (File->f_flags & O_NONBLOCK))
4879 goto ModuleOnly;
4881 Decrement the Logical Drive and Controller Usage Counts.
4883 Controller->LogicalDriveUsageCount[LogicalDriveNumber]--;
4884 Controller->ControllerUsageCount--;
4885 ModuleOnly:
4886 MOD_DEC_USE_COUNT;
4887 return 0;
4892 DAC960_IOCTL is the Device IOCTL Function for the DAC960 Driver.
4895 static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
4896 unsigned int Request, unsigned long Argument)
4898 int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
4899 int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
4900 DiskGeometry_T Geometry, *UserGeometry;
4901 DAC960_Controller_T *Controller;
4902 int PartitionNumber;
4903 if (File->f_flags & O_NONBLOCK)
4904 return DAC960_UserIOCTL(Inode, File, Request, Argument);
4905 if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
4906 return -ENXIO;
4907 Controller = DAC960_Controllers[ControllerNumber];
4908 if (Controller == NULL) return -ENXIO;
4909 switch (Request)
4911 case HDIO_GETGEO:
4912 /* Get BIOS Disk Geometry. */
4913 UserGeometry = (DiskGeometry_T *) Argument;
4914 if (UserGeometry == NULL) return -EINVAL;
4915 if (Controller->FirmwareType == DAC960_V1_Controller)
4917 if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
4918 return -ENXIO;
4919 Geometry.heads = Controller->V1.GeometryTranslationHeads;
4920 Geometry.sectors = Controller->V1.GeometryTranslationSectors;
4921 Geometry.cylinders =
4922 Controller->V1.LogicalDriveInformation[LogicalDriveNumber]
4923 .LogicalDriveSize
4924 / (Geometry.heads * Geometry.sectors);
4926 else
4928 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
4929 Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
4930 if (LogicalDeviceInfo == NULL)
4931 return -EINVAL;
4932 switch(LogicalDeviceInfo->DriveGeometry)
4934 case DAC960_V2_Geometry_128_32:
4935 Geometry.heads = 128;
4936 Geometry.sectors = 32;
4937 break;
4938 case DAC960_V2_Geometry_255_63:
4939 Geometry.heads = 255;
4940 Geometry.sectors = 63;
4941 break;
4942 default:
4943 DAC960_Error("Illegal Logical Device Geometry %d\n",
4944 Controller, LogicalDeviceInfo->DriveGeometry);
4945 return -EINVAL;
4947 Geometry.cylinders =
4948 LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB
4949 / (Geometry.heads * Geometry.sectors);
4951 Geometry.start =
4952 Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].start_sect;
4953 return copy_to_user(UserGeometry, &Geometry, sizeof(DiskGeometry_T));
4954 case BLKGETSIZE:
4955 /* Get Device Size. */
4956 if ((long *) Argument == NULL) return -EINVAL;
4957 return put_user(Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
4958 .nr_sects,
4959 (long *) Argument);
4960 case BLKRAGET:
4961 /* Get Read-Ahead. */
4962 if ((long *) Argument == NULL) return -EINVAL;
4963 return put_user(read_ahead[MAJOR(Inode->i_rdev)], (long *) Argument);
4964 case BLKRASET:
4965 /* Set Read-Ahead. */
4966 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
4967 if (Argument > 256) return -EINVAL;
4968 read_ahead[MAJOR(Inode->i_rdev)] = Argument;
4969 return 0;
4970 case BLKFLSBUF:
4971 /* Flush Buffers. */
4972 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
4973 fsync_dev(Inode->i_rdev);
4974 invalidate_buffers(Inode->i_rdev);
4975 return 0;
4976 case BLKRRPART:
4977 /* Re-Read Partition Table. */
4978 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
4979 if (Controller->LogicalDriveUsageCount[LogicalDriveNumber] > 1)
4980 return -EBUSY;
4981 for (PartitionNumber = 0;
4982 PartitionNumber < DAC960_MaxPartitions;
4983 PartitionNumber++)
4985 KernelDevice_T Device = DAC960_KernelDevice(ControllerNumber,
4986 LogicalDriveNumber,
4987 PartitionNumber);
4988 int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber,
4989 PartitionNumber);
4990 SuperBlock_T *SuperBlock = get_super(Device);
4991 if (Controller->GenericDiskInfo.part[MinorNumber].nr_sects == 0)
4992 continue;
4994 Flush all changes and invalidate buffered state.
4996 sync_dev(Device);
4997 if (SuperBlock != NULL)
4998 invalidate_inodes(SuperBlock);
4999 invalidate_buffers(Device);
5001 Clear existing partition sizes.
5003 if (PartitionNumber > 0)
5005 Controller->GenericDiskInfo.part[MinorNumber].start_sect = 0;
5006 Controller->GenericDiskInfo.part[MinorNumber].nr_sects = 0;
5009 Reset the Block Size so that the partition table can be read.
5011 set_blocksize(Device, BLOCK_SIZE);
5013 if (Controller->FirmwareType == DAC960_V1_Controller)
5014 grok_partitions(&Controller->GenericDiskInfo,
5015 LogicalDriveNumber,
5016 DAC960_MaxPartitions,
5017 Controller->V1.LogicalDriveInformation
5018 [LogicalDriveNumber]
5019 .LogicalDriveSize);
5020 else
5021 grok_partitions(
5022 &Controller->GenericDiskInfo,
5023 LogicalDriveNumber,
5024 DAC960_MaxPartitions,
5025 Controller->V2.LogicalDeviceInformation[LogicalDriveNumber]
5026 ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
5027 return 0;
5029 return -EINVAL;
5034 DAC960_UserIOCTL is the User IOCTL Function for the DAC960 Driver.
5037 static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
5038 unsigned int Request, unsigned long Argument)
5040 int ErrorCode;
5041 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
5042 switch (Request)
5044 case DAC960_IOCTL_GET_CONTROLLER_COUNT:
5045 return DAC960_ControllerCount;
5046 case DAC960_IOCTL_GET_CONTROLLER_INFO:
5048 DAC960_ControllerInfo_T *UserSpaceControllerInfo =
5049 (DAC960_ControllerInfo_T *) Argument;
5050 DAC960_ControllerInfo_T ControllerInfo;
5051 DAC960_Controller_T *Controller;
5052 int ControllerNumber;
5053 if (UserSpaceControllerInfo == NULL) return -EINVAL;
5054 ErrorCode = get_user(ControllerNumber,
5055 &UserSpaceControllerInfo->ControllerNumber);
5056 if (ErrorCode != 0) return ErrorCode;
5057 if (ControllerNumber < 0 ||
5058 ControllerNumber > DAC960_ControllerCount - 1)
5059 return -ENXIO;
5060 Controller = DAC960_Controllers[ControllerNumber];
5061 if (Controller == NULL) return -ENXIO;
5062 memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
5063 ControllerInfo.ControllerNumber = ControllerNumber;
5064 ControllerInfo.FirmwareType = Controller->FirmwareType;
5065 ControllerInfo.Channels = Controller->Channels;
5066 ControllerInfo.Targets = Controller->Targets;
5067 ControllerInfo.PCI_Bus = Controller->Bus;
5068 ControllerInfo.PCI_Device = Controller->Device;
5069 ControllerInfo.PCI_Function = Controller->Function;
5070 ControllerInfo.IRQ_Channel = Controller->IRQ_Channel;
5071 ControllerInfo.PCI_Address = Controller->PCI_Address;
5072 strcpy(ControllerInfo.ModelName, Controller->ModelName);
5073 strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
5074 return copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
5075 sizeof(DAC960_ControllerInfo_T));
5077 case DAC960_IOCTL_V1_EXECUTE_COMMAND:
5079 DAC960_V1_UserCommand_T *UserSpaceUserCommand =
5080 (DAC960_V1_UserCommand_T *) Argument;
5081 DAC960_V1_UserCommand_T UserCommand;
5082 DAC960_Controller_T *Controller;
5083 DAC960_Command_T *Command = NULL;
5084 DAC960_V1_CommandOpcode_T CommandOpcode;
5085 DAC960_V1_CommandStatus_T CommandStatus;
5086 DAC960_V1_DCDB_T DCDB;
5087 ProcessorFlags_T ProcessorFlags;
5088 int ControllerNumber, DataTransferLength;
5089 unsigned char *DataTransferBuffer = NULL;
5090 if (UserSpaceUserCommand == NULL) return -EINVAL;
5091 ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
5092 sizeof(DAC960_V1_UserCommand_T));
5093 if (ErrorCode != 0) goto Failure1;
5094 ControllerNumber = UserCommand.ControllerNumber;
5095 if (ControllerNumber < 0 ||
5096 ControllerNumber > DAC960_ControllerCount - 1)
5097 return -ENXIO;
5098 Controller = DAC960_Controllers[ControllerNumber];
5099 if (Controller == NULL) return -ENXIO;
5100 if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
5101 CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
5102 DataTransferLength = UserCommand.DataTransferLength;
5103 if (CommandOpcode & 0x80) return -EINVAL;
5104 if (CommandOpcode == DAC960_V1_DCDB)
5106 ErrorCode =
5107 copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_V1_DCDB_T));
5108 if (ErrorCode != 0) goto Failure1;
5109 if (!((DataTransferLength == 0 &&
5110 DCDB.Direction
5111 == DAC960_V1_DCDB_NoDataTransfer) ||
5112 (DataTransferLength > 0 &&
5113 DCDB.Direction
5114 == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
5115 (DataTransferLength < 0 &&
5116 DCDB.Direction
5117 == DAC960_V1_DCDB_DataTransferSystemToDevice)))
5118 return -EINVAL;
5119 if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
5120 != abs(DataTransferLength))
5121 return -EINVAL;
5123 if (DataTransferLength > 0)
5125 DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
5126 if (DataTransferBuffer == NULL) return -ENOMEM;
5127 memset(DataTransferBuffer, 0, DataTransferLength);
5129 else if (DataTransferLength < 0)
5131 DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
5132 if (DataTransferBuffer == NULL) return -ENOMEM;
5133 ErrorCode = copy_from_user(DataTransferBuffer,
5134 UserCommand.DataTransferBuffer,
5135 -DataTransferLength);
5136 if (ErrorCode != 0) goto Failure1;
5138 if (CommandOpcode == DAC960_V1_DCDB)
5140 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5141 while (Controller->V1.DirectCommandActive[DCDB.Channel]
5142 [DCDB.TargetID] ||
5143 (Command = DAC960_AllocateCommand(Controller)) == NULL)
5144 DAC960_WaitForCommand(Controller);
5145 Controller->V1.DirectCommandActive[DCDB.Channel]
5146 [DCDB.TargetID] = true;
5147 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5148 DAC960_V1_ClearCommand(Command);
5149 Command->CommandType = DAC960_ImmediateCommand;
5150 memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
5151 sizeof(DAC960_V1_CommandMailbox_T));
5152 Command->V1.CommandMailbox.Type3.BusAddress =
5153 Virtual_to_Bus(&DCDB);
5154 DCDB.BusAddress = Virtual_to_Bus(DataTransferBuffer);
5156 else
5158 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5159 while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
5160 DAC960_WaitForCommand(Controller);
5161 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5162 DAC960_V1_ClearCommand(Command);
5163 Command->CommandType = DAC960_ImmediateCommand;
5164 memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
5165 sizeof(DAC960_V1_CommandMailbox_T));
5166 if (DataTransferBuffer != NULL)
5167 Command->V1.CommandMailbox.Type3.BusAddress =
5168 Virtual_to_Bus(DataTransferBuffer);
5170 DAC960_ExecuteCommand(Command);
5171 CommandStatus = Command->V1.CommandStatus;
5172 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5173 DAC960_DeallocateCommand(Command);
5174 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5175 if (DataTransferLength > 0)
5177 ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
5178 DataTransferBuffer, DataTransferLength);
5179 if (ErrorCode != 0) goto Failure1;
5181 if (CommandOpcode == DAC960_V1_DCDB)
5183 Controller->V1.DirectCommandActive[DCDB.Channel]
5184 [DCDB.TargetID] = false;
5185 ErrorCode =
5186 copy_to_user(UserCommand.DCDB, &DCDB, sizeof(DAC960_V1_DCDB_T));
5187 if (ErrorCode != 0) goto Failure1;
5189 ErrorCode = CommandStatus;
5190 Failure1:
5191 if (DataTransferBuffer != NULL)
5192 kfree(DataTransferBuffer);
5193 return ErrorCode;
5195 case DAC960_IOCTL_V2_EXECUTE_COMMAND:
5197 DAC960_V2_UserCommand_T *UserSpaceUserCommand =
5198 (DAC960_V2_UserCommand_T *) Argument;
5199 DAC960_V2_UserCommand_T UserCommand;
5200 DAC960_Controller_T *Controller;
5201 DAC960_Command_T *Command = NULL;
5202 DAC960_V2_CommandMailbox_T *CommandMailbox;
5203 DAC960_V2_CommandStatus_T CommandStatus;
5204 ProcessorFlags_T ProcessorFlags;
5205 int ControllerNumber, DataTransferLength;
5206 int DataTransferResidue, RequestSenseLength;
5207 unsigned char *DataTransferBuffer = NULL;
5208 unsigned char *RequestSenseBuffer = NULL;
5209 if (UserSpaceUserCommand == NULL) return -EINVAL;
5210 ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
5211 sizeof(DAC960_V2_UserCommand_T));
5212 if (ErrorCode != 0) goto Failure2;
5213 ControllerNumber = UserCommand.ControllerNumber;
5214 if (ControllerNumber < 0 ||
5215 ControllerNumber > DAC960_ControllerCount - 1)
5216 return -ENXIO;
5217 Controller = DAC960_Controllers[ControllerNumber];
5218 if (Controller == NULL) return -ENXIO;
5219 if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
5220 DataTransferLength = UserCommand.DataTransferLength;
5221 if (DataTransferLength > 0)
5223 DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
5224 if (DataTransferBuffer == NULL) return -ENOMEM;
5225 memset(DataTransferBuffer, 0, DataTransferLength);
5227 else if (DataTransferLength < 0)
5229 DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
5230 if (DataTransferBuffer == NULL) return -ENOMEM;
5231 ErrorCode = copy_from_user(DataTransferBuffer,
5232 UserCommand.DataTransferBuffer,
5233 -DataTransferLength);
5234 if (ErrorCode != 0) goto Failure2;
5236 RequestSenseLength = UserCommand.RequestSenseLength;
5237 if (RequestSenseLength > 0)
5239 RequestSenseBuffer = kmalloc(RequestSenseLength, GFP_KERNEL);
5240 if (RequestSenseBuffer == NULL)
5242 ErrorCode = -ENOMEM;
5243 goto Failure2;
5245 memset(RequestSenseBuffer, 0, RequestSenseLength);
5247 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5248 while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
5249 DAC960_WaitForCommand(Controller);
5250 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5251 DAC960_V2_ClearCommand(Command);
5252 Command->CommandType = DAC960_ImmediateCommand;
5253 CommandMailbox = &Command->V2.CommandMailbox;
5254 memcpy(CommandMailbox, &UserCommand.CommandMailbox,
5255 sizeof(DAC960_V2_CommandMailbox_T));
5256 CommandMailbox->Common.CommandControlBits
5257 .AdditionalScatterGatherListMemory = false;
5258 CommandMailbox->Common.CommandControlBits
5259 .NoAutoRequestSense = true;
5260 CommandMailbox->Common.DataTransferSize = 0;
5261 CommandMailbox->Common.DataTransferPageNumber = 0;
5262 memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
5263 sizeof(DAC960_V2_DataTransferMemoryAddress_T));
5264 if (DataTransferLength != 0)
5266 if (DataTransferLength > 0)
5268 CommandMailbox->Common.CommandControlBits
5269 .DataTransferControllerToHost = true;
5270 CommandMailbox->Common.DataTransferSize = DataTransferLength;
5272 else
5274 CommandMailbox->Common.CommandControlBits
5275 .DataTransferControllerToHost = false;
5276 CommandMailbox->Common.DataTransferSize = -DataTransferLength;
5278 CommandMailbox->Common.DataTransferMemoryAddress
5279 .ScatterGatherSegments[0]
5280 .SegmentDataPointer =
5281 Virtual_to_Bus(DataTransferBuffer);
5282 CommandMailbox->Common.DataTransferMemoryAddress
5283 .ScatterGatherSegments[0]
5284 .SegmentByteCount =
5285 CommandMailbox->Common.DataTransferSize;
5287 if (RequestSenseLength > 0)
5289 CommandMailbox->Common.CommandControlBits
5290 .NoAutoRequestSense = false;
5291 CommandMailbox->Common.RequestSenseSize = RequestSenseLength;
5292 CommandMailbox->Common.RequestSenseBusAddress =
5293 Virtual_to_Bus(RequestSenseBuffer);
5295 DAC960_ExecuteCommand(Command);
5296 CommandStatus = Command->V2.CommandStatus;
5297 RequestSenseLength = Command->V2.RequestSenseLength;
5298 DataTransferResidue = Command->V2.DataTransferResidue;
5299 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5300 DAC960_DeallocateCommand(Command);
5301 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5302 if (RequestSenseLength > UserCommand.RequestSenseLength)
5303 RequestSenseLength = UserCommand.RequestSenseLength;
5304 ErrorCode = copy_to_user(&UserSpaceUserCommand->DataTransferLength,
5305 &DataTransferResidue,
5306 sizeof(DataTransferResidue));
5307 if (ErrorCode != 0) goto Failure2;
5308 ErrorCode = copy_to_user(&UserSpaceUserCommand->RequestSenseLength,
5309 &RequestSenseLength,
5310 sizeof(RequestSenseLength));
5311 if (ErrorCode != 0) goto Failure2;
5312 if (DataTransferLength > 0)
5314 ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
5315 DataTransferBuffer, DataTransferLength);
5316 if (ErrorCode != 0) goto Failure2;
5318 if (RequestSenseLength > 0)
5320 ErrorCode = copy_to_user(UserCommand.RequestSenseBuffer,
5321 RequestSenseBuffer, RequestSenseLength);
5322 if (ErrorCode != 0) goto Failure2;
5324 ErrorCode = CommandStatus;
5325 Failure2:
5326 if (DataTransferBuffer != NULL)
5327 kfree(DataTransferBuffer);
5328 if (RequestSenseBuffer != NULL)
5329 kfree(RequestSenseBuffer);
5330 return ErrorCode;
5332 case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
5334 DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus =
5335 (DAC960_V2_GetHealthStatus_T *) Argument;
5336 DAC960_V2_GetHealthStatus_T GetHealthStatus;
5337 DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
5338 DAC960_Controller_T *Controller;
5339 int ControllerNumber;
5340 if (UserSpaceGetHealthStatus == NULL) return -EINVAL;
5341 ErrorCode = copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
5342 sizeof(DAC960_V2_GetHealthStatus_T));
5343 if (ErrorCode != 0) return ErrorCode;
5344 ControllerNumber = GetHealthStatus.ControllerNumber;
5345 if (ControllerNumber < 0 ||
5346 ControllerNumber > DAC960_ControllerCount - 1)
5347 return -ENXIO;
5348 Controller = DAC960_Controllers[ControllerNumber];
5349 if (Controller == NULL) return -ENXIO;
5350 if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
5351 ErrorCode = copy_from_user(&HealthStatusBuffer,
5352 GetHealthStatus.HealthStatusBuffer,
5353 sizeof(DAC960_V2_HealthStatusBuffer_T));
5354 if (ErrorCode != 0) return ErrorCode;
5355 while (Controller->V2.HealthStatusBuffer->StatusChangeCounter
5356 == HealthStatusBuffer.StatusChangeCounter &&
5357 Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
5358 == HealthStatusBuffer.NextEventSequenceNumber)
5360 interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue,
5361 DAC960_MonitoringTimerInterval);
5362 if (signal_pending(current)) return -EINTR;
5364 ErrorCode = copy_to_user(GetHealthStatus.HealthStatusBuffer,
5365 Controller->V2.HealthStatusBuffer,
5366 sizeof(DAC960_V2_HealthStatusBuffer_T));
5367 return ErrorCode;
5370 return -EINVAL;
5375 DAC960_KernelIOCTL is the Kernel IOCTL Function for the DAC960 Driver.
5378 int DAC960_KernelIOCTL(unsigned int Request, void *Argument)
5380 switch (Request)
5382 case DAC960_IOCTL_GET_CONTROLLER_COUNT:
5383 return DAC960_ControllerCount;
5384 case DAC960_IOCTL_GET_CONTROLLER_INFO:
5386 DAC960_ControllerInfo_T *ControllerInfo =
5387 (DAC960_ControllerInfo_T *) Argument;
5388 DAC960_Controller_T *Controller;
5389 int ControllerNumber;
5390 if (ControllerInfo == NULL) return -EINVAL;
5391 ControllerNumber = ControllerInfo->ControllerNumber;
5392 if (ControllerNumber < 0 ||
5393 ControllerNumber > DAC960_ControllerCount - 1)
5394 return -ENXIO;
5395 Controller = DAC960_Controllers[ControllerNumber];
5396 if (Controller == NULL) return -ENXIO;
5397 memset(ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
5398 ControllerInfo->ControllerNumber = ControllerNumber;
5399 ControllerInfo->FirmwareType = Controller->FirmwareType;
5400 ControllerInfo->Channels = Controller->Channels;
5401 ControllerInfo->Targets = Controller->Targets;
5402 ControllerInfo->PCI_Bus = Controller->Bus;
5403 ControllerInfo->PCI_Device = Controller->Device;
5404 ControllerInfo->PCI_Function = Controller->Function;
5405 ControllerInfo->IRQ_Channel = Controller->IRQ_Channel;
5406 ControllerInfo->PCI_Address = Controller->PCI_Address;
5407 strcpy(ControllerInfo->ModelName, Controller->ModelName);
5408 strcpy(ControllerInfo->FirmwareVersion, Controller->FirmwareVersion);
5409 return 0;
5411 case DAC960_IOCTL_V1_EXECUTE_COMMAND:
5413 DAC960_V1_KernelCommand_T *KernelCommand =
5414 (DAC960_V1_KernelCommand_T *) Argument;
5415 DAC960_Controller_T *Controller;
5416 DAC960_Command_T *Command = NULL;
5417 DAC960_V1_CommandOpcode_T CommandOpcode;
5418 DAC960_V1_DCDB_T *DCDB = NULL;
5419 ProcessorFlags_T ProcessorFlags;
5420 int ControllerNumber, DataTransferLength;
5421 unsigned char *DataTransferBuffer = NULL;
5422 if (KernelCommand == NULL) return -EINVAL;
5423 ControllerNumber = KernelCommand->ControllerNumber;
5424 if (ControllerNumber < 0 ||
5425 ControllerNumber > DAC960_ControllerCount - 1)
5426 return -ENXIO;
5427 Controller = DAC960_Controllers[ControllerNumber];
5428 if (Controller == NULL) return -ENXIO;
5429 if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
5430 CommandOpcode = KernelCommand->CommandMailbox.Common.CommandOpcode;
5431 DataTransferLength = KernelCommand->DataTransferLength;
5432 DataTransferBuffer = KernelCommand->DataTransferBuffer;
5433 if (CommandOpcode & 0x80) return -EINVAL;
5434 if (CommandOpcode == DAC960_V1_DCDB)
5436 DCDB = KernelCommand->DCDB;
5437 if (!((DataTransferLength == 0 &&
5438 DCDB->Direction == DAC960_V1_DCDB_NoDataTransfer) ||
5439 (DataTransferLength > 0 &&
5440 DCDB->Direction
5441 == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
5442 (DataTransferLength < 0 &&
5443 DCDB->Direction
5444 == DAC960_V1_DCDB_DataTransferSystemToDevice)))
5445 return -EINVAL;
5446 if (((DCDB->TransferLengthHigh4 << 16) | DCDB->TransferLength)
5447 != abs(DataTransferLength))
5448 return -EINVAL;
5450 if (DataTransferLength != 0 && DataTransferBuffer == NULL)
5451 return -EINVAL;
5452 if (DataTransferLength > 0)
5453 memset(DataTransferBuffer, 0, DataTransferLength);
5454 if (CommandOpcode == DAC960_V1_DCDB)
5456 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5457 if (!Controller->V1.DirectCommandActive[DCDB->Channel]
5458 [DCDB->TargetID])
5459 Command = DAC960_AllocateCommand(Controller);
5460 if (Command == NULL)
5462 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5463 return -EBUSY;
5465 else Controller->V1.DirectCommandActive[DCDB->Channel]
5466 [DCDB->TargetID] = true;
5467 DAC960_V1_ClearCommand(Command);
5468 Command->CommandType = DAC960_QueuedCommand;
5469 memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
5470 sizeof(DAC960_V1_CommandMailbox_T));
5471 Command->V1.CommandMailbox.Type3.BusAddress =
5472 Virtual_to_Bus(DCDB);
5473 Command->V1.KernelCommand = KernelCommand;
5474 DCDB->BusAddress = Virtual_to_Bus(DataTransferBuffer);
5475 DAC960_QueueCommand(Command);
5476 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5478 else
5480 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5481 Command = DAC960_AllocateCommand(Controller);
5482 if (Command == NULL)
5484 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5485 return -EBUSY;
5487 DAC960_V1_ClearCommand(Command);
5488 Command->CommandType = DAC960_QueuedCommand;
5489 memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
5490 sizeof(DAC960_V1_CommandMailbox_T));
5491 if (DataTransferBuffer != NULL)
5492 Command->V1.CommandMailbox.Type3.BusAddress =
5493 Virtual_to_Bus(DataTransferBuffer);
5494 Command->V1.KernelCommand = KernelCommand;
5495 DAC960_QueueCommand(Command);
5496 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5498 return 0;
5500 case DAC960_IOCTL_V2_EXECUTE_COMMAND:
5502 DAC960_V2_KernelCommand_T *KernelCommand =
5503 (DAC960_V2_KernelCommand_T *) Argument;
5504 DAC960_Controller_T *Controller;
5505 DAC960_Command_T *Command = NULL;
5506 DAC960_V2_CommandMailbox_T *CommandMailbox;
5507 ProcessorFlags_T ProcessorFlags;
5508 int ControllerNumber, DataTransferLength, RequestSenseLength;
5509 unsigned char *DataTransferBuffer = NULL;
5510 unsigned char *RequestSenseBuffer = NULL;
5511 if (KernelCommand == NULL) return -EINVAL;
5512 ControllerNumber = KernelCommand->ControllerNumber;
5513 if (ControllerNumber < 0 ||
5514 ControllerNumber > DAC960_ControllerCount - 1)
5515 return -ENXIO;
5516 Controller = DAC960_Controllers[ControllerNumber];
5517 if (Controller == NULL) return -ENXIO;
5518 if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
5519 DataTransferLength = KernelCommand->DataTransferLength;
5520 RequestSenseLength = KernelCommand->RequestSenseLength;
5521 DataTransferBuffer = KernelCommand->DataTransferBuffer;
5522 RequestSenseBuffer = KernelCommand->RequestSenseBuffer;
5523 if (DataTransferLength != 0 && DataTransferBuffer == NULL)
5524 return -EINVAL;
5525 if (RequestSenseLength < 0)
5526 return -EINVAL;
5527 if (RequestSenseLength > 0 && RequestSenseBuffer == NULL)
5528 return -EINVAL;
5529 if (DataTransferLength > 0)
5530 memset(DataTransferBuffer, 0, DataTransferLength);
5531 if (RequestSenseLength > 0)
5532 memset(RequestSenseBuffer, 0, RequestSenseLength);
5533 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5534 Command = DAC960_AllocateCommand(Controller);
5535 if (Command == NULL)
5537 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5538 return -EBUSY;
5540 DAC960_V2_ClearCommand(Command);
5541 Command->CommandType = DAC960_QueuedCommand;
5542 CommandMailbox = &Command->V2.CommandMailbox;
5543 memcpy(CommandMailbox, &KernelCommand->CommandMailbox,
5544 sizeof(DAC960_V2_CommandMailbox_T));
5545 CommandMailbox->Common.CommandControlBits
5546 .AdditionalScatterGatherListMemory = false;
5547 CommandMailbox->Common.CommandControlBits
5548 .NoAutoRequestSense = true;
5549 CommandMailbox->Common.DataTransferSize = 0;
5550 CommandMailbox->Common.DataTransferPageNumber = 0;
5551 memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
5552 sizeof(DAC960_V2_DataTransferMemoryAddress_T));
5553 if (DataTransferLength != 0)
5555 if (DataTransferLength > 0)
5557 CommandMailbox->Common.CommandControlBits
5558 .DataTransferControllerToHost = true;
5559 CommandMailbox->Common.DataTransferSize = DataTransferLength;
5561 else
5563 CommandMailbox->Common.CommandControlBits
5564 .DataTransferControllerToHost = false;
5565 CommandMailbox->Common.DataTransferSize = -DataTransferLength;
5567 CommandMailbox->Common.DataTransferMemoryAddress
5568 .ScatterGatherSegments[0]
5569 .SegmentDataPointer =
5570 Virtual_to_Bus(DataTransferBuffer);
5571 CommandMailbox->Common.DataTransferMemoryAddress
5572 .ScatterGatherSegments[0]
5573 .SegmentByteCount =
5574 CommandMailbox->Common.DataTransferSize;
5576 if (RequestSenseLength > 0)
5578 CommandMailbox->Common.CommandControlBits
5579 .NoAutoRequestSense = false;
5580 CommandMailbox->Common.RequestSenseBusAddress =
5581 Virtual_to_Bus(RequestSenseBuffer);
5583 Command->V2.KernelCommand = KernelCommand;
5584 DAC960_QueueCommand(Command);
5585 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5586 return 0;
5589 return -EINVAL;
5594 DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount
5595 additional bytes in the Combined Status Buffer and grows the buffer if
5596 necessary. It returns true if there is enough room and false otherwise.
5599 static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
5600 unsigned int ByteCount)
5602 unsigned char *NewStatusBuffer;
5603 if (Controller->InitialStatusLength + 1 +
5604 Controller->CurrentStatusLength + ByteCount + 1 <=
5605 Controller->CombinedStatusBufferLength)
5606 return true;
5607 if (Controller->CombinedStatusBufferLength == 0)
5609 unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize;
5610 while (NewStatusBufferLength < ByteCount)
5611 NewStatusBufferLength *= 2;
5612 Controller->CombinedStatusBuffer =
5613 (unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC);
5614 if (Controller->CombinedStatusBuffer == NULL) return false;
5615 Controller->CombinedStatusBufferLength = NewStatusBufferLength;
5616 return true;
5618 NewStatusBuffer = (unsigned char *)
5619 kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC);
5620 if (NewStatusBuffer == NULL)
5622 DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n",
5623 Controller);
5624 return false;
5626 memcpy(NewStatusBuffer, Controller->CombinedStatusBuffer,
5627 Controller->CombinedStatusBufferLength);
5628 kfree(Controller->CombinedStatusBuffer);
5629 Controller->CombinedStatusBuffer = NewStatusBuffer;
5630 Controller->CombinedStatusBufferLength *= 2;
5631 Controller->CurrentStatusBuffer =
5632 &NewStatusBuffer[Controller->InitialStatusLength + 1];
5633 return true;
5638 DAC960_Message prints Driver Messages.
5641 static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
5642 unsigned char *Format,
5643 DAC960_Controller_T *Controller,
5644 ...)
5646 static unsigned char Buffer[DAC960_LineBufferSize];
5647 static boolean BeginningOfLine = true;
5648 va_list Arguments;
5649 int Length = 0;
5650 va_start(Arguments, Controller);
5651 Length = vsprintf(Buffer, Format, Arguments);
5652 va_end(Arguments);
5653 if (Controller == NULL)
5654 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
5655 DAC960_ControllerCount, Buffer);
5656 else if (MessageLevel == DAC960_AnnounceLevel ||
5657 MessageLevel == DAC960_InfoLevel)
5659 if (!Controller->ControllerInitialized)
5661 if (DAC960_CheckStatusBuffer(Controller, Length))
5663 strcpy(&Controller->CombinedStatusBuffer
5664 [Controller->InitialStatusLength],
5665 Buffer);
5666 Controller->InitialStatusLength += Length;
5667 Controller->CurrentStatusBuffer =
5668 &Controller->CombinedStatusBuffer
5669 [Controller->InitialStatusLength + 1];
5671 if (MessageLevel == DAC960_AnnounceLevel)
5673 static int AnnouncementLines = 0;
5674 if (++AnnouncementLines <= 2)
5675 printk("%sDAC960: %s", DAC960_MessageLevelMap[MessageLevel],
5676 Buffer);
5678 else
5680 if (BeginningOfLine)
5682 if (Buffer[0] != '\n' || Length > 1)
5683 printk("%sDAC960#%d: %s",
5684 DAC960_MessageLevelMap[MessageLevel],
5685 Controller->ControllerNumber, Buffer);
5687 else printk("%s", Buffer);
5690 else if (DAC960_CheckStatusBuffer(Controller, Length))
5692 strcpy(&Controller->CurrentStatusBuffer[
5693 Controller->CurrentStatusLength], Buffer);
5694 Controller->CurrentStatusLength += Length;
5697 else if (MessageLevel == DAC960_ProgressLevel)
5699 strcpy(Controller->ProgressBuffer, Buffer);
5700 Controller->ProgressBufferLength = Length;
5701 if (Controller->EphemeralProgressMessage)
5703 if (jiffies - Controller->LastProgressReportTime
5704 >= DAC960_ProgressReportingInterval)
5706 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
5707 Controller->ControllerNumber, Buffer);
5708 Controller->LastProgressReportTime = jiffies;
5711 else printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
5712 Controller->ControllerNumber, Buffer);
5714 else if (MessageLevel == DAC960_UserCriticalLevel)
5716 strcpy(&Controller->UserStatusBuffer[Controller->UserStatusLength],
5717 Buffer);
5718 Controller->UserStatusLength += Length;
5719 if (Buffer[0] != '\n' || Length > 1)
5720 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
5721 Controller->ControllerNumber, Buffer);
5723 else
5725 if (BeginningOfLine)
5726 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
5727 Controller->ControllerNumber, Buffer);
5728 else printk("%s", Buffer);
5730 BeginningOfLine = (Buffer[Length-1] == '\n');
5735 DAC960_ParsePhysicalDevice parses spaces followed by a Physical Device
5736 Channel:TargetID specification from a User Command string. It updates
5737 Channel and TargetID and returns true on success and false on failure.
5740 static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
5741 char *UserCommandString,
5742 unsigned char *Channel,
5743 unsigned char *TargetID)
5745 char *NewUserCommandString = UserCommandString;
5746 unsigned long XChannel, XTargetID;
5747 while (*UserCommandString == ' ') UserCommandString++;
5748 if (UserCommandString == NewUserCommandString)
5749 return false;
5750 XChannel = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
5751 if (NewUserCommandString == UserCommandString ||
5752 *NewUserCommandString != ':' ||
5753 XChannel >= Controller->Channels)
5754 return false;
5755 UserCommandString = ++NewUserCommandString;
5756 XTargetID = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
5757 if (NewUserCommandString == UserCommandString ||
5758 *NewUserCommandString != '\0' ||
5759 XTargetID >= Controller->Targets)
5760 return false;
5761 *Channel = XChannel;
5762 *TargetID = XTargetID;
5763 return true;
5768 DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number
5769 specification from a User Command string. It updates LogicalDriveNumber and
5770 returns true on success and false on failure.
5773 static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
5774 char *UserCommandString,
5775 unsigned char *LogicalDriveNumber)
5777 char *NewUserCommandString = UserCommandString;
5778 unsigned long XLogicalDriveNumber;
5779 while (*UserCommandString == ' ') UserCommandString++;
5780 if (UserCommandString == NewUserCommandString)
5781 return false;
5782 XLogicalDriveNumber =
5783 simple_strtoul(UserCommandString, &NewUserCommandString, 10);
5784 if (NewUserCommandString == UserCommandString ||
5785 *NewUserCommandString != '\0' ||
5786 XLogicalDriveNumber > DAC960_MaxLogicalDrives - 1)
5787 return false;
5788 *LogicalDriveNumber = XLogicalDriveNumber;
5789 return true;
5794 DAC960_V1_SetDeviceState sets the Device State for a Physical Device for
5795 DAC960 V1 Firmware Controllers.
5798 static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller,
5799 DAC960_Command_T *Command,
5800 unsigned char Channel,
5801 unsigned char TargetID,
5802 DAC960_V1_PhysicalDeviceState_T
5803 DeviceState,
5804 const unsigned char *DeviceStateString)
5806 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
5807 CommandMailbox->Type3D.CommandOpcode = DAC960_V1_StartDevice;
5808 CommandMailbox->Type3D.Channel = Channel;
5809 CommandMailbox->Type3D.TargetID = TargetID;
5810 CommandMailbox->Type3D.DeviceState = DeviceState;
5811 CommandMailbox->Type3D.Modifier = 0;
5812 DAC960_ExecuteCommand(Command);
5813 switch (Command->V1.CommandStatus)
5815 case DAC960_V1_NormalCompletion:
5816 DAC960_UserCritical("%s of Physical Device %d:%d Succeeded\n", Controller,
5817 DeviceStateString, Channel, TargetID);
5818 break;
5819 case DAC960_V1_UnableToStartDevice:
5820 DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
5821 "Unable to Start Device\n", Controller,
5822 DeviceStateString, Channel, TargetID);
5823 break;
5824 case DAC960_V1_NoDeviceAtAddress:
5825 DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
5826 "No Device at Address\n", Controller,
5827 DeviceStateString, Channel, TargetID);
5828 break;
5829 case DAC960_V1_InvalidChannelOrTargetOrModifier:
5830 DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
5831 "Invalid Channel or Target or Modifier\n",
5832 Controller, DeviceStateString, Channel, TargetID);
5833 break;
5834 case DAC960_V1_ChannelBusy:
5835 DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
5836 "Channel Busy\n", Controller,
5837 DeviceStateString, Channel, TargetID);
5838 break;
5839 default:
5840 DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
5841 "Unexpected Status %04X\n", Controller,
5842 DeviceStateString, Channel, TargetID,
5843 Command->V1.CommandStatus);
5844 break;
5850 DAC960_V1_ExecuteUserCommand executes a User Command for DAC960 V1 Firmware
5851 Controllers.
5854 static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
5855 unsigned char *UserCommand)
5857 DAC960_Command_T *Command;
5858 DAC960_V1_CommandMailbox_T *CommandMailbox;
5859 ProcessorFlags_T ProcessorFlags;
5860 unsigned char Channel, TargetID, LogicalDriveNumber;
5861 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5862 while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
5863 DAC960_WaitForCommand(Controller);
5864 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5865 Controller->UserStatusLength = 0;
5866 DAC960_V1_ClearCommand(Command);
5867 Command->CommandType = DAC960_ImmediateCommand;
5868 CommandMailbox = &Command->V1.CommandMailbox;
5869 if (strcmp(UserCommand, "flush-cache") == 0)
5871 CommandMailbox->Type3.CommandOpcode = DAC960_V1_Flush;
5872 DAC960_ExecuteCommand(Command);
5873 DAC960_UserCritical("Cache Flush Completed\n", Controller);
5875 else if (strncmp(UserCommand, "kill", 4) == 0 &&
5876 DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
5877 &Channel, &TargetID))
5879 DAC960_V1_DeviceState_T *DeviceState =
5880 &Controller->V1.DeviceState[Channel][TargetID];
5881 if (DeviceState->Present &&
5882 DeviceState->DeviceType == DAC960_V1_DiskType &&
5883 DeviceState->DeviceState != DAC960_V1_Device_Dead)
5884 DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
5885 DAC960_V1_Device_Dead, "Kill");
5886 else DAC960_UserCritical("Kill of Physical Device %d:%d Illegal\n",
5887 Controller, Channel, TargetID);
5889 else if (strncmp(UserCommand, "make-online", 11) == 0 &&
5890 DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
5891 &Channel, &TargetID))
5893 DAC960_V1_DeviceState_T *DeviceState =
5894 &Controller->V1.DeviceState[Channel][TargetID];
5895 if (DeviceState->Present &&
5896 DeviceState->DeviceType == DAC960_V1_DiskType &&
5897 DeviceState->DeviceState == DAC960_V1_Device_Dead)
5898 DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
5899 DAC960_V1_Device_Online, "Make Online");
5900 else DAC960_UserCritical("Make Online of Physical Device %d:%d Illegal\n",
5901 Controller, Channel, TargetID);
5904 else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
5905 DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
5906 &Channel, &TargetID))
5908 DAC960_V1_DeviceState_T *DeviceState =
5909 &Controller->V1.DeviceState[Channel][TargetID];
5910 if (DeviceState->Present &&
5911 DeviceState->DeviceType == DAC960_V1_DiskType &&
5912 DeviceState->DeviceState == DAC960_V1_Device_Dead)
5913 DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
5914 DAC960_V1_Device_Standby, "Make Standby");
5915 else DAC960_UserCritical("Make Standby of Physical "
5916 "Device %d:%d Illegal\n",
5917 Controller, Channel, TargetID);
5919 else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
5920 DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
5921 &Channel, &TargetID))
5923 CommandMailbox->Type3D.CommandOpcode = DAC960_V1_RebuildAsync;
5924 CommandMailbox->Type3D.Channel = Channel;
5925 CommandMailbox->Type3D.TargetID = TargetID;
5926 DAC960_ExecuteCommand(Command);
5927 switch (Command->V1.CommandStatus)
5929 case DAC960_V1_NormalCompletion:
5930 DAC960_UserCritical("Rebuild of Physical Device %d:%d Initiated\n",
5931 Controller, Channel, TargetID);
5932 break;
5933 case DAC960_V1_AttemptToRebuildOnlineDrive:
5934 DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
5935 "Attempt to Rebuild Online or "
5936 "Unresponsive Drive\n",
5937 Controller, Channel, TargetID);
5938 break;
5939 case DAC960_V1_NewDiskFailedDuringRebuild:
5940 DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
5941 "New Disk Failed During Rebuild\n",
5942 Controller, Channel, TargetID);
5943 break;
5944 case DAC960_V1_InvalidDeviceAddress:
5945 DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
5946 "Invalid Device Address\n",
5947 Controller, Channel, TargetID);
5948 break;
5949 case DAC960_V1_RebuildOrCheckAlreadyInProgress:
5950 DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
5951 "Rebuild or Consistency Check Already "
5952 "in Progress\n", Controller, Channel, TargetID);
5953 break;
5954 default:
5955 DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
5956 "Unexpected Status %04X\n", Controller,
5957 Channel, TargetID, Command->V1.CommandStatus);
5958 break;
5961 else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
5962 DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
5963 &LogicalDriveNumber))
5965 CommandMailbox->Type3C.CommandOpcode = DAC960_V1_CheckConsistencyAsync;
5966 CommandMailbox->Type3C.LogicalDriveNumber = LogicalDriveNumber;
5967 CommandMailbox->Type3C.AutoRestore = true;
5968 DAC960_ExecuteCommand(Command);
5969 switch (Command->V1.CommandStatus)
5971 case DAC960_V1_NormalCompletion:
5972 DAC960_UserCritical("Consistency Check of Logical Drive %d "
5973 "(/dev/rd/c%dd%d) Initiated\n",
5974 Controller, LogicalDriveNumber,
5975 Controller->ControllerNumber,
5976 LogicalDriveNumber);
5977 break;
5978 case DAC960_V1_DependentDiskIsDead:
5979 DAC960_UserCritical("Consistency Check of Logical Drive %d "
5980 "(/dev/rd/c%dd%d) Failed - "
5981 "Dependent Physical Device is DEAD\n",
5982 Controller, LogicalDriveNumber,
5983 Controller->ControllerNumber,
5984 LogicalDriveNumber);
5985 break;
5986 case DAC960_V1_InvalidOrNonredundantLogicalDrive:
5987 DAC960_UserCritical("Consistency Check of Logical Drive %d "
5988 "(/dev/rd/c%dd%d) Failed - "
5989 "Invalid or Nonredundant Logical Drive\n",
5990 Controller, LogicalDriveNumber,
5991 Controller->ControllerNumber,
5992 LogicalDriveNumber);
5993 break;
5994 case DAC960_V1_RebuildOrCheckAlreadyInProgress:
5995 DAC960_UserCritical("Consistency Check of Logical Drive %d "
5996 "(/dev/rd/c%dd%d) Failed - Rebuild or "
5997 "Consistency Check Already in Progress\n",
5998 Controller, LogicalDriveNumber,
5999 Controller->ControllerNumber,
6000 LogicalDriveNumber);
6001 break;
6002 default:
6003 DAC960_UserCritical("Consistency Check of Logical Drive %d "
6004 "(/dev/rd/c%dd%d) Failed - "
6005 "Unexpected Status %04X\n",
6006 Controller, LogicalDriveNumber,
6007 Controller->ControllerNumber,
6008 LogicalDriveNumber, Command->V1.CommandStatus);
6009 break;
6012 else if (strcmp(UserCommand, "cancel-rebuild") == 0 ||
6013 strcmp(UserCommand, "cancel-consistency-check") == 0)
6015 unsigned char OldRebuildRateConstant;
6016 CommandMailbox->Type3R.CommandOpcode = DAC960_V1_RebuildControl;
6017 CommandMailbox->Type3R.RebuildRateConstant = 0xFF;
6018 CommandMailbox->Type3R.BusAddress =
6019 Virtual_to_Bus(&OldRebuildRateConstant);
6020 DAC960_ExecuteCommand(Command);
6021 switch (Command->V1.CommandStatus)
6023 case DAC960_V1_NormalCompletion:
6024 DAC960_UserCritical("Rebuild or Consistency Check Cancelled\n",
6025 Controller);
6026 break;
6027 default:
6028 DAC960_UserCritical("Cancellation of Rebuild or "
6029 "Consistency Check Failed - "
6030 "Unexpected Status %04X\n",
6031 Controller, Command->V1.CommandStatus);
6032 break;
6035 else DAC960_UserCritical("Illegal User Command: '%s'\n",
6036 Controller, UserCommand);
6037 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6038 DAC960_DeallocateCommand(Command);
6039 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6040 return true;
6045 DAC960_V2_TranslatePhysicalDevice translates a Physical Device Channel and
6046 TargetID into a Logical Device. It returns true on success and false
6047 on failure.
6050 static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
6051 unsigned char Channel,
6052 unsigned char TargetID,
6053 unsigned short
6054 *LogicalDeviceNumber)
6056 DAC960_V2_CommandMailbox_T SavedCommandMailbox, *CommandMailbox;
6057 DAC960_V2_PhysicalToLogicalDevice_T PhysicalToLogicalDevice;
6058 CommandMailbox = &Command->V2.CommandMailbox;
6059 memcpy(&SavedCommandMailbox, CommandMailbox,
6060 sizeof(DAC960_V2_CommandMailbox_T));
6061 CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
6062 CommandMailbox->PhysicalDeviceInfo.CommandControlBits
6063 .DataTransferControllerToHost = true;
6064 CommandMailbox->PhysicalDeviceInfo.CommandControlBits
6065 .NoAutoRequestSense = true;
6066 CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
6067 sizeof(DAC960_V2_PhysicalToLogicalDevice_T);
6068 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
6069 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
6070 CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
6071 DAC960_V2_TranslatePhysicalToLogicalDevice;
6072 CommandMailbox->Common.DataTransferMemoryAddress
6073 .ScatterGatherSegments[0]
6074 .SegmentDataPointer =
6075 Virtual_to_Bus(&PhysicalToLogicalDevice);
6076 CommandMailbox->Common.DataTransferMemoryAddress
6077 .ScatterGatherSegments[0]
6078 .SegmentByteCount =
6079 CommandMailbox->Common.DataTransferSize;
6080 DAC960_ExecuteCommand(Command);
6081 memcpy(CommandMailbox, &SavedCommandMailbox,
6082 sizeof(DAC960_V2_CommandMailbox_T));
6083 *LogicalDeviceNumber = PhysicalToLogicalDevice.LogicalDeviceNumber;
6084 return (Command->V2.CommandStatus == DAC960_V2_NormalCompletion);
6089 DAC960_V2_ExecuteUserCommand executes a User Command for DAC960 V2 Firmware
6090 Controllers.
6093 static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
6094 unsigned char *UserCommand)
6096 DAC960_Command_T *Command;
6097 DAC960_V2_CommandMailbox_T *CommandMailbox;
6098 ProcessorFlags_T ProcessorFlags;
6099 unsigned char Channel, TargetID, LogicalDriveNumber;
6100 unsigned short LogicalDeviceNumber;
6101 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6102 while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
6103 DAC960_WaitForCommand(Controller);
6104 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6105 Controller->UserStatusLength = 0;
6106 DAC960_V2_ClearCommand(Command);
6107 Command->CommandType = DAC960_ImmediateCommand;
6108 CommandMailbox = &Command->V2.CommandMailbox;
6109 CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
6110 CommandMailbox->Common.CommandControlBits.DataTransferControllerToHost = true;
6111 CommandMailbox->Common.CommandControlBits.NoAutoRequestSense = true;
6112 if (strcmp(UserCommand, "flush-cache") == 0)
6114 CommandMailbox->DeviceOperation.IOCTL_Opcode = DAC960_V2_PauseDevice;
6115 CommandMailbox->DeviceOperation.OperationDevice =
6116 DAC960_V2_RAID_Controller;
6117 DAC960_ExecuteCommand(Command);
6118 DAC960_UserCritical("Cache Flush Completed\n", Controller);
6120 else if (strncmp(UserCommand, "kill", 4) == 0 &&
6121 DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
6122 &Channel, &TargetID) &&
6123 DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6124 &LogicalDeviceNumber))
6126 CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
6127 LogicalDeviceNumber;
6128 CommandMailbox->SetDeviceState.IOCTL_Opcode =
6129 DAC960_V2_SetDeviceState;
6130 CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
6131 DAC960_V2_Device_Dead;
6132 DAC960_ExecuteCommand(Command);
6133 DAC960_UserCritical("Kill of Physical Device %d:%d %s\n",
6134 Controller, Channel, TargetID,
6135 (Command->V2.CommandStatus
6136 == DAC960_V2_NormalCompletion
6137 ? "Succeeded" : "Failed"));
6139 else if (strncmp(UserCommand, "make-online", 11) == 0 &&
6140 DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
6141 &Channel, &TargetID) &&
6142 DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6143 &LogicalDeviceNumber))
6145 CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
6146 LogicalDeviceNumber;
6147 CommandMailbox->SetDeviceState.IOCTL_Opcode =
6148 DAC960_V2_SetDeviceState;
6149 CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
6150 DAC960_V2_Device_Online;
6151 DAC960_ExecuteCommand(Command);
6152 DAC960_UserCritical("Make Online of Physical Device %d:%d %s\n",
6153 Controller, Channel, TargetID,
6154 (Command->V2.CommandStatus
6155 == DAC960_V2_NormalCompletion
6156 ? "Succeeded" : "Failed"));
6158 else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
6159 DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
6160 &Channel, &TargetID) &&
6161 DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6162 &LogicalDeviceNumber))
6164 CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
6165 LogicalDeviceNumber;
6166 CommandMailbox->SetDeviceState.IOCTL_Opcode =
6167 DAC960_V2_SetDeviceState;
6168 CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
6169 DAC960_V2_Device_Standby;
6170 DAC960_ExecuteCommand(Command);
6171 DAC960_UserCritical("Make Standby of Physical Device %d:%d %s\n",
6172 Controller, Channel, TargetID,
6173 (Command->V2.CommandStatus
6174 == DAC960_V2_NormalCompletion
6175 ? "Succeeded" : "Failed"));
6177 else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
6178 DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
6179 &Channel, &TargetID) &&
6180 DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6181 &LogicalDeviceNumber))
6183 CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
6184 LogicalDeviceNumber;
6185 CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
6186 DAC960_V2_RebuildDeviceStart;
6187 DAC960_ExecuteCommand(Command);
6188 DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
6189 Controller, Channel, TargetID,
6190 (Command->V2.CommandStatus
6191 == DAC960_V2_NormalCompletion
6192 ? "Initiated" : "Not Initiated"));
6194 else if (strncmp(UserCommand, "cancel-rebuild", 14) == 0 &&
6195 DAC960_ParsePhysicalDevice(Controller, &UserCommand[14],
6196 &Channel, &TargetID) &&
6197 DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6198 &LogicalDeviceNumber))
6200 CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
6201 LogicalDeviceNumber;
6202 CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
6203 DAC960_V2_RebuildDeviceStop;
6204 DAC960_ExecuteCommand(Command);
6205 DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
6206 Controller, Channel, TargetID,
6207 (Command->V2.CommandStatus
6208 == DAC960_V2_NormalCompletion
6209 ? "Cancelled" : "Not Cancelled"));
6211 else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
6212 DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
6213 &LogicalDriveNumber))
6215 CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
6216 LogicalDriveNumber;
6217 CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
6218 DAC960_V2_ConsistencyCheckStart;
6219 CommandMailbox->ConsistencyCheck.RestoreConsistency = true;
6220 CommandMailbox->ConsistencyCheck.InitializedAreaOnly = false;
6221 DAC960_ExecuteCommand(Command);
6222 DAC960_UserCritical("Consistency Check of Logical Drive %d "
6223 "(/dev/rd/c%dd%d) %s\n",
6224 Controller, LogicalDriveNumber,
6225 Controller->ControllerNumber,
6226 LogicalDriveNumber,
6227 (Command->V2.CommandStatus
6228 == DAC960_V2_NormalCompletion
6229 ? "Initiated" : "Not Initiated"));
6231 else if (strncmp(UserCommand, "cancel-consistency-check", 24) == 0 &&
6232 DAC960_ParseLogicalDrive(Controller, &UserCommand[24],
6233 &LogicalDriveNumber))
6235 CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
6236 LogicalDriveNumber;
6237 CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
6238 DAC960_V2_ConsistencyCheckStop;
6239 DAC960_ExecuteCommand(Command);
6240 DAC960_UserCritical("Consistency Check of Logical Drive %d "
6241 "(/dev/rd/c%dd%d) %s\n",
6242 Controller, LogicalDriveNumber,
6243 Controller->ControllerNumber,
6244 LogicalDriveNumber,
6245 (Command->V2.CommandStatus
6246 == DAC960_V2_NormalCompletion
6247 ? "Cancelled" : "Not Cancelled"));
6249 else DAC960_UserCritical("Illegal User Command: '%s'\n",
6250 Controller, UserCommand);
6251 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6252 DAC960_DeallocateCommand(Command);
6253 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6254 return true;
6259 DAC960_ProcReadStatus implements reading /proc/rd/status.
6262 static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
6263 int Count, int *EOF, void *Data)
6265 unsigned char *StatusMessage = "OK\n";
6266 int ControllerNumber, BytesAvailable;
6267 for (ControllerNumber = 0;
6268 ControllerNumber < DAC960_ControllerCount;
6269 ControllerNumber++)
6271 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
6272 if (Controller == NULL) continue;
6273 if (Controller->MonitoringAlertMode)
6275 StatusMessage = "ALERT\n";
6276 break;
6279 BytesAvailable = strlen(StatusMessage) - Offset;
6280 if (Count >= BytesAvailable)
6282 Count = BytesAvailable;
6283 *EOF = true;
6285 if (Count <= 0) return 0;
6286 *Start = Page;
6287 memcpy(Page, &StatusMessage[Offset], Count);
6288 return Count;
6293 DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status.
6296 static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset,
6297 int Count, int *EOF, void *Data)
6299 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6300 int BytesAvailable = Controller->InitialStatusLength - Offset;
6301 if (Count >= BytesAvailable)
6303 Count = BytesAvailable;
6304 *EOF = true;
6306 if (Count <= 0) return 0;
6307 *Start = Page;
6308 memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
6309 return Count;
6314 DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status.
6317 static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
6318 int Count, int *EOF, void *Data)
6320 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6321 unsigned char *StatusMessage =
6322 "No Rebuild or Consistency Check in Progress\n";
6323 int ProgressMessageLength = strlen(StatusMessage);
6324 int BytesAvailable;
6325 if (jiffies != Controller->LastCurrentStatusTime)
6327 Controller->CurrentStatusLength = 0;
6328 DAC960_AnnounceDriver(Controller);
6329 DAC960_ReportControllerConfiguration(Controller);
6330 DAC960_ReportDeviceConfiguration(Controller);
6331 if (Controller->ProgressBufferLength > 0)
6332 ProgressMessageLength = Controller->ProgressBufferLength;
6333 if (DAC960_CheckStatusBuffer(Controller, 2 + ProgressMessageLength))
6335 unsigned char *CurrentStatusBuffer = Controller->CurrentStatusBuffer;
6336 CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
6337 CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
6338 if (Controller->ProgressBufferLength > 0)
6339 strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
6340 Controller->ProgressBuffer);
6341 else
6342 strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
6343 StatusMessage);
6344 Controller->CurrentStatusLength += ProgressMessageLength;
6346 Controller->LastCurrentStatusTime = jiffies;
6348 BytesAvailable = Controller->CurrentStatusLength - Offset;
6349 if (Count >= BytesAvailable)
6351 Count = BytesAvailable;
6352 *EOF = true;
6354 if (Count <= 0) return 0;
6355 *Start = Page;
6356 memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count);
6357 return Count;
6362 DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command.
6365 static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset,
6366 int Count, int *EOF, void *Data)
6368 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6369 int BytesAvailable = Controller->UserStatusLength - Offset;
6370 if (Count >= BytesAvailable)
6372 Count = BytesAvailable;
6373 *EOF = true;
6375 if (Count <= 0) return 0;
6376 *Start = Page;
6377 memcpy(Page, &Controller->UserStatusBuffer[Offset], Count);
6378 return Count;
6383 DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
6386 static int DAC960_ProcWriteUserCommand(File_T *File, const char *Buffer,
6387 unsigned long Count, void *Data)
6389 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6390 unsigned char CommandBuffer[80];
6391 int Length;
6392 if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
6393 copy_from_user(CommandBuffer, Buffer, Count);
6394 CommandBuffer[Count] = '\0';
6395 Length = strlen(CommandBuffer);
6396 if (CommandBuffer[Length-1] == '\n')
6397 CommandBuffer[--Length] = '\0';
6398 if (Controller->FirmwareType == DAC960_V1_Controller)
6399 return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer)
6400 ? Count : -EBUSY);
6401 else
6402 return (DAC960_V2_ExecuteUserCommand(Controller, CommandBuffer)
6403 ? Count : -EBUSY);
6408 DAC960_CreateProcEntries creates the /proc/rd/... entries for the
6409 DAC960 Driver.
6412 static void DAC960_CreateProcEntries(void)
6414 PROC_DirectoryEntry_T *StatusProcEntry;
6415 int ControllerNumber;
6416 DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
6417 StatusProcEntry = create_proc_read_entry("status", 0,
6418 DAC960_ProcDirectoryEntry,
6419 DAC960_ProcReadStatus, NULL);
6420 for (ControllerNumber = 0;
6421 ControllerNumber < DAC960_ControllerCount;
6422 ControllerNumber++)
6424 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
6425 PROC_DirectoryEntry_T *ControllerProcEntry;
6426 PROC_DirectoryEntry_T *UserCommandProcEntry;
6427 if (Controller == NULL) continue;
6428 ControllerProcEntry = proc_mkdir(Controller->ControllerName,
6429 DAC960_ProcDirectoryEntry);
6430 create_proc_read_entry("initial_status", 0, ControllerProcEntry,
6431 DAC960_ProcReadInitialStatus, Controller);
6432 create_proc_read_entry("current_status", 0, ControllerProcEntry,
6433 DAC960_ProcReadCurrentStatus, Controller);
6434 UserCommandProcEntry =
6435 create_proc_read_entry("user_command", S_IWUSR | S_IRUSR,
6436 ControllerProcEntry, DAC960_ProcReadUserCommand,
6437 Controller);
6438 UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
6439 Controller->ControllerProcEntry = ControllerProcEntry;
6445 DAC960_DestroyProcEntries destroys the /proc/rd/... entries for the
6446 DAC960 Driver.
6449 static void DAC960_DestroyProcEntries(void)
6451 int ControllerNumber;
6452 for (ControllerNumber = 0;
6453 ControllerNumber < DAC960_ControllerCount;
6454 ControllerNumber++)
6456 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
6457 if (Controller == NULL) continue;
6458 remove_proc_entry("initial_status", Controller->ControllerProcEntry);
6459 remove_proc_entry("current_status", Controller->ControllerProcEntry);
6460 remove_proc_entry("user_command", Controller->ControllerProcEntry);
6461 remove_proc_entry(Controller->ControllerName, DAC960_ProcDirectoryEntry);
6463 remove_proc_entry("rd/status", NULL);
6464 remove_proc_entry("rd", NULL);
6469 Include Module support if requested.
6472 #ifdef MODULE
6475 int init_module(void)
6477 DAC960_Initialize();
6478 return (DAC960_ActiveControllerCount > 0 ? 0 : -1);
6482 void cleanup_module(void)
6484 DAC960_Finalize(&DAC960_NotifierBlock, SYS_RESTART, NULL);
6488 #endif