Import 2.3.18pre1
[davej-history.git] / drivers / block / DAC960.c
blob06eed22796e0103c50f1264db36f3122e6f0ebf8
1 /*
3 Linux Driver for Mylex DAC960 and DAC1100 PCI RAID Controllers
5 Copyright 1998-1999 by Leonard N. Zubkoff <lnz@dandelion.com>
7 This program is free software; you may redistribute and/or modify it under
8 the terms of the GNU General Public License Version 2 as published by the
9 Free Software Foundation.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for complete details.
16 The author respectfully requests that any modifications to this software be
17 sent directly to him for evaluation and testing.
22 #define DAC960_DriverVersion "2.2.4"
23 #define DAC960_DriverDate "23 August 1999"
26 #include <linux/version.h>
27 #include <linux/module.h>
28 #include <linux/types.h>
29 #include <linux/blk.h>
30 #include <linux/blkdev.h>
31 #include <linux/delay.h>
32 #include <linux/hdreg.h>
33 #include <linux/interrupt.h>
34 #include <linux/ioport.h>
35 #include <linux/locks.h>
36 #include <linux/mm.h>
37 #include <linux/malloc.h>
38 #include <linux/proc_fs.h>
39 #include <linux/reboot.h>
40 #include <linux/timer.h>
41 #include <linux/pci.h>
42 #include <asm/io.h>
43 #include <asm/segment.h>
44 #include <linux/spinlock.h>
45 #include <asm/uaccess.h>
46 #include "DAC960.h"
50 DAC960_ControllerCount is the number of DAC960 Controllers detected.
53 static int
54 DAC960_ControllerCount = 0;
58 DAC960_ActiveControllerCount is the number of Active DAC960 Controllers
59 detected.
62 static int
63 DAC960_ActiveControllerCount = 0;
67 DAC960_Controllers is an array of pointers to the DAC960 Controller
68 structures.
71 static DAC960_Controller_T
72 *DAC960_Controllers[DAC960_MaxControllers] = { NULL };
76 DAC960_FileOperations is the File Operations structure for DAC960 Logical
77 Disk Devices.
80 static FileOperations_T
81 DAC960_FileOperations =
82 { llseek: NULL,
83 read: block_read,
84 write: block_write,
85 readdir: NULL,
86 poll: NULL,
87 ioctl: DAC960_IOCTL,
88 mmap: NULL,
89 open: DAC960_Open,
90 release: DAC960_Release,
91 fsync: block_fsync,
92 fasync: NULL,
93 check_media_change: NULL,
94 revalidate: NULL };
98 DAC960_ProcDirectoryEntry is the DAC960 /proc/rd directory entry.
101 static PROC_DirectoryEntry_T
102 DAC960_ProcDirectoryEntry;
106 DAC960_NotifierBlock is the Notifier Block structure for DAC960 Driver.
109 static NotifierBlock_T
110 DAC960_NotifierBlock = { DAC960_Finalize, NULL, 0 };
114 DAC960_AnnounceDriver announces the Driver Version and Date, Author's Name,
115 Copyright Notice, and Electronic Mail Address.
118 static void DAC960_AnnounceDriver(DAC960_Controller_T *Controller)
120 DAC960_Announce("***** DAC960 RAID Driver Version "
121 DAC960_DriverVersion " of "
122 DAC960_DriverDate " *****\n", Controller);
123 DAC960_Announce("Copyright 1998-1999 by Leonard N. Zubkoff "
124 "<lnz@dandelion.com>\n", Controller);
129 DAC960_Failure prints a standardized error message, and then returns false.
132 static boolean DAC960_Failure(DAC960_Controller_T *Controller,
133 char *ErrorMessage)
135 DAC960_Error("While configuring DAC960 PCI RAID Controller at\n",
136 Controller);
137 if (Controller->IO_Address == 0)
138 DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
139 "PCI Address 0x%X\n", Controller,
140 Controller->Bus, Controller->Device,
141 Controller->Function, Controller->PCI_Address);
142 else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
143 "0x%X PCI Address 0x%X\n", Controller,
144 Controller->Bus, Controller->Device,
145 Controller->Function, Controller->IO_Address,
146 Controller->PCI_Address);
147 DAC960_Error("%s FAILED - DETACHING\n", Controller, ErrorMessage);
148 return false;
153 DAC960_ClearCommand clears critical fields of Command.
156 static inline void DAC960_ClearCommand(DAC960_Command_T *Command)
158 DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
159 CommandMailbox->Words[0] = 0;
160 CommandMailbox->Words[1] = 0;
161 CommandMailbox->Words[2] = 0;
162 CommandMailbox->Words[3] = 0;
163 Command->CommandStatus = 0;
168 DAC960_AllocateCommand allocates a Command structure from Controller's
169 free list.
172 static inline DAC960_Command_T *DAC960_AllocateCommand(DAC960_Controller_T
173 *Controller)
175 DAC960_Command_T *Command = Controller->FreeCommands;
176 if (Command == NULL) return NULL;
177 Controller->FreeCommands = Command->Next;
178 Command->Next = NULL;
179 return Command;
184 DAC960_DeallocateCommand deallocates Command, returning it to Controller's
185 free list.
188 static inline void DAC960_DeallocateCommand(DAC960_Command_T *Command)
190 DAC960_Controller_T *Controller = Command->Controller;
191 Command->Next = Controller->FreeCommands;
192 Controller->FreeCommands = Command;
197 DAC960_QueueCommand queues Command.
200 static void DAC960_QueueCommand(DAC960_Command_T *Command)
202 DAC960_Controller_T *Controller = Command->Controller;
203 void *ControllerBaseAddress = Controller->BaseAddress;
204 DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
205 DAC960_CommandMailbox_T *NextCommandMailbox;
206 CommandMailbox->Common.CommandIdentifier = Command - Controller->Commands;
207 switch (Controller->ControllerType)
209 case DAC960_V5_Controller:
210 NextCommandMailbox = Controller->NextCommandMailbox;
211 DAC960_V5_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
212 if (Controller->PreviousCommandMailbox1->Words[0] == 0 ||
213 Controller->PreviousCommandMailbox2->Words[0] == 0)
215 if (Controller->DualModeMemoryMailboxInterface)
216 DAC960_V5_MemoryMailboxNewCommand(ControllerBaseAddress);
217 else DAC960_V5_HardwareMailboxNewCommand(ControllerBaseAddress);
219 Controller->PreviousCommandMailbox2 = Controller->PreviousCommandMailbox1;
220 Controller->PreviousCommandMailbox1 = NextCommandMailbox;
221 if (++NextCommandMailbox > Controller->LastCommandMailbox)
222 NextCommandMailbox = Controller->FirstCommandMailbox;
223 Controller->NextCommandMailbox = NextCommandMailbox;
224 break;
225 case DAC960_V4_Controller:
226 NextCommandMailbox = Controller->NextCommandMailbox;
227 DAC960_V4_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
228 if (Controller->PreviousCommandMailbox1->Words[0] == 0 ||
229 Controller->PreviousCommandMailbox2->Words[0] == 0)
231 if (Controller->DualModeMemoryMailboxInterface)
232 DAC960_V4_MemoryMailboxNewCommand(ControllerBaseAddress);
233 else DAC960_V4_HardwareMailboxNewCommand(ControllerBaseAddress);
235 Controller->PreviousCommandMailbox2 = Controller->PreviousCommandMailbox1;
236 Controller->PreviousCommandMailbox1 = NextCommandMailbox;
237 if (++NextCommandMailbox > Controller->LastCommandMailbox)
238 NextCommandMailbox = Controller->FirstCommandMailbox;
239 Controller->NextCommandMailbox = NextCommandMailbox;
240 break;
241 case DAC960_V3_Controller:
242 while (DAC960_V3_MailboxFullP(ControllerBaseAddress))
243 udelay(1);
244 DAC960_V3_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
245 DAC960_V3_NewCommand(ControllerBaseAddress);
246 break;
252 DAC960_ExecuteCommand executes Command and waits for completion. It
253 returns true on success and false on failure.
256 static boolean DAC960_ExecuteCommand(DAC960_Command_T *Command)
258 DAC960_Controller_T *Controller = Command->Controller;
259 Semaphore_T Semaphore = MUTEX_LOCKED;
260 unsigned long ProcessorFlags;
261 Command->Semaphore = &Semaphore;
262 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
263 DAC960_QueueCommand(Command);
264 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
265 if (!in_interrupt())
266 down(&Semaphore);
267 return Command->CommandStatus == DAC960_NormalCompletion;
272 DAC960_ExecuteType3 executes a DAC960 Type 3 Command and waits for
273 completion. It returns true on success and false on failure.
276 static boolean DAC960_ExecuteType3(DAC960_Controller_T *Controller,
277 DAC960_CommandOpcode_T CommandOpcode,
278 void *DataPointer)
280 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
281 DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
282 boolean Result;
283 DAC960_ClearCommand(Command);
284 Command->CommandType = DAC960_ImmediateCommand;
285 CommandMailbox->Type3.CommandOpcode = CommandOpcode;
286 CommandMailbox->Type3.BusAddress = Virtual_to_Bus(DataPointer);
287 Result = DAC960_ExecuteCommand(Command);
288 DAC960_DeallocateCommand(Command);
289 return Result;
294 DAC960_ExecuteType3D executes a DAC960 Type 3D Command and waits for
295 completion. It returns true on success and false on failure.
298 static boolean DAC960_ExecuteType3D(DAC960_Controller_T *Controller,
299 DAC960_CommandOpcode_T CommandOpcode,
300 unsigned char Channel,
301 unsigned char TargetID,
302 void *DataPointer)
304 DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
305 DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
306 boolean Result;
307 DAC960_ClearCommand(Command);
308 Command->CommandType = DAC960_ImmediateCommand;
309 CommandMailbox->Type3D.CommandOpcode = CommandOpcode;
310 CommandMailbox->Type3D.Channel = Channel;
311 CommandMailbox->Type3D.TargetID = TargetID;
312 CommandMailbox->Type3D.BusAddress = Virtual_to_Bus(DataPointer);
313 Result = DAC960_ExecuteCommand(Command);
314 DAC960_DeallocateCommand(Command);
315 return Result;
320 DAC960_EnableMemoryMailboxInterface enables the Memory Mailbox Interface.
323 static boolean DAC960_EnableMemoryMailboxInterface(DAC960_Controller_T
324 *Controller)
326 void *ControllerBaseAddress = Controller->BaseAddress;
327 DAC960_CommandMailbox_T *CommandMailboxesMemory;
328 DAC960_StatusMailbox_T *StatusMailboxesMemory;
329 DAC960_CommandMailbox_T CommandMailbox;
330 DAC960_CommandStatus_T CommandStatus;
331 void *SavedMemoryMailboxesAddress = NULL;
332 short NextCommandMailboxIndex = 0;
333 short NextStatusMailboxIndex = 0;
334 int TimeoutCounter = 1000000, i;
335 if (Controller->ControllerType == DAC960_V5_Controller)
336 DAC960_V5_RestoreMemoryMailboxInfo(Controller,
337 &SavedMemoryMailboxesAddress,
338 &NextCommandMailboxIndex,
339 &NextStatusMailboxIndex);
340 else DAC960_V4_RestoreMemoryMailboxInfo(Controller,
341 &SavedMemoryMailboxesAddress,
342 &NextCommandMailboxIndex,
343 &NextStatusMailboxIndex);
344 if (SavedMemoryMailboxesAddress == NULL)
345 CommandMailboxesMemory =
346 (DAC960_CommandMailbox_T *) __get_free_pages(GFP_KERNEL, 1);
347 else CommandMailboxesMemory = SavedMemoryMailboxesAddress;
348 memset(CommandMailboxesMemory, 0, PAGE_SIZE << 1);
349 Controller->FirstCommandMailbox = CommandMailboxesMemory;
350 CommandMailboxesMemory += DAC960_CommandMailboxCount - 1;
351 Controller->LastCommandMailbox = CommandMailboxesMemory;
352 Controller->NextCommandMailbox =
353 &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
354 if (--NextCommandMailboxIndex < 0)
355 NextCommandMailboxIndex = DAC960_CommandMailboxCount - 1;
356 Controller->PreviousCommandMailbox1 =
357 &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
358 if (--NextCommandMailboxIndex < 0)
359 NextCommandMailboxIndex = DAC960_CommandMailboxCount - 1;
360 Controller->PreviousCommandMailbox2 =
361 &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
362 StatusMailboxesMemory =
363 (DAC960_StatusMailbox_T *) (CommandMailboxesMemory + 1);
364 Controller->FirstStatusMailbox = StatusMailboxesMemory;
365 StatusMailboxesMemory += DAC960_StatusMailboxCount - 1;
366 Controller->LastStatusMailbox = StatusMailboxesMemory;
367 Controller->NextStatusMailbox =
368 &Controller->FirstStatusMailbox[NextStatusMailboxIndex];
369 if (SavedMemoryMailboxesAddress != NULL) return true;
370 /* Enable the Memory Mailbox Interface. */
371 Controller->DualModeMemoryMailboxInterface = true;
372 CommandMailbox.TypeX.CommandOpcode = 0x2B;
373 CommandMailbox.TypeX.CommandIdentifier = 0;
374 CommandMailbox.TypeX.CommandOpcode2 = 0x14;
375 CommandMailbox.TypeX.CommandMailboxesBusAddress =
376 Virtual_to_Bus(Controller->FirstCommandMailbox);
377 CommandMailbox.TypeX.StatusMailboxesBusAddress =
378 Virtual_to_Bus(Controller->FirstStatusMailbox);
379 for (i = 0; i < 2; i++)
380 switch (Controller->ControllerType)
382 case DAC960_V5_Controller:
383 while (--TimeoutCounter >= 0)
385 if (DAC960_V5_HardwareMailboxEmptyP(ControllerBaseAddress))
386 break;
387 udelay(10);
389 if (TimeoutCounter < 0) return false;
390 DAC960_V5_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
391 DAC960_V5_HardwareMailboxNewCommand(ControllerBaseAddress);
392 while (--TimeoutCounter >= 0)
394 if (DAC960_V5_HardwareMailboxStatusAvailableP(
395 ControllerBaseAddress))
396 break;
397 udelay(10);
399 if (TimeoutCounter < 0) return false;
400 CommandStatus = DAC960_V5_ReadStatusRegister(ControllerBaseAddress);
401 DAC960_V5_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
402 DAC960_V5_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
403 if (CommandStatus == DAC960_NormalCompletion) return true;
404 Controller->DualModeMemoryMailboxInterface = false;
405 CommandMailbox.TypeX.CommandOpcode2 = 0x10;
406 break;
407 case DAC960_V4_Controller:
408 while (--TimeoutCounter >= 0)
410 if (!DAC960_V4_HardwareMailboxFullP(ControllerBaseAddress))
411 break;
412 udelay(10);
414 if (TimeoutCounter < 0) return false;
415 DAC960_V4_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
416 DAC960_V4_HardwareMailboxNewCommand(ControllerBaseAddress);
417 while (--TimeoutCounter >= 0)
419 if (DAC960_V4_HardwareMailboxStatusAvailableP(
420 ControllerBaseAddress))
421 break;
422 udelay(10);
424 if (TimeoutCounter < 0) return false;
425 CommandStatus = DAC960_V4_ReadStatusRegister(ControllerBaseAddress);
426 DAC960_V4_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
427 DAC960_V4_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
428 if (CommandStatus == DAC960_NormalCompletion) return true;
429 Controller->DualModeMemoryMailboxInterface = false;
430 CommandMailbox.TypeX.CommandOpcode2 = 0x10;
431 break;
432 default:
433 break;
435 return false;
440 DAC960_DetectControllers detects DAC960 PCI RAID Controllers by interrogating
441 the PCI Configuration Space for Controller Type.
444 static void DAC960_DetectControllers(DAC960_ControllerType_T ControllerType)
446 unsigned short VendorID = 0, DeviceID = 0;
447 unsigned int MemoryWindowSize = 0;
448 PCI_Device_T *PCI_Device = NULL;
449 switch (ControllerType)
451 case DAC960_V5_Controller:
452 VendorID = PCI_VENDOR_ID_DEC;
453 DeviceID = PCI_DEVICE_ID_DEC_21285;
454 MemoryWindowSize = DAC960_V5_RegisterWindowSize;
455 break;
456 case DAC960_V4_Controller:
457 VendorID = PCI_VENDOR_ID_MYLEX;
458 DeviceID = PCI_DEVICE_ID_MYLEX_DAC960P_V4;
459 MemoryWindowSize = DAC960_V4_RegisterWindowSize;
460 break;
461 case DAC960_V3_Controller:
462 VendorID = PCI_VENDOR_ID_MYLEX;
463 DeviceID = PCI_DEVICE_ID_MYLEX_DAC960P_V3;
464 MemoryWindowSize = DAC960_V3_RegisterWindowSize;
465 break;
467 while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
469 DAC960_Controller_T *Controller = (DAC960_Controller_T *)
470 kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
471 DAC960_IO_Address_T IO_Address = 0;
472 DAC960_PCI_Address_T PCI_Address = 0;
473 unsigned char Bus = PCI_Device->bus->number;
474 unsigned char DeviceFunction = PCI_Device->devfn;
475 unsigned char Device = DeviceFunction >> 3;
476 unsigned char Function = DeviceFunction & 0x7;
477 unsigned int IRQ_Channel = PCI_Device->irq;
478 unsigned long BaseAddress0 = PCI_Device->base_address[0];
479 unsigned long BaseAddress1 = PCI_Device->base_address[1];
480 unsigned short SubsystemVendorID, SubsystemDeviceID;
481 int CommandIdentifier;
482 pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_VENDOR_ID,
483 &SubsystemVendorID);
484 pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_ID,
485 &SubsystemDeviceID);
486 switch (ControllerType)
488 case DAC960_V5_Controller:
489 if (!(SubsystemVendorID == PCI_VENDOR_ID_MYLEX &&
490 SubsystemDeviceID == PCI_DEVICE_ID_MYLEX_DAC960P_V5))
491 goto Ignore;
492 PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
493 break;
494 case DAC960_V4_Controller:
495 PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
496 break;
497 case DAC960_V3_Controller:
498 IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
499 PCI_Address = BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK;
500 break;
502 if (DAC960_ControllerCount == DAC960_MaxControllers)
504 DAC960_Error("More than %d DAC960 Controllers detected - "
505 "ignoring from Controller at\n",
506 NULL, DAC960_MaxControllers);
507 goto Ignore;
509 if (Controller == NULL)
511 DAC960_Error("Unable to allocate Controller structure for "
512 "Controller at\n", NULL);
513 goto Ignore;
515 memset(Controller, 0, sizeof(DAC960_Controller_T));
516 init_waitqueue_head(&Controller->CommandWaitQueue);
517 Controller->ControllerNumber = DAC960_ControllerCount;
518 DAC960_Controllers[DAC960_ControllerCount++] = Controller;
519 DAC960_AnnounceDriver(Controller);
520 Controller->ControllerType = ControllerType;
521 Controller->IO_Address = IO_Address;
522 Controller->PCI_Address = PCI_Address;
523 Controller->Bus = Bus;
524 Controller->Device = Device;
525 Controller->Function = Function;
526 sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
528 Acquire shared access to the IRQ Channel.
530 if (IRQ_Channel == 0)
532 DAC960_Error("IRQ Channel %d illegal for Controller at\n",
533 Controller, IRQ_Channel);
534 goto Failure;
536 strcpy(Controller->FullModelName, "DAC960");
537 if (request_irq(IRQ_Channel, DAC960_InterruptHandler,
538 SA_SHIRQ, Controller->FullModelName, Controller) < 0)
540 DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
541 Controller, IRQ_Channel);
542 goto Failure;
544 Controller->IRQ_Channel = IRQ_Channel;
546 Map the Controller Register Window.
548 if (MemoryWindowSize < PAGE_SIZE)
549 MemoryWindowSize = PAGE_SIZE;
550 Controller->MemoryMappedAddress =
551 ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
552 Controller->BaseAddress =
553 Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
554 if (Controller->MemoryMappedAddress == NULL)
556 DAC960_Error("Unable to map Controller Register Window for "
557 "Controller at\n", Controller);
558 goto Failure;
560 switch (ControllerType)
562 case DAC960_V5_Controller:
563 DAC960_V5_DisableInterrupts(Controller->BaseAddress);
564 if (!DAC960_EnableMemoryMailboxInterface(Controller))
566 DAC960_Error("Unable to Enable Memory Mailbox Interface "
567 "for Controller at\n", Controller);
568 goto Failure;
570 DAC960_V5_EnableInterrupts(Controller->BaseAddress);
571 break;
572 case DAC960_V4_Controller:
573 DAC960_V4_DisableInterrupts(Controller->BaseAddress);
574 if (!DAC960_EnableMemoryMailboxInterface(Controller))
576 DAC960_Error("Unable to Enable Memory Mailbox Interface "
577 "for Controller at\n", Controller);
578 goto Failure;
580 DAC960_V4_EnableInterrupts(Controller->BaseAddress);
581 break;
582 case DAC960_V3_Controller:
583 request_region(Controller->IO_Address, 0x80,
584 Controller->FullModelName);
585 DAC960_V3_EnableInterrupts(Controller->BaseAddress);
586 break;
588 DAC960_ActiveControllerCount++;
589 for (CommandIdentifier = 0;
590 CommandIdentifier < DAC960_MaxChannels;
591 CommandIdentifier++)
593 Controller->Commands[CommandIdentifier].Controller = Controller;
594 Controller->Commands[CommandIdentifier].Next =
595 Controller->FreeCommands;
596 Controller->FreeCommands = &Controller->Commands[CommandIdentifier];
598 continue;
599 Failure:
600 if (IO_Address == 0)
601 DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
602 "PCI Address 0x%X\n", Controller,
603 Bus, Device, Function, PCI_Address);
604 else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
605 "0x%X PCI Address 0x%X\n", Controller,
606 Bus, Device, Function, IO_Address, PCI_Address);
607 if (Controller == NULL) break;
608 if (Controller->IRQ_Channel > 0)
609 free_irq(IRQ_Channel, Controller);
610 if (Controller->MemoryMappedAddress != NULL)
611 iounmap(Controller->MemoryMappedAddress);
612 DAC960_Controllers[Controller->ControllerNumber] = NULL;
613 Ignore:
614 kfree(Controller);
620 DAC960_ReadControllerConfiguration reads the Configuration Information
621 from Controller and initializes the Controller structure.
624 static boolean DAC960_ReadControllerConfiguration(DAC960_Controller_T
625 *Controller)
627 DAC960_Enquiry2_T Enquiry2;
628 DAC960_Config2_T Config2;
629 int LogicalDriveNumber, Channel, TargetID;
630 if (!DAC960_ExecuteType3(Controller, DAC960_Enquiry,
631 &Controller->Enquiry[0]))
632 return DAC960_Failure(Controller, "ENQUIRY");
633 if (!DAC960_ExecuteType3(Controller, DAC960_Enquiry2, &Enquiry2))
634 return DAC960_Failure(Controller, "ENQUIRY2");
635 if (!DAC960_ExecuteType3(Controller, DAC960_ReadConfig2, &Config2))
636 return DAC960_Failure(Controller, "READ CONFIG2");
637 if (!DAC960_ExecuteType3(Controller, DAC960_GetLogicalDriveInformation,
638 &Controller->LogicalDriveInformation[0]))
639 return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION");
640 for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++)
641 for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
642 if (!DAC960_ExecuteType3D(Controller, DAC960_GetDeviceState,
643 Channel, TargetID,
644 &Controller->DeviceState[0][Channel][TargetID]))
645 return DAC960_Failure(Controller, "GET DEVICE STATE");
647 Initialize the Controller Model Name and Full Model Name fields.
649 switch (Enquiry2.HardwareID.SubModel)
651 case DAC960_P_PD_PU:
652 if (Enquiry2.SCSICapability.BusSpeed == DAC960_Ultra)
653 strcpy(Controller->ModelName, "DAC960PU");
654 else strcpy(Controller->ModelName, "DAC960PD");
655 break;
656 case DAC960_PL:
657 strcpy(Controller->ModelName, "DAC960PL");
658 break;
659 case DAC960_PG:
660 strcpy(Controller->ModelName, "DAC960PG");
661 break;
662 case DAC960_PJ:
663 strcpy(Controller->ModelName, "DAC960PJ");
664 break;
665 case DAC960_PR:
666 strcpy(Controller->ModelName, "DAC960PR");
667 break;
668 case DAC960_PT:
669 strcpy(Controller->ModelName, "DAC960PT");
670 break;
671 case DAC960_PTL0:
672 strcpy(Controller->ModelName, "DAC960PTL0");
673 break;
674 case DAC960_PRL:
675 strcpy(Controller->ModelName, "DAC960PRL");
676 break;
677 case DAC960_PTL1:
678 strcpy(Controller->ModelName, "DAC960PTL1");
679 break;
680 case DAC1164_P:
681 strcpy(Controller->ModelName, "DAC1164P");
682 break;
683 default:
684 return DAC960_Failure(Controller, "MODEL VERIFICATION");
686 strcpy(Controller->FullModelName, "Mylex ");
687 strcat(Controller->FullModelName, Controller->ModelName);
689 Initialize the Controller Firmware Version field and verify that it
690 is a supported firmware version. The supported firmware versions are:
692 DAC1164P 5.06 and above
693 DAC960PTL/PRL/PJ/PG 4.06 and above
694 DAC960PU/PD/PL 3.51 and above
696 sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
697 Enquiry2.FirmwareID.MajorVersion, Enquiry2.FirmwareID.MinorVersion,
698 Enquiry2.FirmwareID.FirmwareType, Enquiry2.FirmwareID.TurnID);
699 if (!((Controller->FirmwareVersion[0] == '5' &&
700 strcmp(Controller->FirmwareVersion, "5.06") >= 0) ||
701 (Controller->FirmwareVersion[0] == '4' &&
702 strcmp(Controller->FirmwareVersion, "4.06") >= 0) ||
703 (Controller->FirmwareVersion[0] == '3' &&
704 strcmp(Controller->FirmwareVersion, "3.51") >= 0)))
706 DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
707 DAC960_Error("Firmware Version = '%s'\n", Controller,
708 Controller->FirmwareVersion);
709 return false;
712 Initialize the Controller Channels, Memory Size, and SAF-TE Enclosure
713 Management Enabled fields.
715 Controller->Channels = Enquiry2.ActualChannels;
716 Controller->MemorySize = Enquiry2.MemorySize >> 20;
717 Controller->SAFTE_EnclosureManagementEnabled =
718 Enquiry2.FaultManagementType == DAC960_SAFTE;
720 Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
721 Count, Maximum Blocks per Command, and Maximum Scatter/Gather Segments.
722 The Driver Queue Depth must be at most one less than the Controller Queue
723 Depth to allow for an automatic drive rebuild operation.
725 Controller->ControllerQueueDepth = Controller->Enquiry[0].MaxCommands;
726 Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
727 Controller->LogicalDriveCount = Controller->Enquiry[0].NumberOfLogicalDrives;
728 Controller->MaxBlocksPerCommand = Enquiry2.MaxBlocksPerCommand;
729 Controller->MaxScatterGatherSegments = Enquiry2.MaxScatterGatherEntries;
731 Initialize the Stripe Size, Segment Size, and Geometry Translation.
733 Controller->StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
734 >> (10 - DAC960_BlockSizeBits);
735 Controller->SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
736 >> (10 - DAC960_BlockSizeBits);
737 switch (Config2.DriveGeometry)
739 case DAC960_Geometry_128_32:
740 Controller->GeometryTranslationHeads = 128;
741 Controller->GeometryTranslationSectors = 32;
742 break;
743 case DAC960_Geometry_255_63:
744 Controller->GeometryTranslationHeads = 255;
745 Controller->GeometryTranslationSectors = 63;
746 break;
747 default:
748 return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
751 Initialize the Logical Drive Initial State.
753 for (LogicalDriveNumber = 0;
754 LogicalDriveNumber < Controller->LogicalDriveCount;
755 LogicalDriveNumber++)
756 Controller->LogicalDriveInitialState[LogicalDriveNumber] =
757 Controller->LogicalDriveInformation[0]
758 [LogicalDriveNumber].LogicalDriveState;
759 Controller->LastRebuildStatus = DAC960_NoRebuildOrCheckInProgress;
760 return true;
765 DAC960_ReportControllerConfiguration reports the Configuration Information of
766 Controller.
769 static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
770 *Controller)
772 DAC960_Info("Configuring Mylex %s PCI RAID Controller\n",
773 Controller, Controller->ModelName);
774 DAC960_Info(" Firmware Version: %s, Channels: %d, Memory Size: %dMB\n",
775 Controller, Controller->FirmwareVersion,
776 Controller->Channels, Controller->MemorySize);
777 DAC960_Info(" PCI Bus: %d, Device: %d, Function: %d, I/O Address: ",
778 Controller, Controller->Bus,
779 Controller->Device, Controller->Function);
780 if (Controller->IO_Address == 0)
781 DAC960_Info("Unassigned\n", Controller);
782 else DAC960_Info("0x%X\n", Controller, Controller->IO_Address);
783 DAC960_Info(" PCI Address: 0x%X mapped at 0x%lX, IRQ Channel: %d\n",
784 Controller, Controller->PCI_Address,
785 (unsigned long) Controller->BaseAddress,
786 Controller->IRQ_Channel);
787 DAC960_Info(" Controller Queue Depth: %d, "
788 "Maximum Blocks per Command: %d\n",
789 Controller, Controller->ControllerQueueDepth,
790 Controller->MaxBlocksPerCommand);
791 DAC960_Info(" Driver Queue Depth: %d, "
792 "Maximum Scatter/Gather Segments: %d\n",
793 Controller, Controller->DriverQueueDepth,
794 Controller->MaxScatterGatherSegments);
795 DAC960_Info(" Stripe Size: %dKB, Segment Size: %dKB, "
796 "BIOS Geometry: %d/%d\n", Controller,
797 Controller->StripeSize,
798 Controller->SegmentSize,
799 Controller->GeometryTranslationHeads,
800 Controller->GeometryTranslationSectors);
801 if (Controller->SAFTE_EnclosureManagementEnabled)
802 DAC960_Info(" SAF-TE Enclosure Management Enabled\n", Controller);
803 return true;
808 DAC960_ReadDeviceConfiguration reads the Device Configuration Information by
809 requesting the SCSI Inquiry and SCSI Inquiry Unit Serial Number information
810 for each device connected to Controller.
813 static boolean DAC960_ReadDeviceConfiguration(DAC960_Controller_T *Controller)
815 DAC960_DCDB_T DCDBs[DAC960_MaxChannels], *DCDB;
816 Semaphore_T Semaphores[DAC960_MaxChannels], *Semaphore;
817 unsigned long ProcessorFlags;
818 int Channel, TargetID;
819 for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
821 for (Channel = 0; Channel < Controller->Channels; Channel++)
823 DAC960_Command_T *Command = &Controller->Commands[Channel];
824 DAC960_SCSI_Inquiry_T *InquiryStandardData =
825 &Controller->InquiryStandardData[Channel][TargetID];
826 InquiryStandardData->PeripheralDeviceType = 0x1F;
827 Semaphore = &Semaphores[Channel];
828 *Semaphore = MUTEX_LOCKED;
829 DCDB = &DCDBs[Channel];
830 DAC960_ClearCommand(Command);
831 Command->CommandType = DAC960_ImmediateCommand;
832 Command->Semaphore = Semaphore;
833 Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
834 Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
835 DCDB->Channel = Channel;
836 DCDB->TargetID = TargetID;
837 DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
838 DCDB->EarlyStatus = false;
839 DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
840 DCDB->NoAutomaticRequestSense = false;
841 DCDB->DisconnectPermitted = true;
842 DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
843 DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
844 DCDB->CDBLength = 6;
845 DCDB->TransferLengthHigh4 = 0;
846 DCDB->SenseLength = sizeof(DCDB->SenseData);
847 DCDB->CDB[0] = 0x12; /* INQUIRY */
848 DCDB->CDB[1] = 0; /* EVPD = 0 */
849 DCDB->CDB[2] = 0; /* Page Code */
850 DCDB->CDB[3] = 0; /* Reserved */
851 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
852 DCDB->CDB[5] = 0; /* Control */
853 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
854 DAC960_QueueCommand(Command);
855 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
857 for (Channel = 0; Channel < Controller->Channels; Channel++)
859 DAC960_Command_T *Command = &Controller->Commands[Channel];
860 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
861 &Controller->InquiryUnitSerialNumber[Channel][TargetID];
862 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
863 Semaphore = &Semaphores[Channel];
864 down(Semaphore);
865 if (Command->CommandStatus != DAC960_NormalCompletion) continue;
866 Command->Semaphore = Semaphore;
867 DCDB = &DCDBs[Channel];
868 DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
869 DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
870 DCDB->SenseLength = sizeof(DCDB->SenseData);
871 DCDB->CDB[0] = 0x12; /* INQUIRY */
872 DCDB->CDB[1] = 1; /* EVPD = 1 */
873 DCDB->CDB[2] = 0x80; /* Page Code */
874 DCDB->CDB[3] = 0; /* Reserved */
875 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
876 DCDB->CDB[5] = 0; /* Control */
877 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
878 DAC960_QueueCommand(Command);
879 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
880 down(Semaphore);
883 return true;
888 DAC960_ReportDeviceConfiguration reports the Device Configuration Information
889 of Controller.
892 static boolean DAC960_ReportDeviceConfiguration(DAC960_Controller_T *Controller)
894 int LogicalDriveNumber, Channel, TargetID;
895 DAC960_Info(" Physical Devices:\n", Controller);
896 for (Channel = 0; Channel < Controller->Channels; Channel++)
897 for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
899 DAC960_SCSI_Inquiry_T *InquiryStandardData =
900 &Controller->InquiryStandardData[Channel][TargetID];
901 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
902 &Controller->InquiryUnitSerialNumber[Channel][TargetID];
903 DAC960_DeviceState_T *DeviceState =
904 &Controller->DeviceState[Controller->DeviceStateIndex]
905 [Channel][TargetID];
906 DAC960_ErrorTable_T *ErrorTable =
907 &Controller->ErrorTable[Controller->ErrorTableIndex];
908 DAC960_ErrorTableEntry_T *ErrorEntry =
909 &ErrorTable->ErrorTableEntries[Channel][TargetID];
910 char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
911 char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
912 char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
913 char SerialNumber[1+sizeof(InquiryUnitSerialNumber
914 ->ProductSerialNumber)];
915 int i;
916 if (InquiryStandardData->PeripheralDeviceType == 0x1F) continue;
917 for (i = 0; i < sizeof(Vendor)-1; i++)
919 unsigned char VendorCharacter =
920 InquiryStandardData->VendorIdentification[i];
921 Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~'
922 ? VendorCharacter : ' ');
924 Vendor[sizeof(Vendor)-1] = '\0';
925 for (i = 0; i < sizeof(Model)-1; i++)
927 unsigned char ModelCharacter =
928 InquiryStandardData->ProductIdentification[i];
929 Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
930 ? ModelCharacter : ' ');
932 Model[sizeof(Model)-1] = '\0';
933 for (i = 0; i < sizeof(Revision)-1; i++)
935 unsigned char RevisionCharacter =
936 InquiryStandardData->ProductRevisionLevel[i];
937 Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
938 ? RevisionCharacter : ' ');
940 Revision[sizeof(Revision)-1] = '\0';
941 DAC960_Info(" %d:%d%s Vendor: %s Model: %s Revision: %s\n",
942 Controller, Channel, TargetID, (TargetID < 10 ? " " : ""),
943 Vendor, Model, Revision);
944 if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
946 int SerialNumberLength = InquiryUnitSerialNumber->PageLength;
947 if (SerialNumberLength >
948 sizeof(InquiryUnitSerialNumber->ProductSerialNumber))
949 SerialNumberLength =
950 sizeof(InquiryUnitSerialNumber->ProductSerialNumber);
951 for (i = 0; i < SerialNumberLength; i++)
953 unsigned char SerialNumberCharacter =
954 InquiryUnitSerialNumber->ProductSerialNumber[i];
955 SerialNumber[i] =
956 (SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~'
957 ? SerialNumberCharacter : ' ');
959 SerialNumber[SerialNumberLength] = '\0';
960 DAC960_Info(" Serial Number: %s\n",
961 Controller, SerialNumber);
963 if (DeviceState->Present && DeviceState->DeviceType == DAC960_DiskType)
965 if (Controller->DeviceResetCount[Channel][TargetID] > 0)
966 DAC960_Info(" Disk Status: %s, %d blocks, %d resets\n",
967 Controller,
968 (DeviceState->DeviceState == DAC960_Device_Dead
969 ? "Dead"
970 : DeviceState->DeviceState == DAC960_Device_WriteOnly
971 ? "Write-Only"
972 : DeviceState->DeviceState == DAC960_Device_Online
973 ? "Online" : "Standby"),
974 DeviceState->DiskSize,
975 Controller->DeviceResetCount[Channel][TargetID]);
976 else
977 DAC960_Info(" Disk Status: %s, %d blocks\n", Controller,
978 (DeviceState->DeviceState == DAC960_Device_Dead
979 ? "Dead"
980 : DeviceState->DeviceState == DAC960_Device_WriteOnly
981 ? "Write-Only"
982 : DeviceState->DeviceState == DAC960_Device_Online
983 ? "Online" : "Standby"),
984 DeviceState->DiskSize);
986 if (ErrorEntry->ParityErrorCount > 0 ||
987 ErrorEntry->SoftErrorCount > 0 ||
988 ErrorEntry->HardErrorCount > 0 ||
989 ErrorEntry->MiscErrorCount > 0)
990 DAC960_Info(" Errors - Parity: %d, Soft: %d, "
991 "Hard: %d, Misc: %d\n", Controller,
992 ErrorEntry->ParityErrorCount,
993 ErrorEntry->SoftErrorCount,
994 ErrorEntry->HardErrorCount,
995 ErrorEntry->MiscErrorCount);
997 DAC960_Info(" Logical Drives:\n", Controller);
998 for (LogicalDriveNumber = 0;
999 LogicalDriveNumber < Controller->LogicalDriveCount;
1000 LogicalDriveNumber++)
1002 DAC960_LogicalDriveInformation_T *LogicalDriveInformation =
1003 &Controller->LogicalDriveInformation
1004 [Controller->LogicalDriveInformationIndex][LogicalDriveNumber];
1005 DAC960_Info(" /dev/rd/c%dd%d: RAID-%d, %s, %d blocks, %s\n",
1006 Controller, Controller->ControllerNumber, LogicalDriveNumber,
1007 LogicalDriveInformation->RAIDLevel,
1008 (LogicalDriveInformation->LogicalDriveState ==
1009 DAC960_LogicalDrive_Online
1010 ? "Online"
1011 : LogicalDriveInformation->LogicalDriveState ==
1012 DAC960_LogicalDrive_Critical
1013 ? "Critical" : "Offline"),
1014 LogicalDriveInformation->LogicalDriveSize,
1015 (LogicalDriveInformation->WriteBack
1016 ? "Write Back" : "Write Thru"));
1018 return true;
1023 DAC960_RegisterBlockDevice registers the Block Device structures
1024 associated with Controller.
1027 static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
1029 static void (*RequestFunctions[DAC960_MaxControllers])(void) =
1030 { DAC960_RequestFunction0, DAC960_RequestFunction1,
1031 DAC960_RequestFunction2, DAC960_RequestFunction3,
1032 DAC960_RequestFunction4, DAC960_RequestFunction5,
1033 DAC960_RequestFunction6, DAC960_RequestFunction7 };
1034 int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
1035 GenericDiskInfo_T *GenericDiskInfo;
1036 int MinorNumber;
1038 Register the Block Device Major Number for this DAC960 Controller.
1040 if (register_blkdev(MajorNumber, "rd", &DAC960_FileOperations) < 0)
1042 DAC960_Error("UNABLE TO ACQUIRE MAJOR NUMBER %d - DETACHING\n",
1043 Controller, MajorNumber);
1044 return false;
1047 Initialize the I/O Request Function.
1049 blk_dev[MajorNumber].request_fn =
1050 RequestFunctions[Controller->ControllerNumber];
1052 Initialize the Disk Partitions array, Partition Sizes array, Block Sizes
1053 array, Max Sectors per Request array, and Max Segments per Request array.
1055 for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++)
1057 Controller->BlockSizes[MinorNumber] = BLOCK_SIZE;
1058 Controller->MaxSectorsPerRequest[MinorNumber] =
1059 Controller->MaxBlocksPerCommand;
1060 Controller->MaxSegmentsPerRequest[MinorNumber] =
1061 Controller->MaxScatterGatherSegments;
1063 Controller->GenericDiskInfo.part = Controller->DiskPartitions;
1064 Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
1065 blksize_size[MajorNumber] = Controller->BlockSizes;
1066 max_sectors[MajorNumber] = Controller->MaxSectorsPerRequest;
1067 max_segments[MajorNumber] = Controller->MaxSegmentsPerRequest;
1069 Initialize Read Ahead to 128 sectors.
1071 read_ahead[MajorNumber] = 128;
1073 Complete initialization of the Generic Disk Information structure.
1075 Controller->GenericDiskInfo.major = MajorNumber;
1076 Controller->GenericDiskInfo.major_name = "rd";
1077 Controller->GenericDiskInfo.minor_shift = DAC960_MaxPartitionsBits;
1078 Controller->GenericDiskInfo.max_p = DAC960_MaxPartitions;
1079 Controller->GenericDiskInfo.max_nr = DAC960_MaxLogicalDrives;
1080 Controller->GenericDiskInfo.init = DAC960_InitializeGenericDiskInfo;
1081 Controller->GenericDiskInfo.nr_real = Controller->LogicalDriveCount;
1082 Controller->GenericDiskInfo.real_devices = Controller;
1083 Controller->GenericDiskInfo.next = NULL;
1085 Install the Generic Disk Information structure at the end of the list.
1087 if ((GenericDiskInfo = gendisk_head) != NULL)
1089 while (GenericDiskInfo->next != NULL)
1090 GenericDiskInfo = GenericDiskInfo->next;
1091 GenericDiskInfo->next = &Controller->GenericDiskInfo;
1093 else gendisk_head = &Controller->GenericDiskInfo;
1095 Indicate the Block Device Registration completed successfully,
1097 return true;
1102 DAC960_UnregisterBlockDevice unregisters the Block Device structures
1103 associated with Controller.
1106 static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller)
1108 int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
1110 Unregister the Block Device Major Number for this DAC960 Controller.
1112 unregister_blkdev(MajorNumber, "rd");
1114 Remove the I/O Request Function.
1116 blk_dev[MajorNumber].request_fn = NULL;
1118 Remove the Disk Partitions array, Partition Sizes array, Block Sizes
1119 array, Max Sectors per Request array, and Max Segments per Request array.
1121 Controller->GenericDiskInfo.part = NULL;
1122 Controller->GenericDiskInfo.sizes = NULL;
1123 blk_size[MajorNumber] = NULL;
1124 blksize_size[MajorNumber] = NULL;
1125 max_sectors[MajorNumber] = NULL;
1126 max_segments[MajorNumber] = NULL;
1128 Remove the Generic Disk Information structure from the list.
1130 if (gendisk_head != &Controller->GenericDiskInfo)
1132 GenericDiskInfo_T *GenericDiskInfo = gendisk_head;
1133 while (GenericDiskInfo != NULL &&
1134 GenericDiskInfo->next != &Controller->GenericDiskInfo)
1135 GenericDiskInfo = GenericDiskInfo->next;
1136 if (GenericDiskInfo != NULL)
1137 GenericDiskInfo->next = GenericDiskInfo->next->next;
1139 else gendisk_head = Controller->GenericDiskInfo.next;
1144 DAC960_InitializeController initializes Controller.
1147 static void DAC960_InitializeController(DAC960_Controller_T *Controller)
1149 if (DAC960_ReadControllerConfiguration(Controller) &&
1150 DAC960_ReportControllerConfiguration(Controller) &&
1151 DAC960_ReadDeviceConfiguration(Controller) &&
1152 DAC960_ReportDeviceConfiguration(Controller) &&
1153 DAC960_RegisterBlockDevice(Controller))
1156 Initialize the Command structures.
1158 DAC960_Command_T *Commands = Controller->Commands;
1159 int CommandIdentifier;
1160 Controller->FreeCommands = NULL;
1161 for (CommandIdentifier = 0;
1162 CommandIdentifier < Controller->DriverQueueDepth;
1163 CommandIdentifier++)
1165 Commands[CommandIdentifier].Controller = Controller;
1166 Commands[CommandIdentifier].Next = Controller->FreeCommands;
1167 Controller->FreeCommands = &Commands[CommandIdentifier];
1170 Initialize the Monitoring Timer.
1172 init_timer(&Controller->MonitoringTimer);
1173 Controller->MonitoringTimer.expires =
1174 jiffies + DAC960_MonitoringTimerInterval;
1175 Controller->MonitoringTimer.data = (unsigned long) Controller;
1176 Controller->MonitoringTimer.function = DAC960_MonitoringTimerFunction;
1177 add_timer(&Controller->MonitoringTimer);
1178 Controller->ControllerInitialized = true;
1180 else DAC960_FinalizeController(Controller);
1185 DAC960_FinalizeController finalizes Controller.
1188 static void DAC960_FinalizeController(DAC960_Controller_T *Controller)
1190 if (Controller->ControllerInitialized)
1192 del_timer(&Controller->MonitoringTimer);
1193 DAC960_Notice("Flushing Cache...", Controller);
1194 DAC960_ExecuteType3(Controller, DAC960_Flush, NULL);
1195 DAC960_Notice("done\n", Controller);
1196 switch (Controller->ControllerType)
1198 case DAC960_V5_Controller:
1199 if (!Controller->DualModeMemoryMailboxInterface)
1200 DAC960_V5_SaveMemoryMailboxInfo(Controller);
1201 break;
1202 case DAC960_V4_Controller:
1203 if (!Controller->DualModeMemoryMailboxInterface)
1204 DAC960_V4_SaveMemoryMailboxInfo(Controller);
1205 break;
1206 case DAC960_V3_Controller:
1207 break;
1210 free_irq(Controller->IRQ_Channel, Controller);
1211 iounmap(Controller->MemoryMappedAddress);
1212 if (Controller->IO_Address > 0)
1213 release_region(Controller->IO_Address, 0x80);
1214 DAC960_UnregisterBlockDevice(Controller);
1215 DAC960_Controllers[Controller->ControllerNumber] = NULL;
1216 kfree(Controller);
1221 DAC960_Initialize initializes the DAC960 Driver.
1224 void DAC960_Initialize(void)
1226 int ControllerNumber;
1227 DAC960_DetectControllers(DAC960_V5_Controller);
1228 DAC960_DetectControllers(DAC960_V4_Controller);
1229 DAC960_DetectControllers(DAC960_V3_Controller);
1230 if (DAC960_ActiveControllerCount == 0) return;
1231 for (ControllerNumber = 0;
1232 ControllerNumber < DAC960_ControllerCount;
1233 ControllerNumber++)
1234 if (DAC960_Controllers[ControllerNumber] != NULL)
1235 DAC960_InitializeController(DAC960_Controllers[ControllerNumber]);
1236 DAC960_CreateProcEntries();
1237 register_reboot_notifier(&DAC960_NotifierBlock);
1242 DAC960_Finalize finalizes the DAC960 Driver.
1245 static int DAC960_Finalize(NotifierBlock_T *NotifierBlock,
1246 unsigned long Event,
1247 void *Buffer)
1249 int ControllerNumber;
1250 if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
1251 return NOTIFY_DONE;
1252 if (DAC960_ActiveControllerCount == 0) return NOTIFY_OK;
1253 for (ControllerNumber = 0;
1254 ControllerNumber < DAC960_ControllerCount;
1255 ControllerNumber++)
1256 if (DAC960_Controllers[ControllerNumber] != NULL)
1257 DAC960_FinalizeController(DAC960_Controllers[ControllerNumber]);
1258 DAC960_DestroyProcEntries();
1259 unregister_reboot_notifier(&DAC960_NotifierBlock);
1260 return NOTIFY_OK;
1265 DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
1266 I/O Request Queue and queues it to the Controller. WaitForCommand is true if
1267 this function should wait for a Command to become available if necessary.
1268 This function returns true if an I/O Request was queued and false otherwise.
1271 static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
1272 boolean WaitForCommand)
1274 IO_Request_T **RequestQueuePointer =
1275 &blk_dev[DAC960_MAJOR + Controller->ControllerNumber].current_request;
1276 IO_Request_T *Request;
1277 DAC960_Command_T *Command;
1278 char *RequestBuffer;
1279 while (true)
1281 Request = *RequestQueuePointer;
1282 if (Request == NULL || Request->rq_status == RQ_INACTIVE) return false;
1283 Command = DAC960_AllocateCommand(Controller);
1284 if (Command != NULL) break;
1285 if (!WaitForCommand) return false;
1286 spin_unlock(&io_request_lock);
1287 sleep_on(&Controller->CommandWaitQueue);
1288 spin_lock_irq(&io_request_lock);
1290 DAC960_ClearCommand(Command);
1291 if (Request->cmd == READ)
1292 Command->CommandType = DAC960_ReadCommand;
1293 else Command->CommandType = DAC960_WriteCommand;
1294 Command->Semaphore = Request->sem;
1295 Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
1296 Command->BlockNumber =
1297 Request->sector
1298 + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
1299 Command->BlockCount = Request->nr_sectors;
1300 Command->SegmentCount = Request->nr_segments;
1301 Command->BufferHeader = Request->bh;
1302 RequestBuffer = Request->buffer;
1303 Request->rq_status = RQ_INACTIVE;
1304 *RequestQueuePointer = Request->next;
1305 wake_up(&wait_for_request);
1306 if (Command->SegmentCount == 1)
1308 DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
1309 if (Command->CommandType == DAC960_ReadCommand)
1310 CommandMailbox->Type5.CommandOpcode = DAC960_Read;
1311 else CommandMailbox->Type5.CommandOpcode = DAC960_Write;
1312 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
1313 CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
1314 CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
1315 CommandMailbox->Type5.BusAddress = Virtual_to_Bus(RequestBuffer);
1317 else
1319 DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
1320 DAC960_ScatterGatherSegment_T
1321 *ScatterGatherList = Command->ScatterGatherList;
1322 BufferHeader_T *BufferHeader = Command->BufferHeader;
1323 char *LastDataEndPointer = NULL;
1324 int SegmentNumber = 0;
1325 if (Command->CommandType == DAC960_ReadCommand)
1326 CommandMailbox->Type5.CommandOpcode = DAC960_ReadWithOldScatterGather;
1327 else
1328 CommandMailbox->Type5.CommandOpcode = DAC960_WriteWithOldScatterGather;
1329 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
1330 CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
1331 CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
1332 CommandMailbox->Type5.BusAddress = Virtual_to_Bus(ScatterGatherList);
1333 CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount;
1334 while (BufferHeader != NULL)
1336 if (BufferHeader->b_data == LastDataEndPointer)
1338 ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
1339 BufferHeader->b_size;
1340 LastDataEndPointer += BufferHeader->b_size;
1342 else
1344 ScatterGatherList[SegmentNumber].SegmentDataPointer =
1345 Virtual_to_Bus(BufferHeader->b_data);
1346 ScatterGatherList[SegmentNumber].SegmentByteCount =
1347 BufferHeader->b_size;
1348 LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
1349 if (SegmentNumber++ > Controller->MaxScatterGatherSegments)
1350 panic("DAC960: Scatter/Gather Segment Overflow\n");
1352 BufferHeader = BufferHeader->b_reqnext;
1354 if (SegmentNumber != Command->SegmentCount)
1355 panic("DAC960: SegmentNumber != SegmentCount\n");
1357 DAC960_QueueCommand(Command);
1358 return true;
1363 DAC960_ProcessRequests attempts to remove as many I/O Requests as possible
1364 from Controller's I/O Request Queue and queue them to the Controller.
1367 static inline void DAC960_ProcessRequests(DAC960_Controller_T *Controller)
1369 int Counter = 0;
1370 while (DAC960_ProcessRequest(Controller, Counter++ == 0)) ;
1375 DAC960_RequestFunction0 is the I/O Request Function for DAC960 Controller 0.
1378 static void DAC960_RequestFunction0(void)
1380 DAC960_Controller_T *Controller = DAC960_Controllers[0];
1381 ProcessorFlags_T ProcessorFlags;
1383 Acquire exclusive access to Controller.
1385 DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
1387 Process I/O Requests for Controller.
1389 DAC960_ProcessRequests(Controller);
1391 Release exclusive access to Controller.
1393 DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
1398 DAC960_RequestFunction1 is the I/O Request Function for DAC960 Controller 1.
1401 static void DAC960_RequestFunction1(void)
1403 DAC960_Controller_T *Controller = DAC960_Controllers[1];
1404 ProcessorFlags_T ProcessorFlags;
1406 Acquire exclusive access to Controller.
1408 DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
1410 Process I/O Requests for Controller.
1412 DAC960_ProcessRequests(Controller);
1414 Release exclusive access to Controller.
1416 DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
1421 DAC960_RequestFunction2 is the I/O Request Function for DAC960 Controller 2.
1424 static void DAC960_RequestFunction2(void)
1426 DAC960_Controller_T *Controller = DAC960_Controllers[2];
1427 ProcessorFlags_T ProcessorFlags;
1429 Acquire exclusive access to Controller.
1431 DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
1433 Process I/O Requests for Controller.
1435 DAC960_ProcessRequests(Controller);
1437 Release exclusive access to Controller.
1439 DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
1444 DAC960_RequestFunction3 is the I/O Request Function for DAC960 Controller 3.
1447 static void DAC960_RequestFunction3(void)
1449 DAC960_Controller_T *Controller = DAC960_Controllers[3];
1450 ProcessorFlags_T ProcessorFlags;
1452 Acquire exclusive access to Controller.
1454 DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
1456 Process I/O Requests for Controller.
1458 DAC960_ProcessRequests(Controller);
1460 Release exclusive access to Controller.
1462 DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
1467 DAC960_RequestFunction4 is the I/O Request Function for DAC960 Controller 4.
1470 static void DAC960_RequestFunction4(void)
1472 DAC960_Controller_T *Controller = DAC960_Controllers[4];
1473 ProcessorFlags_T ProcessorFlags;
1475 Acquire exclusive access to Controller.
1477 DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
1479 Process I/O Requests for Controller.
1481 DAC960_ProcessRequests(Controller);
1483 Release exclusive access to Controller.
1485 DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
1490 DAC960_RequestFunction5 is the I/O Request Function for DAC960 Controller 5.
1493 static void DAC960_RequestFunction5(void)
1495 DAC960_Controller_T *Controller = DAC960_Controllers[5];
1496 ProcessorFlags_T ProcessorFlags;
1498 Acquire exclusive access to Controller.
1500 DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
1502 Process I/O Requests for Controller.
1504 DAC960_ProcessRequests(Controller);
1506 Release exclusive access to Controller.
1508 DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
1513 DAC960_RequestFunction6 is the I/O Request Function for DAC960 Controller 6.
1516 static void DAC960_RequestFunction6(void)
1518 DAC960_Controller_T *Controller = DAC960_Controllers[6];
1519 ProcessorFlags_T ProcessorFlags;
1521 Acquire exclusive access to Controller.
1523 DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
1525 Process I/O Requests for Controller.
1527 DAC960_ProcessRequests(Controller);
1529 Release exclusive access to Controller.
1531 DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
1536 DAC960_RequestFunction7 is the I/O Request Function for DAC960 Controller 7.
1539 static void DAC960_RequestFunction7(void)
1541 DAC960_Controller_T *Controller = DAC960_Controllers[7];
1542 ProcessorFlags_T ProcessorFlags;
1544 Acquire exclusive access to Controller.
1546 DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
1548 Process I/O Requests for Controller.
1550 DAC960_ProcessRequests(Controller);
1552 Release exclusive access to Controller.
1554 DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
1559 DAC960_ReadWriteError prints an appropriate error message for Command when
1560 an error occurs on a Read or Write operation.
1563 static void DAC960_ReadWriteError(DAC960_Command_T *Command)
1565 DAC960_Controller_T *Controller = Command->Controller;
1566 char *CommandName = "UNKNOWN";
1567 switch (Command->CommandType)
1569 case DAC960_ReadCommand:
1570 case DAC960_ReadRetryCommand:
1571 CommandName = "READ";
1572 break;
1573 case DAC960_WriteCommand:
1574 case DAC960_WriteRetryCommand:
1575 CommandName = "WRITE";
1576 break;
1577 case DAC960_MonitoringCommand:
1578 case DAC960_ImmediateCommand:
1579 case DAC960_QueuedCommand:
1580 break;
1582 switch (Command->CommandStatus)
1584 case DAC960_IrrecoverableDataError:
1585 DAC960_Error("Irrecoverable Data Error on %s:\n",
1586 Controller, CommandName);
1587 break;
1588 case DAC960_LogicalDriveNonexistentOrOffline:
1589 DAC960_Error("Logical Drive Nonexistent or Offline on %s:\n",
1590 Controller, CommandName);
1591 break;
1592 case DAC960_AccessBeyondEndOfLogicalDrive:
1593 DAC960_Error("Attempt to Access Beyond End of Logical Drive "
1594 "on %s:\n", Controller, CommandName);
1595 break;
1596 case DAC960_BadDataEncountered:
1597 DAC960_Error("Bad Data Encountered on %s:\n", Controller, CommandName);
1598 break;
1599 default:
1600 DAC960_Error("Unexpected Error Status %04X on %s:\n",
1601 Controller, Command->CommandStatus, CommandName);
1602 break;
1604 DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %d..%d\n",
1605 Controller, Controller->ControllerNumber,
1606 Command->LogicalDriveNumber, Command->BlockNumber,
1607 Command->BlockNumber + Command->BlockCount - 1);
1608 if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
1609 DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
1610 Controller, Controller->ControllerNumber,
1611 Command->LogicalDriveNumber,
1612 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
1613 Command->BufferHeader->b_rsector,
1614 Command->BufferHeader->b_rsector + Command->BlockCount - 1);
1619 DAC960_ProcessCompletedBuffer performs completion processing for an
1620 individual Buffer.
1623 static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
1624 boolean SuccessfulIO)
1626 BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
1631 DAC960_ProcessCompletedCommand performs completion processing for Command.
1634 static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
1636 DAC960_Controller_T *Controller = Command->Controller;
1637 DAC960_CommandType_T CommandType = Command->CommandType;
1638 DAC960_CommandOpcode_T CommandOpcode =
1639 Command->CommandMailbox.Common.CommandOpcode;
1640 DAC960_CommandStatus_T CommandStatus = Command->CommandStatus;
1641 BufferHeader_T *BufferHeader = Command->BufferHeader;
1642 if (CommandType == DAC960_ReadCommand ||
1643 CommandType == DAC960_WriteCommand)
1645 if (CommandStatus == DAC960_NormalCompletion)
1648 Perform completion processing for all buffers in this I/O Request.
1650 while (BufferHeader != NULL)
1652 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
1653 BufferHeader->b_reqnext = NULL;
1654 DAC960_ProcessCompletedBuffer(BufferHeader, true);
1655 BufferHeader = NextBufferHeader;
1658 Wake up requestor for swap file paging requests.
1660 if (Command->Semaphore != NULL)
1662 up(Command->Semaphore);
1663 Command->Semaphore = NULL;
1665 add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
1667 else if ((CommandStatus == DAC960_IrrecoverableDataError ||
1668 CommandStatus == DAC960_BadDataEncountered) &&
1669 BufferHeader != NULL &&
1670 BufferHeader->b_reqnext != NULL)
1672 DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
1673 if (CommandType == DAC960_ReadCommand)
1675 Command->CommandType = DAC960_ReadRetryCommand;
1676 CommandMailbox->Type5.CommandOpcode = DAC960_Read;
1678 else
1680 Command->CommandType = DAC960_WriteRetryCommand;
1681 CommandMailbox->Type5.CommandOpcode = DAC960_Write;
1683 Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
1684 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
1685 CommandMailbox->Type5.BusAddress =
1686 Virtual_to_Bus(BufferHeader->b_data);
1687 DAC960_QueueCommand(Command);
1688 return;
1690 else
1692 if (CommandStatus != DAC960_LogicalDriveNonexistentOrOffline)
1693 DAC960_ReadWriteError(Command);
1695 Perform completion processing for all buffers in this I/O Request.
1697 while (BufferHeader != NULL)
1699 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
1700 BufferHeader->b_reqnext = NULL;
1701 DAC960_ProcessCompletedBuffer(BufferHeader, false);
1702 BufferHeader = NextBufferHeader;
1705 Wake up requestor for swap file paging requests.
1707 if (Command->Semaphore != NULL)
1709 up(Command->Semaphore);
1710 Command->Semaphore = NULL;
1714 else if (CommandType == DAC960_ReadRetryCommand ||
1715 CommandType == DAC960_WriteRetryCommand)
1717 BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
1718 BufferHeader->b_reqnext = NULL;
1720 Perform completion processing for this single buffer.
1722 if (CommandStatus == DAC960_NormalCompletion)
1723 DAC960_ProcessCompletedBuffer(BufferHeader, true);
1724 else
1726 if (CommandStatus != DAC960_LogicalDriveNonexistentOrOffline)
1727 DAC960_ReadWriteError(Command);
1728 DAC960_ProcessCompletedBuffer(BufferHeader, false);
1730 if (NextBufferHeader != NULL)
1732 DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
1733 Command->BlockNumber +=
1734 BufferHeader->b_size >> DAC960_BlockSizeBits;
1735 Command->BlockCount =
1736 NextBufferHeader->b_size >> DAC960_BlockSizeBits;
1737 Command->BufferHeader = NextBufferHeader;
1738 CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
1739 CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
1740 CommandMailbox->Type5.BusAddress =
1741 Virtual_to_Bus(NextBufferHeader->b_data);
1742 DAC960_QueueCommand(Command);
1743 return;
1746 else if (CommandType == DAC960_MonitoringCommand ||
1747 CommandOpcode == DAC960_Enquiry ||
1748 CommandOpcode == DAC960_GetRebuildProgress)
1750 if (CommandType != DAC960_MonitoringCommand)
1752 if (CommandOpcode == DAC960_Enquiry)
1753 memcpy(&Controller->Enquiry[Controller->EnquiryIndex ^ 1],
1754 Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress),
1755 sizeof(DAC960_Enquiry_T));
1756 else if (CommandOpcode == DAC960_GetRebuildProgress)
1757 memcpy(&Controller->RebuildProgress,
1758 Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress),
1759 sizeof(DAC960_RebuildProgress_T));
1761 if (CommandOpcode == DAC960_Enquiry)
1763 DAC960_Enquiry_T *OldEnquiry =
1764 &Controller->Enquiry[Controller->EnquiryIndex];
1765 DAC960_Enquiry_T *NewEnquiry =
1766 &Controller->Enquiry[Controller->EnquiryIndex ^= 1];
1767 unsigned int OldCriticalLogicalDriveCount =
1768 OldEnquiry->CriticalLogicalDriveCount;
1769 unsigned int NewCriticalLogicalDriveCount =
1770 NewEnquiry->CriticalLogicalDriveCount;
1771 if (NewEnquiry->StatusFlags.DeferredWriteError !=
1772 OldEnquiry->StatusFlags.DeferredWriteError)
1773 DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
1774 (NewEnquiry->StatusFlags.DeferredWriteError
1775 ? "TRUE" : "FALSE"));
1776 if ((NewCriticalLogicalDriveCount > 0 ||
1777 NewCriticalLogicalDriveCount != OldCriticalLogicalDriveCount) ||
1778 (NewEnquiry->OfflineLogicalDriveCount > 0 ||
1779 NewEnquiry->OfflineLogicalDriveCount !=
1780 OldEnquiry->OfflineLogicalDriveCount) ||
1781 (NewEnquiry->DeadDriveCount > 0 ||
1782 NewEnquiry->DeadDriveCount !=
1783 OldEnquiry->DeadDriveCount) ||
1784 (NewEnquiry->EventLogSequenceNumber !=
1785 OldEnquiry->EventLogSequenceNumber) ||
1786 Controller->MonitoringTimerCount == 0 ||
1787 (jiffies - Controller->SecondaryMonitoringTime
1788 >= DAC960_SecondaryMonitoringInterval))
1790 Controller->NeedLogicalDriveInformation = true;
1791 Controller->NewEventLogSequenceNumber =
1792 NewEnquiry->EventLogSequenceNumber;
1793 Controller->NeedErrorTableInformation = true;
1794 Controller->NeedDeviceStateInformation = true;
1795 Controller->DeviceStateChannel = 0;
1796 Controller->DeviceStateTargetID = -1;
1797 Controller->SecondaryMonitoringTime = jiffies;
1799 if (NewEnquiry->RebuildFlag == DAC960_StandbyRebuildInProgress ||
1800 NewEnquiry->RebuildFlag == DAC960_BackgroundRebuildInProgress ||
1801 OldEnquiry->RebuildFlag == DAC960_StandbyRebuildInProgress ||
1802 OldEnquiry->RebuildFlag == DAC960_BackgroundRebuildInProgress)
1803 Controller->NeedRebuildProgress = true;
1804 if (OldEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
1805 switch (NewEnquiry->RebuildFlag)
1807 case DAC960_NoStandbyRebuildOrCheckInProgress:
1808 DAC960_Progress("Consistency Check Completed Successfully\n",
1809 Controller);
1810 break;
1811 case DAC960_StandbyRebuildInProgress:
1812 case DAC960_BackgroundRebuildInProgress:
1813 break;
1814 case DAC960_BackgroundCheckInProgress:
1815 Controller->NeedConsistencyCheckProgress = true;
1816 break;
1817 case DAC960_StandbyRebuildCompletedWithError:
1818 DAC960_Progress("Consistency Check Completed with Error\n",
1819 Controller);
1820 break;
1821 case DAC960_BackgroundRebuildOrCheckFailed_DriveFailed:
1822 DAC960_Progress("Consistency Check Failed - "
1823 "Physical Drive Failed\n", Controller);
1824 break;
1825 case DAC960_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
1826 DAC960_Progress("Consistency Check Failed - "
1827 "Logical Drive Failed\n", Controller);
1828 break;
1829 case DAC960_BackgroundRebuildOrCheckFailed_OtherCauses:
1830 DAC960_Progress("Consistency Check Failed - Other Causes\n",
1831 Controller);
1832 break;
1833 case DAC960_BackgroundRebuildOrCheckSuccessfullyTerminated:
1834 DAC960_Progress("Consistency Check Successfully Terminated\n",
1835 Controller);
1836 break;
1838 else if (NewEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
1839 Controller->NeedConsistencyCheckProgress = true;
1841 else if (CommandOpcode == DAC960_PerformEventLogOperation)
1843 static char
1844 *DAC960_EventMessages[] =
1845 { "killed because write recovery failed",
1846 "killed because of SCSI bus reset failure",
1847 "killed because of double check condition",
1848 "killed because it was removed",
1849 "killed because of gross error on SCSI chip",
1850 "killed because of bad tag returned from drive",
1851 "killed because of timeout on SCSI command",
1852 "killed because of reset SCSI command issued from system",
1853 "killed because busy or parity error count exceeded limit",
1854 "killed because of 'kill drive' command from system",
1855 "killed because of selection timeout",
1856 "killed due to SCSI phase sequence error",
1857 "killed due to unknown status" };
1858 DAC960_EventLogEntry_T *EventLogEntry = &Controller->EventLogEntry;
1859 if (EventLogEntry->SequenceNumber ==
1860 Controller->OldEventLogSequenceNumber)
1862 unsigned char SenseKey = EventLogEntry->SenseKey;
1863 unsigned char AdditionalSenseCode =
1864 EventLogEntry->AdditionalSenseCode;
1865 unsigned char AdditionalSenseCodeQualifier =
1866 EventLogEntry->AdditionalSenseCodeQualifier;
1867 if (SenseKey == 9 &&
1868 AdditionalSenseCode == 0x80 &&
1869 AdditionalSenseCodeQualifier <
1870 sizeof(DAC960_EventMessages) / sizeof(char *))
1871 DAC960_Critical("Physical Drive %d:%d %s\n", Controller,
1872 EventLogEntry->Channel,
1873 EventLogEntry->TargetID,
1874 DAC960_EventMessages[
1875 AdditionalSenseCodeQualifier]);
1876 else if (SenseKey == 6 && AdditionalSenseCode == 0x29)
1878 if (Controller->MonitoringTimerCount > 0)
1879 Controller->DeviceResetCount[EventLogEntry->Channel]
1880 [EventLogEntry->TargetID]++;
1882 else if (!(SenseKey == 0 ||
1883 (SenseKey == 2 &&
1884 AdditionalSenseCode == 0x04 &&
1885 (AdditionalSenseCodeQualifier == 0x01 ||
1886 AdditionalSenseCodeQualifier == 0x02))))
1888 DAC960_Critical("Physical Drive %d:%d Error Log: "
1889 "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
1890 Controller,
1891 EventLogEntry->Channel,
1892 EventLogEntry->TargetID,
1893 SenseKey,
1894 AdditionalSenseCode,
1895 AdditionalSenseCodeQualifier);
1896 DAC960_Critical("Physical Drive %d:%d Error Log: "
1897 "Information = %02X%02X%02X%02X "
1898 "%02X%02X%02X%02X\n",
1899 Controller,
1900 EventLogEntry->Channel,
1901 EventLogEntry->TargetID,
1902 EventLogEntry->Information[0],
1903 EventLogEntry->Information[1],
1904 EventLogEntry->Information[2],
1905 EventLogEntry->Information[3],
1906 EventLogEntry->CommandSpecificInformation[0],
1907 EventLogEntry->CommandSpecificInformation[1],
1908 EventLogEntry->CommandSpecificInformation[2],
1909 EventLogEntry->CommandSpecificInformation[3]);
1912 Controller->OldEventLogSequenceNumber++;
1914 else if (CommandOpcode == DAC960_GetErrorTable)
1916 DAC960_ErrorTable_T *OldErrorTable =
1917 &Controller->ErrorTable[Controller->ErrorTableIndex];
1918 DAC960_ErrorTable_T *NewErrorTable =
1919 &Controller->ErrorTable[Controller->ErrorTableIndex ^= 1];
1920 int Channel, TargetID;
1921 for (Channel = 0; Channel < Controller->Channels; Channel++)
1922 for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
1924 DAC960_ErrorTableEntry_T *NewErrorEntry =
1925 &NewErrorTable->ErrorTableEntries[Channel][TargetID];
1926 DAC960_ErrorTableEntry_T *OldErrorEntry =
1927 &OldErrorTable->ErrorTableEntries[Channel][TargetID];
1928 if ((NewErrorEntry->ParityErrorCount !=
1929 OldErrorEntry->ParityErrorCount) ||
1930 (NewErrorEntry->SoftErrorCount !=
1931 OldErrorEntry->SoftErrorCount) ||
1932 (NewErrorEntry->HardErrorCount !=
1933 OldErrorEntry->HardErrorCount) ||
1934 (NewErrorEntry->MiscErrorCount !=
1935 OldErrorEntry->MiscErrorCount))
1936 DAC960_Critical("Physical Drive %d:%d Errors: "
1937 "Parity = %d, Soft = %d, "
1938 "Hard = %d, Misc = %d\n",
1939 Controller, Channel, TargetID,
1940 NewErrorEntry->ParityErrorCount,
1941 NewErrorEntry->SoftErrorCount,
1942 NewErrorEntry->HardErrorCount,
1943 NewErrorEntry->MiscErrorCount);
1946 else if (CommandOpcode == DAC960_GetDeviceState)
1948 DAC960_DeviceState_T *OldDeviceState =
1949 &Controller->DeviceState[Controller->DeviceStateIndex]
1950 [Controller->DeviceStateChannel]
1951 [Controller->DeviceStateTargetID];
1952 DAC960_DeviceState_T *NewDeviceState =
1953 &Controller->DeviceState[Controller->DeviceStateIndex ^ 1]
1954 [Controller->DeviceStateChannel]
1955 [Controller->DeviceStateTargetID];
1956 if (NewDeviceState->DeviceState != OldDeviceState->DeviceState)
1957 DAC960_Critical("Physical Drive %d:%d is now %s\n", Controller,
1958 Controller->DeviceStateChannel,
1959 Controller->DeviceStateTargetID,
1960 (NewDeviceState->DeviceState == DAC960_Device_Dead
1961 ? "DEAD"
1962 : NewDeviceState->DeviceState
1963 == DAC960_Device_WriteOnly
1964 ? "WRITE-ONLY"
1965 : NewDeviceState->DeviceState
1966 == DAC960_Device_Online
1967 ? "ONLINE" : "STANDBY"));
1968 if (OldDeviceState->DeviceState == DAC960_Device_Dead &&
1969 NewDeviceState->DeviceState != DAC960_Device_Dead)
1971 Controller->NeedDeviceInquiryInformation = true;
1972 Controller->NeedDeviceSerialNumberInformation = true;
1975 else if (CommandOpcode == DAC960_GetLogicalDriveInformation)
1977 int LogicalDriveNumber;
1978 for (LogicalDriveNumber = 0;
1979 LogicalDriveNumber < Controller->LogicalDriveCount;
1980 LogicalDriveNumber++)
1982 DAC960_LogicalDriveInformation_T *OldLogicalDriveInformation =
1983 &Controller->LogicalDriveInformation
1984 [Controller->LogicalDriveInformationIndex]
1985 [LogicalDriveNumber];
1986 DAC960_LogicalDriveInformation_T *NewLogicalDriveInformation =
1987 &Controller->LogicalDriveInformation
1988 [Controller->LogicalDriveInformationIndex ^ 1]
1989 [LogicalDriveNumber];
1990 if (NewLogicalDriveInformation->LogicalDriveState !=
1991 OldLogicalDriveInformation->LogicalDriveState)
1992 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
1993 "is now %s\n", Controller,
1994 LogicalDriveNumber,
1995 Controller->ControllerNumber,
1996 LogicalDriveNumber,
1997 (NewLogicalDriveInformation->LogicalDriveState
1998 == DAC960_LogicalDrive_Online
1999 ? "ONLINE"
2000 : NewLogicalDriveInformation->LogicalDriveState
2001 == DAC960_LogicalDrive_Critical
2002 ? "CRITICAL" : "OFFLINE"));
2003 if (NewLogicalDriveInformation->WriteBack !=
2004 OldLogicalDriveInformation->WriteBack)
2005 DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
2006 "is now %s\n", Controller,
2007 LogicalDriveNumber,
2008 Controller->ControllerNumber,
2009 LogicalDriveNumber,
2010 (NewLogicalDriveInformation->WriteBack
2011 ? "WRITE BACK" : "WRITE THRU"));
2013 Controller->LogicalDriveInformationIndex ^= 1;
2015 else if (CommandOpcode == DAC960_GetRebuildProgress)
2017 unsigned int LogicalDriveNumber =
2018 Controller->RebuildProgress.LogicalDriveNumber;
2019 unsigned int LogicalDriveSize =
2020 Controller->RebuildProgress.LogicalDriveSize;
2021 unsigned int BlocksCompleted =
2022 LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
2023 switch (CommandStatus)
2025 case DAC960_NormalCompletion:
2026 Controller->EphemeralProgressMessage = true;
2027 DAC960_Progress("Rebuild in Progress: "
2028 "Logical Drive %d (/dev/rd/c%dd%d) "
2029 "%d%% completed\n",
2030 Controller, LogicalDriveNumber,
2031 Controller->ControllerNumber,
2032 LogicalDriveNumber,
2033 (100 * (BlocksCompleted >> 7))
2034 / (LogicalDriveSize >> 7));
2035 Controller->EphemeralProgressMessage = false;
2036 break;
2037 case DAC960_RebuildFailed_LogicalDriveFailure:
2038 DAC960_Progress("Rebuild Failed due to "
2039 "Logical Drive Failure\n", Controller);
2040 break;
2041 case DAC960_RebuildFailed_BadBlocksOnOther:
2042 DAC960_Progress("Rebuild Failed due to "
2043 "Bad Blocks on Other Drives\n", Controller);
2044 break;
2045 case DAC960_RebuildFailed_NewDriveFailed:
2046 DAC960_Progress("Rebuild Failed due to "
2047 "Failure of Drive Being Rebuilt\n", Controller);
2048 break;
2049 case DAC960_NoRebuildOrCheckInProgress:
2050 if (Controller->LastRebuildStatus != DAC960_NormalCompletion)
2051 break;
2052 case DAC960_RebuildSuccessful:
2053 DAC960_Progress("Rebuild Completed Successfully\n", Controller);
2054 break;
2056 Controller->LastRebuildStatus = CommandStatus;
2058 else if (CommandOpcode == DAC960_RebuildStat)
2060 unsigned int LogicalDriveNumber =
2061 Controller->RebuildProgress.LogicalDriveNumber;
2062 unsigned int LogicalDriveSize =
2063 Controller->RebuildProgress.LogicalDriveSize;
2064 unsigned int BlocksCompleted =
2065 LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
2066 if (CommandStatus == DAC960_NormalCompletion)
2068 Controller->EphemeralProgressMessage = true;
2069 DAC960_Progress("Consistency Check in Progress: "
2070 "Logical Drive %d (/dev/rd/c%dd%d) "
2071 "%d%% completed\n",
2072 Controller, LogicalDriveNumber,
2073 Controller->ControllerNumber,
2074 LogicalDriveNumber,
2075 (100 * (BlocksCompleted >> 7))
2076 / (LogicalDriveSize >> 7));
2077 Controller->EphemeralProgressMessage = false;
2081 if (CommandType == DAC960_MonitoringCommand)
2083 if (Controller->NewEventLogSequenceNumber
2084 - Controller->OldEventLogSequenceNumber > 0)
2086 Command->CommandMailbox.Type3E.CommandOpcode =
2087 DAC960_PerformEventLogOperation;
2088 Command->CommandMailbox.Type3E.OperationType =
2089 DAC960_GetEventLogEntry;
2090 Command->CommandMailbox.Type3E.OperationQualifier = 1;
2091 Command->CommandMailbox.Type3E.SequenceNumber =
2092 Controller->OldEventLogSequenceNumber;
2093 Command->CommandMailbox.Type3E.BusAddress =
2094 Virtual_to_Bus(&Controller->EventLogEntry);
2095 DAC960_QueueCommand(Command);
2096 return;
2098 if (Controller->NeedErrorTableInformation)
2100 Controller->NeedErrorTableInformation = false;
2101 Command->CommandMailbox.Type3.CommandOpcode = DAC960_GetErrorTable;
2102 Command->CommandMailbox.Type3.BusAddress =
2103 Virtual_to_Bus(
2104 &Controller->ErrorTable[Controller->ErrorTableIndex ^ 1]);
2105 DAC960_QueueCommand(Command);
2106 return;
2108 if (Controller->NeedRebuildProgress &&
2109 Controller->Enquiry[Controller->EnquiryIndex]
2110 .CriticalLogicalDriveCount <
2111 Controller->Enquiry[Controller->EnquiryIndex ^ 1]
2112 .CriticalLogicalDriveCount)
2114 Controller->NeedRebuildProgress = false;
2115 Command->CommandMailbox.Type3.CommandOpcode =
2116 DAC960_GetRebuildProgress;
2117 Command->CommandMailbox.Type3.BusAddress =
2118 Virtual_to_Bus(&Controller->RebuildProgress);
2119 DAC960_QueueCommand(Command);
2120 return;
2122 if (Controller->NeedDeviceStateInformation)
2124 if (Controller->NeedDeviceInquiryInformation)
2126 DAC960_DCDB_T *DCDB = &Controller->MonitoringDCDB;
2127 DAC960_SCSI_Inquiry_T *InquiryStandardData =
2128 &Controller->InquiryStandardData
2129 [Controller->DeviceStateChannel]
2130 [Controller->DeviceStateTargetID];
2131 InquiryStandardData->PeripheralDeviceType = 0x1F;
2132 Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
2133 Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
2134 DCDB->Channel = Controller->DeviceStateChannel;
2135 DCDB->TargetID = Controller->DeviceStateTargetID;
2136 DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
2137 DCDB->EarlyStatus = false;
2138 DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
2139 DCDB->NoAutomaticRequestSense = false;
2140 DCDB->DisconnectPermitted = true;
2141 DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
2142 DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
2143 DCDB->CDBLength = 6;
2144 DCDB->TransferLengthHigh4 = 0;
2145 DCDB->SenseLength = sizeof(DCDB->SenseData);
2146 DCDB->CDB[0] = 0x12; /* INQUIRY */
2147 DCDB->CDB[1] = 0; /* EVPD = 0 */
2148 DCDB->CDB[2] = 0; /* Page Code */
2149 DCDB->CDB[3] = 0; /* Reserved */
2150 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
2151 DCDB->CDB[5] = 0; /* Control */
2152 DAC960_QueueCommand(Command);
2153 Controller->NeedDeviceInquiryInformation = false;
2154 return;
2156 if (Controller->NeedDeviceSerialNumberInformation)
2158 DAC960_DCDB_T *DCDB = &Controller->MonitoringDCDB;
2159 DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
2160 &Controller->InquiryUnitSerialNumber
2161 [Controller->DeviceStateChannel]
2162 [Controller->DeviceStateTargetID];
2163 InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
2164 Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
2165 Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
2166 DCDB->Channel = Controller->DeviceStateChannel;
2167 DCDB->TargetID = Controller->DeviceStateTargetID;
2168 DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
2169 DCDB->EarlyStatus = false;
2170 DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
2171 DCDB->NoAutomaticRequestSense = false;
2172 DCDB->DisconnectPermitted = true;
2173 DCDB->TransferLength =
2174 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
2175 DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
2176 DCDB->CDBLength = 6;
2177 DCDB->TransferLengthHigh4 = 0;
2178 DCDB->SenseLength = sizeof(DCDB->SenseData);
2179 DCDB->CDB[0] = 0x12; /* INQUIRY */
2180 DCDB->CDB[1] = 1; /* EVPD = 1 */
2181 DCDB->CDB[2] = 0x80; /* Page Code */
2182 DCDB->CDB[3] = 0; /* Reserved */
2183 DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
2184 DCDB->CDB[5] = 0; /* Control */
2185 DAC960_QueueCommand(Command);
2186 Controller->NeedDeviceSerialNumberInformation = false;
2187 return;
2189 if (++Controller->DeviceStateTargetID == DAC960_MaxTargets)
2191 Controller->DeviceStateChannel++;
2192 Controller->DeviceStateTargetID = 0;
2194 while (Controller->DeviceStateChannel < Controller->Channels)
2196 DAC960_DeviceState_T *OldDeviceState =
2197 &Controller->DeviceState[Controller->DeviceStateIndex]
2198 [Controller->DeviceStateChannel]
2199 [Controller->DeviceStateTargetID];
2200 if (OldDeviceState->Present &&
2201 OldDeviceState->DeviceType == DAC960_DiskType)
2203 Command->CommandMailbox.Type3D.CommandOpcode =
2204 DAC960_GetDeviceState;
2205 Command->CommandMailbox.Type3D.Channel =
2206 Controller->DeviceStateChannel;
2207 Command->CommandMailbox.Type3D.TargetID =
2208 Controller->DeviceStateTargetID;
2209 Command->CommandMailbox.Type3D.BusAddress =
2210 Virtual_to_Bus(&Controller->DeviceState
2211 [Controller->DeviceStateIndex ^ 1]
2212 [Controller->DeviceStateChannel]
2213 [Controller->DeviceStateTargetID]);
2214 DAC960_QueueCommand(Command);
2215 return;
2217 if (++Controller->DeviceStateTargetID == DAC960_MaxTargets)
2219 Controller->DeviceStateChannel++;
2220 Controller->DeviceStateTargetID = 0;
2223 Controller->NeedDeviceStateInformation = false;
2224 Controller->DeviceStateIndex ^= 1;
2226 if (Controller->NeedLogicalDriveInformation)
2228 Controller->NeedLogicalDriveInformation = false;
2229 Command->CommandMailbox.Type3.CommandOpcode =
2230 DAC960_GetLogicalDriveInformation;
2231 Command->CommandMailbox.Type3.BusAddress =
2232 Virtual_to_Bus(
2233 &Controller->LogicalDriveInformation
2234 [Controller->LogicalDriveInformationIndex ^ 1]);
2235 DAC960_QueueCommand(Command);
2236 return;
2238 if (Controller->NeedRebuildProgress)
2240 Controller->NeedRebuildProgress = false;
2241 Command->CommandMailbox.Type3.CommandOpcode =
2242 DAC960_GetRebuildProgress;
2243 Command->CommandMailbox.Type3.BusAddress =
2244 Virtual_to_Bus(&Controller->RebuildProgress);
2245 DAC960_QueueCommand(Command);
2246 return;
2248 if (Controller->NeedConsistencyCheckProgress)
2250 Controller->NeedConsistencyCheckProgress = false;
2251 Command->CommandMailbox.Type3.CommandOpcode = DAC960_RebuildStat;
2252 Command->CommandMailbox.Type3.BusAddress =
2253 Virtual_to_Bus(&Controller->RebuildProgress);
2254 DAC960_QueueCommand(Command);
2255 return;
2257 Controller->MonitoringTimerCount++;
2258 Controller->MonitoringTimer.expires =
2259 jiffies + DAC960_MonitoringTimerInterval;
2260 add_timer(&Controller->MonitoringTimer);
2262 if (CommandType == DAC960_ImmediateCommand)
2264 up(Command->Semaphore);
2265 Command->Semaphore = NULL;
2266 return;
2268 if (CommandType == DAC960_QueuedCommand)
2270 DAC960_KernelCommand_T *KernelCommand = Command->KernelCommand;
2271 KernelCommand->CommandStatus = CommandStatus;
2272 Command->KernelCommand = NULL;
2273 if (CommandOpcode == DAC960_DCDB)
2274 Controller->DirectCommandActive[KernelCommand->DCDB->Channel]
2275 [KernelCommand->DCDB->TargetID] = false;
2276 DAC960_DeallocateCommand(Command);
2277 KernelCommand->CompletionFunction(KernelCommand);
2278 return;
2281 Queue a Status Monitoring Command to the Controller using the just
2282 completed Command if one was deferred previously due to lack of a
2283 free Command when the Monitoring Timer Function was called.
2285 if (Controller->MonitoringCommandDeferred)
2287 Controller->MonitoringCommandDeferred = false;
2288 DAC960_QueueMonitoringCommand(Command);
2289 return;
2292 Deallocate the Command, and wake up any processes waiting on a free Command.
2294 DAC960_DeallocateCommand(Command);
2295 wake_up(&Controller->CommandWaitQueue);
2300 DAC960_InterruptHandler handles hardware interrupts from DAC960 Controllers.
2303 static void DAC960_InterruptHandler(int IRQ_Channel,
2304 void *DeviceIdentifier,
2305 Registers_T *InterruptRegisters)
2307 DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
2308 void *ControllerBaseAddress = Controller->BaseAddress;
2309 DAC960_StatusMailbox_T *NextStatusMailbox;
2310 ProcessorFlags_T ProcessorFlags;
2312 Acquire exclusive access to Controller.
2314 DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
2316 Process Hardware Interrupts for Controller.
2318 switch (Controller->ControllerType)
2320 case DAC960_V5_Controller:
2321 DAC960_V5_AcknowledgeInterrupt(ControllerBaseAddress);
2322 NextStatusMailbox = Controller->NextStatusMailbox;
2323 while (NextStatusMailbox->Fields.Valid)
2325 DAC960_CommandIdentifier_T CommandIdentifier =
2326 NextStatusMailbox->Fields.CommandIdentifier;
2327 DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
2328 Command->CommandStatus = NextStatusMailbox->Fields.CommandStatus;
2329 NextStatusMailbox->Word = 0;
2330 if (++NextStatusMailbox > Controller->LastStatusMailbox)
2331 NextStatusMailbox = Controller->FirstStatusMailbox;
2332 DAC960_ProcessCompletedCommand(Command);
2334 Controller->NextStatusMailbox = NextStatusMailbox;
2335 break;
2336 case DAC960_V4_Controller:
2337 DAC960_V4_AcknowledgeInterrupt(ControllerBaseAddress);
2338 NextStatusMailbox = Controller->NextStatusMailbox;
2339 while (NextStatusMailbox->Fields.Valid)
2341 DAC960_CommandIdentifier_T CommandIdentifier =
2342 NextStatusMailbox->Fields.CommandIdentifier;
2343 DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
2344 Command->CommandStatus = NextStatusMailbox->Fields.CommandStatus;
2345 NextStatusMailbox->Word = 0;
2346 if (++NextStatusMailbox > Controller->LastStatusMailbox)
2347 NextStatusMailbox = Controller->FirstStatusMailbox;
2348 DAC960_ProcessCompletedCommand(Command);
2350 Controller->NextStatusMailbox = NextStatusMailbox;
2351 break;
2352 case DAC960_V3_Controller:
2353 while (DAC960_V3_StatusAvailableP(ControllerBaseAddress))
2355 DAC960_CommandIdentifier_T CommandIdentifier =
2356 DAC960_V3_ReadStatusCommandIdentifier(ControllerBaseAddress);
2357 DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
2358 Command->CommandStatus =
2359 DAC960_V3_ReadStatusRegister(ControllerBaseAddress);
2360 DAC960_V3_AcknowledgeInterrupt(ControllerBaseAddress);
2361 DAC960_V3_AcknowledgeStatus(ControllerBaseAddress);
2362 DAC960_ProcessCompletedCommand(Command);
2364 break;
2367 Attempt to remove additional I/O Requests from the Controller's
2368 I/O Request Queue and queue them to the Controller.
2370 while (DAC960_ProcessRequest(Controller, false)) ;
2372 Release exclusive access to Controller.
2374 DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
2379 DAC960_QueueMonitoringCommand queues a Monitoring Command to Controller.
2382 static void DAC960_QueueMonitoringCommand(DAC960_Command_T *Command)
2384 DAC960_Controller_T *Controller = Command->Controller;
2385 DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
2386 DAC960_ClearCommand(Command);
2387 Command->CommandType = DAC960_MonitoringCommand;
2388 CommandMailbox->Type3.CommandOpcode = DAC960_Enquiry;
2389 CommandMailbox->Type3.BusAddress =
2390 Virtual_to_Bus(&Controller->Enquiry[Controller->EnquiryIndex ^ 1]);
2391 DAC960_QueueCommand(Command);
2396 DAC960_MonitoringTimerFunction is the timer function for monitoring
2397 the status of DAC960 Controllers.
2400 static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
2402 DAC960_Controller_T *Controller = (DAC960_Controller_T *) TimerData;
2403 DAC960_Command_T *Command;
2404 ProcessorFlags_T ProcessorFlags;
2406 Acquire exclusive access to Controller.
2408 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
2410 Queue a Status Monitoring Command to Controller.
2412 Command = DAC960_AllocateCommand(Controller);
2413 if (Command != NULL)
2414 DAC960_QueueMonitoringCommand(Command);
2415 else Controller->MonitoringCommandDeferred = true;
2417 Release exclusive access to Controller.
2419 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
2424 DAC960_Open is the Device Open Function for the DAC960 Driver.
2427 static int DAC960_Open(Inode_T *Inode, File_T *File)
2429 int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
2430 int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
2431 DAC960_Controller_T *Controller;
2432 if (ControllerNumber == 0 && LogicalDriveNumber == 0 &&
2433 (File->f_flags & O_NONBLOCK))
2434 goto ModuleOnly;
2435 if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
2436 return -ENXIO;
2437 Controller = DAC960_Controllers[ControllerNumber];
2438 if (Controller == NULL ||
2439 LogicalDriveNumber > Controller->LogicalDriveCount - 1)
2440 return -ENXIO;
2441 if (Controller->LogicalDriveInformation
2442 [Controller->LogicalDriveInformationIndex]
2443 [LogicalDriveNumber].LogicalDriveState
2444 == DAC960_LogicalDrive_Offline)
2445 return -ENXIO;
2446 if (Controller->LogicalDriveInitialState[LogicalDriveNumber]
2447 == DAC960_LogicalDrive_Offline)
2449 Controller->LogicalDriveInitialState[LogicalDriveNumber] =
2450 DAC960_LogicalDrive_Online;
2451 DAC960_InitializeGenericDiskInfo(&Controller->GenericDiskInfo);
2452 resetup_one_dev(&Controller->GenericDiskInfo, LogicalDriveNumber);
2454 if (Controller->GenericDiskInfo.sizes[MINOR(Inode->i_rdev)] == 0)
2455 return -ENXIO;
2457 Increment Controller and Logical Drive Usage Counts.
2459 Controller->ControllerUsageCount++;
2460 Controller->LogicalDriveUsageCount[LogicalDriveNumber]++;
2461 ModuleOnly:
2462 MOD_INC_USE_COUNT;
2463 return 0;
2468 DAC960_Release is the Device Release Function for the DAC960 Driver.
2471 static int DAC960_Release(Inode_T *Inode, File_T *File)
2473 int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
2474 int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
2475 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
2476 if (ControllerNumber == 0 && LogicalDriveNumber == 0 &&
2477 File != NULL && (File->f_flags & O_NONBLOCK))
2478 goto ModuleOnly;
2480 Force any buffered data to be written.
2482 fsync_dev(Inode->i_rdev);
2484 Decrement the Logical Drive and Controller Usage Counts.
2486 Controller->LogicalDriveUsageCount[LogicalDriveNumber]--;
2487 Controller->ControllerUsageCount--;
2488 ModuleOnly:
2489 MOD_DEC_USE_COUNT;
2490 return 0;
2495 DAC960_IOCTL is the Device IOCTL Function for the DAC960 Driver.
2498 static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
2499 unsigned int Request, unsigned long Argument)
2501 int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
2502 int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
2503 DiskGeometry_T Geometry, *UserGeometry;
2504 DAC960_Controller_T *Controller;
2505 int PartitionNumber;
2506 if (File->f_flags & O_NONBLOCK)
2507 return DAC960_UserIOCTL(Inode, File, Request, Argument);
2508 if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
2509 return -ENXIO;
2510 Controller = DAC960_Controllers[ControllerNumber];
2511 if (Controller == NULL ||
2512 LogicalDriveNumber > Controller->LogicalDriveCount - 1)
2513 return -ENXIO;
2514 switch (Request)
2516 case HDIO_GETGEO:
2517 /* Get BIOS Disk Geometry. */
2518 UserGeometry = (DiskGeometry_T *) Argument;
2519 if (UserGeometry == NULL) return -EINVAL;
2520 Geometry.heads = Controller->GeometryTranslationHeads;
2521 Geometry.sectors = Controller->GeometryTranslationSectors;
2522 Geometry.cylinders =
2523 Controller->LogicalDriveInformation
2524 [Controller->LogicalDriveInformationIndex]
2525 [LogicalDriveNumber].LogicalDriveSize
2526 / (Controller->GeometryTranslationHeads *
2527 Controller->GeometryTranslationSectors);
2528 Geometry.start = Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
2529 .start_sect;
2530 return copy_to_user(UserGeometry, &Geometry, sizeof(DiskGeometry_T));
2531 case BLKGETSIZE:
2532 /* Get Device Size. */
2533 if ((long *) Argument == NULL) return -EINVAL;
2534 return put_user(Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
2535 .nr_sects,
2536 (long *) Argument);
2537 case BLKRAGET:
2538 /* Get Read-Ahead. */
2539 if ((int *) Argument == NULL) return -EINVAL;
2540 return put_user(read_ahead[MAJOR(Inode->i_rdev)], (int *) Argument);
2541 case BLKRASET:
2542 /* Set Read-Ahead. */
2543 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
2544 if (Argument > 256) return -EINVAL;
2545 read_ahead[MAJOR(Inode->i_rdev)] = Argument;
2546 return 0;
2547 case BLKFLSBUF:
2548 /* Flush Buffers. */
2549 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
2550 fsync_dev(Inode->i_rdev);
2551 invalidate_buffers(Inode->i_rdev);
2552 return 0;
2553 case BLKRRPART:
2554 /* Re-Read Partition Table. */
2555 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
2556 if (Controller->LogicalDriveUsageCount[LogicalDriveNumber] > 1)
2557 return -EBUSY;
2558 for (PartitionNumber = 0;
2559 PartitionNumber < DAC960_MaxPartitions;
2560 PartitionNumber++)
2562 KernelDevice_T Device = DAC960_KernelDevice(ControllerNumber,
2563 LogicalDriveNumber,
2564 PartitionNumber);
2565 int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber,
2566 PartitionNumber);
2567 SuperBlock_T *SuperBlock = get_super(Device);
2568 if (Controller->GenericDiskInfo.part[MinorNumber].nr_sects == 0)
2569 continue;
2571 Flush all changes and invalidate buffered state.
2573 sync_dev(Device);
2574 if (SuperBlock != NULL)
2575 invalidate_inodes(SuperBlock);
2576 invalidate_buffers(Device);
2578 Clear existing partition sizes.
2580 if (PartitionNumber > 0)
2582 Controller->GenericDiskInfo.part[MinorNumber].start_sect = 0;
2583 Controller->GenericDiskInfo.part[MinorNumber].nr_sects = 0;
2586 Reset the Block Size so that the partition table can be read.
2588 set_blocksize(Device, BLOCK_SIZE);
2590 resetup_one_dev(&Controller->GenericDiskInfo, LogicalDriveNumber);
2591 return 0;
2593 return -EINVAL;
2598 DAC960_UserIOCTL is the User IOCTL Function for the DAC960 Driver.
2601 static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
2602 unsigned int Request, unsigned long Argument)
2604 int ErrorCode;
2605 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
2606 switch (Request)
2608 case DAC960_IOCTL_GET_CONTROLLER_COUNT:
2609 return DAC960_ControllerCount;
2610 case DAC960_IOCTL_GET_CONTROLLER_INFO:
2612 DAC960_ControllerInfo_T *UserSpaceControllerInfo =
2613 (DAC960_ControllerInfo_T *) Argument;
2614 DAC960_ControllerInfo_T ControllerInfo;
2615 DAC960_Controller_T *Controller;
2616 int ControllerNumber;
2617 if (UserSpaceControllerInfo == NULL) return -EINVAL;
2618 ErrorCode = get_user(ControllerNumber,
2619 &UserSpaceControllerInfo->ControllerNumber);
2620 if (ErrorCode != 0) return ErrorCode;
2621 if (ControllerNumber < 0 ||
2622 ControllerNumber > DAC960_ControllerCount - 1)
2623 return -ENXIO;
2624 Controller = DAC960_Controllers[ControllerNumber];
2625 if (Controller == NULL)
2626 return -ENXIO;
2627 memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
2628 ControllerInfo.ControllerNumber = ControllerNumber;
2629 ControllerInfo.PCI_Bus = Controller->Bus;
2630 ControllerInfo.PCI_Device = Controller->Device;
2631 ControllerInfo.PCI_Function = Controller->Function;
2632 ControllerInfo.IRQ_Channel = Controller->IRQ_Channel;
2633 ControllerInfo.Channels = Controller->Channels;
2634 ControllerInfo.PCI_Address = Controller->PCI_Address;
2635 strcpy(ControllerInfo.ModelName, Controller->ModelName);
2636 strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
2637 return copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
2638 sizeof(DAC960_ControllerInfo_T));
2640 case DAC960_IOCTL_EXECUTE_COMMAND:
2642 DAC960_UserCommand_T *UserSpaceUserCommand =
2643 (DAC960_UserCommand_T *) Argument;
2644 DAC960_UserCommand_T UserCommand;
2645 DAC960_Controller_T *Controller;
2646 DAC960_Command_T *Command = NULL;
2647 DAC960_CommandOpcode_T CommandOpcode;
2648 DAC960_CommandStatus_T CommandStatus;
2649 DAC960_DCDB_T DCDB;
2650 ProcessorFlags_T ProcessorFlags;
2651 int ControllerNumber, DataTransferLength;
2652 unsigned char *DataTransferBuffer = NULL;
2653 if (UserSpaceUserCommand == NULL) return -EINVAL;
2654 ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
2655 sizeof(DAC960_UserCommand_T));
2656 if (ErrorCode != 0) goto Failure;
2657 ControllerNumber = UserCommand.ControllerNumber;
2658 if (ControllerNumber < 0 ||
2659 ControllerNumber > DAC960_ControllerCount - 1)
2660 return -ENXIO;
2661 Controller = DAC960_Controllers[ControllerNumber];
2662 if (Controller == NULL)
2663 return -ENXIO;
2664 CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
2665 DataTransferLength = UserCommand.DataTransferLength;
2666 if (CommandOpcode & 0x80) return -EINVAL;
2667 if (CommandOpcode == DAC960_DCDB)
2669 ErrorCode =
2670 copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_DCDB_T));
2671 if (ErrorCode != 0) goto Failure;
2672 if (!((DataTransferLength == 0 &&
2673 DCDB.Direction == DAC960_DCDB_NoDataTransfer) ||
2674 (DataTransferLength > 0 &&
2675 DCDB.Direction == DAC960_DCDB_DataTransferDeviceToSystem) ||
2676 (DataTransferLength < 0 &&
2677 DCDB.Direction == DAC960_DCDB_DataTransferSystemToDevice)))
2678 return -EINVAL;
2679 if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
2680 != abs(DataTransferLength))
2681 return -EINVAL;
2683 if (DataTransferLength > 0)
2685 DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
2686 if (DataTransferBuffer == NULL) return -ENOMEM;
2687 memset(DataTransferBuffer, 0, DataTransferLength);
2689 else if (DataTransferLength < 0)
2691 DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
2692 if (DataTransferBuffer == NULL) return -ENOMEM;
2693 ErrorCode = copy_from_user(DataTransferBuffer,
2694 UserCommand.DataTransferBuffer,
2695 -DataTransferLength);
2696 if (ErrorCode != 0) goto Failure;
2698 if (CommandOpcode == DAC960_DCDB)
2700 while (true)
2702 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
2703 if (!Controller->DirectCommandActive[DCDB.Channel]
2704 [DCDB.TargetID])
2705 Command = DAC960_AllocateCommand(Controller);
2706 if (Command != NULL)
2707 Controller->DirectCommandActive[DCDB.Channel]
2708 [DCDB.TargetID] = true;
2709 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
2710 if (Command != NULL) break;
2711 sleep_on(&Controller->CommandWaitQueue);
2713 DAC960_ClearCommand(Command);
2714 Command->CommandType = DAC960_ImmediateCommand;
2715 memcpy(&Command->CommandMailbox, &UserCommand.CommandMailbox,
2716 sizeof(DAC960_CommandMailbox_T));
2717 Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(&DCDB);
2718 DCDB.BusAddress = Virtual_to_Bus(DataTransferBuffer);
2720 else
2722 while (true)
2724 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
2725 Command = DAC960_AllocateCommand(Controller);
2726 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
2727 if (Command != NULL) break;
2728 sleep_on(&Controller->CommandWaitQueue);
2730 DAC960_ClearCommand(Command);
2731 Command->CommandType = DAC960_ImmediateCommand;
2732 memcpy(&Command->CommandMailbox, &UserCommand.CommandMailbox,
2733 sizeof(DAC960_CommandMailbox_T));
2734 if (DataTransferBuffer != NULL)
2735 Command->CommandMailbox.Type3.BusAddress =
2736 Virtual_to_Bus(DataTransferBuffer);
2738 DAC960_ExecuteCommand(Command);
2739 CommandStatus = Command->CommandStatus;
2740 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
2741 DAC960_DeallocateCommand(Command);
2742 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
2743 if (CommandStatus == DAC960_NormalCompletion &&
2744 DataTransferLength > 0)
2746 ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
2747 DataTransferBuffer, DataTransferLength);
2748 if (ErrorCode != 0) goto Failure;
2750 if (CommandOpcode == DAC960_DCDB)
2752 Controller->DirectCommandActive[DCDB.Channel]
2753 [DCDB.TargetID] = false;
2754 ErrorCode =
2755 copy_to_user(UserCommand.DCDB, &DCDB, sizeof(DAC960_DCDB_T));
2756 if (ErrorCode != 0) goto Failure;
2758 ErrorCode = CommandStatus;
2759 Failure:
2760 if (DataTransferBuffer != NULL)
2761 kfree(DataTransferBuffer);
2762 return ErrorCode;
2765 return -EINVAL;
2770 DAC960_KernelIOCTL is the Kernel IOCTL Function for the DAC960 Driver.
2773 int DAC960_KernelIOCTL(unsigned int Request, void *Argument)
2775 switch (Request)
2777 case DAC960_IOCTL_GET_CONTROLLER_COUNT:
2778 return DAC960_ControllerCount;
2779 case DAC960_IOCTL_GET_CONTROLLER_INFO:
2781 DAC960_ControllerInfo_T *ControllerInfo =
2782 (DAC960_ControllerInfo_T *) Argument;
2783 DAC960_Controller_T *Controller;
2784 int ControllerNumber;
2785 if (ControllerInfo == NULL) return -EINVAL;
2786 ControllerNumber = ControllerInfo->ControllerNumber;
2787 if (ControllerNumber < 0 ||
2788 ControllerNumber > DAC960_ControllerCount - 1)
2789 return -ENXIO;
2790 Controller = DAC960_Controllers[ControllerNumber];
2791 if (Controller == NULL)
2792 return -ENXIO;
2793 memset(ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
2794 ControllerInfo->ControllerNumber = ControllerNumber;
2795 ControllerInfo->PCI_Bus = Controller->Bus;
2796 ControllerInfo->PCI_Device = Controller->Device;
2797 ControllerInfo->PCI_Function = Controller->Function;
2798 ControllerInfo->IRQ_Channel = Controller->IRQ_Channel;
2799 ControllerInfo->Channels = Controller->Channels;
2800 ControllerInfo->PCI_Address = Controller->PCI_Address;
2801 strcpy(ControllerInfo->ModelName, Controller->ModelName);
2802 strcpy(ControllerInfo->FirmwareVersion, Controller->FirmwareVersion);
2803 return 0;
2805 case DAC960_IOCTL_EXECUTE_COMMAND:
2807 DAC960_KernelCommand_T *KernelCommand =
2808 (DAC960_KernelCommand_T *) Argument;
2809 DAC960_Controller_T *Controller;
2810 DAC960_Command_T *Command = NULL;
2811 DAC960_CommandOpcode_T CommandOpcode;
2812 DAC960_DCDB_T *DCDB = NULL;
2813 ProcessorFlags_T ProcessorFlags;
2814 int ControllerNumber, DataTransferLength;
2815 unsigned char *DataTransferBuffer = NULL;
2816 if (KernelCommand == NULL) return -EINVAL;
2817 ControllerNumber = KernelCommand->ControllerNumber;
2818 if (ControllerNumber < 0 ||
2819 ControllerNumber > DAC960_ControllerCount - 1)
2820 return -ENXIO;
2821 Controller = DAC960_Controllers[ControllerNumber];
2822 if (Controller == NULL)
2823 return -ENXIO;
2824 CommandOpcode = KernelCommand->CommandMailbox.Common.CommandOpcode;
2825 DataTransferLength = KernelCommand->DataTransferLength;
2826 DataTransferBuffer = KernelCommand->DataTransferBuffer;
2827 if (CommandOpcode & 0x80) return -EINVAL;
2828 if (CommandOpcode == DAC960_DCDB)
2830 DCDB = KernelCommand->DCDB;
2831 if (!((DataTransferLength == 0 &&
2832 DCDB->Direction == DAC960_DCDB_NoDataTransfer) ||
2833 (DataTransferLength > 0 &&
2834 DCDB->Direction == DAC960_DCDB_DataTransferDeviceToSystem) ||
2835 (DataTransferLength < 0 &&
2836 DCDB->Direction == DAC960_DCDB_DataTransferSystemToDevice)))
2837 return -EINVAL;
2838 if (((DCDB->TransferLengthHigh4 << 16) | DCDB->TransferLength)
2839 != abs(DataTransferLength))
2840 return -EINVAL;
2842 if (DataTransferLength != 0 && DataTransferBuffer == NULL)
2843 return -EINVAL;
2844 if (DataTransferLength > 0)
2845 memset(DataTransferBuffer, 0, DataTransferLength);
2846 if (CommandOpcode == DAC960_DCDB)
2848 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
2849 if (!Controller->DirectCommandActive[DCDB->Channel]
2850 [DCDB->TargetID])
2851 Command = DAC960_AllocateCommand(Controller);
2852 if (Command == NULL)
2854 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
2855 return -EBUSY;
2857 else Controller->DirectCommandActive[DCDB->Channel]
2858 [DCDB->TargetID] = true;
2859 DAC960_ClearCommand(Command);
2860 Command->CommandType = DAC960_QueuedCommand;
2861 memcpy(&Command->CommandMailbox, &KernelCommand->CommandMailbox,
2862 sizeof(DAC960_CommandMailbox_T));
2863 Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
2864 Command->KernelCommand = KernelCommand;
2865 DCDB->BusAddress = Virtual_to_Bus(DataTransferBuffer);
2866 DAC960_QueueCommand(Command);
2867 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
2869 else
2871 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
2872 Command = DAC960_AllocateCommand(Controller);
2873 if (Command == NULL)
2875 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
2876 return -EBUSY;
2878 DAC960_ClearCommand(Command);
2879 Command->CommandType = DAC960_QueuedCommand;
2880 memcpy(&Command->CommandMailbox, &KernelCommand->CommandMailbox,
2881 sizeof(DAC960_CommandMailbox_T));
2882 if (DataTransferBuffer != NULL)
2883 Command->CommandMailbox.Type3.BusAddress =
2884 Virtual_to_Bus(DataTransferBuffer);
2885 Command->KernelCommand = KernelCommand;
2886 DAC960_QueueCommand(Command);
2887 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
2889 return 0;
2892 return -EINVAL;
2897 DAC960_GenericDiskInit is the Generic Disk Information Initialization
2898 Function for the DAC960 Driver.
2901 static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
2903 DAC960_Controller_T *Controller =
2904 (DAC960_Controller_T *) GenericDiskInfo->real_devices;
2905 DAC960_LogicalDriveInformation_T *LogicalDriveInformation =
2906 Controller->LogicalDriveInformation
2907 [Controller->LogicalDriveInformationIndex];
2908 int LogicalDriveNumber;
2909 for (LogicalDriveNumber = 0;
2910 LogicalDriveNumber < Controller->LogicalDriveCount;
2911 LogicalDriveNumber++)
2912 GenericDiskInfo->part[DAC960_MinorNumber(LogicalDriveNumber, 0)].nr_sects =
2913 LogicalDriveInformation[LogicalDriveNumber].LogicalDriveSize;
2918 DAC960_Message prints Driver Messages.
2921 static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
2922 char *Format,
2923 DAC960_Controller_T *Controller,
2924 ...)
2926 static char Buffer[DAC960_LineBufferSize];
2927 static boolean BeginningOfLine = true;
2928 va_list Arguments;
2929 int Length = 0;
2930 va_start(Arguments, Controller);
2931 Length = vsprintf(Buffer, Format, Arguments);
2932 va_end(Arguments);
2933 if (Controller == NULL)
2934 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
2935 DAC960_ControllerCount, Buffer);
2936 else if (MessageLevel == DAC960_AnnounceLevel ||
2937 MessageLevel == DAC960_InfoLevel)
2939 if (!Controller->ControllerInitialized)
2941 strcpy(&Controller->InitialStatusBuffer[
2942 Controller->InitialStatusLength], Buffer);
2943 Controller->InitialStatusLength += Length;
2944 if (MessageLevel == DAC960_AnnounceLevel)
2946 static int AnnouncementLines = 0;
2947 if (++AnnouncementLines <= 2)
2948 printk("%sDAC960: %s", DAC960_MessageLevelMap[MessageLevel],
2949 Buffer);
2951 else
2953 if (BeginningOfLine)
2955 if (Buffer[0] != '\n' || Length > 1)
2956 printk("%sDAC960#%d: %s",
2957 DAC960_MessageLevelMap[MessageLevel],
2958 Controller->ControllerNumber, Buffer);
2960 else printk("%s", Buffer);
2963 else
2965 strcpy(&Controller->CurrentStatusBuffer[
2966 Controller->CurrentStatusLength], Buffer);
2967 Controller->CurrentStatusLength += Length;
2970 else if (MessageLevel == DAC960_ProgressLevel)
2972 strcpy(Controller->RebuildProgressBuffer, Buffer);
2973 Controller->RebuildProgressLength = Length;
2974 if (Controller->EphemeralProgressMessage)
2976 if (jiffies - Controller->LastProgressReportTime
2977 >= DAC960_ProgressReportingInterval)
2979 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
2980 Controller->ControllerNumber, Buffer);
2981 Controller->LastProgressReportTime = jiffies;
2984 else printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
2985 Controller->ControllerNumber, Buffer);
2987 else if (MessageLevel == DAC960_UserCriticalLevel)
2989 strcpy(&Controller->UserStatusBuffer[Controller->UserStatusLength],
2990 Buffer);
2991 Controller->UserStatusLength += Length;
2992 if (Buffer[0] != '\n' || Length > 1)
2993 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
2994 Controller->ControllerNumber, Buffer);
2996 else
2998 if (BeginningOfLine)
2999 printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
3000 Controller->ControllerNumber, Buffer);
3001 else printk("%s", Buffer);
3003 BeginningOfLine = (Buffer[Length-1] == '\n');
3008 DAC960_ParsePhysicalDrive parses spaces followed by a Physical Drive
3009 Channel:TargetID specification from a User Command string. It updates
3010 Channel and TargetID and returns true on success and returns false otherwise.
3013 static boolean DAC960_ParsePhysicalDrive(DAC960_Controller_T *Controller,
3014 char *UserCommandString,
3015 unsigned char *Channel,
3016 unsigned char *TargetID)
3018 char *NewUserCommandString = UserCommandString;
3019 unsigned long XChannel, XTargetID;
3020 while (*UserCommandString == ' ') UserCommandString++;
3021 if (UserCommandString == NewUserCommandString)
3022 return false;
3023 XChannel = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
3024 if (NewUserCommandString == UserCommandString ||
3025 *NewUserCommandString != ':' ||
3026 XChannel >= Controller->Channels)
3027 return false;
3028 UserCommandString = ++NewUserCommandString;
3029 XTargetID = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
3030 if (NewUserCommandString == UserCommandString ||
3031 *NewUserCommandString != '\0' ||
3032 XTargetID >= DAC960_MaxTargets)
3033 return false;
3034 *Channel = XChannel;
3035 *TargetID = XTargetID;
3036 return true;
3041 DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number
3042 specification from a User Command string. It updates LogicalDriveNumber and
3043 returns true on success and returns false otherwise.
3046 static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
3047 char *UserCommandString,
3048 unsigned char *LogicalDriveNumber)
3050 char *NewUserCommandString = UserCommandString;
3051 unsigned long XLogicalDriveNumber;
3052 while (*UserCommandString == ' ') UserCommandString++;
3053 if (UserCommandString == NewUserCommandString)
3054 return false;
3055 XLogicalDriveNumber =
3056 simple_strtoul(UserCommandString, &NewUserCommandString, 10);
3057 if (NewUserCommandString == UserCommandString ||
3058 *NewUserCommandString != '\0' ||
3059 XLogicalDriveNumber >= Controller->LogicalDriveCount)
3060 return false;
3061 *LogicalDriveNumber = XLogicalDriveNumber;
3062 return true;
3067 DAC960_SetDeviceState sets the Device State for a Physical Drive.
3070 static void DAC960_SetDeviceState(DAC960_Controller_T *Controller,
3071 DAC960_Command_T *Command,
3072 unsigned char Channel,
3073 unsigned char TargetID,
3074 DAC960_PhysicalDeviceState_T DeviceState,
3075 const char *DeviceStateString)
3077 DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
3078 CommandMailbox->Type3D.CommandOpcode = DAC960_StartDevice;
3079 CommandMailbox->Type3D.Channel = Channel;
3080 CommandMailbox->Type3D.TargetID = TargetID;
3081 CommandMailbox->Type3D.DeviceState = DeviceState;
3082 CommandMailbox->Type3D.Modifier = 0;
3083 DAC960_ExecuteCommand(Command);
3084 switch (Command->CommandStatus)
3086 case DAC960_NormalCompletion:
3087 DAC960_UserCritical("%s of Physical Drive %d:%d Succeeded\n", Controller,
3088 DeviceStateString, Channel, TargetID);
3089 break;
3090 case DAC960_UnableToStartDevice:
3091 DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
3092 "Unable to Start Device\n", Controller,
3093 DeviceStateString, Channel, TargetID);
3094 break;
3095 case DAC960_NoDeviceAtAddress:
3096 DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
3097 "No Device at Address\n", Controller,
3098 DeviceStateString, Channel, TargetID);
3099 break;
3100 case DAC960_InvalidChannelOrTargetOrModifier:
3101 DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
3102 "Invalid Channel or Target or Modifier\n",
3103 Controller, DeviceStateString, Channel, TargetID);
3104 break;
3105 case DAC960_ChannelBusy:
3106 DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
3107 "Channel Busy\n", Controller,
3108 DeviceStateString, Channel, TargetID);
3109 break;
3110 default:
3111 DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
3112 "Unexpected Status %04X\n", Controller,
3113 DeviceStateString, Channel, TargetID,
3114 Command->CommandStatus);
3115 break;
3121 DAC960_ExecuteUserCommand executes a User Command.
3124 static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
3125 char *UserCommand)
3127 DAC960_Command_T *Command;
3128 DAC960_CommandMailbox_T *CommandMailbox;
3129 ProcessorFlags_T ProcessorFlags;
3130 unsigned char Channel, TargetID, LogicalDriveNumber;
3131 while (true)
3133 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
3134 Command = DAC960_AllocateCommand(Controller);
3135 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
3136 if (Command != NULL) break;
3137 sleep_on(&Controller->CommandWaitQueue);
3139 Controller->UserStatusLength = 0;
3140 DAC960_ClearCommand(Command);
3141 Command->CommandType = DAC960_ImmediateCommand;
3142 CommandMailbox = &Command->CommandMailbox;
3143 if (strcmp(UserCommand, "flush-cache") == 0)
3145 CommandMailbox->Type3.CommandOpcode = DAC960_Flush;
3146 DAC960_ExecuteCommand(Command);
3147 DAC960_UserCritical("Cache Flush Completed\n", Controller);
3149 else if (strncmp(UserCommand, "kill", 4) == 0 &&
3150 DAC960_ParsePhysicalDrive(Controller, &UserCommand[4],
3151 &Channel, &TargetID))
3153 DAC960_DeviceState_T *DeviceState =
3154 &Controller->DeviceState[Controller->DeviceStateIndex]
3155 [Channel][TargetID];
3156 if (DeviceState->Present &&
3157 DeviceState->DeviceType == DAC960_DiskType &&
3158 DeviceState->DeviceState != DAC960_Device_Dead)
3159 DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
3160 DAC960_Device_Dead, "Kill");
3161 else DAC960_UserCritical("Kill of Physical Drive %d:%d Illegal\n",
3162 Controller, Channel, TargetID);
3164 else if (strncmp(UserCommand, "make-online", 11) == 0 &&
3165 DAC960_ParsePhysicalDrive(Controller, &UserCommand[11],
3166 &Channel, &TargetID))
3168 DAC960_DeviceState_T *DeviceState =
3169 &Controller->DeviceState[Controller->DeviceStateIndex]
3170 [Channel][TargetID];
3171 if (DeviceState->Present &&
3172 DeviceState->DeviceType == DAC960_DiskType &&
3173 DeviceState->DeviceState == DAC960_Device_Dead)
3174 DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
3175 DAC960_Device_Online, "Make Online");
3176 else DAC960_UserCritical("Make Online of Physical Drive %d:%d Illegal\n",
3177 Controller, Channel, TargetID);
3180 else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
3181 DAC960_ParsePhysicalDrive(Controller, &UserCommand[12],
3182 &Channel, &TargetID))
3184 DAC960_DeviceState_T *DeviceState =
3185 &Controller->DeviceState[Controller->DeviceStateIndex]
3186 [Channel][TargetID];
3187 if (DeviceState->Present &&
3188 DeviceState->DeviceType == DAC960_DiskType &&
3189 DeviceState->DeviceState == DAC960_Device_Dead)
3190 DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
3191 DAC960_Device_Standby, "Make Standby");
3192 else DAC960_UserCritical("Make Standby of Physical Drive %d:%d Illegal\n",
3193 Controller, Channel, TargetID);
3195 else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
3196 DAC960_ParsePhysicalDrive(Controller, &UserCommand[7],
3197 &Channel, &TargetID))
3199 CommandMailbox->Type3D.CommandOpcode = DAC960_RebuildAsync;
3200 CommandMailbox->Type3D.Channel = Channel;
3201 CommandMailbox->Type3D.TargetID = TargetID;
3202 DAC960_ExecuteCommand(Command);
3203 switch (Command->CommandStatus)
3205 case DAC960_NormalCompletion:
3206 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Initiated\n",
3207 Controller, Channel, TargetID);
3208 break;
3209 case DAC960_AttemptToRebuildOnlineDrive:
3210 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
3211 "Attempt to Rebuild Online or "
3212 "Unresponsive Drive\n",
3213 Controller, Channel, TargetID);
3214 break;
3215 case DAC960_NewDiskFailedDuringRebuild:
3216 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
3217 "New Disk Failed During Rebuild\n",
3218 Controller, Channel, TargetID);
3219 break;
3220 case DAC960_InvalidDeviceAddress:
3221 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
3222 "Invalid Device Address\n",
3223 Controller, Channel, TargetID);
3224 break;
3225 case DAC960_RebuildOrCheckAlreadyInProgress:
3226 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
3227 "Rebuild or Consistency Check Already "
3228 "in Progress\n", Controller, Channel, TargetID);
3229 break;
3230 default:
3231 DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
3232 "Unexpected Status %04X\n", Controller,
3233 Channel, TargetID, Command->CommandStatus);
3234 break;
3237 else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
3238 DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
3239 &LogicalDriveNumber))
3241 CommandMailbox->Type3C.CommandOpcode = DAC960_CheckConsistencyAsync;
3242 CommandMailbox->Type3C.LogicalDriveNumber = LogicalDriveNumber;
3243 CommandMailbox->Type3C.AutoRestore = true;
3244 DAC960_ExecuteCommand(Command);
3245 switch (Command->CommandStatus)
3247 case DAC960_NormalCompletion:
3248 DAC960_UserCritical("Consistency Check of Logical Drive %d "
3249 "(/dev/rd/c%dd%d) Initiated\n",
3250 Controller, LogicalDriveNumber,
3251 Controller->ControllerNumber,
3252 LogicalDriveNumber);
3253 break;
3254 case DAC960_DependentDiskIsDead:
3255 DAC960_UserCritical("Consistency Check of Logical Drive %d "
3256 "(/dev/rd/c%dd%d) Failed - "
3257 "Dependent Physical Drive is DEAD\n",
3258 Controller, LogicalDriveNumber,
3259 Controller->ControllerNumber,
3260 LogicalDriveNumber);
3261 break;
3262 case DAC960_InvalidOrNonredundantLogicalDrive:
3263 DAC960_UserCritical("Consistency Check of Logical Drive %d "
3264 "(/dev/rd/c%dd%d) Failed - "
3265 "Invalid or Nonredundant Logical Drive\n",
3266 Controller, LogicalDriveNumber,
3267 Controller->ControllerNumber,
3268 LogicalDriveNumber);
3269 break;
3270 case DAC960_RebuildOrCheckAlreadyInProgress:
3271 DAC960_UserCritical("Consistency Check of Logical Drive %d "
3272 "(/dev/rd/c%dd%d) Failed - Rebuild or "
3273 "Consistency Check Already in Progress\n",
3274 Controller, LogicalDriveNumber,
3275 Controller->ControllerNumber,
3276 LogicalDriveNumber);
3277 break;
3278 default:
3279 DAC960_UserCritical("Consistency Check of Logical Drive %d "
3280 "(/dev/rd/c%dd%d) Failed - "
3281 "Unexpected Status %04X\n",
3282 Controller, LogicalDriveNumber,
3283 Controller->ControllerNumber,
3284 LogicalDriveNumber, Command->CommandStatus);
3285 break;
3288 else if (strcmp(UserCommand, "cancel-rebuild") == 0 ||
3289 strcmp(UserCommand, "cancel-consistency-check") == 0)
3291 unsigned char OldRebuildRateConstant;
3292 CommandMailbox->Type3R.CommandOpcode = DAC960_RebuildControl;
3293 CommandMailbox->Type3R.RebuildRateConstant = 0xFF;
3294 CommandMailbox->Type3R.BusAddress =
3295 Virtual_to_Bus(&OldRebuildRateConstant);
3296 DAC960_ExecuteCommand(Command);
3297 switch (Command->CommandStatus)
3299 case DAC960_NormalCompletion:
3300 DAC960_UserCritical("Rebuild or Consistency Check Cancelled\n",
3301 Controller);
3302 break;
3303 default:
3304 DAC960_UserCritical("Cancellation of Rebuild or "
3305 "Consistency Check Failed - "
3306 "Unexpected Status %04X\n",
3307 Controller, Command->CommandStatus);
3308 break;
3311 else DAC960_UserCritical("Illegal User Command: '%s'\n",
3312 Controller, UserCommand);
3313 DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
3314 DAC960_DeallocateCommand(Command);
3315 DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
3316 return true;
3321 DAC960_ProcReadStatus implements reading /proc/rd/status.
3324 static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
3325 int Count, int *EOF, void *Data)
3327 char *StatusMessage = "OK\n";
3328 int ControllerNumber, BytesAvailable;
3329 for (ControllerNumber = 0;
3330 ControllerNumber < DAC960_ControllerCount;
3331 ControllerNumber++)
3333 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
3334 DAC960_Enquiry_T *Enquiry;
3335 if (Controller == NULL) continue;
3336 Enquiry = &Controller->Enquiry[Controller->EnquiryIndex];
3337 if (Enquiry->CriticalLogicalDriveCount > 0 ||
3338 Enquiry->OfflineLogicalDriveCount > 0 ||
3339 Enquiry->DeadDriveCount > 0)
3341 StatusMessage = "ALERT\n";
3342 break;
3345 BytesAvailable = strlen(StatusMessage) - Offset;
3346 if (Count >= BytesAvailable)
3348 Count = BytesAvailable;
3349 *EOF = true;
3351 if (Count <= 0) return 0;
3352 *Start = Page;
3353 memcpy(Page, &StatusMessage[Offset], Count);
3354 return Count;
3359 DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status.
3362 static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset,
3363 int Count, int *EOF, void *Data)
3365 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
3366 int BytesAvailable = Controller->InitialStatusLength - Offset;
3367 if (Count >= BytesAvailable)
3369 Count = BytesAvailable;
3370 *EOF = true;
3372 if (Count <= 0) return 0;
3373 *Start = Page;
3374 memcpy(Page, &Controller->InitialStatusBuffer[Offset], Count);
3375 return Count;
3380 DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status.
3383 static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
3384 int Count, int *EOF, void *Data)
3386 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
3387 int BytesAvailable;
3388 if (jiffies != Controller->LastCurrentStatusTime)
3390 Controller->CurrentStatusLength = 0;
3391 DAC960_AnnounceDriver(Controller);
3392 DAC960_ReportControllerConfiguration(Controller);
3393 DAC960_ReportDeviceConfiguration(Controller);
3394 Controller->CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
3395 Controller->CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
3396 if (Controller->RebuildProgressLength > 0)
3398 strcpy(&Controller->CurrentStatusBuffer
3399 [Controller->CurrentStatusLength],
3400 Controller->RebuildProgressBuffer);
3401 Controller->CurrentStatusLength += Controller->RebuildProgressLength;
3403 else
3405 char *StatusMessage = "No Rebuild or Consistency Check in Progress\n";
3406 strcpy(&Controller->CurrentStatusBuffer
3407 [Controller->CurrentStatusLength],
3408 StatusMessage);
3409 Controller->CurrentStatusLength += strlen(StatusMessage);
3411 Controller->LastCurrentStatusTime = jiffies;
3413 BytesAvailable = Controller->CurrentStatusLength - Offset;
3414 if (Count >= BytesAvailable)
3416 Count = BytesAvailable;
3417 *EOF = true;
3419 if (Count <= 0) return 0;
3420 *Start = Page;
3421 memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count);
3422 return Count;
3427 DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command.
3430 static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset,
3431 int Count, int *EOF, void *Data)
3433 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
3434 int BytesAvailable = Controller->UserStatusLength - Offset;
3435 if (Count >= BytesAvailable)
3437 Count = BytesAvailable;
3438 *EOF = true;
3440 if (Count <= 0) return 0;
3441 *Start = Page;
3442 memcpy(Page, &Controller->UserStatusBuffer[Offset], Count);
3443 return Count;
3448 DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
3451 static int DAC960_ProcWriteUserCommand(File_T *File, const char *Buffer,
3452 unsigned long Count, void *Data)
3454 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
3455 char CommandBuffer[80];
3456 int Length;
3457 if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
3458 copy_from_user(CommandBuffer, Buffer, Count);
3459 CommandBuffer[Count] = '\0';
3460 Length = strlen(CommandBuffer);
3461 if (CommandBuffer[Length-1] == '\n')
3462 CommandBuffer[--Length] = '\0';
3463 return (DAC960_ExecuteUserCommand(Controller, CommandBuffer)
3464 ? Count : -EBUSY);
3469 DAC960_CreateProcEntries creates the /proc/rd/... entries for the DAC960
3470 Driver.
3473 static void DAC960_CreateProcEntries(void)
3475 static PROC_DirectoryEntry_T StatusProcEntry;
3476 int ControllerNumber;
3477 DAC960_ProcDirectoryEntry.name = "rd";
3478 DAC960_ProcDirectoryEntry.namelen = strlen(DAC960_ProcDirectoryEntry.name);
3479 DAC960_ProcDirectoryEntry.mode = S_IFDIR | S_IRUGO | S_IXUGO;
3480 proc_register(&proc_root, &DAC960_ProcDirectoryEntry);
3481 StatusProcEntry.name = "status";
3482 StatusProcEntry.namelen = strlen(StatusProcEntry.name);
3483 StatusProcEntry.mode = S_IFREG | S_IRUGO;
3484 StatusProcEntry.read_proc = DAC960_ProcReadStatus;
3485 proc_register(&DAC960_ProcDirectoryEntry, &StatusProcEntry);
3486 for (ControllerNumber = 0;
3487 ControllerNumber < DAC960_ControllerCount;
3488 ControllerNumber++)
3490 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
3491 PROC_DirectoryEntry_T *ControllerProcEntry, *InitialStatusProcEntry;
3492 PROC_DirectoryEntry_T *CurrentStatusProcEntry, *UserCommandProcEntry;
3493 if (Controller == NULL) continue;
3494 ControllerProcEntry = &Controller->ControllerProcEntry;
3495 ControllerProcEntry->name = Controller->ControllerName;
3496 ControllerProcEntry->namelen = strlen(ControllerProcEntry->name);
3497 ControllerProcEntry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
3498 proc_register(&DAC960_ProcDirectoryEntry, ControllerProcEntry);
3499 InitialStatusProcEntry = &Controller->InitialStatusProcEntry;
3500 InitialStatusProcEntry->name = "initial_status";
3501 InitialStatusProcEntry->namelen = strlen(InitialStatusProcEntry->name);
3502 InitialStatusProcEntry->mode = S_IFREG | S_IRUGO;
3503 InitialStatusProcEntry->data = Controller;
3504 InitialStatusProcEntry->read_proc = DAC960_ProcReadInitialStatus;
3505 proc_register(ControllerProcEntry, InitialStatusProcEntry);
3506 CurrentStatusProcEntry = &Controller->CurrentStatusProcEntry;
3507 CurrentStatusProcEntry->name = "current_status";
3508 CurrentStatusProcEntry->namelen = strlen(CurrentStatusProcEntry->name);
3509 CurrentStatusProcEntry->mode = S_IFREG | S_IRUGO;
3510 CurrentStatusProcEntry->data = Controller;
3511 CurrentStatusProcEntry->read_proc = DAC960_ProcReadCurrentStatus;
3512 proc_register(ControllerProcEntry, CurrentStatusProcEntry);
3513 UserCommandProcEntry = &Controller->UserCommandProcEntry;
3514 UserCommandProcEntry->name = "user_command";
3515 UserCommandProcEntry->namelen = strlen(UserCommandProcEntry->name);
3516 UserCommandProcEntry->mode = S_IFREG | S_IWUSR | S_IRUSR;
3517 UserCommandProcEntry->data = Controller;
3518 UserCommandProcEntry->read_proc = DAC960_ProcReadUserCommand;
3519 UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
3520 proc_register(ControllerProcEntry, UserCommandProcEntry);
3526 DAC960_DestroyProcEntries destroys the /proc/rd/... entries for the DAC960
3527 Driver.
3530 static void DAC960_DestroyProcEntries(void)
3532 proc_unregister(&proc_root, DAC960_ProcDirectoryEntry.low_ino);
3537 Include Module support if requested.
3540 #ifdef MODULE
3543 int init_module(void)
3545 int ControllerNumber, LogicalDriveNumber;
3546 DAC960_Initialize();
3547 if (DAC960_ActiveControllerCount == 0) return -1;
3548 for (ControllerNumber = 0;
3549 ControllerNumber < DAC960_ControllerCount;
3550 ControllerNumber++)
3552 DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
3553 if (Controller == NULL) continue;
3554 DAC960_InitializeGenericDiskInfo(&Controller->GenericDiskInfo);
3555 for (LogicalDriveNumber = 0;
3556 LogicalDriveNumber < Controller->LogicalDriveCount;
3557 LogicalDriveNumber++)
3558 resetup_one_dev(&Controller->GenericDiskInfo, LogicalDriveNumber);
3560 return 0;
3564 void cleanup_module(void)
3566 DAC960_Finalize(&DAC960_NotifierBlock, SYS_RESTART, NULL);
3570 #endif