Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / block / DAC960.c
blob5e8dc19f9feeb1d3ec7ee0b98eba95e093e8ee9a
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.9"
23 #define DAC960_DriverDate "7 September 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;
58 DAC960_ActiveControllerCount is the number of active DAC960 Controllers
59 detected.
62 static int
63 DAC960_ActiveControllerCount;
67 DAC960_Controllers is an array of pointers to the DAC960 Controller
68 structures.
71 static DAC960_Controller_T
72 *DAC960_Controllers[DAC960_MaxControllers];
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 spin_unlock_irq(&io_request_lock);
304 __wait_event(Controller->CommandWaitQueue, Controller->FreeCommands);
305 spin_lock_irq(&io_request_lock);
310 DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers.
313 static void DAC960_BA_QueueCommand(DAC960_Command_T *Command)
315 DAC960_Controller_T *Controller = Command->Controller;
316 void *ControllerBaseAddress = Controller->BaseAddress;
317 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
318 DAC960_V2_CommandMailbox_T *NextCommandMailbox =
319 Controller->V2.NextCommandMailbox;
320 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
321 DAC960_BA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
322 if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
323 Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
324 DAC960_BA_MemoryMailboxNewCommand(ControllerBaseAddress);
325 Controller->V2.PreviousCommandMailbox2 =
326 Controller->V2.PreviousCommandMailbox1;
327 Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
328 if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
329 NextCommandMailbox = Controller->V2.FirstCommandMailbox;
330 Controller->V2.NextCommandMailbox = NextCommandMailbox;
335 DAC960_LP_QueueCommand queues Command for DAC960 LP Series Controllers.
338 static void DAC960_LP_QueueCommand(DAC960_Command_T *Command)
340 DAC960_Controller_T *Controller = Command->Controller;
341 void *ControllerBaseAddress = Controller->BaseAddress;
342 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
343 DAC960_V2_CommandMailbox_T *NextCommandMailbox =
344 Controller->V2.NextCommandMailbox;
345 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
346 DAC960_LP_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
347 if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
348 Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
349 DAC960_LP_MemoryMailboxNewCommand(ControllerBaseAddress);
350 Controller->V2.PreviousCommandMailbox2 =
351 Controller->V2.PreviousCommandMailbox1;
352 Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
353 if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
354 NextCommandMailbox = Controller->V2.FirstCommandMailbox;
355 Controller->V2.NextCommandMailbox = NextCommandMailbox;
360 DAC960_LA_QueueCommandDualMode queues Command for DAC960 LA Series
361 Controllers with Dual Mode Firmware.
364 static void DAC960_LA_QueueCommandDualMode(DAC960_Command_T *Command)
366 DAC960_Controller_T *Controller = Command->Controller;
367 void *ControllerBaseAddress = Controller->BaseAddress;
368 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
369 DAC960_V1_CommandMailbox_T *NextCommandMailbox =
370 Controller->V1.NextCommandMailbox;
371 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
372 DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
373 if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
374 Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
375 DAC960_LA_MemoryMailboxNewCommand(ControllerBaseAddress);
376 Controller->V1.PreviousCommandMailbox2 =
377 Controller->V1.PreviousCommandMailbox1;
378 Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
379 if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
380 NextCommandMailbox = Controller->V1.FirstCommandMailbox;
381 Controller->V1.NextCommandMailbox = NextCommandMailbox;
386 DAC960_LA_QueueCommandSingleMode queues Command for DAC960 LA Series
387 Controllers with Single Mode Firmware.
390 static void DAC960_LA_QueueCommandSingleMode(DAC960_Command_T *Command)
392 DAC960_Controller_T *Controller = Command->Controller;
393 void *ControllerBaseAddress = Controller->BaseAddress;
394 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
395 DAC960_V1_CommandMailbox_T *NextCommandMailbox =
396 Controller->V1.NextCommandMailbox;
397 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
398 DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
399 if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
400 Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
401 DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
402 Controller->V1.PreviousCommandMailbox2 =
403 Controller->V1.PreviousCommandMailbox1;
404 Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
405 if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
406 NextCommandMailbox = Controller->V1.FirstCommandMailbox;
407 Controller->V1.NextCommandMailbox = NextCommandMailbox;
412 DAC960_PG_QueueCommandDualMode queues Command for DAC960 PG Series
413 Controllers with Dual Mode Firmware.
416 static void DAC960_PG_QueueCommandDualMode(DAC960_Command_T *Command)
418 DAC960_Controller_T *Controller = Command->Controller;
419 void *ControllerBaseAddress = Controller->BaseAddress;
420 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
421 DAC960_V1_CommandMailbox_T *NextCommandMailbox =
422 Controller->V1.NextCommandMailbox;
423 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
424 DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
425 if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
426 Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
427 DAC960_PG_MemoryMailboxNewCommand(ControllerBaseAddress);
428 Controller->V1.PreviousCommandMailbox2 =
429 Controller->V1.PreviousCommandMailbox1;
430 Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
431 if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
432 NextCommandMailbox = Controller->V1.FirstCommandMailbox;
433 Controller->V1.NextCommandMailbox = NextCommandMailbox;
438 DAC960_PG_QueueCommandSingleMode queues Command for DAC960 PG Series
439 Controllers with Single Mode Firmware.
442 static void DAC960_PG_QueueCommandSingleMode(DAC960_Command_T *Command)
444 DAC960_Controller_T *Controller = Command->Controller;
445 void *ControllerBaseAddress = Controller->BaseAddress;
446 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
447 DAC960_V1_CommandMailbox_T *NextCommandMailbox =
448 Controller->V1.NextCommandMailbox;
449 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
450 DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
451 if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
452 Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
453 DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
454 Controller->V1.PreviousCommandMailbox2 =
455 Controller->V1.PreviousCommandMailbox1;
456 Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
457 if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
458 NextCommandMailbox = Controller->V1.FirstCommandMailbox;
459 Controller->V1.NextCommandMailbox = NextCommandMailbox;
464 DAC960_PD_QueueCommand queues Command for DAC960 PD Series Controllers.
467 static void DAC960_PD_QueueCommand(DAC960_Command_T *Command)
469 DAC960_Controller_T *Controller = Command->Controller;
470 void *ControllerBaseAddress = Controller->BaseAddress;
471 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
472 CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
473 while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
474 udelay(1);
475 DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
476 DAC960_PD_NewCommand(ControllerBaseAddress);
481 DAC960_ExecuteCommand executes Command and waits for completion.
484 static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
486 DAC960_Controller_T *Controller = Command->Controller;
487 DECLARE_MUTEX_LOCKED(Semaphore);
488 unsigned long ProcessorFlags;
489 Command->Semaphore = &Semaphore;
490 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
491 DAC960_QueueCommand(Command);
492 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
493 if (in_interrupt()) return;
494 down(&Semaphore);
499 DAC960_V1_ExecuteType3 executes a DAC960 V1 Firmware Controller Type 3
500 Command and waits for completion. It returns true on success and false
501 on failure.
504 static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
505 DAC960_V1_CommandOpcode_T CommandOpcode,
506 void *DataPointer)
508 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
509 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
510 DAC960_V1_CommandStatus_T CommandStatus;
511 DAC960_V1_ClearCommand(Command);
512 Command->CommandType = DAC960_ImmediateCommand;
513 CommandMailbox->Type3.CommandOpcode = CommandOpcode;
514 CommandMailbox->Type3.BusAddress = Virtual_to_Bus(DataPointer);
515 DAC960_ExecuteCommand(Command);
516 CommandStatus = Command->V1.CommandStatus;
517 DAC960_DeallocateCommand(Command);
518 return (CommandStatus == DAC960_V1_NormalCompletion);
523 DAC960_V1_ExecuteType3D executes a DAC960 V1 Firmware Controller Type 3D
524 Command and waits for completion. It returns true on success and false
525 on failure.
528 static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
529 DAC960_V1_CommandOpcode_T CommandOpcode,
530 unsigned char Channel,
531 unsigned char TargetID,
532 void *DataPointer)
534 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
535 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
536 DAC960_V1_CommandStatus_T CommandStatus;
537 DAC960_V1_ClearCommand(Command);
538 Command->CommandType = DAC960_ImmediateCommand;
539 CommandMailbox->Type3D.CommandOpcode = CommandOpcode;
540 CommandMailbox->Type3D.Channel = Channel;
541 CommandMailbox->Type3D.TargetID = TargetID;
542 CommandMailbox->Type3D.BusAddress = Virtual_to_Bus(DataPointer);
543 DAC960_ExecuteCommand(Command);
544 CommandStatus = Command->V1.CommandStatus;
545 DAC960_DeallocateCommand(Command);
546 return (CommandStatus == DAC960_V1_NormalCompletion);
551 DAC960_V2_GeneralInfo executes a DAC960 V2 Firmware General Information
552 Reading IOCTL Command and waits for completion. It returns true on success
553 and false on failure.
556 static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller,
557 DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
558 void *DataPointer,
559 unsigned int DataByteCount)
561 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
562 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
563 DAC960_V2_CommandStatus_T CommandStatus;
564 DAC960_V2_ClearCommand(Command);
565 Command->CommandType = DAC960_ImmediateCommand;
566 CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
567 CommandMailbox->Common.CommandControlBits
568 .DataTransferControllerToHost = true;
569 CommandMailbox->Common.CommandControlBits
570 .NoAutoRequestSense = true;
571 CommandMailbox->Common.DataTransferSize = DataByteCount;
572 CommandMailbox->Common.IOCTL_Opcode = IOCTL_Opcode;
573 CommandMailbox->Common.DataTransferMemoryAddress
574 .ScatterGatherSegments[0]
575 .SegmentDataPointer =
576 Virtual_to_Bus(DataPointer);
577 CommandMailbox->Common.DataTransferMemoryAddress
578 .ScatterGatherSegments[0]
579 .SegmentByteCount =
580 CommandMailbox->Common.DataTransferSize;
581 DAC960_ExecuteCommand(Command);
582 CommandStatus = Command->V2.CommandStatus;
583 DAC960_DeallocateCommand(Command);
584 return (CommandStatus == DAC960_V2_NormalCompletion);
589 DAC960_V2_ControllerInfo executes a DAC960 V2 Firmware Controller
590 Information Reading IOCTL Command and waits for completion. It returns
591 true on success and false on failure.
594 static boolean DAC960_V2_ControllerInfo(DAC960_Controller_T *Controller,
595 DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
596 void *DataPointer,
597 unsigned int DataByteCount)
599 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
600 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
601 DAC960_V2_CommandStatus_T CommandStatus;
602 DAC960_V2_ClearCommand(Command);
603 Command->CommandType = DAC960_ImmediateCommand;
604 CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
605 CommandMailbox->ControllerInfo.CommandControlBits
606 .DataTransferControllerToHost = true;
607 CommandMailbox->ControllerInfo.CommandControlBits
608 .NoAutoRequestSense = true;
609 CommandMailbox->ControllerInfo.DataTransferSize = DataByteCount;
610 CommandMailbox->ControllerInfo.ControllerNumber = 0;
611 CommandMailbox->ControllerInfo.IOCTL_Opcode = IOCTL_Opcode;
612 CommandMailbox->ControllerInfo.DataTransferMemoryAddress
613 .ScatterGatherSegments[0]
614 .SegmentDataPointer =
615 Virtual_to_Bus(DataPointer);
616 CommandMailbox->ControllerInfo.DataTransferMemoryAddress
617 .ScatterGatherSegments[0]
618 .SegmentByteCount =
619 CommandMailbox->ControllerInfo.DataTransferSize;
620 DAC960_ExecuteCommand(Command);
621 CommandStatus = Command->V2.CommandStatus;
622 DAC960_DeallocateCommand(Command);
623 return (CommandStatus == DAC960_V2_NormalCompletion);
628 DAC960_V2_LogicalDeviceInfo executes a DAC960 V2 Firmware Controller Logical
629 Device Information Reading IOCTL Command and waits for completion. It
630 returns true on success and false on failure.
633 static boolean DAC960_V2_LogicalDeviceInfo(DAC960_Controller_T *Controller,
634 DAC960_V2_IOCTL_Opcode_T
635 IOCTL_Opcode,
636 unsigned short
637 LogicalDeviceNumber,
638 void *DataPointer,
639 unsigned int DataByteCount)
641 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
642 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
643 DAC960_V2_CommandStatus_T CommandStatus;
644 DAC960_V2_ClearCommand(Command);
645 Command->CommandType = DAC960_ImmediateCommand;
646 CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
647 CommandMailbox->LogicalDeviceInfo.CommandControlBits
648 .DataTransferControllerToHost = true;
649 CommandMailbox->LogicalDeviceInfo.CommandControlBits
650 .NoAutoRequestSense = true;
651 CommandMailbox->LogicalDeviceInfo.DataTransferSize = DataByteCount;
652 CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
653 LogicalDeviceNumber;
654 CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
655 CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
656 .ScatterGatherSegments[0]
657 .SegmentDataPointer =
658 Virtual_to_Bus(DataPointer);
659 CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
660 .ScatterGatherSegments[0]
661 .SegmentByteCount =
662 CommandMailbox->LogicalDeviceInfo.DataTransferSize;
663 DAC960_ExecuteCommand(Command);
664 CommandStatus = Command->V2.CommandStatus;
665 DAC960_DeallocateCommand(Command);
666 return (CommandStatus == DAC960_V2_NormalCompletion);
671 DAC960_V2_PhysicalDeviceInfo executes a DAC960 V2 Firmware Controller Physical
672 Device Information Reading IOCTL Command and waits for completion. It
673 returns true on success and false on failure.
676 static boolean DAC960_V2_PhysicalDeviceInfo(DAC960_Controller_T *Controller,
677 DAC960_V2_IOCTL_Opcode_T
678 IOCTL_Opcode,
679 unsigned char Channel,
680 unsigned char TargetID,
681 unsigned char LogicalUnit,
682 void *DataPointer,
683 unsigned int DataByteCount)
685 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
686 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
687 DAC960_V2_CommandStatus_T CommandStatus;
688 DAC960_V2_ClearCommand(Command);
689 Command->CommandType = DAC960_ImmediateCommand;
690 CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
691 CommandMailbox->PhysicalDeviceInfo.CommandControlBits
692 .DataTransferControllerToHost = true;
693 CommandMailbox->PhysicalDeviceInfo.CommandControlBits
694 .NoAutoRequestSense = true;
695 CommandMailbox->PhysicalDeviceInfo.DataTransferSize = DataByteCount;
696 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit = LogicalUnit;
697 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
698 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
699 CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
700 CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
701 .ScatterGatherSegments[0]
702 .SegmentDataPointer =
703 Virtual_to_Bus(DataPointer);
704 CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
705 .ScatterGatherSegments[0]
706 .SegmentByteCount =
707 CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
708 DAC960_ExecuteCommand(Command);
709 CommandStatus = Command->V2.CommandStatus;
710 DAC960_DeallocateCommand(Command);
711 return (CommandStatus == DAC960_V2_NormalCompletion);
716 DAC960_V2_DeviceOperation executes a DAC960 V2 Firmware Controller Device
717 Operation IOCTL Command and waits for completion. It returns true on
718 success and false on failure.
721 static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
722 DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
723 DAC960_V2_OperationDevice_T
724 OperationDevice)
726 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
727 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
728 DAC960_V2_CommandStatus_T CommandStatus;
729 DAC960_V2_ClearCommand(Command);
730 Command->CommandType = DAC960_ImmediateCommand;
731 CommandMailbox->DeviceOperation.CommandOpcode = DAC960_V2_IOCTL;
732 CommandMailbox->DeviceOperation.CommandControlBits
733 .DataTransferControllerToHost = true;
734 CommandMailbox->DeviceOperation.CommandControlBits
735 .NoAutoRequestSense = true;
736 CommandMailbox->DeviceOperation.IOCTL_Opcode = IOCTL_Opcode;
737 CommandMailbox->DeviceOperation.OperationDevice = OperationDevice;
738 DAC960_ExecuteCommand(Command);
739 CommandStatus = Command->V2.CommandStatus;
740 DAC960_DeallocateCommand(Command);
741 return (CommandStatus == DAC960_V2_NormalCompletion);
746 DAC960_V1_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
747 for DAC960 V1 Firmware Controllers.
750 static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
751 *Controller)
753 void *ControllerBaseAddress = Controller->BaseAddress;
754 DAC960_V1_CommandMailbox_T *CommandMailboxesMemory;
755 DAC960_V1_StatusMailbox_T *StatusMailboxesMemory;
756 DAC960_V1_CommandMailbox_T CommandMailbox;
757 DAC960_V1_CommandStatus_T CommandStatus;
758 unsigned long MemoryMailboxPagesAddress;
759 unsigned long MemoryMailboxPagesOrder;
760 unsigned long MemoryMailboxPagesSize;
761 void *SavedMemoryMailboxesAddress = NULL;
762 short NextCommandMailboxIndex = 0;
763 short NextStatusMailboxIndex = 0;
764 int TimeoutCounter = 1000000, i;
765 MemoryMailboxPagesOrder = 0;
766 MemoryMailboxPagesSize =
767 DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T) +
768 DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T);
769 while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
770 MemoryMailboxPagesOrder++;
771 if (Controller->HardwareType == DAC960_LA_Controller)
772 DAC960_LA_RestoreMemoryMailboxInfo(Controller,
773 &SavedMemoryMailboxesAddress,
774 &NextCommandMailboxIndex,
775 &NextStatusMailboxIndex);
776 else DAC960_PG_RestoreMemoryMailboxInfo(Controller,
777 &SavedMemoryMailboxesAddress,
778 &NextCommandMailboxIndex,
779 &NextStatusMailboxIndex);
780 if (SavedMemoryMailboxesAddress == NULL)
782 MemoryMailboxPagesAddress =
783 __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
784 Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
785 CommandMailboxesMemory =
786 (DAC960_V1_CommandMailbox_T *) MemoryMailboxPagesAddress;
788 else CommandMailboxesMemory = SavedMemoryMailboxesAddress;
789 if (CommandMailboxesMemory == NULL) return false;
790 Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
791 memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
792 Controller->V1.FirstCommandMailbox = CommandMailboxesMemory;
793 CommandMailboxesMemory += DAC960_V1_CommandMailboxCount - 1;
794 Controller->V1.LastCommandMailbox = CommandMailboxesMemory;
795 Controller->V1.NextCommandMailbox =
796 &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
797 if (--NextCommandMailboxIndex < 0)
798 NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
799 Controller->V1.PreviousCommandMailbox1 =
800 &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
801 if (--NextCommandMailboxIndex < 0)
802 NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
803 Controller->V1.PreviousCommandMailbox2 =
804 &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
805 StatusMailboxesMemory =
806 (DAC960_V1_StatusMailbox_T *) (CommandMailboxesMemory + 1);
807 Controller->V1.FirstStatusMailbox = StatusMailboxesMemory;
808 StatusMailboxesMemory += DAC960_V1_StatusMailboxCount - 1;
809 Controller->V1.LastStatusMailbox = StatusMailboxesMemory;
810 Controller->V1.NextStatusMailbox =
811 &Controller->V1.FirstStatusMailbox[NextStatusMailboxIndex];
812 if (SavedMemoryMailboxesAddress != NULL) return true;
813 /* Enable the Memory Mailbox Interface. */
814 Controller->V1.DualModeMemoryMailboxInterface = true;
815 CommandMailbox.TypeX.CommandOpcode = 0x2B;
816 CommandMailbox.TypeX.CommandIdentifier = 0;
817 CommandMailbox.TypeX.CommandOpcode2 = 0x14;
818 CommandMailbox.TypeX.CommandMailboxesBusAddress =
819 Virtual_to_Bus(Controller->V1.FirstCommandMailbox);
820 CommandMailbox.TypeX.StatusMailboxesBusAddress =
821 Virtual_to_Bus(Controller->V1.FirstStatusMailbox);
822 for (i = 0; i < 2; i++)
823 switch (Controller->HardwareType)
825 case DAC960_LA_Controller:
826 while (--TimeoutCounter >= 0)
828 if (!DAC960_LA_HardwareMailboxFullP(ControllerBaseAddress))
829 break;
830 udelay(10);
832 if (TimeoutCounter < 0) return false;
833 DAC960_LA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
834 DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
835 while (--TimeoutCounter >= 0)
837 if (DAC960_LA_HardwareMailboxStatusAvailableP(
838 ControllerBaseAddress))
839 break;
840 udelay(10);
842 if (TimeoutCounter < 0) return false;
843 CommandStatus = DAC960_LA_ReadStatusRegister(ControllerBaseAddress);
844 DAC960_LA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
845 DAC960_LA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
846 if (CommandStatus == DAC960_V1_NormalCompletion) return true;
847 Controller->V1.DualModeMemoryMailboxInterface = false;
848 CommandMailbox.TypeX.CommandOpcode2 = 0x10;
849 break;
850 case DAC960_PG_Controller:
851 while (--TimeoutCounter >= 0)
853 if (!DAC960_PG_HardwareMailboxFullP(ControllerBaseAddress))
854 break;
855 udelay(10);
857 if (TimeoutCounter < 0) return false;
858 DAC960_PG_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
859 DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
860 while (--TimeoutCounter >= 0)
862 if (DAC960_PG_HardwareMailboxStatusAvailableP(
863 ControllerBaseAddress))
864 break;
865 udelay(10);
867 if (TimeoutCounter < 0) return false;
868 CommandStatus = DAC960_PG_ReadStatusRegister(ControllerBaseAddress);
869 DAC960_PG_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
870 DAC960_PG_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
871 if (CommandStatus == DAC960_V1_NormalCompletion) return true;
872 Controller->V1.DualModeMemoryMailboxInterface = false;
873 CommandMailbox.TypeX.CommandOpcode2 = 0x10;
874 break;
875 default:
876 break;
878 return false;
883 DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
884 for DAC960 V2 Firmware Controllers.
887 static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
888 *Controller)
890 void *ControllerBaseAddress = Controller->BaseAddress;
891 DAC960_V2_CommandMailbox_T *CommandMailboxesMemory;
892 DAC960_V2_StatusMailbox_T *StatusMailboxesMemory;
893 DAC960_V2_CommandMailbox_T CommandMailbox;
894 DAC960_V2_CommandStatus_T CommandStatus = 0;
895 unsigned long MemoryMailboxPagesAddress;
896 unsigned long MemoryMailboxPagesOrder;
897 unsigned long MemoryMailboxPagesSize;
898 MemoryMailboxPagesOrder = 0;
899 MemoryMailboxPagesSize =
900 DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T) +
901 DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T) +
902 sizeof(DAC960_V2_HealthStatusBuffer_T);
903 while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
904 MemoryMailboxPagesOrder++;
905 MemoryMailboxPagesAddress =
906 __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
907 Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
908 CommandMailboxesMemory =
909 (DAC960_V2_CommandMailbox_T *) MemoryMailboxPagesAddress;
910 if (CommandMailboxesMemory == NULL) return false;
911 Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
912 memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
913 Controller->V2.FirstCommandMailbox = CommandMailboxesMemory;
914 CommandMailboxesMemory += DAC960_V2_CommandMailboxCount - 1;
915 Controller->V2.LastCommandMailbox = CommandMailboxesMemory;
916 Controller->V2.NextCommandMailbox = Controller->V2.FirstCommandMailbox;
917 Controller->V2.PreviousCommandMailbox1 = Controller->V2.LastCommandMailbox;
918 Controller->V2.PreviousCommandMailbox2 =
919 Controller->V2.LastCommandMailbox - 1;
920 StatusMailboxesMemory =
921 (DAC960_V2_StatusMailbox_T *) (CommandMailboxesMemory + 1);
922 Controller->V2.FirstStatusMailbox = StatusMailboxesMemory;
923 StatusMailboxesMemory += DAC960_V2_StatusMailboxCount - 1;
924 Controller->V2.LastStatusMailbox = StatusMailboxesMemory;
925 Controller->V2.NextStatusMailbox = Controller->V2.FirstStatusMailbox;
926 Controller->V2.HealthStatusBuffer =
927 (DAC960_V2_HealthStatusBuffer_T *) (StatusMailboxesMemory + 1);
928 /* Enable the Memory Mailbox Interface. */
929 memset(&CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
930 CommandMailbox.SetMemoryMailbox.CommandIdentifier = 1;
931 CommandMailbox.SetMemoryMailbox.CommandOpcode = DAC960_V2_IOCTL;
932 CommandMailbox.SetMemoryMailbox.CommandControlBits.NoAutoRequestSense = true;
933 CommandMailbox.SetMemoryMailbox.FirstCommandMailboxSizeKB =
934 (DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T)) >> 10;
935 CommandMailbox.SetMemoryMailbox.FirstStatusMailboxSizeKB =
936 (DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T)) >> 10;
937 CommandMailbox.SetMemoryMailbox.SecondCommandMailboxSizeKB = 0;
938 CommandMailbox.SetMemoryMailbox.SecondStatusMailboxSizeKB = 0;
939 CommandMailbox.SetMemoryMailbox.RequestSenseSize = 0;
940 CommandMailbox.SetMemoryMailbox.IOCTL_Opcode = DAC960_V2_SetMemoryMailbox;
941 CommandMailbox.SetMemoryMailbox.HealthStatusBufferSizeKB = 1;
942 CommandMailbox.SetMemoryMailbox.HealthStatusBufferBusAddress =
943 Virtual_to_Bus(Controller->V2.HealthStatusBuffer);
944 CommandMailbox.SetMemoryMailbox.FirstCommandMailboxBusAddress =
945 Virtual_to_Bus(Controller->V2.FirstCommandMailbox);
946 CommandMailbox.SetMemoryMailbox.FirstStatusMailboxBusAddress =
947 Virtual_to_Bus(Controller->V2.FirstStatusMailbox);
948 switch (Controller->HardwareType)
950 case DAC960_BA_Controller:
951 while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress))
952 udelay(1);
953 DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
954 DAC960_BA_HardwareMailboxNewCommand(ControllerBaseAddress);
955 while (!DAC960_BA_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
956 udelay(1);
957 CommandStatus = DAC960_BA_ReadCommandStatus(ControllerBaseAddress);
958 DAC960_BA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
959 DAC960_BA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
960 break;
961 case DAC960_LP_Controller:
962 while (DAC960_LP_HardwareMailboxFullP(ControllerBaseAddress))
963 udelay(1);
964 DAC960_LP_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
965 DAC960_LP_HardwareMailboxNewCommand(ControllerBaseAddress);
966 while (!DAC960_LP_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
967 udelay(1);
968 CommandStatus = DAC960_LP_ReadCommandStatus(ControllerBaseAddress);
969 DAC960_LP_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
970 DAC960_LP_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
971 break;
972 default:
973 break;
975 return (CommandStatus == DAC960_V2_NormalCompletion);
980 DAC960_V1_ReadControllerConfiguration reads the Configuration Information
981 from DAC960 V1 Firmware Controllers and initializes the Controller structure.
984 static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
985 *Controller)
987 DAC960_V1_Enquiry2_T Enquiry2;
988 DAC960_V1_Config2_T Config2;
989 int LogicalDriveNumber, Channel, TargetID;
990 if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry,
991 &Controller->V1.Enquiry))
992 return DAC960_Failure(Controller, "ENQUIRY");
993 if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, &Enquiry2))
994 return DAC960_Failure(Controller, "ENQUIRY2");
995 if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, &Config2))
996 return DAC960_Failure(Controller, "READ CONFIG2");
997 if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_GetLogicalDriveInformation,
998 &Controller->V1.LogicalDriveInformation))
999 return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION");
1000 for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++)
1001 for (TargetID = 0; TargetID < Enquiry2.MaxTargets; TargetID++)
1002 if (!DAC960_V1_ExecuteType3D(Controller, DAC960_V1_GetDeviceState,
1003 Channel, TargetID,
1004 &Controller->V1.DeviceState
1005 [Channel][TargetID]))
1006 return DAC960_Failure(Controller, "GET DEVICE STATE");
1008 Initialize the Controller Model Name and Full Model Name fields.
1010 switch (Enquiry2.HardwareID.SubModel)
1012 case DAC960_V1_P_PD_PU:
1013 if (Enquiry2.SCSICapability.BusSpeed == DAC960_V1_Ultra)
1014 strcpy(Controller->ModelName, "DAC960PU");
1015 else strcpy(Controller->ModelName, "DAC960PD");
1016 break;
1017 case DAC960_V1_PL:
1018 strcpy(Controller->ModelName, "DAC960PL");
1019 break;
1020 case DAC960_V1_PG:
1021 strcpy(Controller->ModelName, "DAC960PG");
1022 break;
1023 case DAC960_V1_PJ:
1024 strcpy(Controller->ModelName, "DAC960PJ");
1025 break;
1026 case DAC960_V1_PR:
1027 strcpy(Controller->ModelName, "DAC960PR");
1028 break;
1029 case DAC960_V1_PT:
1030 strcpy(Controller->ModelName, "DAC960PT");
1031 break;
1032 case DAC960_V1_PTL0:
1033 strcpy(Controller->ModelName, "DAC960PTL0");
1034 break;
1035 case DAC960_V1_PRL:
1036 strcpy(Controller->ModelName, "DAC960PRL");
1037 break;
1038 case DAC960_V1_PTL1:
1039 strcpy(Controller->ModelName, "DAC960PTL1");
1040 break;
1041 case DAC960_V1_1164P:
1042 strcpy(Controller->ModelName, "DAC1164P");
1043 break;
1044 default:
1045 return DAC960_Failure(Controller, "MODEL VERIFICATION");
1047 strcpy(Controller->FullModelName, "Mylex ");
1048 strcat(Controller->FullModelName, Controller->ModelName);
1050 Initialize the Controller Firmware Version field and verify that it
1051 is a supported firmware version. The supported firmware versions are:
1053 DAC1164P 5.06 and above
1054 DAC960PTL/PRL/PJ/PG 4.06 and above
1055 DAC960PU/PD/PL 3.51 and above
1057 sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
1058 Enquiry2.FirmwareID.MajorVersion, Enquiry2.FirmwareID.MinorVersion,
1059 Enquiry2.FirmwareID.FirmwareType, Enquiry2.FirmwareID.TurnID);
1060 if (!((Controller->FirmwareVersion[0] == '5' &&
1061 strcmp(Controller->FirmwareVersion, "5.06") >= 0) ||
1062 (Controller->FirmwareVersion[0] == '4' &&
1063 strcmp(Controller->FirmwareVersion, "4.06") >= 0) ||
1064 (Controller->FirmwareVersion[0] == '3' &&
1065 strcmp(Controller->FirmwareVersion, "3.51") >= 0)))
1067 DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
1068 DAC960_Error("Firmware Version = '%s'\n", Controller,
1069 Controller->FirmwareVersion);
1070 return false;
1073 Initialize the Controller Channels, Targets, Memory Size, and SAF-TE
1074 Enclosure Management Enabled fields.
1076 Controller->Channels = Enquiry2.ActualChannels;
1077 Controller->Targets = Enquiry2.MaxTargets;
1078 Controller->MemorySize = Enquiry2.MemorySize >> 20;
1079 Controller->V1.SAFTE_EnclosureManagementEnabled =
1080 (Enquiry2.FaultManagementType == DAC960_V1_SAFTE);
1082 Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
1083 Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
1084 Driver Scatter/Gather Limit. The Driver Queue Depth must be at most one
1085 less than the Controller Queue Depth to allow for an automatic drive
1086 rebuild operation.
1088 Controller->ControllerQueueDepth = Controller->V1.Enquiry.MaxCommands;
1089 Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
1090 if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
1091 Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
1092 Controller->LogicalDriveCount =
1093 Controller->V1.Enquiry.NumberOfLogicalDrives;
1094 Controller->MaxBlocksPerCommand = Enquiry2.MaxBlocksPerCommand;
1095 Controller->ControllerScatterGatherLimit = Enquiry2.MaxScatterGatherEntries;
1096 Controller->DriverScatterGatherLimit =
1097 Controller->ControllerScatterGatherLimit;
1098 if (Controller->DriverScatterGatherLimit > DAC960_V1_ScatterGatherLimit)
1099 Controller->DriverScatterGatherLimit = DAC960_V1_ScatterGatherLimit;
1101 Initialize the Stripe Size, Segment Size, and Geometry Translation.
1103 Controller->V1.StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
1104 >> (10 - DAC960_BlockSizeBits);
1105 Controller->V1.SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
1106 >> (10 - DAC960_BlockSizeBits);
1107 switch (Config2.DriveGeometry)
1109 case DAC960_V1_Geometry_128_32:
1110 Controller->V1.GeometryTranslationHeads = 128;
1111 Controller->V1.GeometryTranslationSectors = 32;
1112 break;
1113 case DAC960_V1_Geometry_255_63:
1114 Controller->V1.GeometryTranslationHeads = 255;
1115 Controller->V1.GeometryTranslationSectors = 63;
1116 break;
1117 default:
1118 return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
1121 Initialize the Logical Drive Initially Accessible flag.
1123 for (LogicalDriveNumber = 0;
1124 LogicalDriveNumber < Controller->LogicalDriveCount;
1125 LogicalDriveNumber++)
1126 if (Controller->V1.LogicalDriveInformation
1127 [LogicalDriveNumber].LogicalDriveState !=
1128 DAC960_V1_LogicalDrive_Offline)
1129 Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
1130 Controller->V1.LastRebuildStatus = DAC960_V1_NoRebuildOrCheckInProgress;
1131 return true;
1136 DAC960_V2_ReadControllerConfiguration reads the Configuration Information
1137 from DAC960 V2 Firmware Controllers and initializes the Controller structure.
1140 static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
1141 *Controller)
1143 DAC960_V2_ControllerInfo_T *ControllerInfo =
1144 &Controller->V2.ControllerInformation;
1145 unsigned short LogicalDeviceNumber = 0;
1146 int ModelNameLength;
1147 if (!DAC960_V2_ControllerInfo(Controller, DAC960_V2_GetControllerInfo,
1148 ControllerInfo,
1149 sizeof(DAC960_V2_ControllerInfo_T)))
1150 return DAC960_Failure(Controller, "GET CONTROLLER INFO");
1151 if (!DAC960_V2_GeneralInfo(Controller, DAC960_V2_GetHealthStatus,
1152 Controller->V2.HealthStatusBuffer,
1153 sizeof(DAC960_V2_HealthStatusBuffer_T)))
1154 return DAC960_Failure(Controller, "GET HEALTH STATUS");
1156 Initialize the Controller Model Name and Full Model Name fields.
1158 ModelNameLength = sizeof(ControllerInfo->ControllerName);
1159 if (ModelNameLength > sizeof(Controller->ModelName)-1)
1160 ModelNameLength = sizeof(Controller->ModelName)-1;
1161 memcpy(Controller->ModelName, ControllerInfo->ControllerName,
1162 ModelNameLength);
1163 ModelNameLength--;
1164 while (Controller->ModelName[ModelNameLength] == ' ' ||
1165 Controller->ModelName[ModelNameLength] == '\0')
1166 ModelNameLength--;
1167 Controller->ModelName[++ModelNameLength] = '\0';
1168 strcpy(Controller->FullModelName, "Mylex ");
1169 strcat(Controller->FullModelName, Controller->ModelName);
1171 Initialize the Controller Firmware Version field.
1173 sprintf(Controller->FirmwareVersion, "%d.%02d-%02d",
1174 ControllerInfo->FirmwareMajorVersion,
1175 ControllerInfo->FirmwareMinorVersion,
1176 ControllerInfo->FirmwareTurnNumber);
1177 if (ControllerInfo->FirmwareMajorVersion == 6 &&
1178 ControllerInfo->FirmwareMinorVersion == 0 &&
1179 ControllerInfo->FirmwareTurnNumber < 1)
1181 DAC960_Info("FIRMWARE VERSION %s DOES NOT PROVIDE THE CONTROLLER\n",
1182 Controller, Controller->FirmwareVersion);
1183 DAC960_Info("STATUS MONITORING FUNCTIONALITY NEEDED BY THIS DRIVER.\n",
1184 Controller);
1185 DAC960_Info("PLEASE UPGRADE TO VERSION 6.00-01 OR ABOVE.\n",
1186 Controller);
1189 Initialize the Controller Channels, Targets, and Memory Size.
1191 Controller->Channels = ControllerInfo->NumberOfPhysicalChannelsPresent;
1192 Controller->Targets =
1193 ControllerInfo->MaximumTargetsPerChannel
1194 [ControllerInfo->NumberOfPhysicalChannelsPresent-1];
1195 Controller->MemorySize = ControllerInfo->MemorySizeMB;
1197 Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
1198 Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
1199 Driver Scatter/Gather Limit. The Driver Queue Depth must be at most one
1200 less than the Controller Queue Depth to allow for an automatic drive
1201 rebuild operation.
1203 Controller->ControllerQueueDepth = ControllerInfo->MaximumParallelCommands;
1204 Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
1205 if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
1206 Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
1207 Controller->LogicalDriveCount = ControllerInfo->LogicalDevicesPresent;
1208 Controller->MaxBlocksPerCommand =
1209 ControllerInfo->MaximumDataTransferSizeInBlocks;
1210 Controller->ControllerScatterGatherLimit =
1211 ControllerInfo->MaximumScatterGatherEntries;
1212 Controller->DriverScatterGatherLimit =
1213 Controller->ControllerScatterGatherLimit;
1214 if (Controller->DriverScatterGatherLimit > DAC960_V2_ScatterGatherLimit)
1215 Controller->DriverScatterGatherLimit = DAC960_V2_ScatterGatherLimit;
1217 Initialize the Logical Device Information.
1219 while (true)
1221 DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
1222 &Controller->V2.NewLogicalDeviceInformation;
1223 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo;
1224 DAC960_V2_PhysicalDevice_T PhysicalDevice;
1225 if (!DAC960_V2_LogicalDeviceInfo(Controller,
1226 DAC960_V2_GetLogicalDeviceInfoValid,
1227 LogicalDeviceNumber,
1228 NewLogicalDeviceInfo,
1229 sizeof(DAC960_V2_LogicalDeviceInfo_T)))
1230 break;
1231 LogicalDeviceNumber = NewLogicalDeviceInfo->LogicalDeviceNumber;
1232 if (LogicalDeviceNumber > DAC960_MaxLogicalDrives)
1233 panic("DAC960: Logical Drive Number %d not supported\n",
1234 LogicalDeviceNumber);
1235 if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize)
1236 panic("DAC960: Logical Drive Block Size %d not supported\n",
1237 NewLogicalDeviceInfo->DeviceBlockSizeInBytes);
1238 PhysicalDevice.Controller = 0;
1239 PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
1240 PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
1241 PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
1242 Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
1243 PhysicalDevice;
1244 if (NewLogicalDeviceInfo->LogicalDeviceState !=
1245 DAC960_V2_LogicalDevice_Offline)
1246 Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true;
1247 LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
1248 kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
1249 if (LogicalDeviceInfo == NULL)
1250 return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION");
1251 Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
1252 LogicalDeviceInfo;
1253 memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
1254 sizeof(DAC960_V2_LogicalDeviceInfo_T));
1255 LogicalDeviceNumber++;
1257 return true;
1262 DAC960_ReportControllerConfiguration reports the Configuration Information
1263 for Controller.
1266 static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
1267 *Controller)
1269 DAC960_Info("Configuring Mylex %s PCI RAID Controller\n",
1270 Controller, Controller->ModelName);
1271 DAC960_Info(" Firmware Version: %s, Channels: %d, Memory Size: %dMB\n",
1272 Controller, Controller->FirmwareVersion,
1273 Controller->Channels, Controller->MemorySize);
1274 DAC960_Info(" PCI Bus: %d, Device: %d, Function: %d, I/O Address: ",
1275 Controller, Controller->Bus,
1276 Controller->Device, Controller->Function);
1277 if (Controller->IO_Address == 0)
1278 DAC960_Info("Unassigned\n", Controller);
1279 else DAC960_Info("0x%X\n", Controller, Controller->IO_Address);
1280 DAC960_Info(" PCI Address: 0x%X mapped at 0x%lX, IRQ Channel: %d\n",
1281 Controller, Controller->PCI_Address,
1282 (unsigned long) Controller->BaseAddress,
1283 Controller->IRQ_Channel);
1284 DAC960_Info(" Controller Queue Depth: %d, "
1285 "Maximum Blocks per Command: %d\n",
1286 Controller, Controller->ControllerQueueDepth,
1287 Controller->MaxBlocksPerCommand);
1288 DAC960_Info(" Driver Queue Depth: %d, "
1289 "Scatter/Gather Limit: %d of %d Segments\n",
1290 Controller, Controller->DriverQueueDepth,
1291 Controller->DriverScatterGatherLimit,
1292 Controller->ControllerScatterGatherLimit);
1293 if (Controller->FirmwareType == DAC960_V1_Controller)
1295 DAC960_Info(" Stripe Size: %dKB, Segment Size: %dKB, "
1296 "BIOS Geometry: %d/%d\n", Controller,
1297 Controller->V1.StripeSize,
1298 Controller->V1.SegmentSize,
1299 Controller->V1.GeometryTranslationHeads,
1300 Controller->V1.GeometryTranslationSectors);
1301 if (Controller->V1.SAFTE_EnclosureManagementEnabled)
1302 DAC960_Info(" SAF-TE Enclosure Management Enabled\n", Controller);
1304 return true;
1309 DAC960_V1_ReadDeviceConfiguration reads the Device Configuration Information
1310 for DAC960 V1 Firmware Controllers by requesting the SCSI Inquiry and SCSI
1311 Inquiry Unit Serial Number information for each device connected to
1312 Controller.
1315 static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
1316 *Controller)
1318 DAC960_V1_DCDB_T DCDBs[DAC960_V1_MaxChannels], *DCDB;
1319 Semaphore_T Semaphores[DAC960_V1_MaxChannels], *Semaphore;
1320 unsigned long ProcessorFlags;
1321 int Channel, TargetID;
1322 for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
1324 for (Channel = 0; Channel < Controller->Channels; Channel++)
1326 DAC960_Command_T *Command = Controller->Commands[Channel];
1327 DAC960_SCSI_Inquiry_T *InquiryStandardData =
1328 &Controller->V1.InquiryStandardData[Channel][TargetID];
1329 InquiryStandardData->PeripheralDeviceType = 0x1F;
1330 Semaphore = &Semaphores[Channel];
1331 init_MUTEX_LOCKED(Semaphore);
1332 DCDB = &DCDBs[Channel];
1333 DAC960_V1_ClearCommand(Command);
1334 Command->CommandType = DAC960_ImmediateCommand;
1335 Command->Semaphore = Semaphore;
1336 Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
1337 Command->V1.CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
1338 DCDB->Channel = Channel;
1339 DCDB->TargetID = TargetID;
1340 DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
1341 DCDB->EarlyStatus = false;
1342 DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
1343 DCDB->NoAutomaticRequestSense = false;
1344 DCDB->DisconnectPermitted = true;
1345 DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
1346 DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
1347 DCDB->CDBLength = 6;
1348 DCDB->TransferLengthHigh4 = 0;
1349 DCDB->SenseLength = sizeof(DCDB->SenseData);
1350 DCDB->CDB[0] = 0x12; /* INQUIRY */
1351 DCDB->CDB[1] = 0; /* EVPD = 0 */
1352 DCDB->CDB[2] = 0; /* Page Code */
1353 DCDB->CDB[3] = 0; /* Reserved */
1354 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
1355 DCDB->CDB[5] = 0; /* Control */
1356 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
1357 DAC960_QueueCommand(Command);
1358 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
1360 for (Channel = 0; Channel < Controller->Channels; Channel++)
1362 DAC960_Command_T *Command = Controller->Commands[Channel];
1363 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
1364 &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
1365 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
1366 Semaphore = &Semaphores[Channel];
1367 down(Semaphore);
1368 if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion)
1369 continue;
1370 Command->Semaphore = Semaphore;
1371 DCDB = &DCDBs[Channel];
1372 DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1373 DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
1374 DCDB->SenseLength = sizeof(DCDB->SenseData);
1375 DCDB->CDB[0] = 0x12; /* INQUIRY */
1376 DCDB->CDB[1] = 1; /* EVPD = 1 */
1377 DCDB->CDB[2] = 0x80; /* Page Code */
1378 DCDB->CDB[3] = 0; /* Reserved */
1379 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1380 DCDB->CDB[5] = 0; /* Control */
1381 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
1382 DAC960_QueueCommand(Command);
1383 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
1384 down(Semaphore);
1387 return true;
1392 DAC960_V2_ReadDeviceConfiguration reads the Device Configuration Information
1393 for DAC960 V2 Firmware Controllers by requesting the Physical Device
1394 Information and SCSI Inquiry Unit Serial Number information for each
1395 device connected to Controller.
1398 static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
1399 *Controller)
1401 unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0;
1402 unsigned short PhysicalDeviceIndex = 0;
1403 while (true)
1405 DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
1406 &Controller->V2.NewPhysicalDeviceInformation;
1407 DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo;
1408 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
1409 DAC960_Command_T *Command;
1410 DAC960_V2_CommandMailbox_T *CommandMailbox;
1411 if (!DAC960_V2_PhysicalDeviceInfo(Controller,
1412 DAC960_V2_GetPhysicalDeviceInfoValid,
1413 Channel,
1414 TargetID,
1415 LogicalUnit,
1416 NewPhysicalDeviceInfo,
1417 sizeof(DAC960_V2_PhysicalDeviceInfo_T)))
1418 break;
1419 Channel = NewPhysicalDeviceInfo->Channel;
1420 TargetID = NewPhysicalDeviceInfo->TargetID;
1421 LogicalUnit = NewPhysicalDeviceInfo->LogicalUnit;
1422 PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
1423 kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
1424 if (PhysicalDeviceInfo == NULL)
1425 return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION");
1426 Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] =
1427 PhysicalDeviceInfo;
1428 memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
1429 sizeof(DAC960_V2_PhysicalDeviceInfo_T));
1430 InquiryUnitSerialNumber = (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
1431 kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
1432 if (InquiryUnitSerialNumber == NULL)
1433 return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION");
1434 Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex] =
1435 InquiryUnitSerialNumber;
1436 memset(InquiryUnitSerialNumber, 0,
1437 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
1438 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
1439 Command = DAC960_AllocateCommand(Controller);
1440 CommandMailbox = &Command->V2.CommandMailbox;
1441 DAC960_V2_ClearCommand(Command);
1442 Command->CommandType = DAC960_ImmediateCommand;
1443 CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10_Passthru;
1444 CommandMailbox->SCSI_10.CommandControlBits
1445 .DataTransferControllerToHost = true;
1446 CommandMailbox->SCSI_10.CommandControlBits
1447 .NoAutoRequestSense = true;
1448 CommandMailbox->SCSI_10.DataTransferSize =
1449 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1450 CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit = LogicalUnit;
1451 CommandMailbox->SCSI_10.PhysicalDevice.TargetID = TargetID;
1452 CommandMailbox->SCSI_10.PhysicalDevice.Channel = Channel;
1453 CommandMailbox->SCSI_10.CDBLength = 6;
1454 CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
1455 CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
1456 CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
1457 CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
1458 CommandMailbox->SCSI_10.SCSI_CDB[4] =
1459 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1460 CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
1461 CommandMailbox->SCSI_10.DataTransferMemoryAddress
1462 .ScatterGatherSegments[0]
1463 .SegmentDataPointer =
1464 Virtual_to_Bus(InquiryUnitSerialNumber);
1465 CommandMailbox->SCSI_10.DataTransferMemoryAddress
1466 .ScatterGatherSegments[0]
1467 .SegmentByteCount =
1468 CommandMailbox->SCSI_10.DataTransferSize;
1469 DAC960_ExecuteCommand(Command);
1470 DAC960_DeallocateCommand(Command);
1471 PhysicalDeviceIndex++;
1472 LogicalUnit++;
1474 return true;
1479 DAC960_SanitizeInquiryData sanitizes the Vendor, Model, Revision, and
1480 Product Serial Number fields of the Inquiry Standard Data and Inquiry
1481 Unit Serial Number structures.
1484 static void DAC960_SanitizeInquiryData(DAC960_SCSI_Inquiry_T
1485 *InquiryStandardData,
1486 DAC960_SCSI_Inquiry_UnitSerialNumber_T
1487 *InquiryUnitSerialNumber,
1488 unsigned char *Vendor,
1489 unsigned char *Model,
1490 unsigned char *Revision,
1491 unsigned char *SerialNumber)
1493 int SerialNumberLength, i;
1494 if (InquiryStandardData->PeripheralDeviceType == 0x1F) return;
1495 for (i = 0; i < sizeof(InquiryStandardData->VendorIdentification); i++)
1497 unsigned char VendorCharacter =
1498 InquiryStandardData->VendorIdentification[i];
1499 Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~'
1500 ? VendorCharacter : ' ');
1502 Vendor[sizeof(InquiryStandardData->VendorIdentification)] = '\0';
1503 for (i = 0; i < sizeof(InquiryStandardData->ProductIdentification); i++)
1505 unsigned char ModelCharacter =
1506 InquiryStandardData->ProductIdentification[i];
1507 Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
1508 ? ModelCharacter : ' ');
1510 Model[sizeof(InquiryStandardData->ProductIdentification)] = '\0';
1511 for (i = 0; i < sizeof(InquiryStandardData->ProductRevisionLevel); i++)
1513 unsigned char RevisionCharacter =
1514 InquiryStandardData->ProductRevisionLevel[i];
1515 Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
1516 ? RevisionCharacter : ' ');
1518 Revision[sizeof(InquiryStandardData->ProductRevisionLevel)] = '\0';
1519 if (InquiryUnitSerialNumber->PeripheralDeviceType == 0x1F) return;
1520 SerialNumberLength = InquiryUnitSerialNumber->PageLength;
1521 if (SerialNumberLength >
1522 sizeof(InquiryUnitSerialNumber->ProductSerialNumber))
1523 SerialNumberLength = sizeof(InquiryUnitSerialNumber->ProductSerialNumber);
1524 for (i = 0; i < SerialNumberLength; i++)
1526 unsigned char SerialNumberCharacter =
1527 InquiryUnitSerialNumber->ProductSerialNumber[i];
1528 SerialNumber[i] =
1529 (SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~'
1530 ? SerialNumberCharacter : ' ');
1532 SerialNumber[SerialNumberLength] = '\0';
1537 DAC960_V1_ReportDeviceConfiguration reports the Device Configuration
1538 Information for DAC960 V1 Firmware Controllers.
1541 static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
1542 *Controller)
1544 int LogicalDriveNumber, Channel, TargetID;
1545 DAC960_Info(" Physical Devices:\n", Controller);
1546 for (Channel = 0; Channel < Controller->Channels; Channel++)
1547 for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
1549 DAC960_SCSI_Inquiry_T *InquiryStandardData =
1550 &Controller->V1.InquiryStandardData[Channel][TargetID];
1551 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
1552 &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
1553 DAC960_V1_DeviceState_T *DeviceState =
1554 &Controller->V1.DeviceState[Channel][TargetID];
1555 DAC960_V1_ErrorTableEntry_T *ErrorEntry =
1556 &Controller->V1.ErrorTable.ErrorTableEntries[Channel][TargetID];
1557 char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
1558 char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
1559 char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
1560 char SerialNumber[1+sizeof(InquiryUnitSerialNumber
1561 ->ProductSerialNumber)];
1562 if (InquiryStandardData->PeripheralDeviceType == 0x1F) continue;
1563 DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
1564 Vendor, Model, Revision, SerialNumber);
1565 DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %s\n",
1566 Controller, Channel, TargetID, (TargetID < 10 ? " " : ""),
1567 Vendor, Model, Revision);
1568 if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
1569 DAC960_Info(" Serial Number: %s\n", Controller, SerialNumber);
1570 if (DeviceState->Present &&
1571 DeviceState->DeviceType == DAC960_V1_DiskType)
1573 if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0)
1574 DAC960_Info(" Disk Status: %s, %d blocks, %d resets\n",
1575 Controller,
1576 (DeviceState->DeviceState == DAC960_V1_Device_Dead
1577 ? "Dead"
1578 : DeviceState->DeviceState
1579 == DAC960_V1_Device_WriteOnly
1580 ? "Write-Only"
1581 : DeviceState->DeviceState
1582 == DAC960_V1_Device_Online
1583 ? "Online" : "Standby"),
1584 DeviceState->DiskSize,
1585 Controller->V1.DeviceResetCount[Channel][TargetID]);
1586 else
1587 DAC960_Info(" Disk Status: %s, %d blocks\n", Controller,
1588 (DeviceState->DeviceState == DAC960_V1_Device_Dead
1589 ? "Dead"
1590 : DeviceState->DeviceState
1591 == DAC960_V1_Device_WriteOnly
1592 ? "Write-Only"
1593 : DeviceState->DeviceState
1594 == DAC960_V1_Device_Online
1595 ? "Online" : "Standby"),
1596 DeviceState->DiskSize);
1598 if (ErrorEntry->ParityErrorCount > 0 ||
1599 ErrorEntry->SoftErrorCount > 0 ||
1600 ErrorEntry->HardErrorCount > 0 ||
1601 ErrorEntry->MiscErrorCount > 0)
1602 DAC960_Info(" Errors - Parity: %d, Soft: %d, "
1603 "Hard: %d, Misc: %d\n", Controller,
1604 ErrorEntry->ParityErrorCount,
1605 ErrorEntry->SoftErrorCount,
1606 ErrorEntry->HardErrorCount,
1607 ErrorEntry->MiscErrorCount);
1609 DAC960_Info(" Logical Drives:\n", Controller);
1610 for (LogicalDriveNumber = 0;
1611 LogicalDriveNumber < Controller->LogicalDriveCount;
1612 LogicalDriveNumber++)
1614 DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation =
1615 &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
1616 DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %d blocks, %s\n",
1617 Controller, Controller->ControllerNumber, LogicalDriveNumber,
1618 LogicalDriveInformation->RAIDLevel,
1619 (LogicalDriveInformation->LogicalDriveState
1620 == DAC960_V1_LogicalDrive_Online
1621 ? "Online"
1622 : LogicalDriveInformation->LogicalDriveState
1623 == DAC960_V1_LogicalDrive_Critical
1624 ? "Critical" : "Offline"),
1625 LogicalDriveInformation->LogicalDriveSize,
1626 (LogicalDriveInformation->WriteBack
1627 ? "Write Back" : "Write Thru"));
1629 return true;
1634 DAC960_V2_ReportDeviceConfiguration reports the Device Configuration
1635 Information for DAC960 V2 Firmware Controllers.
1638 static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
1639 *Controller)
1641 int PhysicalDeviceIndex, LogicalDriveNumber;
1642 DAC960_Info(" Physical Devices:\n", Controller);
1643 for (PhysicalDeviceIndex = 0;
1644 PhysicalDeviceIndex < DAC960_V2_MaxPhysicalDevices;
1645 PhysicalDeviceIndex++)
1647 DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
1648 Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
1649 DAC960_SCSI_Inquiry_T *InquiryStandardData =
1650 (DAC960_SCSI_Inquiry_T *) &PhysicalDeviceInfo->SCSI_InquiryData;
1651 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
1652 Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
1653 char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
1654 char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
1655 char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
1656 char SerialNumber[1+sizeof(InquiryUnitSerialNumber->ProductSerialNumber)];
1657 if (PhysicalDeviceInfo == NULL) break;
1658 DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
1659 Vendor, Model, Revision, SerialNumber);
1660 DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %s\n",
1661 Controller,
1662 PhysicalDeviceInfo->Channel,
1663 PhysicalDeviceInfo->TargetID,
1664 (PhysicalDeviceInfo->TargetID < 10 ? " " : ""),
1665 Vendor, Model, Revision);
1666 if (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers == 0)
1667 DAC960_Info(" %sAsynchronous\n", Controller,
1668 (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
1669 ? "Wide " :""));
1670 else
1671 DAC960_Info(" %sSynchronous at %d MB/sec\n", Controller,
1672 (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
1673 ? "Wide " :""),
1674 (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers
1675 * (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
1676 ? 2 : 1)));
1677 if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
1678 DAC960_Info(" Serial Number: %s\n", Controller, SerialNumber);
1679 if (PhysicalDeviceInfo->PhysicalDeviceState ==
1680 DAC960_V2_Device_Unconfigured)
1681 continue;
1682 DAC960_Info(" Disk Status: %s, %d blocks\n", Controller,
1683 (PhysicalDeviceInfo->PhysicalDeviceState
1684 == DAC960_V2_Device_Online
1685 ? "Online"
1686 : PhysicalDeviceInfo->PhysicalDeviceState
1687 == DAC960_V2_Device_WriteOnly
1688 ? "Write-Only"
1689 : PhysicalDeviceInfo->PhysicalDeviceState
1690 == DAC960_V2_Device_Dead
1691 ? "Dead" : "Standby"),
1692 PhysicalDeviceInfo
1693 ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
1694 if (PhysicalDeviceInfo->ParityErrors == 0 &&
1695 PhysicalDeviceInfo->SoftErrors == 0 &&
1696 PhysicalDeviceInfo->HardErrors == 0 &&
1697 PhysicalDeviceInfo->MiscellaneousErrors == 0 &&
1698 PhysicalDeviceInfo->CommandTimeouts == 0 &&
1699 PhysicalDeviceInfo->Retries == 0 &&
1700 PhysicalDeviceInfo->Aborts == 0 &&
1701 PhysicalDeviceInfo->PredictedFailuresDetected == 0)
1702 continue;
1703 DAC960_Info(" Errors - Parity: %d, Soft: %d, "
1704 "Hard: %d, Misc: %d\n", Controller,
1705 PhysicalDeviceInfo->ParityErrors,
1706 PhysicalDeviceInfo->SoftErrors,
1707 PhysicalDeviceInfo->HardErrors,
1708 PhysicalDeviceInfo->MiscellaneousErrors);
1709 DAC960_Info(" Timeouts: %d, Retries: %d, "
1710 "Aborts: %d, Predicted: %d\n", Controller,
1711 PhysicalDeviceInfo->CommandTimeouts,
1712 PhysicalDeviceInfo->Retries,
1713 PhysicalDeviceInfo->Aborts,
1714 PhysicalDeviceInfo->PredictedFailuresDetected);
1716 DAC960_Info(" Logical Drives:\n", Controller);
1717 for (LogicalDriveNumber = 0;
1718 LogicalDriveNumber < DAC960_MaxLogicalDrives;
1719 LogicalDriveNumber++)
1721 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
1722 Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
1723 unsigned char *ReadCacheStatus[] = { "Read Cache Disabled",
1724 "Read Cache Enabled",
1725 "Read Ahead Enabled",
1726 "Intelligent Read Ahead Enabled",
1727 "-", "-", "-", "-" };
1728 unsigned char *WriteCacheStatus[] = { "Write Cache Disabled",
1729 "Logical Device Read Only",
1730 "Write Cache Enabled",
1731 "Intelligent Write Cache Enabled",
1732 "-", "-", "-", "-" };
1733 unsigned char *GeometryTranslation;
1734 if (LogicalDeviceInfo == NULL) continue;
1735 switch(LogicalDeviceInfo->DriveGeometry)
1737 case DAC960_V2_Geometry_128_32:
1738 GeometryTranslation = "128/32";
1739 break;
1740 case DAC960_V2_Geometry_255_63:
1741 GeometryTranslation = "255/63";
1742 break;
1743 default:
1744 GeometryTranslation = "Invalid";
1745 DAC960_Error("Illegal Logical Device Geometry %d\n",
1746 Controller, LogicalDeviceInfo->DriveGeometry);
1747 break;
1749 DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %d blocks\n",
1750 Controller, Controller->ControllerNumber, LogicalDriveNumber,
1751 LogicalDeviceInfo->RAIDLevel,
1752 (LogicalDeviceInfo->LogicalDeviceState
1753 == DAC960_V2_LogicalDevice_Online
1754 ? "Online"
1755 : LogicalDeviceInfo->LogicalDeviceState
1756 == DAC960_V2_LogicalDevice_Critical
1757 ? "Critical" : "Offline"),
1758 LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
1759 DAC960_Info(" Logical Device %s, BIOS Geometry: %s\n",
1760 Controller,
1761 (LogicalDeviceInfo->LogicalDeviceControl
1762 .LogicalDeviceInitialized
1763 ? "Initialized" : "Uninitialized"),
1764 GeometryTranslation);
1765 if (LogicalDeviceInfo->StripeSize == 0)
1767 if (LogicalDeviceInfo->CacheLineSize == 0)
1768 DAC960_Info(" Stripe Size: N/A, "
1769 "Segment Size: N/A\n", Controller);
1770 else
1771 DAC960_Info(" Stripe Size: N/A, "
1772 "Segment Size: %dKB\n", Controller,
1773 1 << (LogicalDeviceInfo->CacheLineSize - 2));
1775 else
1777 if (LogicalDeviceInfo->CacheLineSize == 0)
1778 DAC960_Info(" Stripe Size: %dKB, "
1779 "Segment Size: N/A\n", Controller,
1780 1 << (LogicalDeviceInfo->StripeSize - 2));
1781 else
1782 DAC960_Info(" Stripe Size: %dKB, "
1783 "Segment Size: %dKB\n", Controller,
1784 1 << (LogicalDeviceInfo->StripeSize - 2),
1785 1 << (LogicalDeviceInfo->CacheLineSize - 2));
1787 DAC960_Info(" %s, %s\n", Controller,
1788 ReadCacheStatus[
1789 LogicalDeviceInfo->LogicalDeviceControl.ReadCache],
1790 WriteCacheStatus[
1791 LogicalDeviceInfo->LogicalDeviceControl.WriteCache]);
1792 if (LogicalDeviceInfo->SoftErrors > 0 ||
1793 LogicalDeviceInfo->CommandsFailed > 0 ||
1794 LogicalDeviceInfo->DeferredWriteErrors)
1795 DAC960_Info(" Errors - Soft: %d, Failed: %d, "
1796 "Deferred Write: %d\n", Controller,
1797 LogicalDeviceInfo->SoftErrors,
1798 LogicalDeviceInfo->CommandsFailed,
1799 LogicalDeviceInfo->DeferredWriteErrors);
1802 return true;
1807 DAC960_BackMergeFunction is the Back Merge Function for the DAC960 driver.
1810 static int DAC960_BackMergeFunction(RequestQueue_T *RequestQueue,
1811 IO_Request_T *Request,
1812 BufferHeader_T *BufferHeader,
1813 int MaxSegments)
1815 DAC960_Controller_T *Controller =
1816 (DAC960_Controller_T *) RequestQueue->queuedata;
1817 if (Request->bhtail->b_data + Request->bhtail->b_size == BufferHeader->b_data)
1818 return true;
1819 if (Request->nr_segments < MaxSegments &&
1820 Request->nr_segments < Controller->DriverScatterGatherLimit)
1822 Request->nr_segments++;
1823 RequestQueue->elevator.nr_segments++;
1824 return true;
1826 return false;
1831 DAC960_FrontMergeFunction is the Front Merge Function for the DAC960 driver.
1834 static int DAC960_FrontMergeFunction(RequestQueue_T *RequestQueue,
1835 IO_Request_T *Request,
1836 BufferHeader_T *BufferHeader,
1837 int MaxSegments)
1839 DAC960_Controller_T *Controller =
1840 (DAC960_Controller_T *) RequestQueue->queuedata;
1841 if (BufferHeader->b_data + BufferHeader->b_size == Request->bh->b_data)
1842 return true;
1843 if (Request->nr_segments < MaxSegments &&
1844 Request->nr_segments < Controller->DriverScatterGatherLimit)
1846 Request->nr_segments++;
1847 RequestQueue->elevator.nr_segments++;
1848 return true;
1850 return false;
1855 DAC960_MergeRequestsFunction is the Merge Requests Function for the
1856 DAC960 driver.
1859 static int DAC960_MergeRequestsFunction(RequestQueue_T *RequestQueue,
1860 IO_Request_T *Request,
1861 IO_Request_T *NextRequest,
1862 int MaxSegments)
1864 DAC960_Controller_T *Controller =
1865 (DAC960_Controller_T *) RequestQueue->queuedata;
1866 int TotalSegments = Request->nr_segments + NextRequest->nr_segments;
1867 int SameSegment = 0;
1868 if (Request->bhtail->b_data + Request->bhtail->b_size
1869 == NextRequest->bh->b_data)
1871 TotalSegments--;
1872 SameSegment = 1;
1874 if (TotalSegments > MaxSegments ||
1875 TotalSegments > Controller->DriverScatterGatherLimit)
1876 return false;
1877 RequestQueue->elevator.nr_segments -= SameSegment;
1878 Request->nr_segments = TotalSegments;
1879 return true;
1884 DAC960_RegisterBlockDevice registers the Block Device structures
1885 associated with Controller.
1888 static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
1890 int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
1891 GenericDiskInfo_T *GenericDiskInfo;
1892 RequestQueue_T *RequestQueue;
1893 int MinorNumber;
1895 Register the Block Device Major Number for this DAC960 Controller.
1897 if (devfs_register_blkdev(MajorNumber, "dac960",
1898 &DAC960_BlockDeviceOperations) < 0)
1900 DAC960_Error("UNABLE TO ACQUIRE MAJOR NUMBER %d - DETACHING\n",
1901 Controller, MajorNumber);
1902 return false;
1905 Initialize the I/O Request Queue.
1907 RequestQueue = BLK_DEFAULT_QUEUE(MajorNumber);
1908 blk_init_queue(RequestQueue, DAC960_RequestFunction);
1909 blk_queue_headactive(RequestQueue, 0);
1910 RequestQueue->back_merge_fn = DAC960_BackMergeFunction;
1911 RequestQueue->front_merge_fn = DAC960_FrontMergeFunction;
1912 RequestQueue->merge_requests_fn = DAC960_MergeRequestsFunction;
1913 RequestQueue->queuedata = Controller;
1914 Controller->RequestQueue = RequestQueue;
1916 Initialize the Disk Partitions array, Partition Sizes array, Block Sizes
1917 array, and Max Sectors per Request array.
1919 for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++)
1921 Controller->BlockSizes[MinorNumber] = BLOCK_SIZE;
1922 Controller->MaxSectorsPerRequest[MinorNumber] =
1923 Controller->MaxBlocksPerCommand;
1925 Controller->GenericDiskInfo.part = Controller->DiskPartitions;
1926 Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
1927 blksize_size[MajorNumber] = Controller->BlockSizes;
1928 max_sectors[MajorNumber] = Controller->MaxSectorsPerRequest;
1930 Initialize Read Ahead to 128 sectors.
1932 read_ahead[MajorNumber] = 128;
1934 Complete initialization of the Generic Disk Information structure.
1936 Controller->GenericDiskInfo.major = MajorNumber;
1937 Controller->GenericDiskInfo.major_name = "rd";
1938 Controller->GenericDiskInfo.minor_shift = DAC960_MaxPartitionsBits;
1939 Controller->GenericDiskInfo.max_p = DAC960_MaxPartitions;
1940 Controller->GenericDiskInfo.nr_real = Controller->LogicalDriveCount;
1941 Controller->GenericDiskInfo.next = NULL;
1942 Controller->GenericDiskInfo.fops = &DAC960_BlockDeviceOperations;
1944 Install the Generic Disk Information structure at the end of the list.
1946 if ((GenericDiskInfo = gendisk_head) != NULL)
1948 while (GenericDiskInfo->next != NULL)
1949 GenericDiskInfo = GenericDiskInfo->next;
1950 GenericDiskInfo->next = &Controller->GenericDiskInfo;
1952 else gendisk_head = &Controller->GenericDiskInfo;
1954 Indicate the Block Device Registration completed successfully,
1956 return true;
1961 DAC960_UnregisterBlockDevice unregisters the Block Device structures
1962 associated with Controller.
1965 static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller)
1967 int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
1969 Unregister the Block Device Major Number for this DAC960 Controller.
1971 devfs_unregister_blkdev(MajorNumber, "dac960");
1973 Remove the I/O Request Queue.
1975 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MajorNumber));
1977 Remove the Disk Partitions array, Partition Sizes array, Block Sizes
1978 array, Max Sectors per Request array, and Max Segments per Request array.
1980 Controller->GenericDiskInfo.part = NULL;
1981 Controller->GenericDiskInfo.sizes = NULL;
1982 blk_size[MajorNumber] = NULL;
1983 blksize_size[MajorNumber] = NULL;
1984 max_sectors[MajorNumber] = NULL;
1986 Remove the Generic Disk Information structure from the list.
1988 if (gendisk_head != &Controller->GenericDiskInfo)
1990 GenericDiskInfo_T *GenericDiskInfo = gendisk_head;
1991 while (GenericDiskInfo != NULL &&
1992 GenericDiskInfo->next != &Controller->GenericDiskInfo)
1993 GenericDiskInfo = GenericDiskInfo->next;
1994 if (GenericDiskInfo != NULL)
1995 GenericDiskInfo->next = GenericDiskInfo->next->next;
1997 else gendisk_head = Controller->GenericDiskInfo.next;
2002 DAC960_RegisterDisk registers the DAC960 Logical Disk Device for Logical
2003 Drive Number if it exists.
2006 static void DAC960_RegisterDisk(DAC960_Controller_T *Controller,
2007 int LogicalDriveNumber)
2009 if (Controller->FirmwareType == DAC960_V1_Controller)
2011 if (LogicalDriveNumber > Controller->LogicalDriveCount - 1) return;
2012 register_disk(&Controller->GenericDiskInfo,
2013 DAC960_KernelDevice(Controller->ControllerNumber,
2014 LogicalDriveNumber, 0),
2015 DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
2016 Controller->V1.LogicalDriveInformation
2017 [LogicalDriveNumber].LogicalDriveSize);
2019 else
2021 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
2022 Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
2023 if (LogicalDeviceInfo == NULL) return;
2024 register_disk(&Controller->GenericDiskInfo,
2025 DAC960_KernelDevice(Controller->ControllerNumber,
2026 LogicalDriveNumber, 0),
2027 DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
2028 LogicalDeviceInfo
2029 ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
2035 DAC960_ReportErrorStatus reports Controller BIOS Messages passed through
2036 the Error Status Register when the driver performs the BIOS handshaking.
2037 It returns true for fatal errors and false otherwise.
2040 static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
2041 unsigned char ErrorStatus,
2042 unsigned char Parameter0,
2043 unsigned char Parameter1)
2045 switch (ErrorStatus)
2047 case 0x00:
2048 DAC960_Notice("Physical Device %d:%d Not Responding\n",
2049 Controller, Parameter1, Parameter0);
2050 break;
2051 case 0x08:
2052 if (Controller->DriveSpinUpMessageDisplayed) break;
2053 DAC960_Notice("Spinning Up Drives\n", Controller);
2054 Controller->DriveSpinUpMessageDisplayed = true;
2055 break;
2056 case 0x30:
2057 DAC960_Notice("Configuration Checksum Error\n", Controller);
2058 break;
2059 case 0x60:
2060 DAC960_Notice("Mirror Race Recovery Failed\n", Controller);
2061 break;
2062 case 0x70:
2063 DAC960_Notice("Mirror Race Recovery In Progress\n", Controller);
2064 break;
2065 case 0x90:
2066 DAC960_Notice("Physical Device %d:%d COD Mismatch\n",
2067 Controller, Parameter1, Parameter0);
2068 break;
2069 case 0xA0:
2070 DAC960_Notice("Logical Drive Installation Aborted\n", Controller);
2071 break;
2072 case 0xB0:
2073 DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller);
2074 break;
2075 case 0xD0:
2076 DAC960_Notice("New Controller Configuration Found\n", Controller);
2077 break;
2078 case 0xF0:
2079 DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller);
2080 return true;
2081 default:
2082 DAC960_Error("Unknown Initialization Error %02X for Controller at\n",
2083 Controller, ErrorStatus);
2084 return true;
2086 return false;
2091 DAC960_DetectControllers detects Mylex DAC960/AcceleRAID/eXtremeRAID
2092 PCI RAID Controllers by interrogating the PCI Configuration Space for
2093 Controller Type.
2096 static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
2098 void (*InterruptHandler)(int, void *, Registers_T *) = NULL;
2099 DAC960_FirmwareType_T FirmwareType = 0;
2100 unsigned short VendorID = 0, DeviceID = 0;
2101 unsigned int MemoryWindowSize = 0;
2102 PCI_Device_T *PCI_Device = NULL;
2103 switch (HardwareType)
2105 case DAC960_BA_Controller:
2106 VendorID = PCI_VENDOR_ID_MYLEX;
2107 DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_BA;
2108 FirmwareType = DAC960_V2_Controller;
2109 InterruptHandler = DAC960_BA_InterruptHandler;
2110 MemoryWindowSize = DAC960_BA_RegisterWindowSize;
2111 break;
2112 case DAC960_LP_Controller:
2113 VendorID = PCI_VENDOR_ID_MYLEX;
2114 DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_LP;
2115 FirmwareType = DAC960_LP_Controller;
2116 InterruptHandler = DAC960_LP_InterruptHandler;
2117 MemoryWindowSize = DAC960_LP_RegisterWindowSize;
2118 break;
2119 case DAC960_LA_Controller:
2120 VendorID = PCI_VENDOR_ID_DEC;
2121 DeviceID = PCI_DEVICE_ID_DEC_21285;
2122 FirmwareType = DAC960_V1_Controller;
2123 InterruptHandler = DAC960_LA_InterruptHandler;
2124 MemoryWindowSize = DAC960_LA_RegisterWindowSize;
2125 break;
2126 case DAC960_PG_Controller:
2127 VendorID = PCI_VENDOR_ID_MYLEX;
2128 DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PG;
2129 FirmwareType = DAC960_V1_Controller;
2130 InterruptHandler = DAC960_PG_InterruptHandler;
2131 MemoryWindowSize = DAC960_PG_RegisterWindowSize;
2132 break;
2133 case DAC960_PD_Controller:
2134 VendorID = PCI_VENDOR_ID_MYLEX;
2135 DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PD;
2136 FirmwareType = DAC960_V1_Controller;
2137 InterruptHandler = DAC960_PD_InterruptHandler;
2138 MemoryWindowSize = DAC960_PD_RegisterWindowSize;
2139 break;
2141 while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
2143 DAC960_Controller_T *Controller = NULL;
2144 DAC960_IO_Address_T IO_Address = 0;
2145 DAC960_PCI_Address_T PCI_Address = 0;
2146 unsigned char Bus = PCI_Device->bus->number;
2147 unsigned char DeviceFunction = PCI_Device->devfn;
2148 unsigned char Device = DeviceFunction >> 3;
2149 unsigned char Function = DeviceFunction & 0x7;
2150 unsigned char ErrorStatus, Parameter0, Parameter1;
2151 unsigned int IRQ_Channel = PCI_Device->irq;
2152 void *BaseAddress;
2153 if (pci_enable_device(PCI_Device) != 0) continue;
2154 switch (HardwareType)
2156 case DAC960_BA_Controller:
2157 PCI_Address = pci_resource_start(PCI_Device, 0);
2158 break;
2159 case DAC960_LP_Controller:
2160 PCI_Address = pci_resource_start(PCI_Device, 0);
2161 break;
2162 case DAC960_LA_Controller:
2163 if (!(PCI_Device->subsystem_vendor == PCI_VENDOR_ID_MYLEX &&
2164 PCI_Device->subsystem_device == PCI_DEVICE_ID_MYLEX_DAC960_LA))
2165 continue;
2166 PCI_Address = pci_resource_start(PCI_Device, 0);
2167 break;
2168 case DAC960_PG_Controller:
2169 PCI_Address = pci_resource_start(PCI_Device, 0);
2170 break;
2171 case DAC960_PD_Controller:
2172 IO_Address = pci_resource_start(PCI_Device, 0);
2173 PCI_Address = pci_resource_start(PCI_Device, 1);
2174 break;
2176 if (DAC960_ControllerCount == DAC960_MaxControllers)
2178 DAC960_Error("More than %d DAC960 Controllers detected - "
2179 "ignoring from Controller at\n",
2180 NULL, DAC960_MaxControllers);
2181 goto Failure;
2183 Controller = (DAC960_Controller_T *)
2184 kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
2185 if (Controller == NULL)
2187 DAC960_Error("Unable to allocate Controller structure for "
2188 "Controller at\n", NULL);
2189 goto Failure;
2191 memset(Controller, 0, sizeof(DAC960_Controller_T));
2192 Controller->ControllerNumber = DAC960_ControllerCount;
2193 init_waitqueue_head(&Controller->CommandWaitQueue);
2194 init_waitqueue_head(&Controller->HealthStatusWaitQueue);
2195 DAC960_Controllers[DAC960_ControllerCount++] = Controller;
2196 DAC960_AnnounceDriver(Controller);
2197 Controller->FirmwareType = FirmwareType;
2198 Controller->HardwareType = HardwareType;
2199 Controller->IO_Address = IO_Address;
2200 Controller->PCI_Address = PCI_Address;
2201 Controller->Bus = Bus;
2202 Controller->Device = Device;
2203 Controller->Function = Function;
2205 Map the Controller Register Window.
2207 if (MemoryWindowSize < PAGE_SIZE)
2208 MemoryWindowSize = PAGE_SIZE;
2209 Controller->MemoryMappedAddress =
2210 ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
2211 Controller->BaseAddress =
2212 Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
2213 if (Controller->MemoryMappedAddress == NULL)
2215 DAC960_Error("Unable to map Controller Register Window for "
2216 "Controller at\n", Controller);
2217 goto Failure;
2219 BaseAddress = Controller->BaseAddress;
2220 switch (HardwareType)
2222 case DAC960_BA_Controller:
2223 DAC960_BA_DisableInterrupts(Controller->BaseAddress);
2224 DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
2225 udelay(1000);
2226 while (DAC960_BA_InitializationInProgressP(BaseAddress))
2228 if (DAC960_BA_ReadErrorStatus(BaseAddress, &ErrorStatus,
2229 &Parameter0, &Parameter1) &&
2230 DAC960_ReportErrorStatus(Controller, ErrorStatus,
2231 Parameter0, Parameter1))
2232 goto Failure;
2233 udelay(10);
2235 if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
2237 DAC960_Error("Unable to Enable Memory Mailbox Interface "
2238 "for Controller at\n", Controller);
2239 goto Failure;
2241 DAC960_BA_EnableInterrupts(Controller->BaseAddress);
2242 Controller->QueueCommand = DAC960_BA_QueueCommand;
2243 Controller->ReadControllerConfiguration =
2244 DAC960_V2_ReadControllerConfiguration;
2245 Controller->ReadDeviceConfiguration =
2246 DAC960_V2_ReadDeviceConfiguration;
2247 Controller->ReportDeviceConfiguration =
2248 DAC960_V2_ReportDeviceConfiguration;
2249 Controller->QueueReadWriteCommand =
2250 DAC960_V2_QueueReadWriteCommand;
2251 break;
2252 case DAC960_LP_Controller:
2253 DAC960_LP_DisableInterrupts(Controller->BaseAddress);
2254 DAC960_LP_AcknowledgeHardwareMailboxStatus(BaseAddress);
2255 udelay(1000);
2256 while (DAC960_LP_InitializationInProgressP(BaseAddress))
2258 if (DAC960_LP_ReadErrorStatus(BaseAddress, &ErrorStatus,
2259 &Parameter0, &Parameter1) &&
2260 DAC960_ReportErrorStatus(Controller, ErrorStatus,
2261 Parameter0, Parameter1))
2262 goto Failure;
2263 udelay(10);
2265 if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
2267 DAC960_Error("Unable to Enable Memory Mailbox Interface "
2268 "for Controller at\n", Controller);
2269 goto Failure;
2271 DAC960_LP_EnableInterrupts(Controller->BaseAddress);
2272 Controller->QueueCommand = DAC960_LP_QueueCommand;
2273 Controller->ReadControllerConfiguration =
2274 DAC960_V2_ReadControllerConfiguration;
2275 Controller->ReadDeviceConfiguration =
2276 DAC960_V2_ReadDeviceConfiguration;
2277 Controller->ReportDeviceConfiguration =
2278 DAC960_V2_ReportDeviceConfiguration;
2279 Controller->QueueReadWriteCommand =
2280 DAC960_V2_QueueReadWriteCommand;
2281 break;
2282 case DAC960_LA_Controller:
2283 DAC960_LA_DisableInterrupts(Controller->BaseAddress);
2284 DAC960_LA_AcknowledgeHardwareMailboxStatus(BaseAddress);
2285 udelay(1000);
2286 while (DAC960_LA_InitializationInProgressP(BaseAddress))
2288 if (DAC960_LA_ReadErrorStatus(BaseAddress, &ErrorStatus,
2289 &Parameter0, &Parameter1) &&
2290 DAC960_ReportErrorStatus(Controller, ErrorStatus,
2291 Parameter0, Parameter1))
2292 goto Failure;
2293 udelay(10);
2295 if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
2297 DAC960_Error("Unable to Enable Memory Mailbox Interface "
2298 "for Controller at\n", Controller);
2299 goto Failure;
2301 DAC960_LA_EnableInterrupts(Controller->BaseAddress);
2302 if (Controller->V1.DualModeMemoryMailboxInterface)
2303 Controller->QueueCommand = DAC960_LA_QueueCommandDualMode;
2304 else Controller->QueueCommand = DAC960_LA_QueueCommandSingleMode;
2305 Controller->ReadControllerConfiguration =
2306 DAC960_V1_ReadControllerConfiguration;
2307 Controller->ReadDeviceConfiguration =
2308 DAC960_V1_ReadDeviceConfiguration;
2309 Controller->ReportDeviceConfiguration =
2310 DAC960_V1_ReportDeviceConfiguration;
2311 Controller->QueueReadWriteCommand =
2312 DAC960_V1_QueueReadWriteCommand;
2313 break;
2314 case DAC960_PG_Controller:
2315 DAC960_PG_DisableInterrupts(Controller->BaseAddress);
2316 DAC960_PG_AcknowledgeHardwareMailboxStatus(BaseAddress);
2317 udelay(1000);
2318 while (DAC960_PG_InitializationInProgressP(BaseAddress))
2320 if (DAC960_PG_ReadErrorStatus(BaseAddress, &ErrorStatus,
2321 &Parameter0, &Parameter1) &&
2322 DAC960_ReportErrorStatus(Controller, ErrorStatus,
2323 Parameter0, Parameter1))
2324 goto Failure;
2325 udelay(10);
2327 if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
2329 DAC960_Error("Unable to Enable Memory Mailbox Interface "
2330 "for Controller at\n", Controller);
2331 goto Failure;
2333 DAC960_PG_EnableInterrupts(Controller->BaseAddress);
2334 if (Controller->V1.DualModeMemoryMailboxInterface)
2335 Controller->QueueCommand = DAC960_PG_QueueCommandDualMode;
2336 else Controller->QueueCommand = DAC960_PG_QueueCommandSingleMode;
2337 Controller->ReadControllerConfiguration =
2338 DAC960_V1_ReadControllerConfiguration;
2339 Controller->ReadDeviceConfiguration =
2340 DAC960_V1_ReadDeviceConfiguration;
2341 Controller->ReportDeviceConfiguration =
2342 DAC960_V1_ReportDeviceConfiguration;
2343 Controller->QueueReadWriteCommand =
2344 DAC960_V1_QueueReadWriteCommand;
2345 break;
2346 case DAC960_PD_Controller:
2347 request_region(Controller->IO_Address, 0x80,
2348 Controller->FullModelName);
2349 DAC960_PD_DisableInterrupts(BaseAddress);
2350 DAC960_PD_AcknowledgeStatus(BaseAddress);
2351 udelay(1000);
2352 while (DAC960_PD_InitializationInProgressP(BaseAddress))
2354 if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
2355 &Parameter0, &Parameter1) &&
2356 DAC960_ReportErrorStatus(Controller, ErrorStatus,
2357 Parameter0, Parameter1))
2358 goto Failure;
2359 udelay(10);
2361 DAC960_PD_EnableInterrupts(Controller->BaseAddress);
2362 Controller->QueueCommand = DAC960_PD_QueueCommand;
2363 Controller->ReadControllerConfiguration =
2364 DAC960_V1_ReadControllerConfiguration;
2365 Controller->ReadDeviceConfiguration =
2366 DAC960_V1_ReadDeviceConfiguration;
2367 Controller->ReportDeviceConfiguration =
2368 DAC960_V1_ReportDeviceConfiguration;
2369 Controller->QueueReadWriteCommand =
2370 DAC960_V1_QueueReadWriteCommand;
2371 break;
2374 Acquire shared access to the IRQ Channel.
2376 if (IRQ_Channel == 0)
2378 DAC960_Error("IRQ Channel %d illegal for Controller at\n",
2379 Controller, IRQ_Channel);
2380 goto Failure;
2382 strcpy(Controller->FullModelName, "DAC960");
2383 if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
2384 Controller->FullModelName, Controller) < 0)
2386 DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
2387 Controller, IRQ_Channel);
2388 goto Failure;
2390 Controller->IRQ_Channel = IRQ_Channel;
2391 DAC960_ActiveControllerCount++;
2392 Controller->InitialCommand.CommandIdentifier = 1;
2393 Controller->InitialCommand.Controller = Controller;
2394 Controller->Commands[0] = &Controller->InitialCommand;
2395 Controller->FreeCommands = &Controller->InitialCommand;
2396 Controller->ControllerDetectionSuccessful = true;
2397 continue;
2398 Failure:
2399 if (IO_Address == 0)
2400 DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
2401 "PCI Address 0x%X\n", Controller,
2402 Bus, Device, Function, PCI_Address);
2403 else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
2404 "0x%X PCI Address 0x%X\n", Controller,
2405 Bus, Device, Function, IO_Address, PCI_Address);
2406 if (Controller == NULL) break;
2407 if (Controller->MemoryMappedAddress != NULL)
2408 iounmap(Controller->MemoryMappedAddress);
2409 if (Controller->IRQ_Channel > 0)
2410 free_irq(IRQ_Channel, Controller);
2416 DAC960_SortControllers sorts the Controllers by PCI Bus and Device Number.
2419 static void DAC960_SortControllers(void)
2421 int ControllerNumber, LastInterchange, Bound, j;
2422 LastInterchange = DAC960_ControllerCount-1;
2423 while (LastInterchange > 0)
2425 Bound = LastInterchange;
2426 LastInterchange = 0;
2427 for (j = 0; j < Bound; j++)
2429 DAC960_Controller_T *Controller1 = DAC960_Controllers[j];
2430 DAC960_Controller_T *Controller2 = DAC960_Controllers[j+1];
2431 if (Controller1->Bus > Controller2->Bus ||
2432 (Controller1->Bus == Controller2->Bus &&
2433 (Controller1->Device > Controller2->Device)))
2435 Controller2->ControllerNumber = j;
2436 DAC960_Controllers[j] = Controller2;
2437 Controller1->ControllerNumber = j+1;
2438 DAC960_Controllers[j+1] = Controller1;
2439 LastInterchange = j;
2443 for (ControllerNumber = 0;
2444 ControllerNumber < DAC960_ControllerCount;
2445 ControllerNumber++)
2447 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
2448 if (!Controller->ControllerDetectionSuccessful)
2450 DAC960_Controllers[ControllerNumber] = NULL;
2451 kfree(Controller);
2458 DAC960_InitializeController initializes Controller.
2461 static void DAC960_InitializeController(DAC960_Controller_T *Controller)
2463 if (DAC960_ReadControllerConfiguration(Controller) &&
2464 DAC960_ReportControllerConfiguration(Controller) &&
2465 DAC960_CreateAuxiliaryStructures(Controller) &&
2466 DAC960_ReadDeviceConfiguration(Controller) &&
2467 DAC960_ReportDeviceConfiguration(Controller) &&
2468 DAC960_RegisterBlockDevice(Controller))
2471 Initialize the Monitoring Timer.
2473 init_timer(&Controller->MonitoringTimer);
2474 Controller->MonitoringTimer.expires =
2475 jiffies + DAC960_MonitoringTimerInterval;
2476 Controller->MonitoringTimer.data = (unsigned long) Controller;
2477 Controller->MonitoringTimer.function = DAC960_MonitoringTimerFunction;
2478 add_timer(&Controller->MonitoringTimer);
2479 Controller->ControllerInitialized = true;
2481 else DAC960_FinalizeController(Controller);
2486 DAC960_FinalizeController finalizes Controller.
2489 static void DAC960_FinalizeController(DAC960_Controller_T *Controller)
2491 if (Controller->ControllerInitialized)
2493 del_timer(&Controller->MonitoringTimer);
2494 if (Controller->FirmwareType == DAC960_V1_Controller)
2496 DAC960_Notice("Flushing Cache...", Controller);
2497 DAC960_V1_ExecuteType3(Controller, DAC960_V1_Flush, NULL);
2498 DAC960_Notice("done\n", Controller);
2499 switch (Controller->HardwareType)
2501 case DAC960_LA_Controller:
2502 if (Controller->V1.DualModeMemoryMailboxInterface)
2503 free_pages(Controller->MemoryMailboxPagesAddress,
2504 Controller->MemoryMailboxPagesOrder);
2505 else DAC960_LA_SaveMemoryMailboxInfo(Controller);
2506 break;
2507 case DAC960_PG_Controller:
2508 if (Controller->V1.DualModeMemoryMailboxInterface)
2509 free_pages(Controller->MemoryMailboxPagesAddress,
2510 Controller->MemoryMailboxPagesOrder);
2511 else DAC960_PG_SaveMemoryMailboxInfo(Controller);
2512 break;
2513 case DAC960_PD_Controller:
2514 release_region(Controller->IO_Address, 0x80);
2515 break;
2516 default:
2517 break;
2520 else
2522 DAC960_Notice("Flushing Cache...", Controller);
2523 DAC960_V2_DeviceOperation(Controller, DAC960_V2_PauseDevice,
2524 DAC960_V2_RAID_Controller);
2525 DAC960_Notice("done\n", Controller);
2526 free_pages(Controller->MemoryMailboxPagesAddress,
2527 Controller->MemoryMailboxPagesOrder);
2530 free_irq(Controller->IRQ_Channel, Controller);
2531 iounmap(Controller->MemoryMappedAddress);
2532 DAC960_UnregisterBlockDevice(Controller);
2533 DAC960_DestroyAuxiliaryStructures(Controller);
2534 DAC960_Controllers[Controller->ControllerNumber] = NULL;
2535 kfree(Controller);
2540 DAC960_Initialize initializes the DAC960 Driver.
2543 void DAC960_Initialize(void)
2545 int ControllerNumber;
2546 DAC960_DetectControllers(DAC960_BA_Controller);
2547 DAC960_DetectControllers(DAC960_LP_Controller);
2548 DAC960_DetectControllers(DAC960_LA_Controller);
2549 DAC960_DetectControllers(DAC960_PG_Controller);
2550 DAC960_DetectControllers(DAC960_PD_Controller);
2551 DAC960_SortControllers();
2552 if (DAC960_ActiveControllerCount == 0) return;
2553 for (ControllerNumber = 0;
2554 ControllerNumber < DAC960_ControllerCount;
2555 ControllerNumber++)
2557 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
2558 int LogicalDriveNumber;
2559 if (Controller == NULL) continue;
2560 DAC960_InitializeController(Controller);
2561 for (LogicalDriveNumber = 0;
2562 LogicalDriveNumber < DAC960_MaxLogicalDrives;
2563 LogicalDriveNumber++)
2564 DAC960_RegisterDisk(Controller, LogicalDriveNumber);
2566 DAC960_CreateProcEntries();
2567 register_reboot_notifier(&DAC960_NotifierBlock);
2572 DAC960_Finalize finalizes the DAC960 Driver.
2575 static int DAC960_Finalize(NotifierBlock_T *NotifierBlock,
2576 unsigned long Event,
2577 void *Buffer)
2579 int ControllerNumber;
2580 if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
2581 return NOTIFY_DONE;
2582 if (DAC960_ActiveControllerCount == 0) return NOTIFY_OK;
2583 for (ControllerNumber = 0;
2584 ControllerNumber < DAC960_ControllerCount;
2585 ControllerNumber++)
2586 if (DAC960_Controllers[ControllerNumber] != NULL)
2587 DAC960_FinalizeController(DAC960_Controllers[ControllerNumber]);
2588 DAC960_DestroyProcEntries();
2589 unregister_reboot_notifier(&DAC960_NotifierBlock);
2590 return NOTIFY_OK;
2595 DAC960_V1_QueueReadWriteCommand prepares and queues a Read/Write Command for
2596 DAC960 V1 Firmware Controllers.
2599 static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command)
2601 DAC960_Controller_T *Controller = Command->Controller;
2602 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
2603 DAC960_V1_ClearCommand(Command);
2604 if (Command->SegmentCount == 1)
2606 if (Command->CommandType == DAC960_ReadCommand)
2607 CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
2608 else CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
2609 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
2610 CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
2611 CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
2612 CommandMailbox->Type5.BusAddress = Virtual_to_Bus(Command->RequestBuffer);
2614 else
2616 DAC960_V1_ScatterGatherSegment_T
2617 *ScatterGatherList = Command->V1.ScatterGatherList;
2618 BufferHeader_T *BufferHeader = Command->BufferHeader;
2619 char *LastDataEndPointer = NULL;
2620 int SegmentNumber = 0;
2621 if (Command->CommandType == DAC960_ReadCommand)
2622 CommandMailbox->Type5.CommandOpcode =
2623 DAC960_V1_ReadWithOldScatterGather;
2624 else
2625 CommandMailbox->Type5.CommandOpcode =
2626 DAC960_V1_WriteWithOldScatterGather;
2627 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
2628 CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
2629 CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
2630 CommandMailbox->Type5.BusAddress = Virtual_to_Bus(ScatterGatherList);
2631 CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount;
2632 while (BufferHeader != NULL)
2634 if (BufferHeader->b_data == LastDataEndPointer)
2636 ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
2637 BufferHeader->b_size;
2638 LastDataEndPointer += BufferHeader->b_size;
2640 else
2642 ScatterGatherList[SegmentNumber].SegmentDataPointer =
2643 Virtual_to_Bus(BufferHeader->b_data);
2644 ScatterGatherList[SegmentNumber].SegmentByteCount =
2645 BufferHeader->b_size;
2646 LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
2647 if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
2648 panic("DAC960: Scatter/Gather Segment Overflow\n");
2650 BufferHeader = BufferHeader->b_reqnext;
2652 if (SegmentNumber != Command->SegmentCount)
2653 panic("DAC960: SegmentNumber != SegmentCount\n");
2655 DAC960_QueueCommand(Command);
2660 DAC960_V2_QueueReadWriteCommand prepares and queues a Read/Write Command for
2661 DAC960 V2 Firmware Controllers.
2664 static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
2666 DAC960_Controller_T *Controller = Command->Controller;
2667 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
2668 DAC960_V2_ClearCommand(Command);
2669 CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10;
2670 CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost =
2671 (Command->CommandType == DAC960_ReadCommand);
2672 CommandMailbox->SCSI_10.DataTransferSize =
2673 Command->BlockCount << DAC960_BlockSizeBits;
2674 CommandMailbox->SCSI_10.RequestSenseBusAddress =
2675 Virtual_to_Bus(&Command->V2.RequestSense);
2676 CommandMailbox->SCSI_10.PhysicalDevice =
2677 Controller->V2.LogicalDriveToVirtualDevice[Command->LogicalDriveNumber];
2678 CommandMailbox->SCSI_10.RequestSenseSize =
2679 sizeof(DAC960_SCSI_RequestSense_T);
2680 CommandMailbox->SCSI_10.CDBLength = 10;
2681 CommandMailbox->SCSI_10.SCSI_CDB[0] =
2682 (Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A);
2683 CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
2684 CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
2685 CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
2686 CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
2687 CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
2688 CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
2689 if (Command->SegmentCount == 1)
2691 CommandMailbox->SCSI_10.DataTransferMemoryAddress
2692 .ScatterGatherSegments[0]
2693 .SegmentDataPointer =
2694 Virtual_to_Bus(Command->RequestBuffer);
2695 CommandMailbox->SCSI_10.DataTransferMemoryAddress
2696 .ScatterGatherSegments[0]
2697 .SegmentByteCount =
2698 CommandMailbox->SCSI_10.DataTransferSize;
2700 else
2702 DAC960_V2_ScatterGatherSegment_T
2703 *ScatterGatherList = Command->V2.ScatterGatherList;
2704 BufferHeader_T *BufferHeader = Command->BufferHeader;
2705 char *LastDataEndPointer = NULL;
2706 int SegmentNumber = 0;
2707 if (Command->SegmentCount > 2)
2709 CommandMailbox->SCSI_10.CommandControlBits
2710 .AdditionalScatterGatherListMemory = true;
2711 CommandMailbox->SCSI_10.DataTransferMemoryAddress
2712 .ExtendedScatterGather.ScatterGatherList0Length =
2713 Command->SegmentCount;
2714 CommandMailbox->SCSI_10.DataTransferMemoryAddress
2715 .ExtendedScatterGather.ScatterGatherList0Address =
2716 Virtual_to_Bus(ScatterGatherList);
2718 else
2719 ScatterGatherList =
2720 CommandMailbox->SCSI_10.DataTransferMemoryAddress
2721 .ScatterGatherSegments;
2722 while (BufferHeader != NULL)
2724 if (BufferHeader->b_data == LastDataEndPointer)
2726 ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
2727 BufferHeader->b_size;
2728 LastDataEndPointer += BufferHeader->b_size;
2730 else
2732 ScatterGatherList[SegmentNumber].SegmentDataPointer =
2733 Virtual_to_Bus(BufferHeader->b_data);
2734 ScatterGatherList[SegmentNumber].SegmentByteCount =
2735 BufferHeader->b_size;
2736 LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
2737 if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
2738 panic("DAC960: Scatter/Gather Segment Overflow\n");
2740 BufferHeader = BufferHeader->b_reqnext;
2742 if (SegmentNumber != Command->SegmentCount)
2743 panic("DAC960: SegmentNumber != SegmentCount\n");
2745 DAC960_QueueCommand(Command);
2750 DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
2751 I/O Request Queue and queues it to the Controller. WaitForCommand is true if
2752 this function should wait for a Command to become available if necessary.
2753 This function returns true if an I/O Request was queued and false otherwise.
2756 static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
2757 boolean WaitForCommand)
2759 RequestQueue_T *RequestQueue = Controller->RequestQueue;
2760 ListHead_T *RequestQueueHead;
2761 IO_Request_T *Request;
2762 DAC960_Command_T *Command;
2763 if (RequestQueue == NULL) return false;
2764 RequestQueueHead = &RequestQueue->queue_head;
2765 while (true)
2767 if (list_empty(RequestQueueHead)) return false;
2768 Request = blkdev_entry_next_request(RequestQueueHead);
2769 Command = DAC960_AllocateCommand(Controller);
2770 if (Command != NULL) break;
2771 if (!WaitForCommand) return false;
2772 DAC960_WaitForCommand(Controller);
2774 if (Request->cmd == READ)
2775 Command->CommandType = DAC960_ReadCommand;
2776 else Command->CommandType = DAC960_WriteCommand;
2777 Command->Semaphore = Request->sem;
2778 Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
2779 Command->BlockNumber =
2780 Request->sector
2781 + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
2782 Command->BlockCount = Request->nr_sectors;
2783 Command->SegmentCount = Request->nr_segments;
2784 Command->BufferHeader = Request->bh;
2785 Command->RequestBuffer = Request->buffer;
2786 blkdev_dequeue_request(Request);
2787 blkdev_release_request(Request);
2788 DAC960_QueueReadWriteCommand(Command);
2789 return true;
2794 DAC960_ProcessRequests attempts to remove as many I/O Requests as possible
2795 from Controller's I/O Request Queue and queue them to the Controller.
2798 static inline void DAC960_ProcessRequests(DAC960_Controller_T *Controller)
2800 int Counter = 0;
2801 while (DAC960_ProcessRequest(Controller, Counter++ == 0)) ;
2806 DAC960_RequestFunction is the I/O Request Function for DAC960 Controllers.
2809 static void DAC960_RequestFunction(RequestQueue_T *RequestQueue)
2811 DAC960_Controller_T *Controller =
2812 (DAC960_Controller_T *) RequestQueue->queuedata;
2813 ProcessorFlags_T ProcessorFlags;
2815 Acquire exclusive access to Controller.
2817 DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
2819 Process I/O Requests for Controller.
2821 DAC960_ProcessRequests(Controller);
2823 Release exclusive access to Controller.
2825 DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
2830 DAC960_ProcessCompletedBuffer performs completion processing for an
2831 individual Buffer.
2834 static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
2835 boolean SuccessfulIO)
2837 BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
2842 DAC960_V1_ReadWriteError prints an appropriate error message for Command
2843 when an error occurs on a Read or Write operation.
2846 static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command)
2848 DAC960_Controller_T *Controller = Command->Controller;
2849 unsigned char *CommandName = "UNKNOWN";
2850 switch (Command->CommandType)
2852 case DAC960_ReadCommand:
2853 case DAC960_ReadRetryCommand:
2854 CommandName = "READ";
2855 break;
2856 case DAC960_WriteCommand:
2857 case DAC960_WriteRetryCommand:
2858 CommandName = "WRITE";
2859 break;
2860 case DAC960_MonitoringCommand:
2861 case DAC960_ImmediateCommand:
2862 case DAC960_QueuedCommand:
2863 break;
2865 switch (Command->V1.CommandStatus)
2867 case DAC960_V1_IrrecoverableDataError:
2868 DAC960_Error("Irrecoverable Data Error on %s:\n",
2869 Controller, CommandName);
2870 break;
2871 case DAC960_V1_LogicalDriveNonexistentOrOffline:
2872 DAC960_Error("Logical Drive Nonexistent or Offline on %s:\n",
2873 Controller, CommandName);
2874 break;
2875 case DAC960_V1_AccessBeyondEndOfLogicalDrive:
2876 DAC960_Error("Attempt to Access Beyond End of Logical Drive "
2877 "on %s:\n", Controller, CommandName);
2878 break;
2879 case DAC960_V1_BadDataEncountered:
2880 DAC960_Error("Bad Data Encountered on %s:\n", Controller, CommandName);
2881 break;
2882 default:
2883 DAC960_Error("Unexpected Error Status %04X on %s:\n",
2884 Controller, Command->V1.CommandStatus, CommandName);
2885 break;
2887 DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %d..%d\n",
2888 Controller, Controller->ControllerNumber,
2889 Command->LogicalDriveNumber, Command->BlockNumber,
2890 Command->BlockNumber + Command->BlockCount - 1);
2891 if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
2892 DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
2893 Controller, Controller->ControllerNumber,
2894 Command->LogicalDriveNumber,
2895 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
2896 Command->BufferHeader->b_rsector,
2897 Command->BufferHeader->b_rsector + Command->BlockCount - 1);
2902 DAC960_V1_ProcessCompletedCommand performs completion processing for Command
2903 for DAC960 V1 Firmware Controllers.
2906 static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
2908 DAC960_Controller_T *Controller = Command->Controller;
2909 DAC960_CommandType_T CommandType = Command->CommandType;
2910 DAC960_V1_CommandOpcode_T CommandOpcode =
2911 Command->V1.CommandMailbox.Common.CommandOpcode;
2912 DAC960_V1_CommandStatus_T CommandStatus = Command->V1.CommandStatus;
2913 BufferHeader_T *BufferHeader = Command->BufferHeader;
2914 if (CommandType == DAC960_ReadCommand ||
2915 CommandType == DAC960_WriteCommand)
2917 if (CommandStatus == DAC960_V1_NormalCompletion)
2920 Perform completion processing for all buffers in this I/O Request.
2922 while (BufferHeader != NULL)
2924 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
2925 BufferHeader->b_reqnext = NULL;
2926 DAC960_ProcessCompletedBuffer(BufferHeader, true);
2927 BufferHeader = NextBufferHeader;
2930 Wake up requestor for swap file paging requests.
2932 if (Command->Semaphore != NULL)
2934 up(Command->Semaphore);
2935 Command->Semaphore = NULL;
2937 add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
2939 else if ((CommandStatus == DAC960_V1_IrrecoverableDataError ||
2940 CommandStatus == DAC960_V1_BadDataEncountered) &&
2941 BufferHeader != NULL &&
2942 BufferHeader->b_reqnext != NULL)
2944 DAC960_V1_CommandMailbox_T *CommandMailbox =
2945 &Command->V1.CommandMailbox;
2946 if (CommandType == DAC960_ReadCommand)
2948 Command->CommandType = DAC960_ReadRetryCommand;
2949 CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
2951 else
2953 Command->CommandType = DAC960_WriteRetryCommand;
2954 CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
2956 Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
2957 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
2958 CommandMailbox->Type5.BusAddress =
2959 Virtual_to_Bus(BufferHeader->b_data);
2960 DAC960_QueueCommand(Command);
2961 return;
2963 else
2965 if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
2966 DAC960_V1_ReadWriteError(Command);
2968 Perform completion processing for all buffers in this I/O Request.
2970 while (BufferHeader != NULL)
2972 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
2973 BufferHeader->b_reqnext = NULL;
2974 DAC960_ProcessCompletedBuffer(BufferHeader, false);
2975 BufferHeader = NextBufferHeader;
2978 Wake up requestor for swap file paging requests.
2980 if (Command->Semaphore != NULL)
2982 up(Command->Semaphore);
2983 Command->Semaphore = NULL;
2987 else if (CommandType == DAC960_ReadRetryCommand ||
2988 CommandType == DAC960_WriteRetryCommand)
2990 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
2991 BufferHeader->b_reqnext = NULL;
2993 Perform completion processing for this single buffer.
2995 if (CommandStatus == DAC960_V1_NormalCompletion)
2996 DAC960_ProcessCompletedBuffer(BufferHeader, true);
2997 else
2999 if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
3000 DAC960_V1_ReadWriteError(Command);
3001 DAC960_ProcessCompletedBuffer(BufferHeader, false);
3003 if (NextBufferHeader != NULL)
3005 DAC960_V1_CommandMailbox_T *CommandMailbox =
3006 &Command->V1.CommandMailbox;
3007 Command->BlockNumber +=
3008 BufferHeader->b_size >> DAC960_BlockSizeBits;
3009 Command->BlockCount =
3010 NextBufferHeader->b_size >> DAC960_BlockSizeBits;
3011 Command->BufferHeader = NextBufferHeader;
3012 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
3013 CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
3014 CommandMailbox->Type5.BusAddress =
3015 Virtual_to_Bus(NextBufferHeader->b_data);
3016 DAC960_QueueCommand(Command);
3017 return;
3020 else if (CommandType == DAC960_MonitoringCommand ||
3021 CommandOpcode == DAC960_V1_Enquiry ||
3022 CommandOpcode == DAC960_V1_GetRebuildProgress)
3024 if (CommandType != DAC960_MonitoringCommand)
3026 if (CommandOpcode == DAC960_V1_Enquiry)
3027 memcpy(&Controller->V1.NewEnquiry,
3028 Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress),
3029 sizeof(DAC960_V1_Enquiry_T));
3030 else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
3031 memcpy(&Controller->V1.RebuildProgress,
3032 Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress),
3033 sizeof(DAC960_V1_RebuildProgress_T));
3035 if (CommandOpcode == DAC960_V1_Enquiry &&
3036 Controller->ControllerInitialized)
3038 DAC960_V1_Enquiry_T *OldEnquiry = &Controller->V1.Enquiry;
3039 DAC960_V1_Enquiry_T *NewEnquiry = &Controller->V1.NewEnquiry;
3040 unsigned int OldCriticalLogicalDriveCount =
3041 OldEnquiry->CriticalLogicalDriveCount;
3042 unsigned int NewCriticalLogicalDriveCount =
3043 NewEnquiry->CriticalLogicalDriveCount;
3044 if (NewEnquiry->NumberOfLogicalDrives > Controller->LogicalDriveCount)
3046 int LogicalDriveNumber = Controller->LogicalDriveCount;
3047 while (LogicalDriveNumber < NewEnquiry->NumberOfLogicalDrives)
3049 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
3050 "Now Exists\n", Controller,
3051 LogicalDriveNumber,
3052 Controller->ControllerNumber,
3053 LogicalDriveNumber);
3054 LogicalDriveNumber++;
3056 Controller->LogicalDriveCount = LogicalDriveNumber;
3058 if (NewEnquiry->StatusFlags.DeferredWriteError !=
3059 OldEnquiry->StatusFlags.DeferredWriteError)
3060 DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
3061 (NewEnquiry->StatusFlags.DeferredWriteError
3062 ? "TRUE" : "FALSE"));
3063 if ((NewCriticalLogicalDriveCount > 0 ||
3064 NewCriticalLogicalDriveCount != OldCriticalLogicalDriveCount) ||
3065 (NewEnquiry->OfflineLogicalDriveCount > 0 ||
3066 NewEnquiry->OfflineLogicalDriveCount !=
3067 OldEnquiry->OfflineLogicalDriveCount) ||
3068 (NewEnquiry->DeadDriveCount > 0 ||
3069 NewEnquiry->DeadDriveCount !=
3070 OldEnquiry->DeadDriveCount) ||
3071 (NewEnquiry->EventLogSequenceNumber !=
3072 OldEnquiry->EventLogSequenceNumber) ||
3073 Controller->MonitoringTimerCount == 0 ||
3074 (jiffies - Controller->SecondaryMonitoringTime
3075 >= DAC960_SecondaryMonitoringInterval))
3077 Controller->V1.NeedLogicalDriveInformation = true;
3078 Controller->V1.NewEventLogSequenceNumber =
3079 NewEnquiry->EventLogSequenceNumber;
3080 Controller->V1.NeedErrorTableInformation = true;
3081 Controller->V1.NeedDeviceStateInformation = true;
3082 Controller->V1.DeviceStateChannel = 0;
3083 Controller->V1.DeviceStateTargetID = -1;
3084 Controller->SecondaryMonitoringTime = jiffies;
3086 if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
3087 NewEnquiry->RebuildFlag
3088 == DAC960_V1_BackgroundRebuildInProgress ||
3089 OldEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
3090 OldEnquiry->RebuildFlag == DAC960_V1_BackgroundRebuildInProgress)
3092 Controller->V1.NeedRebuildProgress = true;
3093 Controller->V1.RebuildProgressFirst =
3094 (NewEnquiry->CriticalLogicalDriveCount <
3095 OldEnquiry->CriticalLogicalDriveCount);
3097 if (OldEnquiry->RebuildFlag == DAC960_V1_BackgroundCheckInProgress)
3098 switch (NewEnquiry->RebuildFlag)
3100 case DAC960_V1_NoStandbyRebuildOrCheckInProgress:
3101 DAC960_Progress("Consistency Check Completed Successfully\n",
3102 Controller);
3103 break;
3104 case DAC960_V1_StandbyRebuildInProgress:
3105 case DAC960_V1_BackgroundRebuildInProgress:
3106 break;
3107 case DAC960_V1_BackgroundCheckInProgress:
3108 Controller->V1.NeedConsistencyCheckProgress = true;
3109 break;
3110 case DAC960_V1_StandbyRebuildCompletedWithError:
3111 DAC960_Progress("Consistency Check Completed with Error\n",
3112 Controller);
3113 break;
3114 case DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed:
3115 DAC960_Progress("Consistency Check Failed - "
3116 "Physical Device Failed\n", Controller);
3117 break;
3118 case DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
3119 DAC960_Progress("Consistency Check Failed - "
3120 "Logical Drive Failed\n", Controller);
3121 break;
3122 case DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses:
3123 DAC960_Progress("Consistency Check Failed - Other Causes\n",
3124 Controller);
3125 break;
3126 case DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated:
3127 DAC960_Progress("Consistency Check Successfully Terminated\n",
3128 Controller);
3129 break;
3131 else if (NewEnquiry->RebuildFlag
3132 == DAC960_V1_BackgroundCheckInProgress)
3133 Controller->V1.NeedConsistencyCheckProgress = true;
3134 Controller->MonitoringAlertMode =
3135 (NewEnquiry->CriticalLogicalDriveCount > 0 ||
3136 NewEnquiry->OfflineLogicalDriveCount > 0 ||
3137 NewEnquiry->DeadDriveCount > 0);
3138 if (CommandType != DAC960_MonitoringCommand &&
3139 Controller->V1.RebuildFlagPending)
3141 DAC960_V1_Enquiry_T *Enquiry = (DAC960_V1_Enquiry_T *)
3142 Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress);
3143 Enquiry->RebuildFlag = Controller->V1.PendingRebuildFlag;
3144 Controller->V1.RebuildFlagPending = false;
3146 else if (CommandType == DAC960_MonitoringCommand &&
3147 NewEnquiry->RebuildFlag >
3148 DAC960_V1_BackgroundCheckInProgress)
3150 Controller->V1.PendingRebuildFlag = NewEnquiry->RebuildFlag;
3151 Controller->V1.RebuildFlagPending = true;
3153 memcpy(&Controller->V1.Enquiry, &Controller->V1.NewEnquiry,
3154 sizeof(DAC960_V1_Enquiry_T));
3156 else if (CommandOpcode == DAC960_V1_PerformEventLogOperation)
3158 static char
3159 *DAC960_EventMessages[] =
3160 { "killed because write recovery failed",
3161 "killed because of SCSI bus reset failure",
3162 "killed because of double check condition",
3163 "killed because it was removed",
3164 "killed because of gross error on SCSI chip",
3165 "killed because of bad tag returned from drive",
3166 "killed because of timeout on SCSI command",
3167 "killed because of reset SCSI command issued from system",
3168 "killed because busy or parity error count exceeded limit",
3169 "killed because of 'kill drive' command from system",
3170 "killed because of selection timeout",
3171 "killed due to SCSI phase sequence error",
3172 "killed due to unknown status" };
3173 DAC960_V1_EventLogEntry_T *EventLogEntry =
3174 &Controller->V1.EventLogEntry;
3175 if (EventLogEntry->SequenceNumber ==
3176 Controller->V1.OldEventLogSequenceNumber)
3178 unsigned char SenseKey = EventLogEntry->SenseKey;
3179 unsigned char AdditionalSenseCode =
3180 EventLogEntry->AdditionalSenseCode;
3181 unsigned char AdditionalSenseCodeQualifier =
3182 EventLogEntry->AdditionalSenseCodeQualifier;
3183 if (SenseKey == DAC960_SenseKey_VendorSpecific &&
3184 AdditionalSenseCode == 0x80 &&
3185 AdditionalSenseCodeQualifier <
3186 sizeof(DAC960_EventMessages) / sizeof(char *))
3187 DAC960_Critical("Physical Device %d:%d %s\n", Controller,
3188 EventLogEntry->Channel,
3189 EventLogEntry->TargetID,
3190 DAC960_EventMessages[
3191 AdditionalSenseCodeQualifier]);
3192 else if (SenseKey == DAC960_SenseKey_UnitAttention &&
3193 AdditionalSenseCode == 0x29)
3195 if (Controller->MonitoringTimerCount > 0)
3196 Controller->V1.DeviceResetCount[EventLogEntry->Channel]
3197 [EventLogEntry->TargetID]++;
3199 else if (!(SenseKey == DAC960_SenseKey_NoSense ||
3200 (SenseKey == DAC960_SenseKey_NotReady &&
3201 AdditionalSenseCode == 0x04 &&
3202 (AdditionalSenseCodeQualifier == 0x01 ||
3203 AdditionalSenseCodeQualifier == 0x02))))
3205 DAC960_Critical("Physical Device %d:%d Error Log: "
3206 "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
3207 Controller,
3208 EventLogEntry->Channel,
3209 EventLogEntry->TargetID,
3210 SenseKey,
3211 AdditionalSenseCode,
3212 AdditionalSenseCodeQualifier);
3213 DAC960_Critical("Physical Device %d:%d Error Log: "
3214 "Information = %02X%02X%02X%02X "
3215 "%02X%02X%02X%02X\n",
3216 Controller,
3217 EventLogEntry->Channel,
3218 EventLogEntry->TargetID,
3219 EventLogEntry->Information[0],
3220 EventLogEntry->Information[1],
3221 EventLogEntry->Information[2],
3222 EventLogEntry->Information[3],
3223 EventLogEntry->CommandSpecificInformation[0],
3224 EventLogEntry->CommandSpecificInformation[1],
3225 EventLogEntry->CommandSpecificInformation[2],
3226 EventLogEntry->CommandSpecificInformation[3]);
3229 Controller->V1.OldEventLogSequenceNumber++;
3231 else if (CommandOpcode == DAC960_V1_GetErrorTable)
3233 DAC960_V1_ErrorTable_T *OldErrorTable = &Controller->V1.ErrorTable;
3234 DAC960_V1_ErrorTable_T *NewErrorTable = &Controller->V1.NewErrorTable;
3235 int Channel, TargetID;
3236 for (Channel = 0; Channel < Controller->Channels; Channel++)
3237 for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
3239 DAC960_V1_ErrorTableEntry_T *NewErrorEntry =
3240 &NewErrorTable->ErrorTableEntries[Channel][TargetID];
3241 DAC960_V1_ErrorTableEntry_T *OldErrorEntry =
3242 &OldErrorTable->ErrorTableEntries[Channel][TargetID];
3243 if ((NewErrorEntry->ParityErrorCount !=
3244 OldErrorEntry->ParityErrorCount) ||
3245 (NewErrorEntry->SoftErrorCount !=
3246 OldErrorEntry->SoftErrorCount) ||
3247 (NewErrorEntry->HardErrorCount !=
3248 OldErrorEntry->HardErrorCount) ||
3249 (NewErrorEntry->MiscErrorCount !=
3250 OldErrorEntry->MiscErrorCount))
3251 DAC960_Critical("Physical Device %d:%d Errors: "
3252 "Parity = %d, Soft = %d, "
3253 "Hard = %d, Misc = %d\n",
3254 Controller, Channel, TargetID,
3255 NewErrorEntry->ParityErrorCount,
3256 NewErrorEntry->SoftErrorCount,
3257 NewErrorEntry->HardErrorCount,
3258 NewErrorEntry->MiscErrorCount);
3260 memcpy(&Controller->V1.ErrorTable, &Controller->V1.NewErrorTable,
3261 sizeof(DAC960_V1_ErrorTable_T));
3263 else if (CommandOpcode == DAC960_V1_GetDeviceState)
3265 DAC960_V1_DeviceState_T *OldDeviceState =
3266 &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
3267 [Controller->V1.DeviceStateTargetID];
3268 DAC960_V1_DeviceState_T *NewDeviceState =
3269 &Controller->V1.NewDeviceState;
3270 if (NewDeviceState->DeviceState != OldDeviceState->DeviceState)
3271 DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
3272 Controller->V1.DeviceStateChannel,
3273 Controller->V1.DeviceStateTargetID,
3274 (NewDeviceState->DeviceState
3275 == DAC960_V1_Device_Dead
3276 ? "DEAD"
3277 : NewDeviceState->DeviceState
3278 == DAC960_V1_Device_WriteOnly
3279 ? "WRITE-ONLY"
3280 : NewDeviceState->DeviceState
3281 == DAC960_V1_Device_Online
3282 ? "ONLINE" : "STANDBY"));
3283 if (OldDeviceState->DeviceState == DAC960_V1_Device_Dead &&
3284 NewDeviceState->DeviceState != DAC960_V1_Device_Dead)
3286 Controller->V1.NeedDeviceInquiryInformation = true;
3287 Controller->V1.NeedDeviceSerialNumberInformation = true;
3289 memcpy(OldDeviceState, NewDeviceState,
3290 sizeof(DAC960_V1_DeviceState_T));
3292 else if (CommandOpcode == DAC960_V1_GetLogicalDriveInformation)
3294 int LogicalDriveNumber;
3295 for (LogicalDriveNumber = 0;
3296 LogicalDriveNumber < Controller->LogicalDriveCount;
3297 LogicalDriveNumber++)
3299 DAC960_V1_LogicalDriveInformation_T *OldLogicalDriveInformation =
3300 &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
3301 DAC960_V1_LogicalDriveInformation_T *NewLogicalDriveInformation =
3302 &Controller->V1.NewLogicalDriveInformation[LogicalDriveNumber];
3303 if (NewLogicalDriveInformation->LogicalDriveState !=
3304 OldLogicalDriveInformation->LogicalDriveState)
3305 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
3306 "is now %s\n", Controller,
3307 LogicalDriveNumber,
3308 Controller->ControllerNumber,
3309 LogicalDriveNumber,
3310 (NewLogicalDriveInformation->LogicalDriveState
3311 == DAC960_V1_LogicalDrive_Online
3312 ? "ONLINE"
3313 : NewLogicalDriveInformation->LogicalDriveState
3314 == DAC960_V1_LogicalDrive_Critical
3315 ? "CRITICAL" : "OFFLINE"));
3316 if (NewLogicalDriveInformation->WriteBack !=
3317 OldLogicalDriveInformation->WriteBack)
3318 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
3319 "is now %s\n", Controller,
3320 LogicalDriveNumber,
3321 Controller->ControllerNumber,
3322 LogicalDriveNumber,
3323 (NewLogicalDriveInformation->WriteBack
3324 ? "WRITE BACK" : "WRITE THRU"));
3326 memcpy(&Controller->V1.LogicalDriveInformation,
3327 &Controller->V1.NewLogicalDriveInformation,
3328 sizeof(DAC960_V1_LogicalDriveInformationArray_T));
3330 else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
3332 unsigned int LogicalDriveNumber =
3333 Controller->V1.RebuildProgress.LogicalDriveNumber;
3334 unsigned int LogicalDriveSize =
3335 Controller->V1.RebuildProgress.LogicalDriveSize;
3336 unsigned int BlocksCompleted =
3337 LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
3338 if (CommandStatus == DAC960_V1_NoRebuildOrCheckInProgress &&
3339 Controller->V1.LastRebuildStatus == DAC960_V1_NormalCompletion)
3340 CommandStatus = DAC960_V1_RebuildSuccessful;
3341 switch (CommandStatus)
3343 case DAC960_V1_NormalCompletion:
3344 Controller->EphemeralProgressMessage = true;
3345 DAC960_Progress("Rebuild in Progress: "
3346 "Logical Drive %d (/dev/rd/c%dd%d) "
3347 "%d%% completed\n",
3348 Controller, LogicalDriveNumber,
3349 Controller->ControllerNumber,
3350 LogicalDriveNumber,
3351 (100 * (BlocksCompleted >> 7))
3352 / (LogicalDriveSize >> 7));
3353 Controller->EphemeralProgressMessage = false;
3354 break;
3355 case DAC960_V1_RebuildFailed_LogicalDriveFailure:
3356 DAC960_Progress("Rebuild Failed due to "
3357 "Logical Drive Failure\n", Controller);
3358 break;
3359 case DAC960_V1_RebuildFailed_BadBlocksOnOther:
3360 DAC960_Progress("Rebuild Failed due to "
3361 "Bad Blocks on Other Drives\n", Controller);
3362 break;
3363 case DAC960_V1_RebuildFailed_NewDriveFailed:
3364 DAC960_Progress("Rebuild Failed due to "
3365 "Failure of Drive Being Rebuilt\n", Controller);
3366 break;
3367 case DAC960_V1_NoRebuildOrCheckInProgress:
3368 break;
3369 case DAC960_V1_RebuildSuccessful:
3370 DAC960_Progress("Rebuild Completed Successfully\n", Controller);
3371 break;
3372 case DAC960_V1_RebuildSuccessfullyTerminated:
3373 DAC960_Progress("Rebuild Successfully Terminated\n", Controller);
3374 break;
3376 Controller->V1.LastRebuildStatus = CommandStatus;
3377 if (CommandType != DAC960_MonitoringCommand &&
3378 Controller->V1.RebuildStatusPending)
3380 Command->V1.CommandStatus = Controller->V1.PendingRebuildStatus;
3381 Controller->V1.RebuildStatusPending = false;
3383 else if (CommandType == DAC960_MonitoringCommand &&
3384 CommandStatus != DAC960_V1_NormalCompletion &&
3385 CommandStatus != DAC960_V1_NoRebuildOrCheckInProgress)
3387 Controller->V1.PendingRebuildStatus = CommandStatus;
3388 Controller->V1.RebuildStatusPending = true;
3391 else if (CommandOpcode == DAC960_V1_RebuildStat)
3393 unsigned int LogicalDriveNumber =
3394 Controller->V1.RebuildProgress.LogicalDriveNumber;
3395 unsigned int LogicalDriveSize =
3396 Controller->V1.RebuildProgress.LogicalDriveSize;
3397 unsigned int BlocksCompleted =
3398 LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
3399 if (CommandStatus == DAC960_V1_NormalCompletion)
3401 Controller->EphemeralProgressMessage = true;
3402 DAC960_Progress("Consistency Check in Progress: "
3403 "Logical Drive %d (/dev/rd/c%dd%d) "
3404 "%d%% completed\n",
3405 Controller, LogicalDriveNumber,
3406 Controller->ControllerNumber,
3407 LogicalDriveNumber,
3408 (100 * (BlocksCompleted >> 7))
3409 / (LogicalDriveSize >> 7));
3410 Controller->EphemeralProgressMessage = false;
3414 if (CommandType == DAC960_MonitoringCommand)
3416 if (Controller->V1.NewEventLogSequenceNumber
3417 - Controller->V1.OldEventLogSequenceNumber > 0)
3419 Command->V1.CommandMailbox.Type3E.CommandOpcode =
3420 DAC960_V1_PerformEventLogOperation;
3421 Command->V1.CommandMailbox.Type3E.OperationType =
3422 DAC960_V1_GetEventLogEntry;
3423 Command->V1.CommandMailbox.Type3E.OperationQualifier = 1;
3424 Command->V1.CommandMailbox.Type3E.SequenceNumber =
3425 Controller->V1.OldEventLogSequenceNumber;
3426 Command->V1.CommandMailbox.Type3E.BusAddress =
3427 Virtual_to_Bus(&Controller->V1.EventLogEntry);
3428 DAC960_QueueCommand(Command);
3429 return;
3431 if (Controller->V1.NeedErrorTableInformation)
3433 Controller->V1.NeedErrorTableInformation = false;
3434 Command->V1.CommandMailbox.Type3.CommandOpcode =
3435 DAC960_V1_GetErrorTable;
3436 Command->V1.CommandMailbox.Type3.BusAddress =
3437 Virtual_to_Bus(&Controller->V1.NewErrorTable);
3438 DAC960_QueueCommand(Command);
3439 return;
3441 if (Controller->V1.NeedRebuildProgress &&
3442 Controller->V1.RebuildProgressFirst)
3444 Controller->V1.NeedRebuildProgress = false;
3445 Command->V1.CommandMailbox.Type3.CommandOpcode =
3446 DAC960_V1_GetRebuildProgress;
3447 Command->V1.CommandMailbox.Type3.BusAddress =
3448 Virtual_to_Bus(&Controller->V1.RebuildProgress);
3449 DAC960_QueueCommand(Command);
3450 return;
3452 if (Controller->V1.NeedDeviceStateInformation)
3454 if (Controller->V1.NeedDeviceInquiryInformation)
3456 DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
3457 DAC960_SCSI_Inquiry_T *InquiryStandardData =
3458 &Controller->V1.InquiryStandardData
3459 [Controller->V1.DeviceStateChannel]
3460 [Controller->V1.DeviceStateTargetID];
3461 InquiryStandardData->PeripheralDeviceType = 0x1F;
3462 Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
3463 Command->V1.CommandMailbox.Type3.BusAddress =
3464 Virtual_to_Bus(DCDB);
3465 DCDB->Channel = Controller->V1.DeviceStateChannel;
3466 DCDB->TargetID = Controller->V1.DeviceStateTargetID;
3467 DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
3468 DCDB->EarlyStatus = false;
3469 DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
3470 DCDB->NoAutomaticRequestSense = false;
3471 DCDB->DisconnectPermitted = true;
3472 DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
3473 DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
3474 DCDB->CDBLength = 6;
3475 DCDB->TransferLengthHigh4 = 0;
3476 DCDB->SenseLength = sizeof(DCDB->SenseData);
3477 DCDB->CDB[0] = 0x12; /* INQUIRY */
3478 DCDB->CDB[1] = 0; /* EVPD = 0 */
3479 DCDB->CDB[2] = 0; /* Page Code */
3480 DCDB->CDB[3] = 0; /* Reserved */
3481 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
3482 DCDB->CDB[5] = 0; /* Control */
3483 DAC960_QueueCommand(Command);
3484 Controller->V1.NeedDeviceInquiryInformation = false;
3485 return;
3487 if (Controller->V1.NeedDeviceSerialNumberInformation)
3489 DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
3490 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
3491 &Controller->V1.InquiryUnitSerialNumber
3492 [Controller->V1.DeviceStateChannel]
3493 [Controller->V1.DeviceStateTargetID];
3494 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
3495 Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
3496 Command->V1.CommandMailbox.Type3.BusAddress =
3497 Virtual_to_Bus(DCDB);
3498 DCDB->Channel = Controller->V1.DeviceStateChannel;
3499 DCDB->TargetID = Controller->V1.DeviceStateTargetID;
3500 DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
3501 DCDB->EarlyStatus = false;
3502 DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
3503 DCDB->NoAutomaticRequestSense = false;
3504 DCDB->DisconnectPermitted = true;
3505 DCDB->TransferLength =
3506 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
3507 DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
3508 DCDB->CDBLength = 6;
3509 DCDB->TransferLengthHigh4 = 0;
3510 DCDB->SenseLength = sizeof(DCDB->SenseData);
3511 DCDB->CDB[0] = 0x12; /* INQUIRY */
3512 DCDB->CDB[1] = 1; /* EVPD = 1 */
3513 DCDB->CDB[2] = 0x80; /* Page Code */
3514 DCDB->CDB[3] = 0; /* Reserved */
3515 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
3516 DCDB->CDB[5] = 0; /* Control */
3517 DAC960_QueueCommand(Command);
3518 Controller->V1.NeedDeviceSerialNumberInformation = false;
3519 return;
3521 if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
3523 Controller->V1.DeviceStateChannel++;
3524 Controller->V1.DeviceStateTargetID = 0;
3526 while (Controller->V1.DeviceStateChannel < Controller->Channels)
3528 DAC960_V1_DeviceState_T *OldDeviceState =
3529 &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
3530 [Controller->V1.DeviceStateTargetID];
3531 if (OldDeviceState->Present &&
3532 OldDeviceState->DeviceType == DAC960_V1_DiskType)
3534 Command->V1.CommandMailbox.Type3D.CommandOpcode =
3535 DAC960_V1_GetDeviceState;
3536 Command->V1.CommandMailbox.Type3D.Channel =
3537 Controller->V1.DeviceStateChannel;
3538 Command->V1.CommandMailbox.Type3D.TargetID =
3539 Controller->V1.DeviceStateTargetID;
3540 Command->V1.CommandMailbox.Type3D.BusAddress =
3541 Virtual_to_Bus(&Controller->V1.NewDeviceState);
3542 DAC960_QueueCommand(Command);
3543 return;
3545 if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
3547 Controller->V1.DeviceStateChannel++;
3548 Controller->V1.DeviceStateTargetID = 0;
3551 Controller->V1.NeedDeviceStateInformation = false;
3553 if (Controller->V1.NeedLogicalDriveInformation)
3555 Controller->V1.NeedLogicalDriveInformation = false;
3556 Command->V1.CommandMailbox.Type3.CommandOpcode =
3557 DAC960_V1_GetLogicalDriveInformation;
3558 Command->V1.CommandMailbox.Type3.BusAddress =
3559 Virtual_to_Bus(&Controller->V1.NewLogicalDriveInformation);
3560 DAC960_QueueCommand(Command);
3561 return;
3563 if (Controller->V1.NeedRebuildProgress)
3565 Controller->V1.NeedRebuildProgress = false;
3566 Command->V1.CommandMailbox.Type3.CommandOpcode =
3567 DAC960_V1_GetRebuildProgress;
3568 Command->V1.CommandMailbox.Type3.BusAddress =
3569 Virtual_to_Bus(&Controller->V1.RebuildProgress);
3570 DAC960_QueueCommand(Command);
3571 return;
3573 if (Controller->V1.NeedConsistencyCheckProgress)
3575 Controller->V1.NeedConsistencyCheckProgress = false;
3576 Command->V1.CommandMailbox.Type3.CommandOpcode =
3577 DAC960_V1_RebuildStat;
3578 Command->V1.CommandMailbox.Type3.BusAddress =
3579 Virtual_to_Bus(&Controller->V1.RebuildProgress);
3580 DAC960_QueueCommand(Command);
3581 return;
3583 Controller->MonitoringTimerCount++;
3584 Controller->MonitoringTimer.expires =
3585 jiffies + DAC960_MonitoringTimerInterval;
3586 add_timer(&Controller->MonitoringTimer);
3588 if (CommandType == DAC960_ImmediateCommand)
3590 up(Command->Semaphore);
3591 Command->Semaphore = NULL;
3592 return;
3594 if (CommandType == DAC960_QueuedCommand)
3596 DAC960_V1_KernelCommand_T *KernelCommand = Command->V1.KernelCommand;
3597 KernelCommand->CommandStatus = Command->V1.CommandStatus;
3598 Command->V1.KernelCommand = NULL;
3599 if (CommandOpcode == DAC960_V1_DCDB)
3600 Controller->V1.DirectCommandActive[KernelCommand->DCDB->Channel]
3601 [KernelCommand->DCDB->TargetID] =
3602 false;
3603 DAC960_DeallocateCommand(Command);
3604 KernelCommand->CompletionFunction(KernelCommand);
3605 return;
3608 Queue a Status Monitoring Command to the Controller using the just
3609 completed Command if one was deferred previously due to lack of a
3610 free Command when the Monitoring Timer Function was called.
3612 if (Controller->MonitoringCommandDeferred)
3614 Controller->MonitoringCommandDeferred = false;
3615 DAC960_V1_QueueMonitoringCommand(Command);
3616 return;
3619 Deallocate the Command.
3621 DAC960_DeallocateCommand(Command);
3623 Wake up any processes waiting on a free Command.
3625 wake_up(&Controller->CommandWaitQueue);
3630 DAC960_V2_ReadWriteError prints an appropriate error message for Command
3631 when an error occurs on a Read or Write operation.
3634 static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
3636 DAC960_Controller_T *Controller = Command->Controller;
3637 unsigned char *SenseErrors[] = { "NO SENSE", "RECOVERED ERROR",
3638 "NOT READY", "MEDIUM ERROR",
3639 "HARDWARE ERROR", "ILLEGAL REQUEST",
3640 "UNIT ATTENTION", "DATA PROTECT",
3641 "BLANK CHECK", "VENDOR-SPECIFIC",
3642 "COPY ABORTED", "ABORTED COMMAND",
3643 "EQUAL", "VOLUME OVERFLOW",
3644 "MISCOMPARE", "RESERVED" };
3645 unsigned char *CommandName = "UNKNOWN";
3646 switch (Command->CommandType)
3648 case DAC960_ReadCommand:
3649 case DAC960_ReadRetryCommand:
3650 CommandName = "READ";
3651 break;
3652 case DAC960_WriteCommand:
3653 case DAC960_WriteRetryCommand:
3654 CommandName = "WRITE";
3655 break;
3656 case DAC960_MonitoringCommand:
3657 case DAC960_ImmediateCommand:
3658 case DAC960_QueuedCommand:
3659 break;
3661 DAC960_Error("Error Condition %s on %s:\n", Controller,
3662 SenseErrors[Command->V2.RequestSense.SenseKey], CommandName);
3663 DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %d..%d\n",
3664 Controller, Controller->ControllerNumber,
3665 Command->LogicalDriveNumber, Command->BlockNumber,
3666 Command->BlockNumber + Command->BlockCount - 1);
3667 if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
3668 DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
3669 Controller, Controller->ControllerNumber,
3670 Command->LogicalDriveNumber,
3671 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
3672 Command->BufferHeader->b_rsector,
3673 Command->BufferHeader->b_rsector + Command->BlockCount - 1);
3678 DAC960_V2_ReportEvent prints an appropriate message when a Controller Event
3679 occurs.
3682 static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
3683 DAC960_V2_Event_T *Event)
3685 DAC960_SCSI_RequestSense_T *RequestSense =
3686 (DAC960_SCSI_RequestSense_T *) &Event->RequestSenseData;
3687 unsigned char MessageBuffer[DAC960_LineBufferSize];
3688 static struct { int EventCode; unsigned char *EventMessage; } EventList[] =
3689 { /* Physical Device Events (0x0000 - 0x007F) */
3690 { 0x0001, "P Online" },
3691 { 0x0002, "P Standby" },
3692 { 0x0005, "P Automatic Rebuild Started" },
3693 { 0x0006, "P Manual Rebuild Started" },
3694 { 0x0007, "P Rebuild Completed" },
3695 { 0x0008, "P Rebuild Cancelled" },
3696 { 0x0009, "P Rebuild Failed for Unknown Reasons" },
3697 { 0x000A, "P Rebuild Failed due to New Physical Device" },
3698 { 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
3699 { 0x000C, "S Offline" },
3700 { 0x000D, "P Found" },
3701 { 0x000E, "P Gone" },
3702 { 0x000F, "P Unconfigured" },
3703 { 0x0010, "P Expand Capacity Started" },
3704 { 0x0011, "P Expand Capacity Completed" },
3705 { 0x0012, "P Expand Capacity Failed" },
3706 { 0x0016, "P Parity Error" },
3707 { 0x0017, "P Soft Error" },
3708 { 0x0018, "P Miscellaneous Error" },
3709 { 0x0019, "P Reset" },
3710 { 0x001A, "P Active Spare Found" },
3711 { 0x001B, "P Warm Spare Found" },
3712 { 0x001C, "S Sense Data Received" },
3713 { 0x001D, "P Initialization Started" },
3714 { 0x001E, "P Initialization Completed" },
3715 { 0x001F, "P Initialization Failed" },
3716 { 0x0020, "P Initialization Cancelled" },
3717 { 0x0021, "P Failed because Write Recovery Failed" },
3718 { 0x0022, "P Failed because SCSI Bus Reset Failed" },
3719 { 0x0023, "P Failed because of Double Check Condition" },
3720 { 0x0024, "P Failed because Device Cannot Be Accessed" },
3721 { 0x0025, "P Failed because of Gross Error on SCSI Processor" },
3722 { 0x0026, "P Failed because of Bad Tag from Device" },
3723 { 0x0027, "P Failed because of Command Timeout" },
3724 { 0x0028, "P Failed because of System Reset" },
3725 { 0x0029, "P Failed because of Busy Status or Parity Error" },
3726 { 0x002A, "P Failed because Host Set Device to Failed State" },
3727 { 0x002B, "P Failed because of Selection Timeout" },
3728 { 0x002C, "P Failed because of SCSI Bus Phase Error" },
3729 { 0x002D, "P Failed because Device Returned Unknown Status" },
3730 { 0x002E, "P Failed because Device Not Ready" },
3731 { 0x002F, "P Failed because Device Not Found at Startup" },
3732 { 0x0030, "P Failed because COD Write Operation Failed" },
3733 { 0x0031, "P Failed because BDT Write Operation Failed" },
3734 { 0x0039, "P Missing at Startup" },
3735 { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
3736 /* Logical Device Events (0x0080 - 0x00FF) */
3737 { 0x0080, "M Consistency Check Started" },
3738 { 0x0081, "M Consistency Check Completed" },
3739 { 0x0082, "M Consistency Check Cancelled" },
3740 { 0x0083, "M Consistency Check Completed With Errors" },
3741 { 0x0084, "M Consistency Check Failed due to Logical Drive Failure" },
3742 { 0x0085, "M Consistency Check Failed due to Physical Device Failure" },
3743 { 0x0086, "L Offline" },
3744 { 0x0087, "L Critical" },
3745 { 0x0088, "L Online" },
3746 { 0x0089, "M Automatic Rebuild Started" },
3747 { 0x008A, "M Manual Rebuild Started" },
3748 { 0x008B, "M Rebuild Completed" },
3749 { 0x008C, "M Rebuild Cancelled" },
3750 { 0x008D, "M Rebuild Failed for Unknown Reasons" },
3751 { 0x008E, "M Rebuild Failed due to New Physical Device" },
3752 { 0x008F, "M Rebuild Failed due to Logical Drive Failure" },
3753 { 0x0090, "M Initialization Started" },
3754 { 0x0091, "M Initialization Completed" },
3755 { 0x0092, "M Initialization Cancelled" },
3756 { 0x0093, "M Initialization Failed" },
3757 { 0x0094, "L Found" },
3758 { 0x0095, "L Gone" },
3759 { 0x0096, "M Expand Capacity Started" },
3760 { 0x0097, "M Expand Capacity Completed" },
3761 { 0x0098, "M Expand Capacity Failed" },
3762 { 0x0099, "L Bad Block Found" },
3763 { 0x009A, "L Size Changed" },
3764 { 0x009B, "L Type Changed" },
3765 { 0x009C, "L Bad Data Block Found" },
3766 { 0x009E, "L Read of Data Block in BDT" },
3767 { 0x009F, "L Write Back Data for Disk Block Lost" },
3768 /* Fault Management Events (0x0100 - 0x017F) */
3769 { 0x0140, "E Fan %d Failed" },
3770 { 0x0141, "E Fan %d OK" },
3771 { 0x0142, "E Fan %d Not Present" },
3772 { 0x0143, "E Power Supply %d Failed" },
3773 { 0x0144, "E Power Supply %d OK" },
3774 { 0x0145, "E Power Supply %d Not Present" },
3775 { 0x0146, "E Temperature Sensor %d Failed" },
3776 { 0x0147, "E Temperature Sensor %d Critical" },
3777 { 0x0148, "E Temperature Sensor %d OK" },
3778 { 0x0149, "E Temperature Sensor %d Not Present" },
3779 { 0x014A, "E Unit %d Access Critical" },
3780 { 0x014B, "E Unit %d Access OK" },
3781 { 0x014C, "E Unit %d Access Offline" },
3782 /* Controller Events (0x0180 - 0x01FF) */
3783 { 0x0181, "C Cache Write Back Error" },
3784 { 0x0188, "C Battery Backup Unit Found" },
3785 { 0x0189, "C Battery Backup Unit Charge Level Low" },
3786 { 0x018A, "C Battery Backup Unit Charge Level OK" },
3787 { 0x0193, "C Installation Aborted" },
3788 { 0x0195, "C Mirror Race Recovery In Progress" },
3789 { 0x0196, "C Mirror Race on Critical Drive" },
3790 { 0x019E, "C Memory Soft ECC Error" },
3791 { 0x019F, "C Memory Hard ECC Error" },
3792 { 0x01A2, "C Battery Backup Unit Failed" },
3793 { 0, "" } };
3794 int EventListIndex = 0, EventCode;
3795 unsigned char EventType, *EventMessage;
3796 if (Event->EventCode == 0x1C &&
3797 RequestSense->SenseKey == DAC960_SenseKey_VendorSpecific &&
3798 (RequestSense->AdditionalSenseCode == 0x80 ||
3799 RequestSense->AdditionalSenseCode == 0x81))
3800 Event->EventCode = ((RequestSense->AdditionalSenseCode - 0x80) << 8) |
3801 RequestSense->AdditionalSenseCodeQualifier;
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 if (Controller->SuppressEnclosureMessages) break;
3866 sprintf(MessageBuffer, EventMessage, Event->LogicalUnit);
3867 DAC960_Critical("Enclosure %d %s\n", Controller,
3868 Event->TargetID, MessageBuffer);
3869 break;
3870 case 'C':
3871 DAC960_Critical("Controller %s\n", Controller, EventMessage);
3872 break;
3873 default:
3874 DAC960_Critical("Unknown Controller Event Code %04X\n",
3875 Controller, Event->EventCode);
3876 break;
3882 DAC960_V2_ReportProgress prints an appropriate progress message for
3883 Logical Device Long Operations.
3886 static void DAC960_V2_ReportProgress(DAC960_Controller_T *Controller,
3887 unsigned char *MessageString,
3888 unsigned int LogicalDeviceNumber,
3889 unsigned long BlocksCompleted,
3890 unsigned long LogicalDeviceSize)
3892 Controller->EphemeralProgressMessage = true;
3893 DAC960_Progress("%s in Progress: Logical Drive %d (/dev/rd/c%dd%d) "
3894 "%d%% completed\n", Controller,
3895 MessageString,
3896 LogicalDeviceNumber,
3897 Controller->ControllerNumber,
3898 LogicalDeviceNumber,
3899 (100 * (BlocksCompleted >> 7)) / (LogicalDeviceSize >> 7));
3900 Controller->EphemeralProgressMessage = false;
3905 DAC960_V2_ProcessCompletedCommand performs completion processing for Command
3906 for DAC960 V2 Firmware Controllers.
3909 static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
3911 DAC960_Controller_T *Controller = Command->Controller;
3912 DAC960_CommandType_T CommandType = Command->CommandType;
3913 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
3914 DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode;
3915 DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus;
3916 BufferHeader_T *BufferHeader = Command->BufferHeader;
3917 if (CommandType == DAC960_ReadCommand ||
3918 CommandType == DAC960_WriteCommand)
3920 if (CommandStatus == DAC960_V2_NormalCompletion)
3923 Perform completion processing for all buffers in this I/O Request.
3925 while (BufferHeader != NULL)
3927 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
3928 BufferHeader->b_reqnext = NULL;
3929 DAC960_ProcessCompletedBuffer(BufferHeader, true);
3930 BufferHeader = NextBufferHeader;
3933 Wake up requestor for swap file paging requests.
3935 if (Command->Semaphore != NULL)
3937 up(Command->Semaphore);
3938 Command->Semaphore = NULL;
3940 add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
3942 else if (Command->V2.RequestSense.SenseKey
3943 == DAC960_SenseKey_MediumError &&
3944 BufferHeader != NULL &&
3945 BufferHeader->b_reqnext != NULL)
3947 if (CommandType == DAC960_ReadCommand)
3948 Command->CommandType = DAC960_ReadRetryCommand;
3949 else Command->CommandType = DAC960_WriteRetryCommand;
3950 Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
3951 CommandMailbox->SCSI_10.CommandControlBits
3952 .AdditionalScatterGatherListMemory = false;
3953 CommandMailbox->SCSI_10.DataTransferSize =
3954 Command->BlockCount << DAC960_BlockSizeBits;
3955 CommandMailbox->SCSI_10.DataTransferMemoryAddress
3956 .ScatterGatherSegments[0].SegmentDataPointer =
3957 Virtual_to_Bus(BufferHeader->b_data);
3958 CommandMailbox->SCSI_10.DataTransferMemoryAddress
3959 .ScatterGatherSegments[0].SegmentByteCount =
3960 CommandMailbox->SCSI_10.DataTransferSize;
3961 CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
3962 CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
3963 DAC960_QueueCommand(Command);
3964 return;
3966 else
3968 if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
3969 DAC960_V2_ReadWriteError(Command);
3971 Perform completion processing for all buffers in this I/O Request.
3973 while (BufferHeader != NULL)
3975 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
3976 BufferHeader->b_reqnext = NULL;
3977 DAC960_ProcessCompletedBuffer(BufferHeader, false);
3978 BufferHeader = NextBufferHeader;
3981 Wake up requestor for swap file paging requests.
3983 if (Command->Semaphore != NULL)
3985 up(Command->Semaphore);
3986 Command->Semaphore = NULL;
3990 else if (CommandType == DAC960_ReadRetryCommand ||
3991 CommandType == DAC960_WriteRetryCommand)
3993 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
3994 BufferHeader->b_reqnext = NULL;
3996 Perform completion processing for this single buffer.
3998 if (CommandStatus == DAC960_V2_NormalCompletion)
3999 DAC960_ProcessCompletedBuffer(BufferHeader, true);
4000 else
4002 if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
4003 DAC960_V2_ReadWriteError(Command);
4004 DAC960_ProcessCompletedBuffer(BufferHeader, false);
4006 if (NextBufferHeader != NULL)
4008 Command->BlockNumber +=
4009 BufferHeader->b_size >> DAC960_BlockSizeBits;
4010 Command->BlockCount =
4011 NextBufferHeader->b_size >> DAC960_BlockSizeBits;
4012 Command->BufferHeader = NextBufferHeader;
4013 CommandMailbox->SCSI_10.DataTransferSize =
4014 Command->BlockCount << DAC960_BlockSizeBits;
4015 CommandMailbox->SCSI_10.DataTransferMemoryAddress
4016 .ScatterGatherSegments[0]
4017 .SegmentDataPointer =
4018 Virtual_to_Bus(NextBufferHeader->b_data);
4019 CommandMailbox->SCSI_10.DataTransferMemoryAddress
4020 .ScatterGatherSegments[0]
4021 .SegmentByteCount =
4022 CommandMailbox->SCSI_10.DataTransferSize;
4023 CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
4024 CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
4025 CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
4026 CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
4027 CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
4028 CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
4029 DAC960_QueueCommand(Command);
4030 return;
4033 else if (CommandType == DAC960_MonitoringCommand)
4035 if (CommandOpcode == DAC960_V2_GetControllerInfo)
4037 DAC960_V2_ControllerInfo_T *NewControllerInfo =
4038 &Controller->V2.NewControllerInformation;
4039 DAC960_V2_ControllerInfo_T *ControllerInfo =
4040 &Controller->V2.ControllerInformation;
4041 Controller->LogicalDriveCount =
4042 NewControllerInfo->LogicalDevicesPresent;
4043 Controller->V2.NeedLogicalDeviceInformation = true;
4044 Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber = 0;
4045 Controller->V2.NeedPhysicalDeviceInformation = true;
4046 Controller->V2.PhysicalDeviceIndex = 0;
4047 Controller->V2.NewPhysicalDeviceInformation.Channel = 0;
4048 Controller->V2.NewPhysicalDeviceInformation.TargetID = 0;
4049 Controller->V2.NewPhysicalDeviceInformation.LogicalUnit = 0;
4050 Controller->MonitoringAlertMode =
4051 (NewControllerInfo->LogicalDevicesCritical > 0 ||
4052 NewControllerInfo->LogicalDevicesOffline > 0 ||
4053 NewControllerInfo->PhysicalDisksCritical > 0 ||
4054 NewControllerInfo->PhysicalDisksOffline > 0);
4055 memcpy(ControllerInfo, NewControllerInfo,
4056 sizeof(DAC960_V2_ControllerInfo_T));
4058 else if (CommandOpcode == DAC960_V2_GetEvent)
4060 if (CommandStatus == DAC960_V2_NormalCompletion)
4061 DAC960_V2_ReportEvent(Controller, &Controller->V2.Event);
4062 Controller->V2.NextEventSequenceNumber++;
4064 else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
4065 CommandStatus == DAC960_V2_NormalCompletion)
4067 DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
4068 &Controller->V2.NewPhysicalDeviceInformation;
4069 unsigned int PhysicalDeviceIndex = Controller->V2.PhysicalDeviceIndex;
4070 DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
4071 Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
4072 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
4073 if (PhysicalDeviceInfo == NULL ||
4074 (NewPhysicalDeviceInfo->Channel !=
4075 PhysicalDeviceInfo->Channel) ||
4076 (NewPhysicalDeviceInfo->TargetID !=
4077 PhysicalDeviceInfo->TargetID) ||
4078 (NewPhysicalDeviceInfo->LogicalUnit !=
4079 PhysicalDeviceInfo->LogicalUnit))
4081 unsigned int DeviceIndex;
4082 PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
4083 kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
4084 InquiryUnitSerialNumber =
4085 (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
4086 kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
4087 GFP_ATOMIC);
4088 if (InquiryUnitSerialNumber == NULL)
4090 kfree(PhysicalDeviceInfo);
4091 PhysicalDeviceInfo = NULL;
4093 DAC960_Critical("Physical Device %d:%d Now Exists%s\n",
4094 Controller,
4095 NewPhysicalDeviceInfo->Channel,
4096 NewPhysicalDeviceInfo->TargetID,
4097 (PhysicalDeviceInfo != NULL
4098 ? "" : " - Allocation Failed"));
4099 if (PhysicalDeviceInfo != NULL)
4101 for (DeviceIndex = PhysicalDeviceIndex;
4102 DeviceIndex < DAC960_V2_MaxPhysicalDevices - 1;
4103 DeviceIndex++)
4105 Controller->V2.PhysicalDeviceInformation[DeviceIndex+1] =
4106 Controller->V2.PhysicalDeviceInformation[DeviceIndex];
4107 Controller->V2.InquiryUnitSerialNumber[DeviceIndex+1] =
4108 Controller->V2.InquiryUnitSerialNumber[DeviceIndex];
4109 Controller->V2.PhysicalDeviceInformation
4110 [PhysicalDeviceIndex] =
4111 PhysicalDeviceInfo;
4112 Controller->V2.InquiryUnitSerialNumber
4113 [PhysicalDeviceIndex] =
4114 InquiryUnitSerialNumber;
4116 memset(PhysicalDeviceInfo, 0,
4117 sizeof(DAC960_V2_PhysicalDeviceInfo_T));
4118 PhysicalDeviceInfo->PhysicalDeviceState =
4119 DAC960_V2_Device_InvalidState;
4120 memset(InquiryUnitSerialNumber, 0,
4121 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
4122 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
4123 Controller->V2.NeedDeviceSerialNumberInformation = true;
4126 if (PhysicalDeviceInfo != NULL)
4128 if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
4129 PhysicalDeviceInfo->PhysicalDeviceState)
4130 DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
4131 NewPhysicalDeviceInfo->Channel,
4132 NewPhysicalDeviceInfo->TargetID,
4133 (NewPhysicalDeviceInfo->PhysicalDeviceState
4134 == DAC960_V2_Device_Unconfigured
4135 ? "UNCONFIGURED"
4136 : NewPhysicalDeviceInfo->PhysicalDeviceState
4137 == DAC960_V2_Device_Online
4138 ? "ONLINE"
4139 : NewPhysicalDeviceInfo->PhysicalDeviceState
4140 == DAC960_V2_Device_WriteOnly
4141 ? "WRITE-ONLY"
4142 : NewPhysicalDeviceInfo
4143 ->PhysicalDeviceState
4144 == DAC960_V2_Device_Dead
4145 ? "DEAD" : "STANDBY"));
4146 if ((NewPhysicalDeviceInfo->ParityErrors !=
4147 PhysicalDeviceInfo->ParityErrors) ||
4148 (NewPhysicalDeviceInfo->SoftErrors !=
4149 PhysicalDeviceInfo->SoftErrors) ||
4150 (NewPhysicalDeviceInfo->HardErrors !=
4151 PhysicalDeviceInfo->HardErrors) ||
4152 (NewPhysicalDeviceInfo->MiscellaneousErrors !=
4153 PhysicalDeviceInfo->MiscellaneousErrors) ||
4154 (NewPhysicalDeviceInfo->CommandTimeouts !=
4155 PhysicalDeviceInfo->CommandTimeouts) ||
4156 (NewPhysicalDeviceInfo->Retries !=
4157 PhysicalDeviceInfo->Retries) ||
4158 (NewPhysicalDeviceInfo->Aborts !=
4159 PhysicalDeviceInfo->Aborts) ||
4160 (NewPhysicalDeviceInfo->PredictedFailuresDetected !=
4161 PhysicalDeviceInfo->PredictedFailuresDetected))
4163 DAC960_Critical("Physical Device %d:%d Errors: "
4164 "Parity = %d, Soft = %d, "
4165 "Hard = %d, Misc = %d\n",
4166 Controller,
4167 NewPhysicalDeviceInfo->Channel,
4168 NewPhysicalDeviceInfo->TargetID,
4169 NewPhysicalDeviceInfo->ParityErrors,
4170 NewPhysicalDeviceInfo->SoftErrors,
4171 NewPhysicalDeviceInfo->HardErrors,
4172 NewPhysicalDeviceInfo->MiscellaneousErrors);
4173 DAC960_Critical("Physical Device %d:%d Errors: "
4174 "Timeouts = %d, Retries = %d, "
4175 "Aborts = %d, Predicted = %d\n",
4176 Controller,
4177 NewPhysicalDeviceInfo->Channel,
4178 NewPhysicalDeviceInfo->TargetID,
4179 NewPhysicalDeviceInfo->CommandTimeouts,
4180 NewPhysicalDeviceInfo->Retries,
4181 NewPhysicalDeviceInfo->Aborts,
4182 NewPhysicalDeviceInfo
4183 ->PredictedFailuresDetected);
4185 if (PhysicalDeviceInfo->PhysicalDeviceState
4186 == DAC960_V2_Device_Dead &&
4187 NewPhysicalDeviceInfo->PhysicalDeviceState
4188 != DAC960_V2_Device_Dead)
4189 Controller->V2.NeedDeviceSerialNumberInformation = true;
4190 memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
4191 sizeof(DAC960_V2_PhysicalDeviceInfo_T));
4193 NewPhysicalDeviceInfo->LogicalUnit++;
4194 Controller->V2.PhysicalDeviceIndex++;
4196 else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
4197 Controller->V2.NeedPhysicalDeviceInformation = false;
4198 else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
4199 CommandStatus == DAC960_V2_NormalCompletion)
4201 DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
4202 &Controller->V2.NewLogicalDeviceInformation;
4203 unsigned short LogicalDeviceNumber =
4204 NewLogicalDeviceInfo->LogicalDeviceNumber;
4205 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
4206 Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber];
4207 if (LogicalDeviceInfo == NULL)
4209 DAC960_V2_PhysicalDevice_T PhysicalDevice;
4210 PhysicalDevice.Controller = 0;
4211 PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
4212 PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
4213 PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
4214 Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
4215 PhysicalDevice;
4216 LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
4217 kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
4218 Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
4219 LogicalDeviceInfo;
4220 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
4221 "Now Exists%s\n", Controller,
4222 LogicalDeviceNumber,
4223 Controller->ControllerNumber,
4224 LogicalDeviceNumber,
4225 (LogicalDeviceInfo != NULL
4226 ? "" : " - Allocation Failed"));
4227 if (LogicalDeviceInfo != NULL)
4228 memset(LogicalDeviceInfo, 0,
4229 sizeof(DAC960_V2_LogicalDeviceInfo_T));
4231 if (LogicalDeviceInfo != NULL)
4233 unsigned long LogicalDeviceSize =
4234 NewLogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB;
4235 if (NewLogicalDeviceInfo->LogicalDeviceState !=
4236 LogicalDeviceInfo->LogicalDeviceState)
4237 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
4238 "is now %s\n", Controller,
4239 LogicalDeviceNumber,
4240 Controller->ControllerNumber,
4241 LogicalDeviceNumber,
4242 (NewLogicalDeviceInfo->LogicalDeviceState
4243 == DAC960_V2_LogicalDevice_Online
4244 ? "ONLINE"
4245 : NewLogicalDeviceInfo->LogicalDeviceState
4246 == DAC960_V2_LogicalDevice_Critical
4247 ? "CRITICAL" : "OFFLINE"));
4248 if ((NewLogicalDeviceInfo->SoftErrors !=
4249 LogicalDeviceInfo->SoftErrors) ||
4250 (NewLogicalDeviceInfo->CommandsFailed !=
4251 LogicalDeviceInfo->CommandsFailed) ||
4252 (NewLogicalDeviceInfo->DeferredWriteErrors !=
4253 LogicalDeviceInfo->DeferredWriteErrors))
4254 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) Errors: "
4255 "Soft = %d, Failed = %d, Deferred Write = %d\n",
4256 Controller, LogicalDeviceNumber,
4257 Controller->ControllerNumber,
4258 LogicalDeviceNumber,
4259 NewLogicalDeviceInfo->SoftErrors,
4260 NewLogicalDeviceInfo->CommandsFailed,
4261 NewLogicalDeviceInfo->DeferredWriteErrors);
4262 if (NewLogicalDeviceInfo->ConsistencyCheckInProgress)
4263 DAC960_V2_ReportProgress(Controller,
4264 "Consistency Check",
4265 LogicalDeviceNumber,
4266 NewLogicalDeviceInfo
4267 ->ConsistencyCheckBlockNumber,
4268 LogicalDeviceSize);
4269 else if (NewLogicalDeviceInfo->RebuildInProgress)
4270 DAC960_V2_ReportProgress(Controller,
4271 "Rebuild",
4272 LogicalDeviceNumber,
4273 NewLogicalDeviceInfo
4274 ->RebuildBlockNumber,
4275 LogicalDeviceSize);
4276 else if (NewLogicalDeviceInfo->BackgroundInitializationInProgress)
4277 DAC960_V2_ReportProgress(Controller,
4278 "Background Initialization",
4279 LogicalDeviceNumber,
4280 NewLogicalDeviceInfo
4281 ->BackgroundInitializationBlockNumber,
4282 LogicalDeviceSize);
4283 else if (NewLogicalDeviceInfo->ForegroundInitializationInProgress)
4284 DAC960_V2_ReportProgress(Controller,
4285 "Foreground Initialization",
4286 LogicalDeviceNumber,
4287 NewLogicalDeviceInfo
4288 ->ForegroundInitializationBlockNumber,
4289 LogicalDeviceSize);
4290 else if (NewLogicalDeviceInfo->DataMigrationInProgress)
4291 DAC960_V2_ReportProgress(Controller,
4292 "Data Migration",
4293 LogicalDeviceNumber,
4294 NewLogicalDeviceInfo
4295 ->DataMigrationBlockNumber,
4296 LogicalDeviceSize);
4297 else if (NewLogicalDeviceInfo->PatrolOperationInProgress)
4298 DAC960_V2_ReportProgress(Controller,
4299 "Patrol Operation",
4300 LogicalDeviceNumber,
4301 NewLogicalDeviceInfo
4302 ->PatrolOperationBlockNumber,
4303 LogicalDeviceSize);
4304 memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
4305 sizeof(DAC960_V2_LogicalDeviceInfo_T));
4307 NewLogicalDeviceInfo->LogicalDeviceNumber++;
4309 else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
4310 Controller->V2.NeedLogicalDeviceInformation = false;
4311 if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
4312 - Controller->V2.NextEventSequenceNumber > 0)
4314 CommandMailbox->GetEvent.CommandOpcode = DAC960_V2_IOCTL;
4315 CommandMailbox->GetEvent.DataTransferSize = sizeof(DAC960_V2_Event_T);
4316 CommandMailbox->GetEvent.EventSequenceNumberHigh16 =
4317 Controller->V2.NextEventSequenceNumber >> 16;
4318 CommandMailbox->GetEvent.ControllerNumber = 0;
4319 CommandMailbox->GetEvent.IOCTL_Opcode =
4320 DAC960_V2_GetEvent;
4321 CommandMailbox->GetEvent.EventSequenceNumberLow16 =
4322 Controller->V2.NextEventSequenceNumber & 0xFFFF;
4323 CommandMailbox->GetEvent.DataTransferMemoryAddress
4324 .ScatterGatherSegments[0]
4325 .SegmentDataPointer =
4326 Virtual_to_Bus(&Controller->V2.Event);
4327 CommandMailbox->GetEvent.DataTransferMemoryAddress
4328 .ScatterGatherSegments[0]
4329 .SegmentByteCount =
4330 CommandMailbox->GetEvent.DataTransferSize;
4331 DAC960_QueueCommand(Command);
4332 return;
4334 if (Controller->V2.NeedPhysicalDeviceInformation)
4336 if (Controller->V2.NeedDeviceSerialNumberInformation)
4338 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
4339 Controller->V2.InquiryUnitSerialNumber
4340 [Controller->V2.PhysicalDeviceIndex - 1];
4341 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
4342 CommandMailbox->SCSI_10.CommandOpcode =
4343 DAC960_V2_SCSI_10_Passthru;
4344 CommandMailbox->SCSI_10.DataTransferSize =
4345 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
4346 CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit =
4347 Controller->V2.NewPhysicalDeviceInformation.LogicalUnit - 1;
4348 CommandMailbox->SCSI_10.PhysicalDevice.TargetID =
4349 Controller->V2.NewPhysicalDeviceInformation.TargetID;
4350 CommandMailbox->SCSI_10.PhysicalDevice.Channel =
4351 Controller->V2.NewPhysicalDeviceInformation.Channel;
4352 CommandMailbox->SCSI_10.CDBLength = 6;
4353 CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
4354 CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
4355 CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
4356 CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
4357 CommandMailbox->SCSI_10.SCSI_CDB[4] =
4358 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
4359 CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
4360 CommandMailbox->SCSI_10.DataTransferMemoryAddress
4361 .ScatterGatherSegments[0]
4362 .SegmentDataPointer =
4363 Virtual_to_Bus(InquiryUnitSerialNumber);
4364 CommandMailbox->SCSI_10.DataTransferMemoryAddress
4365 .ScatterGatherSegments[0]
4366 .SegmentByteCount =
4367 CommandMailbox->SCSI_10.DataTransferSize;
4368 DAC960_QueueCommand(Command);
4369 Controller->V2.NeedDeviceSerialNumberInformation = false;
4370 return;
4372 CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
4373 CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
4374 sizeof(DAC960_V2_PhysicalDeviceInfo_T);
4375 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit =
4376 Controller->V2.NewPhysicalDeviceInformation.LogicalUnit;
4377 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID =
4378 Controller->V2.NewPhysicalDeviceInformation.TargetID;
4379 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel =
4380 Controller->V2.NewPhysicalDeviceInformation.Channel;
4381 CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
4382 DAC960_V2_GetPhysicalDeviceInfoValid;
4383 CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
4384 .ScatterGatherSegments[0]
4385 .SegmentDataPointer =
4386 Virtual_to_Bus(&Controller->V2.NewPhysicalDeviceInformation);
4387 CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
4388 .ScatterGatherSegments[0]
4389 .SegmentByteCount =
4390 CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
4391 DAC960_QueueCommand(Command);
4392 return;
4394 if (Controller->V2.NeedLogicalDeviceInformation)
4396 CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
4397 CommandMailbox->LogicalDeviceInfo.DataTransferSize =
4398 sizeof(DAC960_V2_LogicalDeviceInfo_T);
4399 CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
4400 Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber;
4401 CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
4402 DAC960_V2_GetLogicalDeviceInfoValid;
4403 CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
4404 .ScatterGatherSegments[0]
4405 .SegmentDataPointer =
4406 Virtual_to_Bus(&Controller->V2.NewLogicalDeviceInformation);
4407 CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
4408 .ScatterGatherSegments[0]
4409 .SegmentByteCount =
4410 CommandMailbox->LogicalDeviceInfo.DataTransferSize;
4411 DAC960_QueueCommand(Command);
4412 return;
4414 Controller->MonitoringTimerCount++;
4415 Controller->MonitoringTimer.expires =
4416 jiffies + DAC960_HealthStatusMonitoringInterval;
4417 add_timer(&Controller->MonitoringTimer);
4419 if (CommandType == DAC960_ImmediateCommand)
4421 up(Command->Semaphore);
4422 Command->Semaphore = NULL;
4423 return;
4425 if (CommandType == DAC960_QueuedCommand)
4427 DAC960_V2_KernelCommand_T *KernelCommand = Command->V2.KernelCommand;
4428 KernelCommand->CommandStatus = CommandStatus;
4429 KernelCommand->RequestSenseLength = Command->V2.RequestSenseLength;
4430 KernelCommand->DataTransferLength = Command->V2.DataTransferResidue;
4431 Command->V2.KernelCommand = NULL;
4432 DAC960_DeallocateCommand(Command);
4433 KernelCommand->CompletionFunction(KernelCommand);
4434 return;
4437 Queue a Status Monitoring Command to the Controller using the just
4438 completed Command if one was deferred previously due to lack of a
4439 free Command when the Monitoring Timer Function was called.
4441 if (Controller->MonitoringCommandDeferred)
4443 Controller->MonitoringCommandDeferred = false;
4444 DAC960_V2_QueueMonitoringCommand(Command);
4445 return;
4448 Deallocate the Command.
4450 DAC960_DeallocateCommand(Command);
4452 Wake up any processes waiting on a free Command.
4454 wake_up(&Controller->CommandWaitQueue);
4459 DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
4460 Controllers.
4463 static void DAC960_BA_InterruptHandler(int IRQ_Channel,
4464 void *DeviceIdentifier,
4465 Registers_T *InterruptRegisters)
4467 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4468 void *ControllerBaseAddress = Controller->BaseAddress;
4469 DAC960_V2_StatusMailbox_T *NextStatusMailbox;
4470 ProcessorFlags_T ProcessorFlags;
4472 Acquire exclusive access to Controller.
4474 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4476 Process Hardware Interrupts for Controller.
4478 DAC960_BA_AcknowledgeInterrupt(ControllerBaseAddress);
4479 NextStatusMailbox = Controller->V2.NextStatusMailbox;
4480 while (NextStatusMailbox->Fields.CommandIdentifier > 0)
4482 DAC960_V2_CommandIdentifier_T CommandIdentifier =
4483 NextStatusMailbox->Fields.CommandIdentifier;
4484 DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4485 Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
4486 Command->V2.RequestSenseLength =
4487 NextStatusMailbox->Fields.RequestSenseLength;
4488 Command->V2.DataTransferResidue =
4489 NextStatusMailbox->Fields.DataTransferResidue;
4490 NextStatusMailbox->Words[0] = 0;
4491 if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
4492 NextStatusMailbox = Controller->V2.FirstStatusMailbox;
4493 DAC960_V2_ProcessCompletedCommand(Command);
4495 Controller->V2.NextStatusMailbox = NextStatusMailbox;
4497 Attempt to remove additional I/O Requests from the Controller's
4498 I/O Request Queue and queue them to the Controller.
4500 while (DAC960_ProcessRequest(Controller, false)) ;
4502 Release exclusive access to Controller.
4504 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4509 DAC960_LP_InterruptHandler handles hardware interrupts from DAC960 LP Series
4510 Controllers.
4513 static void DAC960_LP_InterruptHandler(int IRQ_Channel,
4514 void *DeviceIdentifier,
4515 Registers_T *InterruptRegisters)
4517 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4518 void *ControllerBaseAddress = Controller->BaseAddress;
4519 DAC960_V2_StatusMailbox_T *NextStatusMailbox;
4520 ProcessorFlags_T ProcessorFlags;
4522 Acquire exclusive access to Controller.
4524 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4526 Process Hardware Interrupts for Controller.
4528 DAC960_LP_AcknowledgeInterrupt(ControllerBaseAddress);
4529 NextStatusMailbox = Controller->V2.NextStatusMailbox;
4530 while (NextStatusMailbox->Fields.CommandIdentifier > 0)
4532 DAC960_V2_CommandIdentifier_T CommandIdentifier =
4533 NextStatusMailbox->Fields.CommandIdentifier;
4534 DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4535 Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
4536 Command->V2.RequestSenseLength =
4537 NextStatusMailbox->Fields.RequestSenseLength;
4538 Command->V2.DataTransferResidue =
4539 NextStatusMailbox->Fields.DataTransferResidue;
4540 NextStatusMailbox->Words[0] = 0;
4541 if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
4542 NextStatusMailbox = Controller->V2.FirstStatusMailbox;
4543 DAC960_V2_ProcessCompletedCommand(Command);
4545 Controller->V2.NextStatusMailbox = NextStatusMailbox;
4547 Attempt to remove additional I/O Requests from the Controller's
4548 I/O Request Queue and queue them to the Controller.
4550 while (DAC960_ProcessRequest(Controller, false)) ;
4552 Release exclusive access to Controller.
4554 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4559 DAC960_LA_InterruptHandler handles hardware interrupts from DAC960 LA Series
4560 Controllers.
4563 static void DAC960_LA_InterruptHandler(int IRQ_Channel,
4564 void *DeviceIdentifier,
4565 Registers_T *InterruptRegisters)
4567 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4568 void *ControllerBaseAddress = Controller->BaseAddress;
4569 DAC960_V1_StatusMailbox_T *NextStatusMailbox;
4570 ProcessorFlags_T ProcessorFlags;
4572 Acquire exclusive access to Controller.
4574 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4576 Process Hardware Interrupts for Controller.
4578 DAC960_LA_AcknowledgeInterrupt(ControllerBaseAddress);
4579 NextStatusMailbox = Controller->V1.NextStatusMailbox;
4580 while (NextStatusMailbox->Fields.Valid)
4582 DAC960_V1_CommandIdentifier_T CommandIdentifier =
4583 NextStatusMailbox->Fields.CommandIdentifier;
4584 DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4585 Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
4586 NextStatusMailbox->Word = 0;
4587 if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
4588 NextStatusMailbox = Controller->V1.FirstStatusMailbox;
4589 DAC960_V1_ProcessCompletedCommand(Command);
4591 Controller->V1.NextStatusMailbox = NextStatusMailbox;
4593 Attempt to remove additional I/O Requests from the Controller's
4594 I/O Request Queue and queue them to the Controller.
4596 while (DAC960_ProcessRequest(Controller, false)) ;
4598 Release exclusive access to Controller.
4600 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4605 DAC960_PG_InterruptHandler handles hardware interrupts from DAC960 PG Series
4606 Controllers.
4609 static void DAC960_PG_InterruptHandler(int IRQ_Channel,
4610 void *DeviceIdentifier,
4611 Registers_T *InterruptRegisters)
4613 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4614 void *ControllerBaseAddress = Controller->BaseAddress;
4615 DAC960_V1_StatusMailbox_T *NextStatusMailbox;
4616 ProcessorFlags_T ProcessorFlags;
4618 Acquire exclusive access to Controller.
4620 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4622 Process Hardware Interrupts for Controller.
4624 DAC960_PG_AcknowledgeInterrupt(ControllerBaseAddress);
4625 NextStatusMailbox = Controller->V1.NextStatusMailbox;
4626 while (NextStatusMailbox->Fields.Valid)
4628 DAC960_V1_CommandIdentifier_T CommandIdentifier =
4629 NextStatusMailbox->Fields.CommandIdentifier;
4630 DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4631 Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
4632 NextStatusMailbox->Word = 0;
4633 if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
4634 NextStatusMailbox = Controller->V1.FirstStatusMailbox;
4635 DAC960_V1_ProcessCompletedCommand(Command);
4637 Controller->V1.NextStatusMailbox = NextStatusMailbox;
4639 Attempt to remove additional I/O Requests from the Controller's
4640 I/O Request Queue and queue them to the Controller.
4642 while (DAC960_ProcessRequest(Controller, false)) ;
4644 Release exclusive access to Controller.
4646 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4651 DAC960_PD_InterruptHandler handles hardware interrupts from DAC960 PD Series
4652 Controllers.
4655 static void DAC960_PD_InterruptHandler(int IRQ_Channel,
4656 void *DeviceIdentifier,
4657 Registers_T *InterruptRegisters)
4659 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4660 void *ControllerBaseAddress = Controller->BaseAddress;
4661 ProcessorFlags_T ProcessorFlags;
4663 Acquire exclusive access to Controller.
4665 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4667 Process Hardware Interrupts for Controller.
4669 while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
4671 DAC960_V1_CommandIdentifier_T CommandIdentifier =
4672 DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
4673 DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4674 Command->V1.CommandStatus =
4675 DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
4676 DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
4677 DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
4678 DAC960_V1_ProcessCompletedCommand(Command);
4681 Attempt to remove additional I/O Requests from the Controller's
4682 I/O Request Queue and queue them to the Controller.
4684 while (DAC960_ProcessRequest(Controller, false)) ;
4686 Release exclusive access to Controller.
4688 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4693 DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1
4694 Firmware Controllers.
4697 static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *Command)
4699 DAC960_Controller_T *Controller = Command->Controller;
4700 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
4701 DAC960_V1_ClearCommand(Command);
4702 Command->CommandType = DAC960_MonitoringCommand;
4703 CommandMailbox->Type3.CommandOpcode = DAC960_V1_Enquiry;
4704 CommandMailbox->Type3.BusAddress = Virtual_to_Bus(&Controller->V1.NewEnquiry);
4705 DAC960_QueueCommand(Command);
4710 DAC960_V2_QueueMonitoringCommand queues a Monitoring Command to DAC960 V2
4711 Firmware Controllers.
4714 static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *Command)
4716 DAC960_Controller_T *Controller = Command->Controller;
4717 DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
4718 DAC960_V2_ClearCommand(Command);
4719 Command->CommandType = DAC960_MonitoringCommand;
4720 CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
4721 CommandMailbox->ControllerInfo.CommandControlBits
4722 .DataTransferControllerToHost = true;
4723 CommandMailbox->ControllerInfo.CommandControlBits
4724 .NoAutoRequestSense = true;
4725 CommandMailbox->ControllerInfo.DataTransferSize =
4726 sizeof(DAC960_V2_ControllerInfo_T);
4727 CommandMailbox->ControllerInfo.ControllerNumber = 0;
4728 CommandMailbox->ControllerInfo.IOCTL_Opcode = DAC960_V2_GetControllerInfo;
4729 CommandMailbox->ControllerInfo.DataTransferMemoryAddress
4730 .ScatterGatherSegments[0]
4731 .SegmentDataPointer =
4732 Virtual_to_Bus(&Controller->V2.NewControllerInformation);
4733 CommandMailbox->ControllerInfo.DataTransferMemoryAddress
4734 .ScatterGatherSegments[0]
4735 .SegmentByteCount =
4736 CommandMailbox->ControllerInfo.DataTransferSize;
4737 DAC960_QueueCommand(Command);
4742 DAC960_MonitoringTimerFunction is the timer function for monitoring
4743 the status of DAC960 Controllers.
4746 static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
4748 DAC960_Controller_T *Controller = (DAC960_Controller_T *) TimerData;
4749 DAC960_Command_T *Command;
4750 ProcessorFlags_T ProcessorFlags;
4751 if (Controller->FirmwareType == DAC960_V1_Controller)
4754 Acquire exclusive access to Controller.
4756 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
4758 Queue a Status Monitoring Command to Controller.
4760 Command = DAC960_AllocateCommand(Controller);
4761 if (Command != NULL)
4762 DAC960_V1_QueueMonitoringCommand(Command);
4763 else Controller->MonitoringCommandDeferred = true;
4765 Release exclusive access to Controller.
4767 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
4769 else
4771 DAC960_V2_ControllerInfo_T *ControllerInfo =
4772 &Controller->V2.ControllerInformation;
4773 unsigned int StatusChangeCounter =
4774 Controller->V2.HealthStatusBuffer->StatusChangeCounter;
4775 if (StatusChangeCounter == Controller->V2.StatusChangeCounter &&
4776 Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
4777 == Controller->V2.NextEventSequenceNumber &&
4778 (ControllerInfo->BackgroundInitializationsActive +
4779 ControllerInfo->LogicalDeviceInitializationsActive +
4780 ControllerInfo->PhysicalDeviceInitializationsActive +
4781 ControllerInfo->ConsistencyChecksActive +
4782 ControllerInfo->RebuildsActive +
4783 ControllerInfo->OnlineExpansionsActive == 0 ||
4784 jiffies - Controller->PrimaryMonitoringTime
4785 < DAC960_MonitoringTimerInterval))
4787 Controller->MonitoringTimer.expires =
4788 jiffies + DAC960_HealthStatusMonitoringInterval;
4789 add_timer(&Controller->MonitoringTimer);
4790 return;
4792 Controller->V2.StatusChangeCounter = StatusChangeCounter;
4793 Controller->PrimaryMonitoringTime = jiffies;
4795 Acquire exclusive access to Controller.
4797 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
4799 Queue a Status Monitoring Command to Controller.
4801 Command = DAC960_AllocateCommand(Controller);
4802 if (Command != NULL)
4803 DAC960_V2_QueueMonitoringCommand(Command);
4804 else Controller->MonitoringCommandDeferred = true;
4806 Release exclusive access to Controller.
4808 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
4810 Wake up any processes waiting on a Health Status Buffer change.
4812 wake_up(&Controller->HealthStatusWaitQueue);
4818 DAC960_Open is the Device Open Function for the DAC960 Driver.
4821 static int DAC960_Open(Inode_T *Inode, File_T *File)
4823 int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
4824 int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
4825 DAC960_Controller_T *Controller;
4826 if (ControllerNumber == 0 && LogicalDriveNumber == 0 &&
4827 (File->f_flags & O_NONBLOCK))
4828 goto ModuleOnly;
4829 if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
4830 return -ENXIO;
4831 Controller = DAC960_Controllers[ControllerNumber];
4832 if (Controller == NULL) return -ENXIO;
4833 if (Controller->FirmwareType == DAC960_V1_Controller)
4835 if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
4836 return -ENXIO;
4837 if (Controller->V1.LogicalDriveInformation
4838 [LogicalDriveNumber].LogicalDriveState
4839 == DAC960_V1_LogicalDrive_Offline)
4840 return -ENXIO;
4842 else
4844 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
4845 Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
4846 if (LogicalDeviceInfo == NULL ||
4847 LogicalDeviceInfo->LogicalDeviceState
4848 == DAC960_V2_LogicalDevice_Offline)
4849 return -ENXIO;
4851 if (!Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber])
4853 Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
4854 DAC960_RegisterDisk(Controller, LogicalDriveNumber);
4856 if (Controller->GenericDiskInfo.sizes[MINOR(Inode->i_rdev)] == 0)
4857 return -ENXIO;
4859 Increment Controller and Logical Drive Usage Counts.
4861 Controller->ControllerUsageCount++;
4862 Controller->LogicalDriveUsageCount[LogicalDriveNumber]++;
4863 ModuleOnly:
4864 MOD_INC_USE_COUNT;
4865 return 0;
4870 DAC960_Release is the Device Release Function for the DAC960 Driver.
4873 static int DAC960_Release(Inode_T *Inode, File_T *File)
4875 int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
4876 int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
4877 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
4878 if (ControllerNumber == 0 && LogicalDriveNumber == 0 &&
4879 File != NULL && (File->f_flags & O_NONBLOCK))
4880 goto ModuleOnly;
4882 Decrement the Logical Drive and Controller Usage Counts.
4884 Controller->LogicalDriveUsageCount[LogicalDriveNumber]--;
4885 Controller->ControllerUsageCount--;
4886 ModuleOnly:
4887 MOD_DEC_USE_COUNT;
4888 return 0;
4893 DAC960_IOCTL is the Device IOCTL Function for the DAC960 Driver.
4896 static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
4897 unsigned int Request, unsigned long Argument)
4899 int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
4900 int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
4901 DiskGeometry_T Geometry, *UserGeometry;
4902 DAC960_Controller_T *Controller;
4903 int PartitionNumber;
4904 if (File == NULL) return -EINVAL;
4905 if (File->f_flags & O_NONBLOCK)
4906 return DAC960_UserIOCTL(Inode, File, Request, Argument);
4907 if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
4908 return -ENXIO;
4909 Controller = DAC960_Controllers[ControllerNumber];
4910 if (Controller == NULL) return -ENXIO;
4911 switch (Request)
4913 case HDIO_GETGEO:
4914 /* Get BIOS Disk Geometry. */
4915 UserGeometry = (DiskGeometry_T *) Argument;
4916 if (UserGeometry == NULL) return -EINVAL;
4917 if (Controller->FirmwareType == DAC960_V1_Controller)
4919 if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
4920 return -ENXIO;
4921 Geometry.heads = Controller->V1.GeometryTranslationHeads;
4922 Geometry.sectors = Controller->V1.GeometryTranslationSectors;
4923 Geometry.cylinders =
4924 Controller->V1.LogicalDriveInformation[LogicalDriveNumber]
4925 .LogicalDriveSize
4926 / (Geometry.heads * Geometry.sectors);
4928 else
4930 DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
4931 Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
4932 if (LogicalDeviceInfo == NULL)
4933 return -EINVAL;
4934 switch(LogicalDeviceInfo->DriveGeometry)
4936 case DAC960_V2_Geometry_128_32:
4937 Geometry.heads = 128;
4938 Geometry.sectors = 32;
4939 break;
4940 case DAC960_V2_Geometry_255_63:
4941 Geometry.heads = 255;
4942 Geometry.sectors = 63;
4943 break;
4944 default:
4945 DAC960_Error("Illegal Logical Device Geometry %d\n",
4946 Controller, LogicalDeviceInfo->DriveGeometry);
4947 return -EINVAL;
4949 Geometry.cylinders =
4950 LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB
4951 / (Geometry.heads * Geometry.sectors);
4953 Geometry.start =
4954 Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].start_sect;
4955 return (copy_to_user(UserGeometry, &Geometry,
4956 sizeof(DiskGeometry_T)) ? -EFAULT : 0);
4957 case BLKGETSIZE:
4958 /* Get Device Size. */
4959 if ((long *) Argument == NULL) return -EINVAL;
4960 return put_user(Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
4961 .nr_sects,
4962 (long *) Argument);
4963 case BLKRAGET:
4964 /* Get Read-Ahead. */
4965 if ((long *) Argument == NULL) return -EINVAL;
4966 return put_user(read_ahead[MAJOR(Inode->i_rdev)], (long *) Argument);
4967 case BLKRASET:
4968 /* Set Read-Ahead. */
4969 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
4970 if (Argument > 256) return -EINVAL;
4971 read_ahead[MAJOR(Inode->i_rdev)] = Argument;
4972 return 0;
4973 case BLKFLSBUF:
4974 /* Flush Buffers. */
4975 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
4976 fsync_dev(Inode->i_rdev);
4977 invalidate_buffers(Inode->i_rdev);
4978 return 0;
4979 case BLKRRPART:
4980 /* Re-Read Partition Table. */
4981 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
4982 if (Controller->LogicalDriveUsageCount[LogicalDriveNumber] > 1)
4983 return -EBUSY;
4984 for (PartitionNumber = 0;
4985 PartitionNumber < DAC960_MaxPartitions;
4986 PartitionNumber++)
4988 KernelDevice_T Device = DAC960_KernelDevice(ControllerNumber,
4989 LogicalDriveNumber,
4990 PartitionNumber);
4991 int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber,
4992 PartitionNumber);
4993 SuperBlock_T *SuperBlock = get_super(Device);
4994 if (Controller->GenericDiskInfo.part[MinorNumber].nr_sects == 0)
4995 continue;
4997 Flush all changes and invalidate buffered state.
4999 sync_dev(Device);
5000 if (SuperBlock != NULL)
5001 invalidate_inodes(SuperBlock);
5002 invalidate_buffers(Device);
5004 Clear existing partition sizes.
5006 if (PartitionNumber > 0)
5008 Controller->GenericDiskInfo.part[MinorNumber].start_sect = 0;
5009 Controller->GenericDiskInfo.part[MinorNumber].nr_sects = 0;
5012 Reset the Block Size so that the partition table can be read.
5014 set_blocksize(Device, BLOCK_SIZE);
5016 if (Controller->FirmwareType == DAC960_V1_Controller)
5017 grok_partitions(&Controller->GenericDiskInfo,
5018 LogicalDriveNumber,
5019 DAC960_MaxPartitions,
5020 Controller->V1.LogicalDriveInformation
5021 [LogicalDriveNumber]
5022 .LogicalDriveSize);
5023 else
5024 grok_partitions(
5025 &Controller->GenericDiskInfo,
5026 LogicalDriveNumber,
5027 DAC960_MaxPartitions,
5028 Controller->V2.LogicalDeviceInformation[LogicalDriveNumber]
5029 ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
5030 return 0;
5032 return -EINVAL;
5037 DAC960_UserIOCTL is the User IOCTL Function for the DAC960 Driver.
5040 static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
5041 unsigned int Request, unsigned long Argument)
5043 int ErrorCode;
5044 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
5045 switch (Request)
5047 case DAC960_IOCTL_GET_CONTROLLER_COUNT:
5048 return DAC960_ControllerCount;
5049 case DAC960_IOCTL_GET_CONTROLLER_INFO:
5051 DAC960_ControllerInfo_T *UserSpaceControllerInfo =
5052 (DAC960_ControllerInfo_T *) Argument;
5053 DAC960_ControllerInfo_T ControllerInfo;
5054 DAC960_Controller_T *Controller;
5055 int ControllerNumber;
5056 if (UserSpaceControllerInfo == NULL) return -EINVAL;
5057 ErrorCode = get_user(ControllerNumber,
5058 &UserSpaceControllerInfo->ControllerNumber);
5059 if (ErrorCode != 0) return ErrorCode;
5060 if (ControllerNumber < 0 ||
5061 ControllerNumber > DAC960_ControllerCount - 1)
5062 return -ENXIO;
5063 Controller = DAC960_Controllers[ControllerNumber];
5064 if (Controller == NULL) return -ENXIO;
5065 memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
5066 ControllerInfo.ControllerNumber = ControllerNumber;
5067 ControllerInfo.FirmwareType = Controller->FirmwareType;
5068 ControllerInfo.Channels = Controller->Channels;
5069 ControllerInfo.Targets = Controller->Targets;
5070 ControllerInfo.PCI_Bus = Controller->Bus;
5071 ControllerInfo.PCI_Device = Controller->Device;
5072 ControllerInfo.PCI_Function = Controller->Function;
5073 ControllerInfo.IRQ_Channel = Controller->IRQ_Channel;
5074 ControllerInfo.PCI_Address = Controller->PCI_Address;
5075 strcpy(ControllerInfo.ModelName, Controller->ModelName);
5076 strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
5077 return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
5078 sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0);
5080 case DAC960_IOCTL_V1_EXECUTE_COMMAND:
5082 DAC960_V1_UserCommand_T *UserSpaceUserCommand =
5083 (DAC960_V1_UserCommand_T *) Argument;
5084 DAC960_V1_UserCommand_T UserCommand;
5085 DAC960_Controller_T *Controller;
5086 DAC960_Command_T *Command = NULL;
5087 DAC960_V1_CommandOpcode_T CommandOpcode;
5088 DAC960_V1_CommandStatus_T CommandStatus;
5089 DAC960_V1_DCDB_T DCDB;
5090 ProcessorFlags_T ProcessorFlags;
5091 int ControllerNumber, DataTransferLength;
5092 unsigned char *DataTransferBuffer = NULL;
5093 if (UserSpaceUserCommand == NULL) return -EINVAL;
5094 ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
5095 sizeof(DAC960_V1_UserCommand_T));
5096 if (ErrorCode != 0) goto Failure1;
5097 ControllerNumber = UserCommand.ControllerNumber;
5098 if (ControllerNumber < 0 ||
5099 ControllerNumber > DAC960_ControllerCount - 1)
5100 return -ENXIO;
5101 Controller = DAC960_Controllers[ControllerNumber];
5102 if (Controller == NULL) return -ENXIO;
5103 if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
5104 CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
5105 DataTransferLength = UserCommand.DataTransferLength;
5106 if (CommandOpcode & 0x80) return -EINVAL;
5107 if (CommandOpcode == DAC960_V1_DCDB)
5109 ErrorCode =
5110 copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_V1_DCDB_T));
5111 if (ErrorCode != 0) goto Failure1;
5112 if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL;
5113 if (!((DataTransferLength == 0 &&
5114 DCDB.Direction
5115 == DAC960_V1_DCDB_NoDataTransfer) ||
5116 (DataTransferLength > 0 &&
5117 DCDB.Direction
5118 == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
5119 (DataTransferLength < 0 &&
5120 DCDB.Direction
5121 == DAC960_V1_DCDB_DataTransferSystemToDevice)))
5122 return -EINVAL;
5123 if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
5124 != abs(DataTransferLength))
5125 return -EINVAL;
5127 if (DataTransferLength > 0)
5129 DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
5130 if (DataTransferBuffer == NULL) return -ENOMEM;
5131 memset(DataTransferBuffer, 0, DataTransferLength);
5133 else if (DataTransferLength < 0)
5135 DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
5136 if (DataTransferBuffer == NULL) return -ENOMEM;
5137 ErrorCode = copy_from_user(DataTransferBuffer,
5138 UserCommand.DataTransferBuffer,
5139 -DataTransferLength);
5140 if (ErrorCode != 0) goto Failure1;
5142 if (CommandOpcode == DAC960_V1_DCDB)
5144 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5145 while (Controller->V1.DirectCommandActive[DCDB.Channel]
5146 [DCDB.TargetID] ||
5147 (Command = DAC960_AllocateCommand(Controller)) == NULL)
5148 DAC960_WaitForCommand(Controller);
5149 Controller->V1.DirectCommandActive[DCDB.Channel]
5150 [DCDB.TargetID] = true;
5151 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5152 DAC960_V1_ClearCommand(Command);
5153 Command->CommandType = DAC960_ImmediateCommand;
5154 memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
5155 sizeof(DAC960_V1_CommandMailbox_T));
5156 Command->V1.CommandMailbox.Type3.BusAddress =
5157 Virtual_to_Bus(&DCDB);
5158 DCDB.BusAddress = Virtual_to_Bus(DataTransferBuffer);
5160 else
5162 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5163 while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
5164 DAC960_WaitForCommand(Controller);
5165 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5166 DAC960_V1_ClearCommand(Command);
5167 Command->CommandType = DAC960_ImmediateCommand;
5168 memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
5169 sizeof(DAC960_V1_CommandMailbox_T));
5170 if (DataTransferBuffer != NULL)
5171 Command->V1.CommandMailbox.Type3.BusAddress =
5172 Virtual_to_Bus(DataTransferBuffer);
5174 DAC960_ExecuteCommand(Command);
5175 CommandStatus = Command->V1.CommandStatus;
5176 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5177 DAC960_DeallocateCommand(Command);
5178 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5179 if (DataTransferLength > 0)
5181 ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
5182 DataTransferBuffer, DataTransferLength);
5183 if (ErrorCode != 0) goto Failure1;
5185 if (CommandOpcode == DAC960_V1_DCDB)
5187 Controller->V1.DirectCommandActive[DCDB.Channel]
5188 [DCDB.TargetID] = false;
5189 ErrorCode =
5190 copy_to_user(UserCommand.DCDB, &DCDB, sizeof(DAC960_V1_DCDB_T));
5191 if (ErrorCode != 0) goto Failure1;
5193 ErrorCode = CommandStatus;
5194 Failure1:
5195 if (DataTransferBuffer != NULL)
5196 kfree(DataTransferBuffer);
5197 return ErrorCode;
5199 case DAC960_IOCTL_V2_EXECUTE_COMMAND:
5201 DAC960_V2_UserCommand_T *UserSpaceUserCommand =
5202 (DAC960_V2_UserCommand_T *) Argument;
5203 DAC960_V2_UserCommand_T UserCommand;
5204 DAC960_Controller_T *Controller;
5205 DAC960_Command_T *Command = NULL;
5206 DAC960_V2_CommandMailbox_T *CommandMailbox;
5207 DAC960_V2_CommandStatus_T CommandStatus;
5208 ProcessorFlags_T ProcessorFlags;
5209 int ControllerNumber, DataTransferLength;
5210 int DataTransferResidue, RequestSenseLength;
5211 unsigned char *DataTransferBuffer = NULL;
5212 unsigned char *RequestSenseBuffer = NULL;
5213 if (UserSpaceUserCommand == NULL) return -EINVAL;
5214 ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
5215 sizeof(DAC960_V2_UserCommand_T));
5216 if (ErrorCode != 0) goto Failure2;
5217 ControllerNumber = UserCommand.ControllerNumber;
5218 if (ControllerNumber < 0 ||
5219 ControllerNumber > DAC960_ControllerCount - 1)
5220 return -ENXIO;
5221 Controller = DAC960_Controllers[ControllerNumber];
5222 if (Controller == NULL) return -ENXIO;
5223 if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
5224 DataTransferLength = UserCommand.DataTransferLength;
5225 if (DataTransferLength > 0)
5227 DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
5228 if (DataTransferBuffer == NULL) return -ENOMEM;
5229 memset(DataTransferBuffer, 0, DataTransferLength);
5231 else if (DataTransferLength < 0)
5233 DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
5234 if (DataTransferBuffer == NULL) return -ENOMEM;
5235 ErrorCode = copy_from_user(DataTransferBuffer,
5236 UserCommand.DataTransferBuffer,
5237 -DataTransferLength);
5238 if (ErrorCode != 0) goto Failure2;
5240 RequestSenseLength = UserCommand.RequestSenseLength;
5241 if (RequestSenseLength > 0)
5243 RequestSenseBuffer = kmalloc(RequestSenseLength, GFP_KERNEL);
5244 if (RequestSenseBuffer == NULL)
5246 ErrorCode = -ENOMEM;
5247 goto Failure2;
5249 memset(RequestSenseBuffer, 0, RequestSenseLength);
5251 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5252 while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
5253 DAC960_WaitForCommand(Controller);
5254 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5255 DAC960_V2_ClearCommand(Command);
5256 Command->CommandType = DAC960_ImmediateCommand;
5257 CommandMailbox = &Command->V2.CommandMailbox;
5258 memcpy(CommandMailbox, &UserCommand.CommandMailbox,
5259 sizeof(DAC960_V2_CommandMailbox_T));
5260 CommandMailbox->Common.CommandControlBits
5261 .AdditionalScatterGatherListMemory = false;
5262 CommandMailbox->Common.CommandControlBits
5263 .NoAutoRequestSense = true;
5264 CommandMailbox->Common.DataTransferSize = 0;
5265 CommandMailbox->Common.DataTransferPageNumber = 0;
5266 memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
5267 sizeof(DAC960_V2_DataTransferMemoryAddress_T));
5268 if (DataTransferLength != 0)
5270 if (DataTransferLength > 0)
5272 CommandMailbox->Common.CommandControlBits
5273 .DataTransferControllerToHost = true;
5274 CommandMailbox->Common.DataTransferSize = DataTransferLength;
5276 else
5278 CommandMailbox->Common.CommandControlBits
5279 .DataTransferControllerToHost = false;
5280 CommandMailbox->Common.DataTransferSize = -DataTransferLength;
5282 CommandMailbox->Common.DataTransferMemoryAddress
5283 .ScatterGatherSegments[0]
5284 .SegmentDataPointer =
5285 Virtual_to_Bus(DataTransferBuffer);
5286 CommandMailbox->Common.DataTransferMemoryAddress
5287 .ScatterGatherSegments[0]
5288 .SegmentByteCount =
5289 CommandMailbox->Common.DataTransferSize;
5291 if (RequestSenseLength > 0)
5293 CommandMailbox->Common.CommandControlBits
5294 .NoAutoRequestSense = false;
5295 CommandMailbox->Common.RequestSenseSize = RequestSenseLength;
5296 CommandMailbox->Common.RequestSenseBusAddress =
5297 Virtual_to_Bus(RequestSenseBuffer);
5299 DAC960_ExecuteCommand(Command);
5300 CommandStatus = Command->V2.CommandStatus;
5301 RequestSenseLength = Command->V2.RequestSenseLength;
5302 DataTransferResidue = Command->V2.DataTransferResidue;
5303 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5304 DAC960_DeallocateCommand(Command);
5305 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5306 if (RequestSenseLength > UserCommand.RequestSenseLength)
5307 RequestSenseLength = UserCommand.RequestSenseLength;
5308 ErrorCode = copy_to_user(&UserSpaceUserCommand->DataTransferLength,
5309 &DataTransferResidue,
5310 sizeof(DataTransferResidue));
5311 if (ErrorCode != 0) goto Failure2;
5312 ErrorCode = copy_to_user(&UserSpaceUserCommand->RequestSenseLength,
5313 &RequestSenseLength,
5314 sizeof(RequestSenseLength));
5315 if (ErrorCode != 0) goto Failure2;
5316 if (DataTransferLength > 0)
5318 ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
5319 DataTransferBuffer, DataTransferLength);
5320 if (ErrorCode != 0) goto Failure2;
5322 if (RequestSenseLength > 0)
5324 ErrorCode = copy_to_user(UserCommand.RequestSenseBuffer,
5325 RequestSenseBuffer, RequestSenseLength);
5326 if (ErrorCode != 0) goto Failure2;
5328 ErrorCode = CommandStatus;
5329 Failure2:
5330 if (DataTransferBuffer != NULL)
5331 kfree(DataTransferBuffer);
5332 if (RequestSenseBuffer != NULL)
5333 kfree(RequestSenseBuffer);
5334 return ErrorCode;
5336 case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
5338 DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus =
5339 (DAC960_V2_GetHealthStatus_T *) Argument;
5340 DAC960_V2_GetHealthStatus_T GetHealthStatus;
5341 DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
5342 DAC960_Controller_T *Controller;
5343 int ControllerNumber;
5344 if (UserSpaceGetHealthStatus == NULL) return -EINVAL;
5345 ErrorCode = copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
5346 sizeof(DAC960_V2_GetHealthStatus_T));
5347 if (ErrorCode != 0) return ErrorCode;
5348 ControllerNumber = GetHealthStatus.ControllerNumber;
5349 if (ControllerNumber < 0 ||
5350 ControllerNumber > DAC960_ControllerCount - 1)
5351 return -ENXIO;
5352 Controller = DAC960_Controllers[ControllerNumber];
5353 if (Controller == NULL) return -ENXIO;
5354 if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
5355 ErrorCode = copy_from_user(&HealthStatusBuffer,
5356 GetHealthStatus.HealthStatusBuffer,
5357 sizeof(DAC960_V2_HealthStatusBuffer_T));
5358 if (ErrorCode != 0) return ErrorCode;
5359 while (Controller->V2.HealthStatusBuffer->StatusChangeCounter
5360 == HealthStatusBuffer.StatusChangeCounter &&
5361 Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
5362 == HealthStatusBuffer.NextEventSequenceNumber)
5364 interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue,
5365 DAC960_MonitoringTimerInterval);
5366 if (signal_pending(current)) return -EINTR;
5368 ErrorCode = copy_to_user(GetHealthStatus.HealthStatusBuffer,
5369 Controller->V2.HealthStatusBuffer,
5370 sizeof(DAC960_V2_HealthStatusBuffer_T));
5371 return ErrorCode;
5374 return -EINVAL;
5379 DAC960_KernelIOCTL is the Kernel IOCTL Function for the DAC960 Driver.
5382 int DAC960_KernelIOCTL(unsigned int Request, void *Argument)
5384 switch (Request)
5386 case DAC960_IOCTL_GET_CONTROLLER_COUNT:
5387 return DAC960_ControllerCount;
5388 case DAC960_IOCTL_GET_CONTROLLER_INFO:
5390 DAC960_ControllerInfo_T *ControllerInfo =
5391 (DAC960_ControllerInfo_T *) Argument;
5392 DAC960_Controller_T *Controller;
5393 int ControllerNumber;
5394 if (ControllerInfo == NULL) return -EINVAL;
5395 ControllerNumber = ControllerInfo->ControllerNumber;
5396 if (ControllerNumber < 0 ||
5397 ControllerNumber > DAC960_ControllerCount - 1)
5398 return -ENXIO;
5399 Controller = DAC960_Controllers[ControllerNumber];
5400 if (Controller == NULL) return -ENXIO;
5401 memset(ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
5402 ControllerInfo->ControllerNumber = ControllerNumber;
5403 ControllerInfo->FirmwareType = Controller->FirmwareType;
5404 ControllerInfo->Channels = Controller->Channels;
5405 ControllerInfo->Targets = Controller->Targets;
5406 ControllerInfo->PCI_Bus = Controller->Bus;
5407 ControllerInfo->PCI_Device = Controller->Device;
5408 ControllerInfo->PCI_Function = Controller->Function;
5409 ControllerInfo->IRQ_Channel = Controller->IRQ_Channel;
5410 ControllerInfo->PCI_Address = Controller->PCI_Address;
5411 strcpy(ControllerInfo->ModelName, Controller->ModelName);
5412 strcpy(ControllerInfo->FirmwareVersion, Controller->FirmwareVersion);
5413 return 0;
5415 case DAC960_IOCTL_V1_EXECUTE_COMMAND:
5417 DAC960_V1_KernelCommand_T *KernelCommand =
5418 (DAC960_V1_KernelCommand_T *) Argument;
5419 DAC960_Controller_T *Controller;
5420 DAC960_Command_T *Command = NULL;
5421 DAC960_V1_CommandOpcode_T CommandOpcode;
5422 DAC960_V1_DCDB_T *DCDB = NULL;
5423 ProcessorFlags_T ProcessorFlags;
5424 int ControllerNumber, DataTransferLength;
5425 unsigned char *DataTransferBuffer = NULL;
5426 if (KernelCommand == NULL) return -EINVAL;
5427 ControllerNumber = KernelCommand->ControllerNumber;
5428 if (ControllerNumber < 0 ||
5429 ControllerNumber > DAC960_ControllerCount - 1)
5430 return -ENXIO;
5431 Controller = DAC960_Controllers[ControllerNumber];
5432 if (Controller == NULL) return -ENXIO;
5433 if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
5434 CommandOpcode = KernelCommand->CommandMailbox.Common.CommandOpcode;
5435 DataTransferLength = KernelCommand->DataTransferLength;
5436 DataTransferBuffer = KernelCommand->DataTransferBuffer;
5437 if (CommandOpcode & 0x80) return -EINVAL;
5438 if (CommandOpcode == DAC960_V1_DCDB)
5440 DCDB = KernelCommand->DCDB;
5441 if (DCDB->Channel >= DAC960_V1_MaxChannels) return -EINVAL;
5442 if (!((DataTransferLength == 0 &&
5443 DCDB->Direction == DAC960_V1_DCDB_NoDataTransfer) ||
5444 (DataTransferLength > 0 &&
5445 DCDB->Direction
5446 == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
5447 (DataTransferLength < 0 &&
5448 DCDB->Direction
5449 == DAC960_V1_DCDB_DataTransferSystemToDevice)))
5450 return -EINVAL;
5451 if (((DCDB->TransferLengthHigh4 << 16) | DCDB->TransferLength)
5452 != abs(DataTransferLength))
5453 return -EINVAL;
5455 if (DataTransferLength != 0 && DataTransferBuffer == NULL)
5456 return -EINVAL;
5457 if (DataTransferLength > 0)
5458 memset(DataTransferBuffer, 0, DataTransferLength);
5459 if (CommandOpcode == DAC960_V1_DCDB)
5461 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5462 if (!Controller->V1.DirectCommandActive[DCDB->Channel]
5463 [DCDB->TargetID])
5464 Command = DAC960_AllocateCommand(Controller);
5465 if (Command == NULL)
5467 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5468 return -EBUSY;
5470 else Controller->V1.DirectCommandActive[DCDB->Channel]
5471 [DCDB->TargetID] = true;
5472 DAC960_V1_ClearCommand(Command);
5473 Command->CommandType = DAC960_QueuedCommand;
5474 memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
5475 sizeof(DAC960_V1_CommandMailbox_T));
5476 Command->V1.CommandMailbox.Type3.BusAddress =
5477 Virtual_to_Bus(DCDB);
5478 Command->V1.KernelCommand = KernelCommand;
5479 DCDB->BusAddress = Virtual_to_Bus(DataTransferBuffer);
5480 DAC960_QueueCommand(Command);
5481 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5483 else
5485 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5486 Command = DAC960_AllocateCommand(Controller);
5487 if (Command == NULL)
5489 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5490 return -EBUSY;
5492 DAC960_V1_ClearCommand(Command);
5493 Command->CommandType = DAC960_QueuedCommand;
5494 memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
5495 sizeof(DAC960_V1_CommandMailbox_T));
5496 if (DataTransferBuffer != NULL)
5497 Command->V1.CommandMailbox.Type3.BusAddress =
5498 Virtual_to_Bus(DataTransferBuffer);
5499 Command->V1.KernelCommand = KernelCommand;
5500 DAC960_QueueCommand(Command);
5501 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5503 return 0;
5505 case DAC960_IOCTL_V2_EXECUTE_COMMAND:
5507 DAC960_V2_KernelCommand_T *KernelCommand =
5508 (DAC960_V2_KernelCommand_T *) Argument;
5509 DAC960_Controller_T *Controller;
5510 DAC960_Command_T *Command = NULL;
5511 DAC960_V2_CommandMailbox_T *CommandMailbox;
5512 ProcessorFlags_T ProcessorFlags;
5513 int ControllerNumber, DataTransferLength, RequestSenseLength;
5514 unsigned char *DataTransferBuffer = NULL;
5515 unsigned char *RequestSenseBuffer = NULL;
5516 if (KernelCommand == NULL) return -EINVAL;
5517 ControllerNumber = KernelCommand->ControllerNumber;
5518 if (ControllerNumber < 0 ||
5519 ControllerNumber > DAC960_ControllerCount - 1)
5520 return -ENXIO;
5521 Controller = DAC960_Controllers[ControllerNumber];
5522 if (Controller == NULL) return -ENXIO;
5523 if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
5524 DataTransferLength = KernelCommand->DataTransferLength;
5525 RequestSenseLength = KernelCommand->RequestSenseLength;
5526 DataTransferBuffer = KernelCommand->DataTransferBuffer;
5527 RequestSenseBuffer = KernelCommand->RequestSenseBuffer;
5528 if (DataTransferLength != 0 && DataTransferBuffer == NULL)
5529 return -EINVAL;
5530 if (RequestSenseLength < 0)
5531 return -EINVAL;
5532 if (RequestSenseLength > 0 && RequestSenseBuffer == NULL)
5533 return -EINVAL;
5534 if (DataTransferLength > 0)
5535 memset(DataTransferBuffer, 0, DataTransferLength);
5536 if (RequestSenseLength > 0)
5537 memset(RequestSenseBuffer, 0, RequestSenseLength);
5538 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5539 Command = DAC960_AllocateCommand(Controller);
5540 if (Command == NULL)
5542 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5543 return -EBUSY;
5545 DAC960_V2_ClearCommand(Command);
5546 Command->CommandType = DAC960_QueuedCommand;
5547 CommandMailbox = &Command->V2.CommandMailbox;
5548 memcpy(CommandMailbox, &KernelCommand->CommandMailbox,
5549 sizeof(DAC960_V2_CommandMailbox_T));
5550 CommandMailbox->Common.CommandControlBits
5551 .AdditionalScatterGatherListMemory = false;
5552 CommandMailbox->Common.CommandControlBits
5553 .NoAutoRequestSense = true;
5554 CommandMailbox->Common.DataTransferSize = 0;
5555 CommandMailbox->Common.DataTransferPageNumber = 0;
5556 memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
5557 sizeof(DAC960_V2_DataTransferMemoryAddress_T));
5558 if (DataTransferLength != 0)
5560 if (DataTransferLength > 0)
5562 CommandMailbox->Common.CommandControlBits
5563 .DataTransferControllerToHost = true;
5564 CommandMailbox->Common.DataTransferSize = DataTransferLength;
5566 else
5568 CommandMailbox->Common.CommandControlBits
5569 .DataTransferControllerToHost = false;
5570 CommandMailbox->Common.DataTransferSize = -DataTransferLength;
5572 CommandMailbox->Common.DataTransferMemoryAddress
5573 .ScatterGatherSegments[0]
5574 .SegmentDataPointer =
5575 Virtual_to_Bus(DataTransferBuffer);
5576 CommandMailbox->Common.DataTransferMemoryAddress
5577 .ScatterGatherSegments[0]
5578 .SegmentByteCount =
5579 CommandMailbox->Common.DataTransferSize;
5581 if (RequestSenseLength > 0)
5583 CommandMailbox->Common.CommandControlBits
5584 .NoAutoRequestSense = false;
5585 CommandMailbox->Common.RequestSenseBusAddress =
5586 Virtual_to_Bus(RequestSenseBuffer);
5588 Command->V2.KernelCommand = KernelCommand;
5589 DAC960_QueueCommand(Command);
5590 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5591 return 0;
5594 return -EINVAL;
5599 DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount
5600 additional bytes in the Combined Status Buffer and grows the buffer if
5601 necessary. It returns true if there is enough room and false otherwise.
5604 static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
5605 unsigned int ByteCount)
5607 unsigned char *NewStatusBuffer;
5608 if (Controller->InitialStatusLength + 1 +
5609 Controller->CurrentStatusLength + ByteCount + 1 <=
5610 Controller->CombinedStatusBufferLength)
5611 return true;
5612 if (Controller->CombinedStatusBufferLength == 0)
5614 unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize;
5615 while (NewStatusBufferLength < ByteCount)
5616 NewStatusBufferLength *= 2;
5617 Controller->CombinedStatusBuffer =
5618 (unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC);
5619 if (Controller->CombinedStatusBuffer == NULL) return false;
5620 Controller->CombinedStatusBufferLength = NewStatusBufferLength;
5621 return true;
5623 NewStatusBuffer = (unsigned char *)
5624 kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC);
5625 if (NewStatusBuffer == NULL)
5627 DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n",
5628 Controller);
5629 return false;
5631 memcpy(NewStatusBuffer, Controller->CombinedStatusBuffer,
5632 Controller->CombinedStatusBufferLength);
5633 kfree(Controller->CombinedStatusBuffer);
5634 Controller->CombinedStatusBuffer = NewStatusBuffer;
5635 Controller->CombinedStatusBufferLength *= 2;
5636 Controller->CurrentStatusBuffer =
5637 &NewStatusBuffer[Controller->InitialStatusLength + 1];
5638 return true;
5643 DAC960_Message prints Driver Messages.
5646 static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
5647 unsigned char *Format,
5648 DAC960_Controller_T *Controller,
5649 ...)
5651 static unsigned char Buffer[DAC960_LineBufferSize];
5652 static boolean BeginningOfLine = true;
5653 va_list Arguments;
5654 int Length = 0;
5655 va_start(Arguments, Controller);
5656 Length = vsprintf(Buffer, Format, Arguments);
5657 va_end(Arguments);
5658 if (Controller == NULL)
5659 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
5660 DAC960_ControllerCount, Buffer);
5661 else if (MessageLevel == DAC960_AnnounceLevel ||
5662 MessageLevel == DAC960_InfoLevel)
5664 if (!Controller->ControllerInitialized)
5666 if (DAC960_CheckStatusBuffer(Controller, Length))
5668 strcpy(&Controller->CombinedStatusBuffer
5669 [Controller->InitialStatusLength],
5670 Buffer);
5671 Controller->InitialStatusLength += Length;
5672 Controller->CurrentStatusBuffer =
5673 &Controller->CombinedStatusBuffer
5674 [Controller->InitialStatusLength + 1];
5676 if (MessageLevel == DAC960_AnnounceLevel)
5678 static int AnnouncementLines;
5679 if (++AnnouncementLines <= 2)
5680 printk("%sDAC960: %s", DAC960_MessageLevelMap[MessageLevel],
5681 Buffer);
5683 else
5685 if (BeginningOfLine)
5687 if (Buffer[0] != '\n' || Length > 1)
5688 printk("%sDAC960#%d: %s",
5689 DAC960_MessageLevelMap[MessageLevel],
5690 Controller->ControllerNumber, Buffer);
5692 else printk("%s", Buffer);
5695 else if (DAC960_CheckStatusBuffer(Controller, Length))
5697 strcpy(&Controller->CurrentStatusBuffer[
5698 Controller->CurrentStatusLength], Buffer);
5699 Controller->CurrentStatusLength += Length;
5702 else if (MessageLevel == DAC960_ProgressLevel)
5704 strcpy(Controller->ProgressBuffer, Buffer);
5705 Controller->ProgressBufferLength = Length;
5706 if (Controller->EphemeralProgressMessage)
5708 if (jiffies - Controller->LastProgressReportTime
5709 >= DAC960_ProgressReportingInterval)
5711 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
5712 Controller->ControllerNumber, Buffer);
5713 Controller->LastProgressReportTime = jiffies;
5716 else printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
5717 Controller->ControllerNumber, Buffer);
5719 else if (MessageLevel == DAC960_UserCriticalLevel)
5721 strcpy(&Controller->UserStatusBuffer[Controller->UserStatusLength],
5722 Buffer);
5723 Controller->UserStatusLength += Length;
5724 if (Buffer[0] != '\n' || Length > 1)
5725 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
5726 Controller->ControllerNumber, Buffer);
5728 else
5730 if (BeginningOfLine)
5731 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
5732 Controller->ControllerNumber, Buffer);
5733 else printk("%s", Buffer);
5735 BeginningOfLine = (Buffer[Length-1] == '\n');
5740 DAC960_ParsePhysicalDevice parses spaces followed by a Physical Device
5741 Channel:TargetID specification from a User Command string. It updates
5742 Channel and TargetID and returns true on success and false on failure.
5745 static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
5746 char *UserCommandString,
5747 unsigned char *Channel,
5748 unsigned char *TargetID)
5750 char *NewUserCommandString = UserCommandString;
5751 unsigned long XChannel, XTargetID;
5752 while (*UserCommandString == ' ') UserCommandString++;
5753 if (UserCommandString == NewUserCommandString)
5754 return false;
5755 XChannel = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
5756 if (NewUserCommandString == UserCommandString ||
5757 *NewUserCommandString != ':' ||
5758 XChannel >= Controller->Channels)
5759 return false;
5760 UserCommandString = ++NewUserCommandString;
5761 XTargetID = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
5762 if (NewUserCommandString == UserCommandString ||
5763 *NewUserCommandString != '\0' ||
5764 XTargetID >= Controller->Targets)
5765 return false;
5766 *Channel = XChannel;
5767 *TargetID = XTargetID;
5768 return true;
5773 DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number
5774 specification from a User Command string. It updates LogicalDriveNumber and
5775 returns true on success and false on failure.
5778 static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
5779 char *UserCommandString,
5780 unsigned char *LogicalDriveNumber)
5782 char *NewUserCommandString = UserCommandString;
5783 unsigned long XLogicalDriveNumber;
5784 while (*UserCommandString == ' ') UserCommandString++;
5785 if (UserCommandString == NewUserCommandString)
5786 return false;
5787 XLogicalDriveNumber =
5788 simple_strtoul(UserCommandString, &NewUserCommandString, 10);
5789 if (NewUserCommandString == UserCommandString ||
5790 *NewUserCommandString != '\0' ||
5791 XLogicalDriveNumber > DAC960_MaxLogicalDrives - 1)
5792 return false;
5793 *LogicalDriveNumber = XLogicalDriveNumber;
5794 return true;
5799 DAC960_V1_SetDeviceState sets the Device State for a Physical Device for
5800 DAC960 V1 Firmware Controllers.
5803 static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller,
5804 DAC960_Command_T *Command,
5805 unsigned char Channel,
5806 unsigned char TargetID,
5807 DAC960_V1_PhysicalDeviceState_T
5808 DeviceState,
5809 const unsigned char *DeviceStateString)
5811 DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
5812 CommandMailbox->Type3D.CommandOpcode = DAC960_V1_StartDevice;
5813 CommandMailbox->Type3D.Channel = Channel;
5814 CommandMailbox->Type3D.TargetID = TargetID;
5815 CommandMailbox->Type3D.DeviceState = DeviceState;
5816 CommandMailbox->Type3D.Modifier = 0;
5817 DAC960_ExecuteCommand(Command);
5818 switch (Command->V1.CommandStatus)
5820 case DAC960_V1_NormalCompletion:
5821 DAC960_UserCritical("%s of Physical Device %d:%d Succeeded\n", Controller,
5822 DeviceStateString, Channel, TargetID);
5823 break;
5824 case DAC960_V1_UnableToStartDevice:
5825 DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
5826 "Unable to Start Device\n", Controller,
5827 DeviceStateString, Channel, TargetID);
5828 break;
5829 case DAC960_V1_NoDeviceAtAddress:
5830 DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
5831 "No Device at Address\n", Controller,
5832 DeviceStateString, Channel, TargetID);
5833 break;
5834 case DAC960_V1_InvalidChannelOrTargetOrModifier:
5835 DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
5836 "Invalid Channel or Target or Modifier\n",
5837 Controller, DeviceStateString, Channel, TargetID);
5838 break;
5839 case DAC960_V1_ChannelBusy:
5840 DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
5841 "Channel Busy\n", Controller,
5842 DeviceStateString, Channel, TargetID);
5843 break;
5844 default:
5845 DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
5846 "Unexpected Status %04X\n", Controller,
5847 DeviceStateString, Channel, TargetID,
5848 Command->V1.CommandStatus);
5849 break;
5855 DAC960_V1_ExecuteUserCommand executes a User Command for DAC960 V1 Firmware
5856 Controllers.
5859 static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
5860 unsigned char *UserCommand)
5862 DAC960_Command_T *Command;
5863 DAC960_V1_CommandMailbox_T *CommandMailbox;
5864 ProcessorFlags_T ProcessorFlags;
5865 unsigned char Channel, TargetID, LogicalDriveNumber;
5866 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5867 while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
5868 DAC960_WaitForCommand(Controller);
5869 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5870 Controller->UserStatusLength = 0;
5871 DAC960_V1_ClearCommand(Command);
5872 Command->CommandType = DAC960_ImmediateCommand;
5873 CommandMailbox = &Command->V1.CommandMailbox;
5874 if (strcmp(UserCommand, "flush-cache") == 0)
5876 CommandMailbox->Type3.CommandOpcode = DAC960_V1_Flush;
5877 DAC960_ExecuteCommand(Command);
5878 DAC960_UserCritical("Cache Flush Completed\n", Controller);
5880 else if (strncmp(UserCommand, "kill", 4) == 0 &&
5881 DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
5882 &Channel, &TargetID))
5884 DAC960_V1_DeviceState_T *DeviceState =
5885 &Controller->V1.DeviceState[Channel][TargetID];
5886 if (DeviceState->Present &&
5887 DeviceState->DeviceType == DAC960_V1_DiskType &&
5888 DeviceState->DeviceState != DAC960_V1_Device_Dead)
5889 DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
5890 DAC960_V1_Device_Dead, "Kill");
5891 else DAC960_UserCritical("Kill of Physical Device %d:%d Illegal\n",
5892 Controller, Channel, TargetID);
5894 else if (strncmp(UserCommand, "make-online", 11) == 0 &&
5895 DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
5896 &Channel, &TargetID))
5898 DAC960_V1_DeviceState_T *DeviceState =
5899 &Controller->V1.DeviceState[Channel][TargetID];
5900 if (DeviceState->Present &&
5901 DeviceState->DeviceType == DAC960_V1_DiskType &&
5902 DeviceState->DeviceState == DAC960_V1_Device_Dead)
5903 DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
5904 DAC960_V1_Device_Online, "Make Online");
5905 else DAC960_UserCritical("Make Online of Physical Device %d:%d Illegal\n",
5906 Controller, Channel, TargetID);
5909 else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
5910 DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
5911 &Channel, &TargetID))
5913 DAC960_V1_DeviceState_T *DeviceState =
5914 &Controller->V1.DeviceState[Channel][TargetID];
5915 if (DeviceState->Present &&
5916 DeviceState->DeviceType == DAC960_V1_DiskType &&
5917 DeviceState->DeviceState == DAC960_V1_Device_Dead)
5918 DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
5919 DAC960_V1_Device_Standby, "Make Standby");
5920 else DAC960_UserCritical("Make Standby of Physical "
5921 "Device %d:%d Illegal\n",
5922 Controller, Channel, TargetID);
5924 else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
5925 DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
5926 &Channel, &TargetID))
5928 CommandMailbox->Type3D.CommandOpcode = DAC960_V1_RebuildAsync;
5929 CommandMailbox->Type3D.Channel = Channel;
5930 CommandMailbox->Type3D.TargetID = TargetID;
5931 DAC960_ExecuteCommand(Command);
5932 switch (Command->V1.CommandStatus)
5934 case DAC960_V1_NormalCompletion:
5935 DAC960_UserCritical("Rebuild of Physical Device %d:%d Initiated\n",
5936 Controller, Channel, TargetID);
5937 break;
5938 case DAC960_V1_AttemptToRebuildOnlineDrive:
5939 DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
5940 "Attempt to Rebuild Online or "
5941 "Unresponsive Drive\n",
5942 Controller, Channel, TargetID);
5943 break;
5944 case DAC960_V1_NewDiskFailedDuringRebuild:
5945 DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
5946 "New Disk Failed During Rebuild\n",
5947 Controller, Channel, TargetID);
5948 break;
5949 case DAC960_V1_InvalidDeviceAddress:
5950 DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
5951 "Invalid Device Address\n",
5952 Controller, Channel, TargetID);
5953 break;
5954 case DAC960_V1_RebuildOrCheckAlreadyInProgress:
5955 DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
5956 "Rebuild or Consistency Check Already "
5957 "in Progress\n", Controller, Channel, TargetID);
5958 break;
5959 default:
5960 DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
5961 "Unexpected Status %04X\n", Controller,
5962 Channel, TargetID, Command->V1.CommandStatus);
5963 break;
5966 else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
5967 DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
5968 &LogicalDriveNumber))
5970 CommandMailbox->Type3C.CommandOpcode = DAC960_V1_CheckConsistencyAsync;
5971 CommandMailbox->Type3C.LogicalDriveNumber = LogicalDriveNumber;
5972 CommandMailbox->Type3C.AutoRestore = true;
5973 DAC960_ExecuteCommand(Command);
5974 switch (Command->V1.CommandStatus)
5976 case DAC960_V1_NormalCompletion:
5977 DAC960_UserCritical("Consistency Check of Logical Drive %d "
5978 "(/dev/rd/c%dd%d) Initiated\n",
5979 Controller, LogicalDriveNumber,
5980 Controller->ControllerNumber,
5981 LogicalDriveNumber);
5982 break;
5983 case DAC960_V1_DependentDiskIsDead:
5984 DAC960_UserCritical("Consistency Check of Logical Drive %d "
5985 "(/dev/rd/c%dd%d) Failed - "
5986 "Dependent Physical Device is DEAD\n",
5987 Controller, LogicalDriveNumber,
5988 Controller->ControllerNumber,
5989 LogicalDriveNumber);
5990 break;
5991 case DAC960_V1_InvalidOrNonredundantLogicalDrive:
5992 DAC960_UserCritical("Consistency Check of Logical Drive %d "
5993 "(/dev/rd/c%dd%d) Failed - "
5994 "Invalid or Nonredundant Logical Drive\n",
5995 Controller, LogicalDriveNumber,
5996 Controller->ControllerNumber,
5997 LogicalDriveNumber);
5998 break;
5999 case DAC960_V1_RebuildOrCheckAlreadyInProgress:
6000 DAC960_UserCritical("Consistency Check of Logical Drive %d "
6001 "(/dev/rd/c%dd%d) Failed - Rebuild or "
6002 "Consistency Check Already in Progress\n",
6003 Controller, LogicalDriveNumber,
6004 Controller->ControllerNumber,
6005 LogicalDriveNumber);
6006 break;
6007 default:
6008 DAC960_UserCritical("Consistency Check of Logical Drive %d "
6009 "(/dev/rd/c%dd%d) Failed - "
6010 "Unexpected Status %04X\n",
6011 Controller, LogicalDriveNumber,
6012 Controller->ControllerNumber,
6013 LogicalDriveNumber, Command->V1.CommandStatus);
6014 break;
6017 else if (strcmp(UserCommand, "cancel-rebuild") == 0 ||
6018 strcmp(UserCommand, "cancel-consistency-check") == 0)
6020 unsigned char OldRebuildRateConstant;
6021 CommandMailbox->Type3R.CommandOpcode = DAC960_V1_RebuildControl;
6022 CommandMailbox->Type3R.RebuildRateConstant = 0xFF;
6023 CommandMailbox->Type3R.BusAddress =
6024 Virtual_to_Bus(&OldRebuildRateConstant);
6025 DAC960_ExecuteCommand(Command);
6026 switch (Command->V1.CommandStatus)
6028 case DAC960_V1_NormalCompletion:
6029 DAC960_UserCritical("Rebuild or Consistency Check Cancelled\n",
6030 Controller);
6031 break;
6032 default:
6033 DAC960_UserCritical("Cancellation of Rebuild or "
6034 "Consistency Check Failed - "
6035 "Unexpected Status %04X\n",
6036 Controller, Command->V1.CommandStatus);
6037 break;
6040 else DAC960_UserCritical("Illegal User Command: '%s'\n",
6041 Controller, UserCommand);
6042 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6043 DAC960_DeallocateCommand(Command);
6044 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6045 return true;
6050 DAC960_V2_TranslatePhysicalDevice translates a Physical Device Channel and
6051 TargetID into a Logical Device. It returns true on success and false
6052 on failure.
6055 static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
6056 unsigned char Channel,
6057 unsigned char TargetID,
6058 unsigned short
6059 *LogicalDeviceNumber)
6061 DAC960_V2_CommandMailbox_T SavedCommandMailbox, *CommandMailbox;
6062 DAC960_V2_PhysicalToLogicalDevice_T PhysicalToLogicalDevice;
6063 CommandMailbox = &Command->V2.CommandMailbox;
6064 memcpy(&SavedCommandMailbox, CommandMailbox,
6065 sizeof(DAC960_V2_CommandMailbox_T));
6066 CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
6067 CommandMailbox->PhysicalDeviceInfo.CommandControlBits
6068 .DataTransferControllerToHost = true;
6069 CommandMailbox->PhysicalDeviceInfo.CommandControlBits
6070 .NoAutoRequestSense = true;
6071 CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
6072 sizeof(DAC960_V2_PhysicalToLogicalDevice_T);
6073 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
6074 CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
6075 CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
6076 DAC960_V2_TranslatePhysicalToLogicalDevice;
6077 CommandMailbox->Common.DataTransferMemoryAddress
6078 .ScatterGatherSegments[0]
6079 .SegmentDataPointer =
6080 Virtual_to_Bus(&PhysicalToLogicalDevice);
6081 CommandMailbox->Common.DataTransferMemoryAddress
6082 .ScatterGatherSegments[0]
6083 .SegmentByteCount =
6084 CommandMailbox->Common.DataTransferSize;
6085 DAC960_ExecuteCommand(Command);
6086 memcpy(CommandMailbox, &SavedCommandMailbox,
6087 sizeof(DAC960_V2_CommandMailbox_T));
6088 *LogicalDeviceNumber = PhysicalToLogicalDevice.LogicalDeviceNumber;
6089 return (Command->V2.CommandStatus == DAC960_V2_NormalCompletion);
6094 DAC960_V2_ExecuteUserCommand executes a User Command for DAC960 V2 Firmware
6095 Controllers.
6098 static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
6099 unsigned char *UserCommand)
6101 DAC960_Command_T *Command;
6102 DAC960_V2_CommandMailbox_T *CommandMailbox;
6103 ProcessorFlags_T ProcessorFlags;
6104 unsigned char Channel, TargetID, LogicalDriveNumber;
6105 unsigned short LogicalDeviceNumber;
6106 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6107 while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
6108 DAC960_WaitForCommand(Controller);
6109 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6110 Controller->UserStatusLength = 0;
6111 DAC960_V2_ClearCommand(Command);
6112 Command->CommandType = DAC960_ImmediateCommand;
6113 CommandMailbox = &Command->V2.CommandMailbox;
6114 CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
6115 CommandMailbox->Common.CommandControlBits.DataTransferControllerToHost = true;
6116 CommandMailbox->Common.CommandControlBits.NoAutoRequestSense = true;
6117 if (strcmp(UserCommand, "flush-cache") == 0)
6119 CommandMailbox->DeviceOperation.IOCTL_Opcode = DAC960_V2_PauseDevice;
6120 CommandMailbox->DeviceOperation.OperationDevice =
6121 DAC960_V2_RAID_Controller;
6122 DAC960_ExecuteCommand(Command);
6123 DAC960_UserCritical("Cache Flush Completed\n", Controller);
6125 else if (strncmp(UserCommand, "kill", 4) == 0 &&
6126 DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
6127 &Channel, &TargetID) &&
6128 DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6129 &LogicalDeviceNumber))
6131 CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
6132 LogicalDeviceNumber;
6133 CommandMailbox->SetDeviceState.IOCTL_Opcode =
6134 DAC960_V2_SetDeviceState;
6135 CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
6136 DAC960_V2_Device_Dead;
6137 DAC960_ExecuteCommand(Command);
6138 DAC960_UserCritical("Kill of Physical Device %d:%d %s\n",
6139 Controller, Channel, TargetID,
6140 (Command->V2.CommandStatus
6141 == DAC960_V2_NormalCompletion
6142 ? "Succeeded" : "Failed"));
6144 else if (strncmp(UserCommand, "make-online", 11) == 0 &&
6145 DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
6146 &Channel, &TargetID) &&
6147 DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6148 &LogicalDeviceNumber))
6150 CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
6151 LogicalDeviceNumber;
6152 CommandMailbox->SetDeviceState.IOCTL_Opcode =
6153 DAC960_V2_SetDeviceState;
6154 CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
6155 DAC960_V2_Device_Online;
6156 DAC960_ExecuteCommand(Command);
6157 DAC960_UserCritical("Make Online of Physical Device %d:%d %s\n",
6158 Controller, Channel, TargetID,
6159 (Command->V2.CommandStatus
6160 == DAC960_V2_NormalCompletion
6161 ? "Succeeded" : "Failed"));
6163 else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
6164 DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
6165 &Channel, &TargetID) &&
6166 DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6167 &LogicalDeviceNumber))
6169 CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
6170 LogicalDeviceNumber;
6171 CommandMailbox->SetDeviceState.IOCTL_Opcode =
6172 DAC960_V2_SetDeviceState;
6173 CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
6174 DAC960_V2_Device_Standby;
6175 DAC960_ExecuteCommand(Command);
6176 DAC960_UserCritical("Make Standby of Physical Device %d:%d %s\n",
6177 Controller, Channel, TargetID,
6178 (Command->V2.CommandStatus
6179 == DAC960_V2_NormalCompletion
6180 ? "Succeeded" : "Failed"));
6182 else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
6183 DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
6184 &Channel, &TargetID) &&
6185 DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6186 &LogicalDeviceNumber))
6188 CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
6189 LogicalDeviceNumber;
6190 CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
6191 DAC960_V2_RebuildDeviceStart;
6192 DAC960_ExecuteCommand(Command);
6193 DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
6194 Controller, Channel, TargetID,
6195 (Command->V2.CommandStatus
6196 == DAC960_V2_NormalCompletion
6197 ? "Initiated" : "Not Initiated"));
6199 else if (strncmp(UserCommand, "cancel-rebuild", 14) == 0 &&
6200 DAC960_ParsePhysicalDevice(Controller, &UserCommand[14],
6201 &Channel, &TargetID) &&
6202 DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6203 &LogicalDeviceNumber))
6205 CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
6206 LogicalDeviceNumber;
6207 CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
6208 DAC960_V2_RebuildDeviceStop;
6209 DAC960_ExecuteCommand(Command);
6210 DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
6211 Controller, Channel, TargetID,
6212 (Command->V2.CommandStatus
6213 == DAC960_V2_NormalCompletion
6214 ? "Cancelled" : "Not Cancelled"));
6216 else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
6217 DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
6218 &LogicalDriveNumber))
6220 CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
6221 LogicalDriveNumber;
6222 CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
6223 DAC960_V2_ConsistencyCheckStart;
6224 CommandMailbox->ConsistencyCheck.RestoreConsistency = true;
6225 CommandMailbox->ConsistencyCheck.InitializedAreaOnly = false;
6226 DAC960_ExecuteCommand(Command);
6227 DAC960_UserCritical("Consistency Check of Logical Drive %d "
6228 "(/dev/rd/c%dd%d) %s\n",
6229 Controller, LogicalDriveNumber,
6230 Controller->ControllerNumber,
6231 LogicalDriveNumber,
6232 (Command->V2.CommandStatus
6233 == DAC960_V2_NormalCompletion
6234 ? "Initiated" : "Not Initiated"));
6236 else if (strncmp(UserCommand, "cancel-consistency-check", 24) == 0 &&
6237 DAC960_ParseLogicalDrive(Controller, &UserCommand[24],
6238 &LogicalDriveNumber))
6240 CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
6241 LogicalDriveNumber;
6242 CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
6243 DAC960_V2_ConsistencyCheckStop;
6244 DAC960_ExecuteCommand(Command);
6245 DAC960_UserCritical("Consistency Check of Logical Drive %d "
6246 "(/dev/rd/c%dd%d) %s\n",
6247 Controller, LogicalDriveNumber,
6248 Controller->ControllerNumber,
6249 LogicalDriveNumber,
6250 (Command->V2.CommandStatus
6251 == DAC960_V2_NormalCompletion
6252 ? "Cancelled" : "Not Cancelled"));
6254 else if (strcmp(UserCommand, "suppress-enclosure-messages") == 0)
6255 Controller->SuppressEnclosureMessages = true;
6256 else DAC960_UserCritical("Illegal User Command: '%s'\n",
6257 Controller, UserCommand);
6258 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6259 DAC960_DeallocateCommand(Command);
6260 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6261 return true;
6266 DAC960_ProcReadStatus implements reading /proc/rd/status.
6269 static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
6270 int Count, int *EOF, void *Data)
6272 unsigned char *StatusMessage = "OK\n";
6273 int ControllerNumber, BytesAvailable;
6274 for (ControllerNumber = 0;
6275 ControllerNumber < DAC960_ControllerCount;
6276 ControllerNumber++)
6278 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
6279 if (Controller == NULL) continue;
6280 if (Controller->MonitoringAlertMode)
6282 StatusMessage = "ALERT\n";
6283 break;
6286 BytesAvailable = strlen(StatusMessage) - Offset;
6287 if (Count >= BytesAvailable)
6289 Count = BytesAvailable;
6290 *EOF = true;
6292 if (Count <= 0) return 0;
6293 *Start = Page;
6294 memcpy(Page, &StatusMessage[Offset], Count);
6295 return Count;
6300 DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status.
6303 static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset,
6304 int Count, int *EOF, void *Data)
6306 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6307 int BytesAvailable = Controller->InitialStatusLength - Offset;
6308 if (Count >= BytesAvailable)
6310 Count = BytesAvailable;
6311 *EOF = true;
6313 if (Count <= 0) return 0;
6314 *Start = Page;
6315 memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
6316 return Count;
6321 DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status.
6324 static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
6325 int Count, int *EOF, void *Data)
6327 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6328 unsigned char *StatusMessage =
6329 "No Rebuild or Consistency Check in Progress\n";
6330 int ProgressMessageLength = strlen(StatusMessage);
6331 int BytesAvailable;
6332 if (jiffies != Controller->LastCurrentStatusTime)
6334 Controller->CurrentStatusLength = 0;
6335 DAC960_AnnounceDriver(Controller);
6336 DAC960_ReportControllerConfiguration(Controller);
6337 DAC960_ReportDeviceConfiguration(Controller);
6338 if (Controller->ProgressBufferLength > 0)
6339 ProgressMessageLength = Controller->ProgressBufferLength;
6340 if (DAC960_CheckStatusBuffer(Controller, 2 + ProgressMessageLength))
6342 unsigned char *CurrentStatusBuffer = Controller->CurrentStatusBuffer;
6343 CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
6344 CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
6345 if (Controller->ProgressBufferLength > 0)
6346 strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
6347 Controller->ProgressBuffer);
6348 else
6349 strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
6350 StatusMessage);
6351 Controller->CurrentStatusLength += ProgressMessageLength;
6353 Controller->LastCurrentStatusTime = jiffies;
6355 BytesAvailable = Controller->CurrentStatusLength - Offset;
6356 if (Count >= BytesAvailable)
6358 Count = BytesAvailable;
6359 *EOF = true;
6361 if (Count <= 0) return 0;
6362 *Start = Page;
6363 memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count);
6364 return Count;
6369 DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command.
6372 static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset,
6373 int Count, int *EOF, void *Data)
6375 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6376 int BytesAvailable = Controller->UserStatusLength - Offset;
6377 if (Count >= BytesAvailable)
6379 Count = BytesAvailable;
6380 *EOF = true;
6382 if (Count <= 0) return 0;
6383 *Start = Page;
6384 memcpy(Page, &Controller->UserStatusBuffer[Offset], Count);
6385 return Count;
6390 DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
6393 static int DAC960_ProcWriteUserCommand(File_T *File, const char *Buffer,
6394 unsigned long Count, void *Data)
6396 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6397 unsigned char CommandBuffer[80];
6398 int Length;
6399 if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
6400 if (copy_from_user(CommandBuffer, Buffer, Count)) return -EFAULT;
6401 CommandBuffer[Count] = '\0';
6402 Length = strlen(CommandBuffer);
6403 if (CommandBuffer[Length-1] == '\n')
6404 CommandBuffer[--Length] = '\0';
6405 if (Controller->FirmwareType == DAC960_V1_Controller)
6406 return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer)
6407 ? Count : -EBUSY);
6408 else
6409 return (DAC960_V2_ExecuteUserCommand(Controller, CommandBuffer)
6410 ? Count : -EBUSY);
6415 DAC960_CreateProcEntries creates the /proc/rd/... entries for the
6416 DAC960 Driver.
6419 static void DAC960_CreateProcEntries(void)
6421 PROC_DirectoryEntry_T *StatusProcEntry;
6422 int ControllerNumber;
6423 DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
6424 StatusProcEntry = create_proc_read_entry("status", 0,
6425 DAC960_ProcDirectoryEntry,
6426 DAC960_ProcReadStatus, NULL);
6427 for (ControllerNumber = 0;
6428 ControllerNumber < DAC960_ControllerCount;
6429 ControllerNumber++)
6431 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
6432 PROC_DirectoryEntry_T *ControllerProcEntry;
6433 PROC_DirectoryEntry_T *UserCommandProcEntry;
6434 if (Controller == NULL) continue;
6435 sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
6436 ControllerProcEntry = proc_mkdir(Controller->ControllerName,
6437 DAC960_ProcDirectoryEntry);
6438 create_proc_read_entry("initial_status", 0, ControllerProcEntry,
6439 DAC960_ProcReadInitialStatus, Controller);
6440 create_proc_read_entry("current_status", 0, ControllerProcEntry,
6441 DAC960_ProcReadCurrentStatus, Controller);
6442 UserCommandProcEntry =
6443 create_proc_read_entry("user_command", S_IWUSR | S_IRUSR,
6444 ControllerProcEntry, DAC960_ProcReadUserCommand,
6445 Controller);
6446 UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
6447 Controller->ControllerProcEntry = ControllerProcEntry;
6453 DAC960_DestroyProcEntries destroys the /proc/rd/... entries for the
6454 DAC960 Driver.
6457 static void DAC960_DestroyProcEntries(void)
6459 int ControllerNumber;
6460 for (ControllerNumber = 0;
6461 ControllerNumber < DAC960_ControllerCount;
6462 ControllerNumber++)
6464 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
6465 if (Controller == NULL) continue;
6466 remove_proc_entry("initial_status", Controller->ControllerProcEntry);
6467 remove_proc_entry("current_status", Controller->ControllerProcEntry);
6468 remove_proc_entry("user_command", Controller->ControllerProcEntry);
6469 remove_proc_entry(Controller->ControllerName, DAC960_ProcDirectoryEntry);
6471 remove_proc_entry("rd/status", NULL);
6472 remove_proc_entry("rd", NULL);
6477 Include Module support if requested.
6480 #ifdef MODULE
6483 int init_module(void)
6485 DAC960_Initialize();
6486 return (DAC960_ActiveControllerCount > 0 ? 0 : -1);
6490 void cleanup_module(void)
6492 DAC960_Finalize(&DAC960_NotifierBlock, SYS_RESTART, NULL);
6496 #endif