patch-2.3.99-pre9 linux/drivers/block/DAC960.c
Next file: linux/drivers/block/DAC960.h
Previous file: linux/drivers/block/Config.in
Back to the patch index
Back to the overall index
- Lines: 421
- Date:
Sat May 13 07:35:38 2000
- Orig file:
v2.3.99-pre8/linux/drivers/block/DAC960.c
- Orig date:
Thu May 11 15:30:06 2000
diff -u --recursive --new-file v2.3.99-pre8/linux/drivers/block/DAC960.c linux/drivers/block/DAC960.c
@@ -19,8 +19,9 @@
*/
-#define DAC960_DriverVersion "2.3.4"
-#define DAC960_DriverDate "23 September 1999"
+#define DAC960_DriverVersion "2.3.5"
+#define DAC960_DriverDate "23 January 2000"
+
#include <linux/version.h>
@@ -110,7 +111,7 @@
DAC960_Announce("***** DAC960 RAID Driver Version "
DAC960_DriverVersion " of "
DAC960_DriverDate " *****\n", Controller);
- DAC960_Announce("Copyright 1998-1999 by Leonard N. Zubkoff "
+ DAC960_Announce("Copyright 1998-2000 by Leonard N. Zubkoff "
"<lnz@dandelion.com>\n", Controller);
}
@@ -184,6 +185,23 @@
/*
+ DAC960_WaitForCommand waits for a wake_up on Controller's Command Wait Queue.
+*/
+
+static void DAC960_WaitForCommand(DAC960_Controller_T *Controller)
+{
+ DECLARE_WAITQUEUE(WaitQueueEntry, current);
+ add_wait_queue(&Controller->CommandWaitQueue, &WaitQueueEntry);
+ current->state = TASK_UNINTERRUPTIBLE;
+ spin_unlock(&io_request_lock);
+ schedule();
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&Controller->CommandWaitQueue, &WaitQueueEntry);
+ spin_lock_irq(&io_request_lock);
+}
+
+
+/*
DAC960_QueueCommand queues Command.
*/
@@ -307,6 +325,62 @@
/*
+ DAC960_ReportErrorStatus reports Controller BIOS Messages passed through
+ the Error Status Register when the driver performs the BIOS handshaking.
+ It returns true for fatal errors and false otherwise.
+*/
+
+static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
+ unsigned char ErrorStatus,
+ unsigned char Parameter0,
+ unsigned char Parameter1)
+{
+ switch (ErrorStatus)
+ {
+ case 0x00:
+ DAC960_Notice("Physical Drive %d:%d Not Responding\n",
+ Controller, Parameter1, Parameter0);
+ break;
+ case 0x08:
+ if (Controller->DriveSpinUpMessageDisplayed) break;
+ DAC960_Notice("Spinning Up Drives\n", Controller);
+ Controller->DriveSpinUpMessageDisplayed = true;
+ break;
+ case 0x30:
+ DAC960_Notice("Configuration Checksum Error\n", Controller);
+ break;
+ case 0x60:
+ DAC960_Notice("Mirror Race Recovery Failed\n", Controller);
+ break;
+ case 0x70:
+ DAC960_Notice("Mirror Race Recovery In Progress\n", Controller);
+ break;
+ case 0x90:
+ DAC960_Notice("Physical Drive %d:%d COD Mismatch\n",
+ Controller, Parameter1, Parameter0);
+ break;
+ case 0xA0:
+ DAC960_Notice("Logical Drive Installation Aborted\n", Controller);
+ break;
+ case 0xB0:
+ DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller);
+ break;
+ case 0xD0:
+ DAC960_Notice("New Controller Configuration Found\n", Controller);
+ break;
+ case 0xF0:
+ DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller);
+ return true;
+ default:
+ DAC960_Error("Unknown Initialization Error %02X for Controller at\n",
+ Controller, ErrorStatus);
+ return true;
+ }
+ return false;
+}
+
+
+/*
DAC960_EnableMemoryMailboxInterface enables the Memory Mailbox Interface.
*/
@@ -372,7 +446,7 @@
case DAC960_V5_Controller:
while (--TimeoutCounter >= 0)
{
- if (DAC960_V5_HardwareMailboxEmptyP(ControllerBaseAddress))
+ if (!DAC960_V5_HardwareMailboxFullP(ControllerBaseAddress))
break;
udelay(10);
}
@@ -469,6 +543,9 @@
unsigned long BaseAddress1 = pci_resource_start (PCI_Device, 1);
unsigned short SubsystemVendorID, SubsystemDeviceID;
int CommandIdentifier;
+ unsigned char ErrorStatus, Parameter0, Parameter1;
+ void *BaseAddress;
+
if (pci_enable_device(PCI_Device))
goto Ignore;
@@ -517,24 +594,6 @@
Controller->Function = Function;
sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
/*
- Acquire shared access to the IRQ Channel.
- */
- if (IRQ_Channel == 0)
- {
- DAC960_Error("IRQ Channel %d illegal for Controller at\n",
- Controller, IRQ_Channel);
- goto Failure;
- }
- strcpy(Controller->FullModelName, "DAC960");
- if (request_irq(IRQ_Channel, DAC960_InterruptHandler,
- SA_SHIRQ, Controller->FullModelName, Controller) < 0)
- {
- DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
- Controller, IRQ_Channel);
- goto Failure;
- }
- Controller->IRQ_Channel = IRQ_Channel;
- /*
Map the Controller Register Window.
*/
if (MemoryWindowSize < PAGE_SIZE)
@@ -549,34 +608,87 @@
"Controller at\n", Controller);
goto Failure;
}
+ BaseAddress = Controller->BaseAddress;
switch (ControllerType)
{
case DAC960_V5_Controller:
- DAC960_V5_DisableInterrupts(Controller->BaseAddress);
+ DAC960_V5_DisableInterrupts(BaseAddress);
+ DAC960_V5_AcknowledgeHardwareMailboxStatus(BaseAddress);
+ udelay(1000);
+ while (DAC960_V5_InitializationInProgressP(BaseAddress))
+ {
+ if (DAC960_V5_ReadErrorStatus(BaseAddress, &ErrorStatus,
+ &Parameter0, &Parameter1) &&
+ DAC960_ReportErrorStatus(Controller, ErrorStatus,
+ Parameter0, Parameter1))
+ goto Failure;
+ udelay(10);
+ }
if (!DAC960_EnableMemoryMailboxInterface(Controller))
{
DAC960_Error("Unable to Enable Memory Mailbox Interface "
"for Controller at\n", Controller);
goto Failure;
}
- DAC960_V5_EnableInterrupts(Controller->BaseAddress);
+ DAC960_V5_EnableInterrupts(BaseAddress);
break;
case DAC960_V4_Controller:
- DAC960_V4_DisableInterrupts(Controller->BaseAddress);
+ DAC960_V4_DisableInterrupts(BaseAddress);
+ DAC960_V4_AcknowledgeHardwareMailboxStatus(BaseAddress);
+ udelay(1000);
+ while (DAC960_V4_InitializationInProgressP(BaseAddress))
+ {
+ if (DAC960_V4_ReadErrorStatus(BaseAddress, &ErrorStatus,
+ &Parameter0, &Parameter1) &&
+ DAC960_ReportErrorStatus(Controller, ErrorStatus,
+ Parameter0, Parameter1))
+ goto Failure;
+ udelay(10);
+ }
if (!DAC960_EnableMemoryMailboxInterface(Controller))
{
DAC960_Error("Unable to Enable Memory Mailbox Interface "
"for Controller at\n", Controller);
goto Failure;
}
- DAC960_V4_EnableInterrupts(Controller->BaseAddress);
+ DAC960_V4_EnableInterrupts(BaseAddress);
break;
case DAC960_V3_Controller:
request_region(Controller->IO_Address, 0x80,
Controller->FullModelName);
- DAC960_V3_EnableInterrupts(Controller->BaseAddress);
+ DAC960_V3_DisableInterrupts(BaseAddress);
+ DAC960_V3_AcknowledgeStatus(BaseAddress);
+ udelay(1000);
+ while (DAC960_V3_InitializationInProgressP(BaseAddress))
+ {
+ if (DAC960_V3_ReadErrorStatus(BaseAddress, &ErrorStatus,
+ &Parameter0, &Parameter1) &&
+ DAC960_ReportErrorStatus(Controller, ErrorStatus,
+ Parameter0, Parameter1))
+ goto Failure;
+ udelay(10);
+ }
+ DAC960_V3_EnableInterrupts(BaseAddress);
break;
}
+ /*
+ Acquire shared access to the IRQ Channel.
+ */
+ if (IRQ_Channel == 0)
+ {
+ DAC960_Error("IRQ Channel %d illegal for Controller at\n",
+ Controller, IRQ_Channel);
+ goto Failure;
+ }
+ strcpy(Controller->FullModelName, "DAC960");
+ if (request_irq(IRQ_Channel, DAC960_InterruptHandler,
+ SA_SHIRQ, Controller->FullModelName, Controller) < 0)
+ {
+ DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
+ Controller, IRQ_Channel);
+ goto Failure;
+ }
+ Controller->IRQ_Channel = IRQ_Channel;
DAC960_ActiveControllerCount++;
for (CommandIdentifier = 0;
CommandIdentifier < DAC960_MaxChannels;
@@ -597,11 +709,11 @@
"0x%X PCI Address 0x%X\n", Controller,
Bus, Device, Function, IO_Address, PCI_Address);
if (Controller == NULL) break;
- if (Controller->IRQ_Channel > 0)
- free_irq(IRQ_Channel, Controller);
if (Controller->MemoryMappedAddress != NULL)
iounmap(Controller->MemoryMappedAddress);
DAC960_Controllers[Controller->ControllerNumber] = NULL;
+ if (Controller->IRQ_Channel > 0)
+ free_irq(IRQ_Channel, Controller);
Ignore:
kfree(Controller);
}
@@ -1346,9 +1458,7 @@
Command = DAC960_AllocateCommand(Controller);
if (Command != NULL) break;
if (!WaitForCommand) return false;
- spin_unlock(&io_request_lock);
- sleep_on(&Controller->CommandWaitQueue);
- spin_lock_irq(&io_request_lock);
+ DAC960_WaitForCommand(Controller);
}
DAC960_ClearCommand(Command);
if (Request->cmd == READ)
@@ -1900,6 +2010,20 @@
}
else if (NewEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
Controller->NeedConsistencyCheckProgress = true;
+ if (CommandType != DAC960_MonitoringCommand &&
+ Controller->RebuildFlagPending)
+ {
+ DAC960_Enquiry_T *Enquiry = (DAC960_Enquiry_T *)
+ Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress);
+ Enquiry->RebuildFlag = Controller->PendingRebuildFlag;
+ Controller->RebuildFlagPending = false;
+ }
+ else if (CommandType == DAC960_MonitoringCommand &&
+ NewEnquiry->RebuildFlag > DAC960_BackgroundCheckInProgress)
+ {
+ Controller->PendingRebuildFlag = NewEnquiry->RebuildFlag;
+ Controller->RebuildFlagPending = true;
+ }
}
else if (CommandOpcode == DAC960_PerformEventLogOperation)
{
@@ -2083,6 +2207,9 @@
Controller->RebuildProgress.LogicalDriveSize;
unsigned int BlocksCompleted =
LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
+ if (CommandStatus == DAC960_NoRebuildOrCheckInProgress &&
+ Controller->LastRebuildStatus == DAC960_NormalCompletion)
+ CommandStatus = DAC960_RebuildSuccessful;
switch (CommandStatus)
{
case DAC960_NormalCompletion:
@@ -2110,13 +2237,28 @@
"Failure of Drive Being Rebuilt\n", Controller);
break;
case DAC960_NoRebuildOrCheckInProgress:
- if (Controller->LastRebuildStatus != DAC960_NormalCompletion)
- break;
+ break;
case DAC960_RebuildSuccessful:
DAC960_Progress("Rebuild Completed Successfully\n", Controller);
break;
+ case DAC960_RebuildSuccessfullyTerminated:
+ DAC960_Progress("Rebuild Successfully Terminated\n", Controller);
+ break;
}
Controller->LastRebuildStatus = CommandStatus;
+ if (CommandType != DAC960_MonitoringCommand &&
+ Controller->RebuildStatusPending)
+ {
+ Command->CommandStatus = Controller->PendingRebuildStatus;
+ Controller->RebuildStatusPending = false;
+ }
+ else if (CommandType == DAC960_MonitoringCommand &&
+ CommandStatus != DAC960_NormalCompletion &&
+ CommandStatus != DAC960_NoRebuildOrCheckInProgress)
+ {
+ Controller->PendingRebuildStatus = CommandStatus;
+ Controller->RebuildStatusPending = true;
+ }
}
else if (CommandOpcode == DAC960_RebuildStat)
{
@@ -2331,7 +2473,7 @@
if (CommandType == DAC960_QueuedCommand)
{
DAC960_KernelCommand_T *KernelCommand = Command->KernelCommand;
- KernelCommand->CommandStatus = CommandStatus;
+ KernelCommand->CommandStatus = Command->CommandStatus;
Command->KernelCommand = NULL;
if (CommandOpcode == DAC960_DCDB)
Controller->DirectCommandActive[KernelCommand->DCDB->Channel]
@@ -2352,9 +2494,12 @@
return;
}
/*
- Deallocate the Command, and wake up any processes waiting on a free Command.
+ Deallocate the Command.
*/
DAC960_DeallocateCommand(Command);
+ /*
+ Wake up any processes waiting on a free Command.
+ */
wake_up(&Controller->CommandWaitQueue);
}
@@ -2761,19 +2906,14 @@
}
if (CommandOpcode == DAC960_DCDB)
{
- while (true)
- {
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- if (!Controller->DirectCommandActive[DCDB.Channel]
- [DCDB.TargetID])
- Command = DAC960_AllocateCommand(Controller);
- if (Command != NULL)
- Controller->DirectCommandActive[DCDB.Channel]
- [DCDB.TargetID] = true;
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- if (Command != NULL) break;
- sleep_on(&Controller->CommandWaitQueue);
- }
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ while (Controller->DirectCommandActive[DCDB.Channel]
+ [DCDB.TargetID] ||
+ (Command = DAC960_AllocateCommand(Controller)) == NULL)
+ DAC960_WaitForCommand(Controller);
+ Controller->DirectCommandActive[DCDB.Channel]
+ [DCDB.TargetID] = true;
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
DAC960_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
memcpy(&Command->CommandMailbox, &UserCommand.CommandMailbox,
@@ -2783,14 +2923,10 @@
}
else
{
- while (true)
- {
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- Command = DAC960_AllocateCommand(Controller);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- if (Command != NULL) break;
- sleep_on(&Controller->CommandWaitQueue);
- }
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
+ DAC960_WaitForCommand(Controller);
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
DAC960_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
memcpy(&Command->CommandMailbox, &UserCommand.CommandMailbox,
@@ -3194,14 +3330,10 @@
DAC960_CommandMailbox_T *CommandMailbox;
ProcessorFlags_T ProcessorFlags;
unsigned char Channel, TargetID, LogicalDriveNumber;
- while (true)
- {
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- Command = DAC960_AllocateCommand(Controller);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- if (Command != NULL) break;
- sleep_on(&Controller->CommandWaitQueue);
- }
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
+ DAC960_WaitForCommand(Controller);
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
Controller->UserStatusLength = 0;
DAC960_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)