DAC960.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:257k
- else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
- {
- int LogicalDriveNumber;
- for (LogicalDriveNumber = 0;
- LogicalDriveNumber < DAC960_MaxLogicalDrives;
- LogicalDriveNumber++)
- {
- DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
- Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
- if (LogicalDeviceInfo == NULL ||
- Controller->V2.LogicalDriveFoundDuringScan
- [LogicalDriveNumber])
- continue;
- DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
- "No Longer Existsn", Controller,
- LogicalDriveNumber,
- Controller->ControllerNumber,
- LogicalDriveNumber);
- Controller->V2.LogicalDeviceInformation
- [LogicalDriveNumber] = NULL;
- kfree(LogicalDeviceInfo);
- Controller->LogicalDriveInitiallyAccessible
- [LogicalDriveNumber] = false;
- DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
- }
- Controller->V2.NeedLogicalDeviceInformation = false;
- }
- if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
- - Controller->V2.NextEventSequenceNumber > 0)
- {
- CommandMailbox->GetEvent.CommandOpcode = DAC960_V2_IOCTL;
- CommandMailbox->GetEvent.DataTransferSize = sizeof(DAC960_V2_Event_T);
- CommandMailbox->GetEvent.EventSequenceNumberHigh16 =
- Controller->V2.NextEventSequenceNumber >> 16;
- CommandMailbox->GetEvent.ControllerNumber = 0;
- CommandMailbox->GetEvent.IOCTL_Opcode =
- DAC960_V2_GetEvent;
- CommandMailbox->GetEvent.EventSequenceNumberLow16 =
- Controller->V2.NextEventSequenceNumber & 0xFFFF;
- CommandMailbox->GetEvent.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(&Controller->V2.Event);
- CommandMailbox->GetEvent.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->GetEvent.DataTransferSize;
- DAC960_QueueCommand(Command);
- return;
- }
- if (Controller->V2.NeedPhysicalDeviceInformation)
- {
- if (Controller->V2.NeedDeviceSerialNumberInformation)
- {
- DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
- Controller->V2.InquiryUnitSerialNumber
- [Controller->V2.PhysicalDeviceIndex - 1];
- InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
- CommandMailbox->SCSI_10.CommandOpcode =
- DAC960_V2_SCSI_10_Passthru;
- CommandMailbox->SCSI_10.DataTransferSize =
- sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
- CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit =
- Controller->V2.NewPhysicalDeviceInformation.LogicalUnit - 1;
- CommandMailbox->SCSI_10.PhysicalDevice.TargetID =
- Controller->V2.NewPhysicalDeviceInformation.TargetID;
- CommandMailbox->SCSI_10.PhysicalDevice.Channel =
- Controller->V2.NewPhysicalDeviceInformation.Channel;
- CommandMailbox->SCSI_10.CDBLength = 6;
- CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
- CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
- CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
- CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
- CommandMailbox->SCSI_10.SCSI_CDB[4] =
- sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
- CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(InquiryUnitSerialNumber);
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->SCSI_10.DataTransferSize;
- DAC960_QueueCommand(Command);
- Controller->V2.NeedDeviceSerialNumberInformation = false;
- return;
- }
- if (Controller->V2.StartPhysicalDeviceInformationScan)
- {
- Controller->V2.PhysicalDeviceIndex = 0;
- Controller->V2.NewPhysicalDeviceInformation.Channel = 0;
- Controller->V2.NewPhysicalDeviceInformation.TargetID = 0;
- Controller->V2.NewPhysicalDeviceInformation.LogicalUnit = 0;
- Controller->V2.StartPhysicalDeviceInformationScan = false;
- }
- CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
- CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
- sizeof(DAC960_V2_PhysicalDeviceInfo_T);
- CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit =
- Controller->V2.NewPhysicalDeviceInformation.LogicalUnit;
- CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID =
- Controller->V2.NewPhysicalDeviceInformation.TargetID;
- CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel =
- Controller->V2.NewPhysicalDeviceInformation.Channel;
- CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
- DAC960_V2_GetPhysicalDeviceInfoValid;
- CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(&Controller->V2.NewPhysicalDeviceInformation);
- CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
- DAC960_QueueCommand(Command);
- return;
- }
- if (Controller->V2.NeedLogicalDeviceInformation)
- {
- if (Controller->V2.StartLogicalDeviceInformationScan)
- {
- int LogicalDriveNumber;
- for (LogicalDriveNumber = 0;
- LogicalDriveNumber < DAC960_MaxLogicalDrives;
- LogicalDriveNumber++)
- Controller->V2.LogicalDriveFoundDuringScan
- [LogicalDriveNumber] = false;
- Controller->V2.NewLogicalDeviceInformation
- .LogicalDeviceNumber = 0;
- Controller->V2.StartLogicalDeviceInformationScan = false;
- }
- CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
- CommandMailbox->LogicalDeviceInfo.DataTransferSize =
- sizeof(DAC960_V2_LogicalDeviceInfo_T);
- CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
- Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber;
- CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
- DAC960_V2_GetLogicalDeviceInfoValid;
- CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(&Controller->V2.NewLogicalDeviceInformation);
- CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->LogicalDeviceInfo.DataTransferSize;
- DAC960_QueueCommand(Command);
- return;
- }
- Controller->MonitoringTimerCount++;
- Controller->MonitoringTimer.expires =
- jiffies + DAC960_HealthStatusMonitoringInterval;
- add_timer(&Controller->MonitoringTimer);
- }
- if (CommandType == DAC960_ImmediateCommand)
- {
- complete(Command->Completion);
- Command->Completion = NULL;
- return;
- }
- if (CommandType == DAC960_QueuedCommand)
- {
- DAC960_V2_KernelCommand_T *KernelCommand = Command->V2.KernelCommand;
- KernelCommand->CommandStatus = CommandStatus;
- KernelCommand->RequestSenseLength = Command->V2.RequestSenseLength;
- KernelCommand->DataTransferLength = Command->V2.DataTransferResidue;
- Command->V2.KernelCommand = NULL;
- DAC960_DeallocateCommand(Command);
- KernelCommand->CompletionFunction(KernelCommand);
- return;
- }
- /*
- Queue a Status Monitoring Command to the Controller using the just
- completed Command if one was deferred previously due to lack of a
- free Command when the Monitoring Timer Function was called.
- */
- if (Controller->MonitoringCommandDeferred)
- {
- Controller->MonitoringCommandDeferred = false;
- DAC960_V2_QueueMonitoringCommand(Command);
- return;
- }
- /*
- Deallocate the Command.
- */
- DAC960_DeallocateCommand(Command);
- /*
- Wake up any processes waiting on a free Command.
- */
- wake_up(&Controller->CommandWaitQueue);
- }
- /*
- DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
- Controllers.
- */
- static void DAC960_BA_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- Registers_T *InterruptRegisters)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
- void *ControllerBaseAddress = Controller->BaseAddress;
- DAC960_V2_StatusMailbox_T *NextStatusMailbox;
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
- /*
- Process Hardware Interrupts for Controller.
- */
- DAC960_BA_AcknowledgeInterrupt(ControllerBaseAddress);
- NextStatusMailbox = Controller->V2.NextStatusMailbox;
- while (NextStatusMailbox->Fields.CommandIdentifier > 0)
- {
- DAC960_V2_CommandIdentifier_T CommandIdentifier =
- NextStatusMailbox->Fields.CommandIdentifier;
- DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
- Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
- Command->V2.RequestSenseLength =
- NextStatusMailbox->Fields.RequestSenseLength;
- Command->V2.DataTransferResidue =
- NextStatusMailbox->Fields.DataTransferResidue;
- NextStatusMailbox->Words[0] = 0;
- if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
- NextStatusMailbox = Controller->V2.FirstStatusMailbox;
- DAC960_V2_ProcessCompletedCommand(Command);
- }
- Controller->V2.NextStatusMailbox = NextStatusMailbox;
- /*
- Attempt to remove additional I/O Requests from the Controller's
- I/O Request Queue and queue them to the Controller.
- */
- while (DAC960_ProcessRequest(Controller, false)) ;
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
- }
- /*
- DAC960_LP_InterruptHandler handles hardware interrupts from DAC960 LP Series
- Controllers.
- */
- static void DAC960_LP_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- Registers_T *InterruptRegisters)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
- void *ControllerBaseAddress = Controller->BaseAddress;
- DAC960_V2_StatusMailbox_T *NextStatusMailbox;
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
- /*
- Process Hardware Interrupts for Controller.
- */
- DAC960_LP_AcknowledgeInterrupt(ControllerBaseAddress);
- NextStatusMailbox = Controller->V2.NextStatusMailbox;
- while (NextStatusMailbox->Fields.CommandIdentifier > 0)
- {
- DAC960_V2_CommandIdentifier_T CommandIdentifier =
- NextStatusMailbox->Fields.CommandIdentifier;
- DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
- Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
- Command->V2.RequestSenseLength =
- NextStatusMailbox->Fields.RequestSenseLength;
- Command->V2.DataTransferResidue =
- NextStatusMailbox->Fields.DataTransferResidue;
- NextStatusMailbox->Words[0] = 0;
- if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
- NextStatusMailbox = Controller->V2.FirstStatusMailbox;
- DAC960_V2_ProcessCompletedCommand(Command);
- }
- Controller->V2.NextStatusMailbox = NextStatusMailbox;
- /*
- Attempt to remove additional I/O Requests from the Controller's
- I/O Request Queue and queue them to the Controller.
- */
- while (DAC960_ProcessRequest(Controller, false)) ;
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
- }
- /*
- DAC960_LA_InterruptHandler handles hardware interrupts from DAC960 LA Series
- Controllers.
- */
- static void DAC960_LA_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- Registers_T *InterruptRegisters)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
- void *ControllerBaseAddress = Controller->BaseAddress;
- DAC960_V1_StatusMailbox_T *NextStatusMailbox;
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
- /*
- Process Hardware Interrupts for Controller.
- */
- DAC960_LA_AcknowledgeInterrupt(ControllerBaseAddress);
- NextStatusMailbox = Controller->V1.NextStatusMailbox;
- while (NextStatusMailbox->Fields.Valid)
- {
- DAC960_V1_CommandIdentifier_T CommandIdentifier =
- NextStatusMailbox->Fields.CommandIdentifier;
- DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
- Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
- NextStatusMailbox->Word = 0;
- if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
- NextStatusMailbox = Controller->V1.FirstStatusMailbox;
- DAC960_V1_ProcessCompletedCommand(Command);
- }
- Controller->V1.NextStatusMailbox = NextStatusMailbox;
- /*
- Attempt to remove additional I/O Requests from the Controller's
- I/O Request Queue and queue them to the Controller.
- */
- while (DAC960_ProcessRequest(Controller, false)) ;
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
- }
- /*
- DAC960_PG_InterruptHandler handles hardware interrupts from DAC960 PG Series
- Controllers.
- */
- static void DAC960_PG_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- Registers_T *InterruptRegisters)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
- void *ControllerBaseAddress = Controller->BaseAddress;
- DAC960_V1_StatusMailbox_T *NextStatusMailbox;
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
- /*
- Process Hardware Interrupts for Controller.
- */
- DAC960_PG_AcknowledgeInterrupt(ControllerBaseAddress);
- NextStatusMailbox = Controller->V1.NextStatusMailbox;
- while (NextStatusMailbox->Fields.Valid)
- {
- DAC960_V1_CommandIdentifier_T CommandIdentifier =
- NextStatusMailbox->Fields.CommandIdentifier;
- DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
- Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
- NextStatusMailbox->Word = 0;
- if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
- NextStatusMailbox = Controller->V1.FirstStatusMailbox;
- DAC960_V1_ProcessCompletedCommand(Command);
- }
- Controller->V1.NextStatusMailbox = NextStatusMailbox;
- /*
- Attempt to remove additional I/O Requests from the Controller's
- I/O Request Queue and queue them to the Controller.
- */
- while (DAC960_ProcessRequest(Controller, false)) ;
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
- }
- /*
- DAC960_PD_InterruptHandler handles hardware interrupts from DAC960 PD Series
- Controllers.
- */
- static void DAC960_PD_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- Registers_T *InterruptRegisters)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
- void *ControllerBaseAddress = Controller->BaseAddress;
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
- /*
- Process Hardware Interrupts for Controller.
- */
- while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
- {
- DAC960_V1_CommandIdentifier_T CommandIdentifier =
- DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
- DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
- Command->V1.CommandStatus =
- DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
- DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
- DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
- DAC960_V1_ProcessCompletedCommand(Command);
- }
- /*
- Attempt to remove additional I/O Requests from the Controller's
- I/O Request Queue and queue them to the Controller.
- */
- while (DAC960_ProcessRequest(Controller, false)) ;
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
- }
- /*
- DAC960_P_InterruptHandler handles hardware interrupts from DAC960 P Series
- Controllers.
- */
- static void DAC960_P_InterruptHandler(int IRQ_Channel,
- void *DeviceIdentifier,
- Registers_T *InterruptRegisters)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
- void *ControllerBaseAddress = Controller->BaseAddress;
- ProcessorFlags_T ProcessorFlags;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
- /*
- Process Hardware Interrupts for Controller.
- */
- while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
- {
- DAC960_V1_CommandIdentifier_T CommandIdentifier =
- DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
- DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
- DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
- DAC960_V1_CommandOpcode_T CommandOpcode =
- CommandMailbox->Common.CommandOpcode;
- Command->V1.CommandStatus =
- DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
- DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
- DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
- switch (CommandOpcode)
- {
- case DAC960_V1_Enquiry_Old:
- Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Enquiry;
- DAC960_P_To_PD_TranslateEnquiry(
- Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
- break;
- case DAC960_V1_GetDeviceState_Old:
- Command->V1.CommandMailbox.Common.CommandOpcode =
- DAC960_V1_GetDeviceState;
- DAC960_P_To_PD_TranslateDeviceState(
- Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
- break;
- case DAC960_V1_Read_Old:
- Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Read;
- DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
- break;
- case DAC960_V1_Write_Old:
- Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Write;
- DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
- break;
- case DAC960_V1_ReadWithScatterGather_Old:
- Command->V1.CommandMailbox.Common.CommandOpcode =
- DAC960_V1_ReadWithScatterGather;
- DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
- break;
- case DAC960_V1_WriteWithScatterGather_Old:
- Command->V1.CommandMailbox.Common.CommandOpcode =
- DAC960_V1_WriteWithScatterGather;
- DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
- break;
- default:
- break;
- }
- DAC960_V1_ProcessCompletedCommand(Command);
- }
- /*
- Attempt to remove additional I/O Requests from the Controller's
- I/O Request Queue and queue them to the Controller.
- */
- while (DAC960_ProcessRequest(Controller, false)) ;
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
- }
- /*
- DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1
- Firmware Controllers.
- */
- static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *Command)
- {
- DAC960_Controller_T *Controller = Command->Controller;
- DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_MonitoringCommand;
- CommandMailbox->Type3.CommandOpcode = DAC960_V1_Enquiry;
- CommandMailbox->Type3.BusAddress =
- Virtual_to_Bus32(&Controller->V1.NewEnquiry);
- DAC960_QueueCommand(Command);
- }
- /*
- DAC960_V2_QueueMonitoringCommand queues a Monitoring Command to DAC960 V2
- Firmware Controllers.
- */
- static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *Command)
- {
- DAC960_Controller_T *Controller = Command->Controller;
- DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
- DAC960_V2_ClearCommand(Command);
- Command->CommandType = DAC960_MonitoringCommand;
- CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
- CommandMailbox->ControllerInfo.CommandControlBits
- .DataTransferControllerToHost = true;
- CommandMailbox->ControllerInfo.CommandControlBits
- .NoAutoRequestSense = true;
- CommandMailbox->ControllerInfo.DataTransferSize =
- sizeof(DAC960_V2_ControllerInfo_T);
- CommandMailbox->ControllerInfo.ControllerNumber = 0;
- CommandMailbox->ControllerInfo.IOCTL_Opcode = DAC960_V2_GetControllerInfo;
- CommandMailbox->ControllerInfo.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(&Controller->V2.NewControllerInformation);
- CommandMailbox->ControllerInfo.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->ControllerInfo.DataTransferSize;
- DAC960_QueueCommand(Command);
- }
- /*
- DAC960_MonitoringTimerFunction is the timer function for monitoring
- the status of DAC960 Controllers.
- */
- static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) TimerData;
- DAC960_Command_T *Command;
- ProcessorFlags_T ProcessorFlags;
- if (Controller->FirmwareType == DAC960_V1_Controller)
- {
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- /*
- Queue a Status Monitoring Command to Controller.
- */
- Command = DAC960_AllocateCommand(Controller);
- if (Command != NULL)
- DAC960_V1_QueueMonitoringCommand(Command);
- else Controller->MonitoringCommandDeferred = true;
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- }
- else
- {
- DAC960_V2_ControllerInfo_T *ControllerInfo =
- &Controller->V2.ControllerInformation;
- unsigned int StatusChangeCounter =
- Controller->V2.HealthStatusBuffer->StatusChangeCounter;
- boolean ForceMonitoringCommand = false;
- if (jiffies - Controller->SecondaryMonitoringTime
- > DAC960_SecondaryMonitoringInterval)
- {
- int LogicalDriveNumber;
- for (LogicalDriveNumber = 0;
- LogicalDriveNumber < DAC960_MaxLogicalDrives;
- LogicalDriveNumber++)
- {
- DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
- Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
- if (LogicalDeviceInfo == NULL) continue;
- if (!LogicalDeviceInfo->LogicalDeviceControl
- .LogicalDeviceInitialized)
- {
- ForceMonitoringCommand = true;
- break;
- }
- }
- Controller->SecondaryMonitoringTime = jiffies;
- }
- if (StatusChangeCounter == Controller->V2.StatusChangeCounter &&
- Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
- == Controller->V2.NextEventSequenceNumber &&
- (ControllerInfo->BackgroundInitializationsActive +
- ControllerInfo->LogicalDeviceInitializationsActive +
- ControllerInfo->PhysicalDeviceInitializationsActive +
- ControllerInfo->ConsistencyChecksActive +
- ControllerInfo->RebuildsActive +
- ControllerInfo->OnlineExpansionsActive == 0 ||
- jiffies - Controller->PrimaryMonitoringTime
- < DAC960_MonitoringTimerInterval) &&
- !ForceMonitoringCommand)
- {
- Controller->MonitoringTimer.expires =
- jiffies + DAC960_HealthStatusMonitoringInterval;
- add_timer(&Controller->MonitoringTimer);
- return;
- }
- Controller->V2.StatusChangeCounter = StatusChangeCounter;
- Controller->PrimaryMonitoringTime = jiffies;
- /*
- Acquire exclusive access to Controller.
- */
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- /*
- Queue a Status Monitoring Command to Controller.
- */
- Command = DAC960_AllocateCommand(Controller);
- if (Command != NULL)
- DAC960_V2_QueueMonitoringCommand(Command);
- else Controller->MonitoringCommandDeferred = true;
- /*
- Release exclusive access to Controller.
- */
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- /*
- Wake up any processes waiting on a Health Status Buffer change.
- */
- wake_up(&Controller->HealthStatusWaitQueue);
- }
- }
- /*
- DAC960_Open is the Device Open Function for the DAC960 Driver.
- */
- static int DAC960_Open(Inode_T *Inode, File_T *File)
- {
- int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
- int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
- DAC960_Controller_T *Controller;
- if (ControllerNumber == 0 && LogicalDriveNumber == 0 &&
- (File->f_flags & O_NONBLOCK))
- goto ModuleOnly;
- if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- if (Controller->FirmwareType == DAC960_V1_Controller)
- {
- if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
- return -ENXIO;
- if (Controller->V1.LogicalDriveInformation
- [LogicalDriveNumber].LogicalDriveState
- == DAC960_V1_LogicalDrive_Offline)
- return -ENXIO;
- }
- else
- {
- DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
- Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
- if (LogicalDeviceInfo == NULL ||
- LogicalDeviceInfo->LogicalDeviceState
- == DAC960_V2_LogicalDevice_Offline)
- return -ENXIO;
- }
- if (!Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber])
- {
- Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
- DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
- DAC960_RegisterDisk(Controller, LogicalDriveNumber);
- }
- if (Controller->GenericDiskInfo.sizes[MINOR(Inode->i_rdev)] == 0)
- return -ENXIO;
- /*
- Increment Controller and Logical Drive Usage Counts.
- */
- Controller->ControllerUsageCount++;
- Controller->LogicalDriveUsageCount[LogicalDriveNumber]++;
- ModuleOnly:
- return 0;
- }
- /*
- DAC960_Release is the Device Release Function for the DAC960 Driver.
- */
- static int DAC960_Release(Inode_T *Inode, File_T *File)
- {
- int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
- int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
- DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
- if (ControllerNumber == 0 && LogicalDriveNumber == 0 &&
- File != NULL && (File->f_flags & O_NONBLOCK))
- goto ModuleOnly;
- /*
- Decrement the Logical Drive and Controller Usage Counts.
- */
- Controller->LogicalDriveUsageCount[LogicalDriveNumber]--;
- Controller->ControllerUsageCount--;
- ModuleOnly:
- return 0;
- }
- /*
- DAC960_IOCTL is the Device IOCTL Function for the DAC960 Driver.
- */
- static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
- unsigned int Request, unsigned long Argument)
- {
- int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
- int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
- DiskGeometry_T Geometry, *UserGeometry;
- DAC960_Controller_T *Controller;
- int PartitionNumber;
- if (File != NULL && (File->f_flags & O_NONBLOCK))
- return DAC960_UserIOCTL(Inode, File, Request, Argument);
- if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- switch (Request)
- {
- case HDIO_GETGEO:
- /* Get BIOS Disk Geometry. */
- UserGeometry = (DiskGeometry_T *) Argument;
- if (UserGeometry == NULL) return -EINVAL;
- if (Controller->FirmwareType == DAC960_V1_Controller)
- {
- if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
- return -ENXIO;
- Geometry.heads = Controller->V1.GeometryTranslationHeads;
- Geometry.sectors = Controller->V1.GeometryTranslationSectors;
- Geometry.cylinders =
- Controller->V1.LogicalDriveInformation[LogicalDriveNumber]
- .LogicalDriveSize
- / (Geometry.heads * Geometry.sectors);
- }
- else
- {
- DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
- Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
- if (LogicalDeviceInfo == NULL)
- return -EINVAL;
- switch (LogicalDeviceInfo->DriveGeometry)
- {
- case DAC960_V2_Geometry_128_32:
- Geometry.heads = 128;
- Geometry.sectors = 32;
- break;
- case DAC960_V2_Geometry_255_63:
- Geometry.heads = 255;
- Geometry.sectors = 63;
- break;
- default:
- DAC960_Error("Illegal Logical Device Geometry %dn",
- Controller, LogicalDeviceInfo->DriveGeometry);
- return -EINVAL;
- }
- Geometry.cylinders =
- LogicalDeviceInfo->ConfigurableDeviceSize
- / (Geometry.heads * Geometry.sectors);
- }
- Geometry.start =
- Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].start_sect;
- return (copy_to_user(UserGeometry, &Geometry,
- sizeof(DiskGeometry_T)) ? -EFAULT : 0);
- case BLKGETSIZE:
- /* Get Device Size. */
- if ((unsigned long *) Argument == NULL) return -EINVAL;
- return put_user(Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
- .nr_sects,
- (unsigned long *) Argument);
- case BLKGETSIZE64:
- if ((u64 *) Argument == NULL) return -EINVAL;
- return put_user((u64) Controller->GenericDiskInfo
- .part[MINOR(Inode->i_rdev)]
- .nr_sects << 9,
- (u64 *) Argument);
- case BLKRAGET:
- case BLKRASET:
- case BLKFLSBUF:
- case BLKBSZGET:
- case BLKBSZSET:
- return blk_ioctl(Inode->i_rdev, Request, Argument);
- case BLKRRPART:
- /* Re-Read Partition Table. */
- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
- if (Controller->LogicalDriveUsageCount[LogicalDriveNumber] > 1)
- return -EBUSY;
- for (PartitionNumber = 0;
- PartitionNumber < DAC960_MaxPartitions;
- PartitionNumber++)
- {
- KernelDevice_T Device = DAC960_KernelDevice(ControllerNumber,
- LogicalDriveNumber,
- PartitionNumber);
- int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber,
- PartitionNumber);
- if (Controller->GenericDiskInfo.part[MinorNumber].nr_sects == 0)
- continue;
- /*
- Flush all changes and invalidate buffered state.
- */
- invalidate_device(Device, 1);
- /*
- Clear existing partition sizes.
- */
- if (PartitionNumber > 0)
- {
- Controller->GenericDiskInfo.part[MinorNumber].start_sect = 0;
- Controller->GenericDiskInfo.part[MinorNumber].nr_sects = 0;
- }
- /*
- Reset the Block Size so that the partition table can be read.
- */
- set_blocksize(Device, BLOCK_SIZE);
- }
- DAC960_RegisterDisk(Controller, LogicalDriveNumber);
- return 0;
- }
- return -EINVAL;
- }
- /*
- DAC960_UserIOCTL is the User IOCTL Function for the DAC960 Driver.
- */
- static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
- unsigned int Request, unsigned long Argument)
- {
- int ErrorCode;
- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
- switch (Request)
- {
- case DAC960_IOCTL_GET_CONTROLLER_COUNT:
- return DAC960_ControllerCount;
- case DAC960_IOCTL_GET_CONTROLLER_INFO:
- {
- DAC960_ControllerInfo_T *UserSpaceControllerInfo =
- (DAC960_ControllerInfo_T *) Argument;
- DAC960_ControllerInfo_T ControllerInfo;
- DAC960_Controller_T *Controller;
- int ControllerNumber;
- if (UserSpaceControllerInfo == NULL) return -EINVAL;
- ErrorCode = get_user(ControllerNumber,
- &UserSpaceControllerInfo->ControllerNumber);
- if (ErrorCode != 0) return ErrorCode;
- if (ControllerNumber < 0 ||
- ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
- ControllerInfo.ControllerNumber = ControllerNumber;
- ControllerInfo.FirmwareType = Controller->FirmwareType;
- ControllerInfo.Channels = Controller->Channels;
- ControllerInfo.Targets = Controller->Targets;
- ControllerInfo.PCI_Bus = Controller->Bus;
- ControllerInfo.PCI_Device = Controller->Device;
- ControllerInfo.PCI_Function = Controller->Function;
- ControllerInfo.IRQ_Channel = Controller->IRQ_Channel;
- ControllerInfo.PCI_Address = Controller->PCI_Address;
- strcpy(ControllerInfo.ModelName, Controller->ModelName);
- strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
- return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
- sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0);
- }
- case DAC960_IOCTL_V1_EXECUTE_COMMAND:
- {
- DAC960_V1_UserCommand_T *UserSpaceUserCommand =
- (DAC960_V1_UserCommand_T *) Argument;
- DAC960_V1_UserCommand_T UserCommand;
- DAC960_Controller_T *Controller;
- DAC960_Command_T *Command = NULL;
- DAC960_V1_CommandOpcode_T CommandOpcode;
- DAC960_V1_CommandStatus_T CommandStatus;
- DAC960_V1_DCDB_T DCDB;
- ProcessorFlags_T ProcessorFlags;
- int ControllerNumber, DataTransferLength;
- unsigned char *DataTransferBuffer = NULL;
- if (UserSpaceUserCommand == NULL) return -EINVAL;
- ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
- sizeof(DAC960_V1_UserCommand_T));
- if (ErrorCode != 0) goto Failure1;
- ControllerNumber = UserCommand.ControllerNumber;
- if (ControllerNumber < 0 ||
- ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
- CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
- DataTransferLength = UserCommand.DataTransferLength;
- if (CommandOpcode & 0x80) return -EINVAL;
- if (CommandOpcode == DAC960_V1_DCDB)
- {
- ErrorCode =
- copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_V1_DCDB_T));
- if (ErrorCode != 0) goto Failure1;
- if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL;
- if (!((DataTransferLength == 0 &&
- DCDB.Direction
- == DAC960_V1_DCDB_NoDataTransfer) ||
- (DataTransferLength > 0 &&
- DCDB.Direction
- == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
- (DataTransferLength < 0 &&
- DCDB.Direction
- == DAC960_V1_DCDB_DataTransferSystemToDevice)))
- return -EINVAL;
- if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
- != abs(DataTransferLength))
- return -EINVAL;
- }
- if (DataTransferLength > 0)
- {
- DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
- if (DataTransferBuffer == NULL) return -ENOMEM;
- memset(DataTransferBuffer, 0, DataTransferLength);
- }
- else if (DataTransferLength < 0)
- {
- DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
- if (DataTransferBuffer == NULL) return -ENOMEM;
- ErrorCode = copy_from_user(DataTransferBuffer,
- UserCommand.DataTransferBuffer,
- -DataTransferLength);
- if (ErrorCode != 0) goto Failure1;
- }
- if (CommandOpcode == DAC960_V1_DCDB)
- {
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
- DAC960_WaitForCommand(Controller);
- while (Controller->V1.DirectCommandActive[DCDB.Channel]
- [DCDB.TargetID])
- {
- spin_unlock_irq(&io_request_lock);
- __wait_event(Controller->CommandWaitQueue,
- !Controller->V1.DirectCommandActive
- [DCDB.Channel][DCDB.TargetID]);
- spin_lock_irq(&io_request_lock);
- }
- Controller->V1.DirectCommandActive[DCDB.Channel]
- [DCDB.TargetID] = true;
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_ImmediateCommand;
- memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
- sizeof(DAC960_V1_CommandMailbox_T));
- Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(&DCDB);
- DCDB.BusAddress = Virtual_to_Bus32(DataTransferBuffer);
- }
- else
- {
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
- DAC960_WaitForCommand(Controller);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_ImmediateCommand;
- memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
- sizeof(DAC960_V1_CommandMailbox_T));
- if (DataTransferBuffer != NULL)
- Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(DataTransferBuffer);
- }
- DAC960_ExecuteCommand(Command);
- CommandStatus = Command->V1.CommandStatus;
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- DAC960_DeallocateCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- if (DataTransferLength > 0)
- {
- ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
- DataTransferBuffer, DataTransferLength);
- if (ErrorCode != 0) goto Failure1;
- }
- if (CommandOpcode == DAC960_V1_DCDB)
- {
- Controller->V1.DirectCommandActive[DCDB.Channel]
- [DCDB.TargetID] = false;
- ErrorCode =
- copy_to_user(UserCommand.DCDB, &DCDB, sizeof(DAC960_V1_DCDB_T));
- if (ErrorCode != 0) goto Failure1;
- }
- ErrorCode = CommandStatus;
- Failure1:
- if (DataTransferBuffer != NULL)
- kfree(DataTransferBuffer);
- return ErrorCode;
- }
- case DAC960_IOCTL_V2_EXECUTE_COMMAND:
- {
- DAC960_V2_UserCommand_T *UserSpaceUserCommand =
- (DAC960_V2_UserCommand_T *) Argument;
- DAC960_V2_UserCommand_T UserCommand;
- DAC960_Controller_T *Controller;
- DAC960_Command_T *Command = NULL;
- DAC960_V2_CommandMailbox_T *CommandMailbox;
- DAC960_V2_CommandStatus_T CommandStatus;
- ProcessorFlags_T ProcessorFlags;
- int ControllerNumber, DataTransferLength;
- int DataTransferResidue, RequestSenseLength;
- unsigned char *DataTransferBuffer = NULL;
- unsigned char *RequestSenseBuffer = NULL;
- if (UserSpaceUserCommand == NULL) return -EINVAL;
- ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
- sizeof(DAC960_V2_UserCommand_T));
- if (ErrorCode != 0) goto Failure2;
- ControllerNumber = UserCommand.ControllerNumber;
- if (ControllerNumber < 0 ||
- ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
- DataTransferLength = UserCommand.DataTransferLength;
- if (DataTransferLength > 0)
- {
- DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
- if (DataTransferBuffer == NULL) return -ENOMEM;
- memset(DataTransferBuffer, 0, DataTransferLength);
- }
- else if (DataTransferLength < 0)
- {
- DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
- if (DataTransferBuffer == NULL) return -ENOMEM;
- ErrorCode = copy_from_user(DataTransferBuffer,
- UserCommand.DataTransferBuffer,
- -DataTransferLength);
- if (ErrorCode != 0) goto Failure2;
- }
- RequestSenseLength = UserCommand.RequestSenseLength;
- if (RequestSenseLength > 0)
- {
- RequestSenseBuffer = kmalloc(RequestSenseLength, GFP_KERNEL);
- if (RequestSenseBuffer == NULL)
- {
- ErrorCode = -ENOMEM;
- goto Failure2;
- }
- memset(RequestSenseBuffer, 0, RequestSenseLength);
- }
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
- DAC960_WaitForCommand(Controller);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- DAC960_V2_ClearCommand(Command);
- Command->CommandType = DAC960_ImmediateCommand;
- CommandMailbox = &Command->V2.CommandMailbox;
- memcpy(CommandMailbox, &UserCommand.CommandMailbox,
- sizeof(DAC960_V2_CommandMailbox_T));
- CommandMailbox->Common.CommandControlBits
- .AdditionalScatterGatherListMemory = false;
- CommandMailbox->Common.CommandControlBits
- .NoAutoRequestSense = true;
- CommandMailbox->Common.DataTransferSize = 0;
- CommandMailbox->Common.DataTransferPageNumber = 0;
- memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
- sizeof(DAC960_V2_DataTransferMemoryAddress_T));
- if (DataTransferLength != 0)
- {
- if (DataTransferLength > 0)
- {
- CommandMailbox->Common.CommandControlBits
- .DataTransferControllerToHost = true;
- CommandMailbox->Common.DataTransferSize = DataTransferLength;
- }
- else
- {
- CommandMailbox->Common.CommandControlBits
- .DataTransferControllerToHost = false;
- CommandMailbox->Common.DataTransferSize = -DataTransferLength;
- }
- CommandMailbox->Common.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(DataTransferBuffer);
- CommandMailbox->Common.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->Common.DataTransferSize;
- }
- if (RequestSenseLength > 0)
- {
- CommandMailbox->Common.CommandControlBits
- .NoAutoRequestSense = false;
- CommandMailbox->Common.RequestSenseSize = RequestSenseLength;
- CommandMailbox->Common.RequestSenseBusAddress =
- Virtual_to_Bus64(RequestSenseBuffer);
- }
- DAC960_ExecuteCommand(Command);
- CommandStatus = Command->V2.CommandStatus;
- RequestSenseLength = Command->V2.RequestSenseLength;
- DataTransferResidue = Command->V2.DataTransferResidue;
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- DAC960_DeallocateCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- if (RequestSenseLength > UserCommand.RequestSenseLength)
- RequestSenseLength = UserCommand.RequestSenseLength;
- ErrorCode = copy_to_user(&UserSpaceUserCommand->DataTransferLength,
- &DataTransferResidue,
- sizeof(DataTransferResidue));
- if (ErrorCode != 0) goto Failure2;
- ErrorCode = copy_to_user(&UserSpaceUserCommand->RequestSenseLength,
- &RequestSenseLength,
- sizeof(RequestSenseLength));
- if (ErrorCode != 0) goto Failure2;
- if (DataTransferLength > 0)
- {
- ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
- DataTransferBuffer, DataTransferLength);
- if (ErrorCode != 0) goto Failure2;
- }
- if (RequestSenseLength > 0)
- {
- ErrorCode = copy_to_user(UserCommand.RequestSenseBuffer,
- RequestSenseBuffer, RequestSenseLength);
- if (ErrorCode != 0) goto Failure2;
- }
- ErrorCode = CommandStatus;
- Failure2:
- if (DataTransferBuffer != NULL)
- kfree(DataTransferBuffer);
- if (RequestSenseBuffer != NULL)
- kfree(RequestSenseBuffer);
- return ErrorCode;
- }
- case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
- {
- DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus =
- (DAC960_V2_GetHealthStatus_T *) Argument;
- DAC960_V2_GetHealthStatus_T GetHealthStatus;
- DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
- DAC960_Controller_T *Controller;
- int ControllerNumber;
- if (UserSpaceGetHealthStatus == NULL) return -EINVAL;
- ErrorCode = copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
- sizeof(DAC960_V2_GetHealthStatus_T));
- if (ErrorCode != 0) return ErrorCode;
- ControllerNumber = GetHealthStatus.ControllerNumber;
- if (ControllerNumber < 0 ||
- ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
- ErrorCode = copy_from_user(&HealthStatusBuffer,
- GetHealthStatus.HealthStatusBuffer,
- sizeof(DAC960_V2_HealthStatusBuffer_T));
- if (ErrorCode != 0) return ErrorCode;
- while (Controller->V2.HealthStatusBuffer->StatusChangeCounter
- == HealthStatusBuffer.StatusChangeCounter &&
- Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
- == HealthStatusBuffer.NextEventSequenceNumber)
- {
- interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue,
- DAC960_MonitoringTimerInterval);
- if (signal_pending(current)) return -EINTR;
- }
- ErrorCode = copy_to_user(GetHealthStatus.HealthStatusBuffer,
- Controller->V2.HealthStatusBuffer,
- sizeof(DAC960_V2_HealthStatusBuffer_T));
- return ErrorCode;
- }
- }
- return -EINVAL;
- }
- /*
- DAC960_KernelIOCTL is the Kernel IOCTL Function for the DAC960 Driver.
- */
- int DAC960_KernelIOCTL(unsigned int Request, void *Argument)
- {
- switch (Request)
- {
- case DAC960_IOCTL_GET_CONTROLLER_COUNT:
- return DAC960_ControllerCount;
- case DAC960_IOCTL_GET_CONTROLLER_INFO:
- {
- DAC960_ControllerInfo_T *ControllerInfo =
- (DAC960_ControllerInfo_T *) Argument;
- DAC960_Controller_T *Controller;
- int ControllerNumber;
- if (ControllerInfo == NULL) return -EINVAL;
- ControllerNumber = ControllerInfo->ControllerNumber;
- if (ControllerNumber < 0 ||
- ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- memset(ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
- ControllerInfo->ControllerNumber = ControllerNumber;
- ControllerInfo->FirmwareType = Controller->FirmwareType;
- ControllerInfo->Channels = Controller->Channels;
- ControllerInfo->Targets = Controller->Targets;
- ControllerInfo->PCI_Bus = Controller->Bus;
- ControllerInfo->PCI_Device = Controller->Device;
- ControllerInfo->PCI_Function = Controller->Function;
- ControllerInfo->IRQ_Channel = Controller->IRQ_Channel;
- ControllerInfo->PCI_Address = Controller->PCI_Address;
- strcpy(ControllerInfo->ModelName, Controller->ModelName);
- strcpy(ControllerInfo->FirmwareVersion, Controller->FirmwareVersion);
- return 0;
- }
- case DAC960_IOCTL_V1_EXECUTE_COMMAND:
- {
- DAC960_V1_KernelCommand_T *KernelCommand =
- (DAC960_V1_KernelCommand_T *) Argument;
- DAC960_Controller_T *Controller;
- DAC960_Command_T *Command = NULL;
- DAC960_V1_CommandOpcode_T CommandOpcode;
- DAC960_V1_DCDB_T *DCDB = NULL;
- ProcessorFlags_T ProcessorFlags;
- int ControllerNumber, DataTransferLength;
- unsigned char *DataTransferBuffer = NULL;
- if (KernelCommand == NULL) return -EINVAL;
- ControllerNumber = KernelCommand->ControllerNumber;
- if (ControllerNumber < 0 ||
- ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
- CommandOpcode = KernelCommand->CommandMailbox.Common.CommandOpcode;
- DataTransferLength = KernelCommand->DataTransferLength;
- DataTransferBuffer = KernelCommand->DataTransferBuffer;
- if (CommandOpcode & 0x80) return -EINVAL;
- if (CommandOpcode == DAC960_V1_DCDB)
- {
- DCDB = KernelCommand->DCDB;
- if (DCDB->Channel >= DAC960_V1_MaxChannels) return -EINVAL;
- if (!((DataTransferLength == 0 &&
- DCDB->Direction == DAC960_V1_DCDB_NoDataTransfer) ||
- (DataTransferLength > 0 &&
- DCDB->Direction
- == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
- (DataTransferLength < 0 &&
- DCDB->Direction
- == DAC960_V1_DCDB_DataTransferSystemToDevice)))
- return -EINVAL;
- if (((DCDB->TransferLengthHigh4 << 16) | DCDB->TransferLength)
- != abs(DataTransferLength))
- return -EINVAL;
- }
- if (DataTransferLength != 0 && DataTransferBuffer == NULL)
- return -EINVAL;
- if (DataTransferLength > 0)
- memset(DataTransferBuffer, 0, DataTransferLength);
- if (CommandOpcode == DAC960_V1_DCDB)
- {
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- if (!Controller->V1.DirectCommandActive[DCDB->Channel]
- [DCDB->TargetID])
- Command = DAC960_AllocateCommand(Controller);
- if (Command == NULL)
- {
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- return -EBUSY;
- }
- else Controller->V1.DirectCommandActive[DCDB->Channel]
- [DCDB->TargetID] = true;
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_QueuedCommand;
- memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
- sizeof(DAC960_V1_CommandMailbox_T));
- Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(DCDB);
- Command->V1.KernelCommand = KernelCommand;
- DCDB->BusAddress = Virtual_to_Bus32(DataTransferBuffer);
- DAC960_QueueCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- }
- else
- {
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- Command = DAC960_AllocateCommand(Controller);
- if (Command == NULL)
- {
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- return -EBUSY;
- }
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_QueuedCommand;
- memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
- sizeof(DAC960_V1_CommandMailbox_T));
- if (DataTransferBuffer != NULL)
- Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(DataTransferBuffer);
- Command->V1.KernelCommand = KernelCommand;
- DAC960_QueueCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- }
- return 0;
- }
- case DAC960_IOCTL_V2_EXECUTE_COMMAND:
- {
- DAC960_V2_KernelCommand_T *KernelCommand =
- (DAC960_V2_KernelCommand_T *) Argument;
- DAC960_Controller_T *Controller;
- DAC960_Command_T *Command = NULL;
- DAC960_V2_CommandMailbox_T *CommandMailbox;
- ProcessorFlags_T ProcessorFlags;
- int ControllerNumber, DataTransferLength, RequestSenseLength;
- unsigned char *DataTransferBuffer = NULL;
- unsigned char *RequestSenseBuffer = NULL;
- if (KernelCommand == NULL) return -EINVAL;
- ControllerNumber = KernelCommand->ControllerNumber;
- if (ControllerNumber < 0 ||
- ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
- DataTransferLength = KernelCommand->DataTransferLength;
- RequestSenseLength = KernelCommand->RequestSenseLength;
- DataTransferBuffer = KernelCommand->DataTransferBuffer;
- RequestSenseBuffer = KernelCommand->RequestSenseBuffer;
- if (DataTransferLength != 0 && DataTransferBuffer == NULL)
- return -EINVAL;
- if (RequestSenseLength < 0)
- return -EINVAL;
- if (RequestSenseLength > 0 && RequestSenseBuffer == NULL)
- return -EINVAL;
- if (DataTransferLength > 0)
- memset(DataTransferBuffer, 0, DataTransferLength);
- if (RequestSenseLength > 0)
- memset(RequestSenseBuffer, 0, RequestSenseLength);
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- Command = DAC960_AllocateCommand(Controller);
- if (Command == NULL)
- {
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- return -EBUSY;
- }
- DAC960_V2_ClearCommand(Command);
- Command->CommandType = DAC960_QueuedCommand;
- CommandMailbox = &Command->V2.CommandMailbox;
- memcpy(CommandMailbox, &KernelCommand->CommandMailbox,
- sizeof(DAC960_V2_CommandMailbox_T));
- CommandMailbox->Common.CommandControlBits
- .AdditionalScatterGatherListMemory = false;
- CommandMailbox->Common.CommandControlBits
- .NoAutoRequestSense = true;
- CommandMailbox->Common.DataTransferSize = 0;
- CommandMailbox->Common.DataTransferPageNumber = 0;
- memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
- sizeof(DAC960_V2_DataTransferMemoryAddress_T));
- if (DataTransferLength != 0)
- {
- if (DataTransferLength > 0)
- {
- CommandMailbox->Common.CommandControlBits
- .DataTransferControllerToHost = true;
- CommandMailbox->Common.DataTransferSize = DataTransferLength;
- }
- else
- {
- CommandMailbox->Common.CommandControlBits
- .DataTransferControllerToHost = false;
- CommandMailbox->Common.DataTransferSize = -DataTransferLength;
- }
- CommandMailbox->Common.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(DataTransferBuffer);
- CommandMailbox->Common.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->Common.DataTransferSize;
- }
- if (RequestSenseLength > 0)
- {
- CommandMailbox->Common.CommandControlBits
- .NoAutoRequestSense = false;
- CommandMailbox->Common.RequestSenseBusAddress =
- Virtual_to_Bus64(RequestSenseBuffer);
- }
- Command->V2.KernelCommand = KernelCommand;
- DAC960_QueueCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- return 0;
- }
- }
- return -EINVAL;
- }
- /*
- DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount
- additional bytes in the Combined Status Buffer and grows the buffer if
- necessary. It returns true if there is enough room and false otherwise.
- */
- static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
- unsigned int ByteCount)
- {
- unsigned char *NewStatusBuffer;
- if (Controller->InitialStatusLength + 1 +
- Controller->CurrentStatusLength + ByteCount + 1 <=
- Controller->CombinedStatusBufferLength)
- return true;
- if (Controller->CombinedStatusBufferLength == 0)
- {
- unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize;
- while (NewStatusBufferLength < ByteCount)
- NewStatusBufferLength *= 2;
- Controller->CombinedStatusBuffer =
- (unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC);
- if (Controller->CombinedStatusBuffer == NULL) return false;
- Controller->CombinedStatusBufferLength = NewStatusBufferLength;
- return true;
- }
- NewStatusBuffer = (unsigned char *)
- kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC);
- if (NewStatusBuffer == NULL)
- {
- DAC960_Warning("Unable to expand Combined Status Buffer - Truncatingn",
- Controller);
- return false;
- }
- memcpy(NewStatusBuffer, Controller->CombinedStatusBuffer,
- Controller->CombinedStatusBufferLength);
- kfree(Controller->CombinedStatusBuffer);
- Controller->CombinedStatusBuffer = NewStatusBuffer;
- Controller->CombinedStatusBufferLength *= 2;
- Controller->CurrentStatusBuffer =
- &NewStatusBuffer[Controller->InitialStatusLength + 1];
- return true;
- }
- /*
- DAC960_Message prints Driver Messages.
- */
- static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
- unsigned char *Format,
- DAC960_Controller_T *Controller,
- ...)
- {
- static unsigned char Buffer[DAC960_LineBufferSize];
- static boolean BeginningOfLine = true;
- va_list Arguments;
- int Length = 0;
- va_start(Arguments, Controller);
- Length = vsprintf(Buffer, Format, Arguments);
- va_end(Arguments);
- if (Controller == NULL)
- printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
- DAC960_ControllerCount, Buffer);
- else if (MessageLevel == DAC960_AnnounceLevel ||
- MessageLevel == DAC960_InfoLevel)
- {
- if (!Controller->ControllerInitialized)
- {
- if (DAC960_CheckStatusBuffer(Controller, Length))
- {
- strcpy(&Controller->CombinedStatusBuffer
- [Controller->InitialStatusLength],
- Buffer);
- Controller->InitialStatusLength += Length;
- Controller->CurrentStatusBuffer =
- &Controller->CombinedStatusBuffer
- [Controller->InitialStatusLength + 1];
- }
- if (MessageLevel == DAC960_AnnounceLevel)
- {
- static int AnnouncementLines = 0;
- if (++AnnouncementLines <= 2)
- printk("%sDAC960: %s", DAC960_MessageLevelMap[MessageLevel],
- Buffer);
- }
- else
- {
- if (BeginningOfLine)
- {
- if (Buffer[0] != 'n' || Length > 1)
- printk("%sDAC960#%d: %s",
- DAC960_MessageLevelMap[MessageLevel],
- Controller->ControllerNumber, Buffer);
- }
- else printk("%s", Buffer);
- }
- }
- else if (DAC960_CheckStatusBuffer(Controller, Length))
- {
- strcpy(&Controller->CurrentStatusBuffer[
- Controller->CurrentStatusLength], Buffer);
- Controller->CurrentStatusLength += Length;
- }
- }
- else if (MessageLevel == DAC960_ProgressLevel)
- {
- strcpy(Controller->ProgressBuffer, Buffer);
- Controller->ProgressBufferLength = Length;
- if (Controller->EphemeralProgressMessage)
- {
- if (jiffies - Controller->LastProgressReportTime
- >= DAC960_ProgressReportingInterval)
- {
- printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
- Controller->ControllerNumber, Buffer);
- Controller->LastProgressReportTime = jiffies;
- }
- }
- else printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
- Controller->ControllerNumber, Buffer);
- }
- else if (MessageLevel == DAC960_UserCriticalLevel)
- {
- strcpy(&Controller->UserStatusBuffer[Controller->UserStatusLength],
- Buffer);
- Controller->UserStatusLength += Length;
- if (Buffer[0] != 'n' || Length > 1)
- printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
- Controller->ControllerNumber, Buffer);
- }
- else
- {
- if (BeginningOfLine)
- printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
- Controller->ControllerNumber, Buffer);
- else printk("%s", Buffer);
- }
- BeginningOfLine = (Buffer[Length-1] == 'n');
- }
- /*
- DAC960_ParsePhysicalDevice parses spaces followed by a Physical Device
- Channel:TargetID specification from a User Command string. It updates
- Channel and TargetID and returns true on success and false on failure.
- */
- static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
- char *UserCommandString,
- unsigned char *Channel,
- unsigned char *TargetID)
- {
- char *NewUserCommandString = UserCommandString;
- unsigned long XChannel, XTargetID;
- while (*UserCommandString == ' ') UserCommandString++;
- if (UserCommandString == NewUserCommandString)
- return false;
- XChannel = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
- if (NewUserCommandString == UserCommandString ||
- *NewUserCommandString != ':' ||
- XChannel >= Controller->Channels)
- return false;
- UserCommandString = ++NewUserCommandString;
- XTargetID = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
- if (NewUserCommandString == UserCommandString ||
- *NewUserCommandString != ' ' ||
- XTargetID >= Controller->Targets)
- return false;
- *Channel = XChannel;
- *TargetID = XTargetID;
- return true;
- }
- /*
- DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number
- specification from a User Command string. It updates LogicalDriveNumber and
- returns true on success and false on failure.
- */
- static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
- char *UserCommandString,
- unsigned char *LogicalDriveNumber)
- {
- char *NewUserCommandString = UserCommandString;
- unsigned long XLogicalDriveNumber;
- while (*UserCommandString == ' ') UserCommandString++;
- if (UserCommandString == NewUserCommandString)
- return false;
- XLogicalDriveNumber =
- simple_strtoul(UserCommandString, &NewUserCommandString, 10);
- if (NewUserCommandString == UserCommandString ||
- *NewUserCommandString != ' ' ||
- XLogicalDriveNumber > DAC960_MaxLogicalDrives - 1)
- return false;
- *LogicalDriveNumber = XLogicalDriveNumber;
- return true;
- }
- /*
- DAC960_V1_SetDeviceState sets the Device State for a Physical Device for
- DAC960 V1 Firmware Controllers.
- */
- static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller,
- DAC960_Command_T *Command,
- unsigned char Channel,
- unsigned char TargetID,
- DAC960_V1_PhysicalDeviceState_T
- DeviceState,
- const unsigned char *DeviceStateString)
- {
- DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
- CommandMailbox->Type3D.CommandOpcode = DAC960_V1_StartDevice;
- CommandMailbox->Type3D.Channel = Channel;
- CommandMailbox->Type3D.TargetID = TargetID;
- CommandMailbox->Type3D.DeviceState = DeviceState;
- CommandMailbox->Type3D.Modifier = 0;
- DAC960_ExecuteCommand(Command);
- switch (Command->V1.CommandStatus)
- {
- case DAC960_V1_NormalCompletion:
- DAC960_UserCritical("%s of Physical Device %d:%d Succeededn", Controller,
- DeviceStateString, Channel, TargetID);
- break;
- case DAC960_V1_UnableToStartDevice:
- DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
- "Unable to Start Devicen", Controller,
- DeviceStateString, Channel, TargetID);
- break;
- case DAC960_V1_NoDeviceAtAddress:
- DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
- "No Device at Addressn", Controller,
- DeviceStateString, Channel, TargetID);
- break;
- case DAC960_V1_InvalidChannelOrTargetOrModifier:
- DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
- "Invalid Channel or Target or Modifiern",
- Controller, DeviceStateString, Channel, TargetID);
- break;
- case DAC960_V1_ChannelBusy:
- DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
- "Channel Busyn", Controller,
- DeviceStateString, Channel, TargetID);
- break;
- default:
- DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
- "Unexpected Status %04Xn", Controller,
- DeviceStateString, Channel, TargetID,
- Command->V1.CommandStatus);
- break;
- }
- }
- /*
- DAC960_V1_ExecuteUserCommand executes a User Command for DAC960 V1 Firmware
- Controllers.
- */
- static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
- unsigned char *UserCommand)
- {
- DAC960_Command_T *Command;
- DAC960_V1_CommandMailbox_T *CommandMailbox;
- ProcessorFlags_T ProcessorFlags;
- unsigned char Channel, TargetID, LogicalDriveNumber;
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
- DAC960_WaitForCommand(Controller);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- Controller->UserStatusLength = 0;
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_ImmediateCommand;
- CommandMailbox = &Command->V1.CommandMailbox;
- if (strcmp(UserCommand, "flush-cache") == 0)
- {
- CommandMailbox->Type3.CommandOpcode = DAC960_V1_Flush;
- DAC960_ExecuteCommand(Command);
- DAC960_UserCritical("Cache Flush Completedn", Controller);
- }
- else if (strncmp(UserCommand, "kill", 4) == 0 &&
- DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
- &Channel, &TargetID))
- {
- DAC960_V1_DeviceState_T *DeviceState =
- &Controller->V1.DeviceState[Channel][TargetID];
- if (DeviceState->Present &&
- DeviceState->DeviceType == DAC960_V1_DiskType &&
- DeviceState->DeviceState != DAC960_V1_Device_Dead)
- DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
- DAC960_V1_Device_Dead, "Kill");
- else DAC960_UserCritical("Kill of Physical Device %d:%d Illegaln",
- Controller, Channel, TargetID);
- }
- else if (strncmp(UserCommand, "make-online", 11) == 0 &&
- DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
- &Channel, &TargetID))
- {
- DAC960_V1_DeviceState_T *DeviceState =
- &Controller->V1.DeviceState[Channel][TargetID];
- if (DeviceState->Present &&
- DeviceState->DeviceType == DAC960_V1_DiskType &&
- DeviceState->DeviceState == DAC960_V1_Device_Dead)
- DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
- DAC960_V1_Device_Online, "Make Online");
- else DAC960_UserCritical("Make Online of Physical Device %d:%d Illegaln",
- Controller, Channel, TargetID);
- }
- else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
- DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
- &Channel, &TargetID))
- {
- DAC960_V1_DeviceState_T *DeviceState =
- &Controller->V1.DeviceState[Channel][TargetID];
- if (DeviceState->Present &&
- DeviceState->DeviceType == DAC960_V1_DiskType &&
- DeviceState->DeviceState == DAC960_V1_Device_Dead)
- DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
- DAC960_V1_Device_Standby, "Make Standby");
- else DAC960_UserCritical("Make Standby of Physical "
- "Device %d:%d Illegaln",
- Controller, Channel, TargetID);
- }
- else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
- DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
- &Channel, &TargetID))
- {
- CommandMailbox->Type3D.CommandOpcode = DAC960_V1_RebuildAsync;
- CommandMailbox->Type3D.Channel = Channel;
- CommandMailbox->Type3D.TargetID = TargetID;
- DAC960_ExecuteCommand(Command);
- switch (Command->V1.CommandStatus)
- {
- case DAC960_V1_NormalCompletion:
- DAC960_UserCritical("Rebuild of Physical Device %d:%d Initiatedn",
- Controller, Channel, TargetID);
- break;
- case DAC960_V1_AttemptToRebuildOnlineDrive:
- DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
- "Attempt to Rebuild Online or "
- "Unresponsive Driven",
- Controller, Channel, TargetID);
- break;
- case DAC960_V1_NewDiskFailedDuringRebuild:
- DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
- "New Disk Failed During Rebuildn",
- Controller, Channel, TargetID);
- break;
- case DAC960_V1_InvalidDeviceAddress:
- DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
- "Invalid Device Addressn",
- Controller, Channel, TargetID);
- break;
- case DAC960_V1_RebuildOrCheckAlreadyInProgress:
- DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
- "Rebuild or Consistency Check Already "
- "in Progressn", Controller, Channel, TargetID);
- break;
- default:
- DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
- "Unexpected Status %04Xn", Controller,
- Channel, TargetID, Command->V1.CommandStatus);
- break;
- }
- }
- else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
- DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
- &LogicalDriveNumber))
- {
- CommandMailbox->Type3C.CommandOpcode = DAC960_V1_CheckConsistencyAsync;
- CommandMailbox->Type3C.LogicalDriveNumber = LogicalDriveNumber;
- CommandMailbox->Type3C.AutoRestore = true;
- DAC960_ExecuteCommand(Command);
- switch (Command->V1.CommandStatus)
- {
- case DAC960_V1_NormalCompletion:
- DAC960_UserCritical("Consistency Check of Logical Drive %d "
- "(/dev/rd/c%dd%d) Initiatedn",
- Controller, LogicalDriveNumber,
- Controller->ControllerNumber,
- LogicalDriveNumber);
- break;
- case DAC960_V1_DependentDiskIsDead:
- DAC960_UserCritical("Consistency Check of Logical Drive %d "
- "(/dev/rd/c%dd%d) Failed - "
- "Dependent Physical Device is DEADn",
- Controller, LogicalDriveNumber,
- Controller->ControllerNumber,
- LogicalDriveNumber);
- break;
- case DAC960_V1_InvalidOrNonredundantLogicalDrive:
- DAC960_UserCritical("Consistency Check of Logical Drive %d "
- "(/dev/rd/c%dd%d) Failed - "
- "Invalid or Nonredundant Logical Driven",
- Controller, LogicalDriveNumber,
- Controller->ControllerNumber,
- LogicalDriveNumber);
- break;
- case DAC960_V1_RebuildOrCheckAlreadyInProgress:
- DAC960_UserCritical("Consistency Check of Logical Drive %d "
- "(/dev/rd/c%dd%d) Failed - Rebuild or "
- "Consistency Check Already in Progressn",
- Controller, LogicalDriveNumber,
- Controller->ControllerNumber,
- LogicalDriveNumber);
- break;
- default:
- DAC960_UserCritical("Consistency Check of Logical Drive %d "
- "(/dev/rd/c%dd%d) Failed - "
- "Unexpected Status %04Xn",
- Controller, LogicalDriveNumber,
- Controller->ControllerNumber,
- LogicalDriveNumber, Command->V1.CommandStatus);
- break;
- }
- }
- else if (strcmp(UserCommand, "cancel-rebuild") == 0 ||
- strcmp(UserCommand, "cancel-consistency-check") == 0)
- {
- unsigned char OldRebuildRateConstant;
- CommandMailbox->Type3R.CommandOpcode = DAC960_V1_RebuildControl;
- CommandMailbox->Type3R.RebuildRateConstant = 0xFF;
- CommandMailbox->Type3R.BusAddress =
- Virtual_to_Bus32(&OldRebuildRateConstant);
- DAC960_ExecuteCommand(Command);
- switch (Command->V1.CommandStatus)
- {
- case DAC960_V1_NormalCompletion:
- DAC960_UserCritical("Rebuild or Consistency Check Cancelledn",
- Controller);
- break;
- default:
- DAC960_UserCritical("Cancellation of Rebuild or "
- "Consistency Check Failed - "
- "Unexpected Status %04Xn",
- Controller, Command->V1.CommandStatus);
- break;
- }
- }
- else DAC960_UserCritical("Illegal User Command: '%s'n",
- Controller, UserCommand);
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- DAC960_DeallocateCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- return true;
- }
- /*
- DAC960_V2_TranslatePhysicalDevice translates a Physical Device Channel and
- TargetID into a Logical Device. It returns true on success and false
- on failure.
- */
- static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
- unsigned char Channel,
- unsigned char TargetID,
- unsigned short
- *LogicalDeviceNumber)
- {
- DAC960_V2_CommandMailbox_T SavedCommandMailbox, *CommandMailbox;
- DAC960_V2_PhysicalToLogicalDevice_T PhysicalToLogicalDevice;
- CommandMailbox = &Command->V2.CommandMailbox;
- memcpy(&SavedCommandMailbox, CommandMailbox,
- sizeof(DAC960_V2_CommandMailbox_T));
- CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
- CommandMailbox->PhysicalDeviceInfo.CommandControlBits
- .DataTransferControllerToHost = true;
- CommandMailbox->PhysicalDeviceInfo.CommandControlBits
- .NoAutoRequestSense = true;
- CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
- sizeof(DAC960_V2_PhysicalToLogicalDevice_T);
- CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
- CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
- CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
- DAC960_V2_TranslatePhysicalToLogicalDevice;
- CommandMailbox->Common.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(&PhysicalToLogicalDevice);
- CommandMailbox->Common.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->Common.DataTransferSize;
- DAC960_ExecuteCommand(Command);
- memcpy(CommandMailbox, &SavedCommandMailbox,
- sizeof(DAC960_V2_CommandMailbox_T));
- *LogicalDeviceNumber = PhysicalToLogicalDevice.LogicalDeviceNumber;
- return (Command->V2.CommandStatus == DAC960_V2_NormalCompletion);
- }
- /*
- DAC960_V2_ExecuteUserCommand executes a User Command for DAC960 V2 Firmware
- Controllers.
- */
- static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
- unsigned char *UserCommand)
- {
- DAC960_Command_T *Command;
- DAC960_V2_CommandMailbox_T *CommandMailbox;
- ProcessorFlags_T ProcessorFlags;
- unsigned char Channel, TargetID, LogicalDriveNumber;
- unsigned short LogicalDeviceNumber;
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
- DAC960_WaitForCommand(Controller);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- Controller->UserStatusLength = 0;
- DAC960_V2_ClearCommand(Command);
- Command->CommandType = DAC960_ImmediateCommand;
- CommandMailbox = &Command->V2.CommandMailbox;
- CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
- CommandMailbox->Common.CommandControlBits.DataTransferControllerToHost = true;
- CommandMailbox->Common.CommandControlBits.NoAutoRequestSense = true;
- if (strcmp(UserCommand, "flush-cache") == 0)
- {
- CommandMailbox->DeviceOperation.IOCTL_Opcode = DAC960_V2_PauseDevice;
- CommandMailbox->DeviceOperation.OperationDevice =
- DAC960_V2_RAID_Controller;
- DAC960_ExecuteCommand(Command);
- DAC960_UserCritical("Cache Flush Completedn", Controller);
- }
- else if (strncmp(UserCommand, "kill", 4) == 0 &&
- DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
- &Channel, &TargetID) &&
- DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
- &LogicalDeviceNumber))
- {
- CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
- LogicalDeviceNumber;
- CommandMailbox->SetDeviceState.IOCTL_Opcode =
- DAC960_V2_SetDeviceState;
- CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
- DAC960_V2_Device_Dead;
- DAC960_ExecuteCommand(Command);
- DAC960_UserCritical("Kill of Physical Device %d:%d %sn",
- Controller, Channel, TargetID,
- (Command->V2.CommandStatus
- == DAC960_V2_NormalCompletion
- ? "Succeeded" : "Failed"));
- }
- else if (strncmp(UserCommand, "make-online", 11) == 0 &&
- DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
- &Channel, &TargetID) &&
- DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
- &LogicalDeviceNumber))
- {
- CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
- LogicalDeviceNumber;
- CommandMailbox->SetDeviceState.IOCTL_Opcode =
- DAC960_V2_SetDeviceState;
- CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
- DAC960_V2_Device_Online;
- DAC960_ExecuteCommand(Command);
- DAC960_UserCritical("Make Online of Physical Device %d:%d %sn",
- Controller, Channel, TargetID,
- (Command->V2.CommandStatus
- == DAC960_V2_NormalCompletion
- ? "Succeeded" : "Failed"));
- }
- else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
- DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
- &Channel, &TargetID) &&
- DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
- &LogicalDeviceNumber))
- {
- CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
- LogicalDeviceNumber;
- CommandMailbox->SetDeviceState.IOCTL_Opcode =
- DAC960_V2_SetDeviceState;
- CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
- DAC960_V2_Device_Standby;
- DAC960_ExecuteCommand(Command);
- DAC960_UserCritical("Make Standby of Physical Device %d:%d %sn",
- Controller, Channel, TargetID,
- (Command->V2.CommandStatus
- == DAC960_V2_NormalCompletion
- ? "Succeeded" : "Failed"));
- }
- else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
- DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
- &Channel, &TargetID) &&
- DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
- &LogicalDeviceNumber))
- {
- CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
- LogicalDeviceNumber;
- CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
- DAC960_V2_RebuildDeviceStart;
- DAC960_ExecuteCommand(Command);
- DAC960_UserCritical("Rebuild of Physical Device %d:%d %sn",
- Controller, Channel, TargetID,
- (Command->V2.CommandStatus
- == DAC960_V2_NormalCompletion
- ? "Initiated" : "Not Initiated"));
- }
- else if (strncmp(UserCommand, "cancel-rebuild", 14) == 0 &&
- DAC960_ParsePhysicalDevice(Controller, &UserCommand[14],
- &Channel, &TargetID) &&
- DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
- &LogicalDeviceNumber))
- {
- CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
- LogicalDeviceNumber;
- CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
- DAC960_V2_RebuildDeviceStop;
- DAC960_ExecuteCommand(Command);
- DAC960_UserCritical("Rebuild of Physical Device %d:%d %sn",
- Controller, Channel, TargetID,
- (Command->V2.CommandStatus
- == DAC960_V2_NormalCompletion
- ? "Cancelled" : "Not Cancelled"));
- }
- else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
- DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
- &LogicalDriveNumber))
- {
- CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
- LogicalDriveNumber;
- CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
- DAC960_V2_ConsistencyCheckStart;
- CommandMailbox->ConsistencyCheck.RestoreConsistency = true;
- CommandMailbox->ConsistencyCheck.InitializedAreaOnly = false;
- DAC960_ExecuteCommand(Command);
- DAC960_UserCritical("Consistency Check of Logical Drive %d "
- "(/dev/rd/c%dd%d) %sn",
- Controller, LogicalDriveNumber,
- Controller->ControllerNumber,
- LogicalDriveNumber,
- (Command->V2.CommandStatus
- == DAC960_V2_NormalCompletion
- ? "Initiated" : "Not Initiated"));
- }
- else if (strncmp(UserCommand, "cancel-consistency-check", 24) == 0 &&
- DAC960_ParseLogicalDrive(Controller, &UserCommand[24],
- &LogicalDriveNumber))
- {
- CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
- LogicalDriveNumber;
- CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
- DAC960_V2_ConsistencyCheckStop;
- DAC960_ExecuteCommand(Command);
- DAC960_UserCritical("Consistency Check of Logical Drive %d "
- "(/dev/rd/c%dd%d) %sn",
- Controller, LogicalDriveNumber,
- Controller->ControllerNumber,
- LogicalDriveNumber,
- (Command->V2.CommandStatus
- == DAC960_V2_NormalCompletion
- ? "Cancelled" : "Not Cancelled"));
- }
- else if (strcmp(UserCommand, "perform-discovery") == 0)
- {
- CommandMailbox->Common.IOCTL_Opcode = DAC960_V2_StartDiscovery;
- DAC960_ExecuteCommand(Command);
- DAC960_UserCritical("Discovery %sn", Controller,
- (Command->V2.CommandStatus
- == DAC960_V2_NormalCompletion
- ? "Initiated" : "Not Initiated"));
- if (Command->V2.CommandStatus == DAC960_V2_NormalCompletion)
- {
- CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
- CommandMailbox->ControllerInfo.CommandControlBits
- .DataTransferControllerToHost = true;
- CommandMailbox->ControllerInfo.CommandControlBits
- .NoAutoRequestSense = true;
- CommandMailbox->ControllerInfo.DataTransferSize =
- sizeof(DAC960_V2_ControllerInfo_T);
- CommandMailbox->ControllerInfo.ControllerNumber = 0;
- CommandMailbox->ControllerInfo.IOCTL_Opcode =
- DAC960_V2_GetControllerInfo;
- CommandMailbox->ControllerInfo.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(&Controller->V2.NewControllerInformation);
- CommandMailbox->ControllerInfo.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->ControllerInfo.DataTransferSize;
- DAC960_ExecuteCommand(Command);
- while (Controller->V2.NewControllerInformation.PhysicalScanActive)
- {
- DAC960_ExecuteCommand(Command);
- sleep_on_timeout(&Controller->CommandWaitQueue, HZ);
- }
- DAC960_UserCritical("Discovery Completedn", Controller);
- }
- }
- else if (strcmp(UserCommand, "suppress-enclosure-messages") == 0)
- Controller->SuppressEnclosureMessages = true;
- else DAC960_UserCritical("Illegal User Command: '%s'n",
- Controller, UserCommand);
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- DAC960_DeallocateCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- return true;
- }
- /*
- DAC960_ProcReadStatus implements reading /proc/rd/status.
- */
- static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
- int Count, int *EOF, void *Data)
- {
- unsigned char *StatusMessage = "OKn";
- int ControllerNumber, BytesAvailable;
- for (ControllerNumber = 0;
- ControllerNumber < DAC960_ControllerCount;
- ControllerNumber++)
- {
- DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) continue;
- if (Controller->MonitoringAlertMode)
- {
- StatusMessage = "ALERTn";
- break;
- }
- }
- BytesAvailable = strlen(StatusMessage) - Offset;
- if (Count >= BytesAvailable)
- {
- Count = BytesAvailable;
- *EOF = true;
- }
- if (Count <= 0) return 0;
- *Start = Page;
- memcpy(Page, &StatusMessage[Offset], Count);
- return Count;
- }
- /*
- DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status.
- */
- static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset,
- int Count, int *EOF, void *Data)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
- int BytesAvailable = Controller->InitialStatusLength - Offset;
- if (Count >= BytesAvailable)
- {
- Count = BytesAvailable;
- *EOF = true;
- }
- if (Count <= 0) return 0;
- *Start = Page;
- memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
- return Count;
- }
- /*
- DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status.
- */
- static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
- int Count, int *EOF, void *Data)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
- unsigned char *StatusMessage =
- "No Rebuild or Consistency Check in Progressn";
- int ProgressMessageLength = strlen(StatusMessage);
- int BytesAvailable;
- if (jiffies != Controller->LastCurrentStatusTime)
- {
- Controller->CurrentStatusLength = 0;
- DAC960_AnnounceDriver(Controller);
- DAC960_ReportControllerConfiguration(Controller);
- DAC960_ReportDeviceConfiguration(Controller);
- if (Controller->ProgressBufferLength > 0)
- ProgressMessageLength = Controller->ProgressBufferLength;
- if (DAC960_CheckStatusBuffer(Controller, 2 + ProgressMessageLength))
- {
- unsigned char *CurrentStatusBuffer = Controller->CurrentStatusBuffer;
- CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
- CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
- if (Controller->ProgressBufferLength > 0)
- strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
- Controller->ProgressBuffer);
- else
- strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
- StatusMessage);
- Controller->CurrentStatusLength += ProgressMessageLength;
- }
- Controller->LastCurrentStatusTime = jiffies;
- }
- BytesAvailable = Controller->CurrentStatusLength - Offset;
- if (Count >= BytesAvailable)
- {
- Count = BytesAvailable;
- *EOF = true;
- }
- if (Count <= 0) return 0;
- *Start = Page;
- memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count);
- return Count;
- }
- /*
- DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command.
- */
- static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset,
- int Count, int *EOF, void *Data)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
- int BytesAvailable = Controller->UserStatusLength - Offset;
- if (Count >= BytesAvailable)
- {
- Count = BytesAvailable;
- *EOF = true;
- }
- if (Count <= 0) return 0;
- *Start = Page;
- memcpy(Page, &Controller->UserStatusBuffer[Offset], Count);
- return Count;
- }
- /*
- DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
- */
- static int DAC960_ProcWriteUserCommand(File_T *File, const char *Buffer,
- unsigned long Count, void *Data)
- {
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
- unsigned char CommandBuffer[80];
- int Length;
- if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
- if (copy_from_user(CommandBuffer, Buffer, Count)) return -EFAULT;
- CommandBuffer[Count] = ' ';
- Length = strlen(CommandBuffer);
- if (CommandBuffer[Length-1] == 'n')
- CommandBuffer[--Length] = ' ';
- if (Controller->FirmwareType == DAC960_V1_Controller)
- return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer)
- ? Count : -EBUSY);
- else
- return (DAC960_V2_ExecuteUserCommand(Controller, CommandBuffer)
- ? Count : -EBUSY);
- }
- /*
- DAC960_CreateProcEntries creates the /proc/rd/... entries for the
- DAC960 Driver.
- */
- static void DAC960_CreateProcEntries(void)
- {
- PROC_DirectoryEntry_T *StatusProcEntry;
- int ControllerNumber;
- DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
- StatusProcEntry = create_proc_read_entry("status", 0,
- DAC960_ProcDirectoryEntry,
- DAC960_ProcReadStatus, NULL);
- for (ControllerNumber = 0;
- ControllerNumber < DAC960_ControllerCount;
- ControllerNumber++)
- {
- DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
- PROC_DirectoryEntry_T *ControllerProcEntry;
- PROC_DirectoryEntry_T *UserCommandProcEntry;
- if (Controller == NULL) continue;
- sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
- ControllerProcEntry = proc_mkdir(Controller->ControllerName,
- DAC960_ProcDirectoryEntry);
- create_proc_read_entry("initial_status", 0, ControllerProcEntry,
- DAC960_ProcReadInitialStatus, Controller);
- create_proc_read_entry("current_status", 0, ControllerProcEntry,
- DAC960_ProcReadCurrentStatus, Controller);
- UserCommandProcEntry =
- create_proc_read_entry("user_command", S_IWUSR | S_IRUSR,
- ControllerProcEntry, DAC960_ProcReadUserCommand,
- Controller);
- UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
- Controller->ControllerProcEntry = ControllerProcEntry;
- }
- }
- /*
- DAC960_DestroyProcEntries destroys the /proc/rd/... entries for the
- DAC960 Driver.
- */
- static void DAC960_DestroyProcEntries(void)
- {
- int ControllerNumber;
- for (ControllerNumber = 0;
- ControllerNumber < DAC960_ControllerCount;
- ControllerNumber++)
- {
- DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) continue;
- remove_proc_entry("initial_status", Controller->ControllerProcEntry);
- remove_proc_entry("current_status", Controller->ControllerProcEntry);
- remove_proc_entry("user_command", Controller->ControllerProcEntry);
- remove_proc_entry(Controller->ControllerName, DAC960_ProcDirectoryEntry);
- }
- remove_proc_entry("rd/status", NULL);
- remove_proc_entry("rd", NULL);
- }
- module_init(DAC960_Initialize);
- module_exit(DAC960_Finalize);