📄 dac960.c
字号:
DAC960_V2_PhysicalDeviceInfo executes a DAC960 V2 Firmware Controller Physical Device Information Reading IOCTL Command and waits for completion. It returns true on success and false on failure.*/static boolean DAC960_V2_PhysicalDeviceInfo(DAC960_Controller_T *Controller, DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode, unsigned char Channel, unsigned char TargetID, unsigned char LogicalUnit, void *DataPointer, unsigned int DataByteCount){ DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; DAC960_V2_CommandStatus_T CommandStatus; DAC960_V2_ClearCommand(Command); Command->CommandType = DAC960_ImmediateCommand; CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL; CommandMailbox->PhysicalDeviceInfo.CommandControlBits .DataTransferControllerToHost = true; CommandMailbox->PhysicalDeviceInfo.CommandControlBits .NoAutoRequestSense = true; CommandMailbox->PhysicalDeviceInfo.DataTransferSize = DataByteCount; CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit = LogicalUnit; CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID; CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel; CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode; CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress .ScatterGatherSegments[0] .SegmentDataPointer = Virtual_to_Bus(DataPointer); CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress .ScatterGatherSegments[0] .SegmentByteCount = CommandMailbox->PhysicalDeviceInfo.DataTransferSize; DAC960_ExecuteCommand(Command); CommandStatus = Command->V2.CommandStatus; DAC960_DeallocateCommand(Command); return (CommandStatus == DAC960_V2_NormalCompletion);}/* DAC960_V2_DeviceOperation executes a DAC960 V2 Firmware Controller Device Operation IOCTL Command and waits for completion. It returns true on success and false on failure.*/static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller, DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode, DAC960_V2_OperationDevice_T OperationDevice){ DAC960_Command_T *Command = DAC960_AllocateCommand(Controller); DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; DAC960_V2_CommandStatus_T CommandStatus; DAC960_V2_ClearCommand(Command); Command->CommandType = DAC960_ImmediateCommand; CommandMailbox->DeviceOperation.CommandOpcode = DAC960_V2_IOCTL; CommandMailbox->DeviceOperation.CommandControlBits .DataTransferControllerToHost = true; CommandMailbox->DeviceOperation.CommandControlBits .NoAutoRequestSense = true; CommandMailbox->DeviceOperation.IOCTL_Opcode = IOCTL_Opcode; CommandMailbox->DeviceOperation.OperationDevice = OperationDevice; DAC960_ExecuteCommand(Command); CommandStatus = Command->V2.CommandStatus; DAC960_DeallocateCommand(Command); return (CommandStatus == DAC960_V2_NormalCompletion);}/* DAC960_V1_EnableMemoryMailboxInterface enables the Memory Mailbox Interface for DAC960 V1 Firmware Controllers.*/static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T *Controller){ void *ControllerBaseAddress = Controller->BaseAddress; DAC960_V1_CommandMailbox_T *CommandMailboxesMemory; DAC960_V1_StatusMailbox_T *StatusMailboxesMemory; DAC960_V1_CommandMailbox_T CommandMailbox; DAC960_V1_CommandStatus_T CommandStatus; unsigned long MemoryMailboxPagesAddress; unsigned long MemoryMailboxPagesOrder; unsigned long MemoryMailboxPagesSize; void *SavedMemoryMailboxesAddress = NULL; short NextCommandMailboxIndex = 0; short NextStatusMailboxIndex = 0; int TimeoutCounter = 1000000, i; MemoryMailboxPagesOrder = 0; MemoryMailboxPagesSize = DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T) + DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T); while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder) MemoryMailboxPagesOrder++; if (Controller->HardwareType == DAC960_LA_Controller) DAC960_LA_RestoreMemoryMailboxInfo(Controller, &SavedMemoryMailboxesAddress, &NextCommandMailboxIndex, &NextStatusMailboxIndex); else DAC960_PG_RestoreMemoryMailboxInfo(Controller, &SavedMemoryMailboxesAddress, &NextCommandMailboxIndex, &NextStatusMailboxIndex); if (SavedMemoryMailboxesAddress == NULL) { MemoryMailboxPagesAddress = __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder); Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress; CommandMailboxesMemory = (DAC960_V1_CommandMailbox_T *) MemoryMailboxPagesAddress; } else CommandMailboxesMemory = SavedMemoryMailboxesAddress; if (CommandMailboxesMemory == NULL) return false; Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder; memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize); Controller->V1.FirstCommandMailbox = CommandMailboxesMemory; CommandMailboxesMemory += DAC960_V1_CommandMailboxCount - 1; Controller->V1.LastCommandMailbox = CommandMailboxesMemory; Controller->V1.NextCommandMailbox = &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex]; if (--NextCommandMailboxIndex < 0) NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1; Controller->V1.PreviousCommandMailbox1 = &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex]; if (--NextCommandMailboxIndex < 0) NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1; Controller->V1.PreviousCommandMailbox2 = &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex]; StatusMailboxesMemory = (DAC960_V1_StatusMailbox_T *) (CommandMailboxesMemory + 1); Controller->V1.FirstStatusMailbox = StatusMailboxesMemory; StatusMailboxesMemory += DAC960_V1_StatusMailboxCount - 1; Controller->V1.LastStatusMailbox = StatusMailboxesMemory; Controller->V1.NextStatusMailbox = &Controller->V1.FirstStatusMailbox[NextStatusMailboxIndex]; if (SavedMemoryMailboxesAddress != NULL) return true; /* Enable the Memory Mailbox Interface. */ Controller->V1.DualModeMemoryMailboxInterface = true; CommandMailbox.TypeX.CommandOpcode = 0x2B; CommandMailbox.TypeX.CommandIdentifier = 0; CommandMailbox.TypeX.CommandOpcode2 = 0x14; CommandMailbox.TypeX.CommandMailboxesBusAddress = Virtual_to_Bus(Controller->V1.FirstCommandMailbox); CommandMailbox.TypeX.StatusMailboxesBusAddress = Virtual_to_Bus(Controller->V1.FirstStatusMailbox); for (i = 0; i < 2; i++) switch (Controller->HardwareType) { case DAC960_LA_Controller: while (--TimeoutCounter >= 0) { if (!DAC960_LA_HardwareMailboxFullP(ControllerBaseAddress)) break; udelay(10); } if (TimeoutCounter < 0) return false; DAC960_LA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox); DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress); while (--TimeoutCounter >= 0) { if (DAC960_LA_HardwareMailboxStatusAvailableP( ControllerBaseAddress)) break; udelay(10); } if (TimeoutCounter < 0) return false; CommandStatus = DAC960_LA_ReadStatusRegister(ControllerBaseAddress); DAC960_LA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); DAC960_LA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); if (CommandStatus == DAC960_V1_NormalCompletion) return true; Controller->V1.DualModeMemoryMailboxInterface = false; CommandMailbox.TypeX.CommandOpcode2 = 0x10; break; case DAC960_PG_Controller: while (--TimeoutCounter >= 0) { if (!DAC960_PG_HardwareMailboxFullP(ControllerBaseAddress)) break; udelay(10); } if (TimeoutCounter < 0) return false; DAC960_PG_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox); DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress); while (--TimeoutCounter >= 0) { if (DAC960_PG_HardwareMailboxStatusAvailableP( ControllerBaseAddress)) break; udelay(10); } if (TimeoutCounter < 0) return false; CommandStatus = DAC960_PG_ReadStatusRegister(ControllerBaseAddress); DAC960_PG_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); DAC960_PG_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); if (CommandStatus == DAC960_V1_NormalCompletion) return true; Controller->V1.DualModeMemoryMailboxInterface = false; CommandMailbox.TypeX.CommandOpcode2 = 0x10; break; default: break; } return false;}/* DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface for DAC960 V2 Firmware Controllers.*/static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T *Controller){ void *ControllerBaseAddress = Controller->BaseAddress; DAC960_V2_CommandMailbox_T *CommandMailboxesMemory; DAC960_V2_StatusMailbox_T *StatusMailboxesMemory; DAC960_V2_CommandMailbox_T CommandMailbox; DAC960_V2_CommandStatus_T CommandStatus = 0; unsigned long MemoryMailboxPagesAddress; unsigned long MemoryMailboxPagesOrder; unsigned long MemoryMailboxPagesSize; MemoryMailboxPagesOrder = 0; MemoryMailboxPagesSize = DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T) + DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T) + sizeof(DAC960_V2_HealthStatusBuffer_T); while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder) MemoryMailboxPagesOrder++; MemoryMailboxPagesAddress = __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder); Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress; CommandMailboxesMemory = (DAC960_V2_CommandMailbox_T *) MemoryMailboxPagesAddress; if (CommandMailboxesMemory == NULL) return false; Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder; memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize); Controller->V2.FirstCommandMailbox = CommandMailboxesMemory; CommandMailboxesMemory += DAC960_V2_CommandMailboxCount - 1; Controller->V2.LastCommandMailbox = CommandMailboxesMemory; Controller->V2.NextCommandMailbox = Controller->V2.FirstCommandMailbox; Controller->V2.PreviousCommandMailbox1 = Controller->V2.LastCommandMailbox; Controller->V2.PreviousCommandMailbox2 = Controller->V2.LastCommandMailbox - 1; StatusMailboxesMemory = (DAC960_V2_StatusMailbox_T *) (CommandMailboxesMemory + 1); Controller->V2.FirstStatusMailbox = StatusMailboxesMemory; StatusMailboxesMemory += DAC960_V2_StatusMailboxCount - 1; Controller->V2.LastStatusMailbox = StatusMailboxesMemory; Controller->V2.NextStatusMailbox = Controller->V2.FirstStatusMailbox; Controller->V2.HealthStatusBuffer = (DAC960_V2_HealthStatusBuffer_T *) (StatusMailboxesMemory + 1); /* Enable the Memory Mailbox Interface. */ memset(&CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T)); CommandMailbox.SetMemoryMailbox.CommandIdentifier = 1; CommandMailbox.SetMemoryMailbox.CommandOpcode = DAC960_V2_IOCTL; CommandMailbox.SetMemoryMailbox.CommandControlBits.NoAutoRequestSense = true; CommandMailbox.SetMemoryMailbox.FirstCommandMailboxSizeKB = (DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T)) >> 10; CommandMailbox.SetMemoryMailbox.FirstStatusMailboxSizeKB = (DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T)) >> 10; CommandMailbox.SetMemoryMailbox.SecondCommandMailboxSizeKB = 0; CommandMailbox.SetMemoryMailbox.SecondStatusMailboxSizeKB = 0; CommandMailbox.SetMemoryMailbox.RequestSenseSize = 0; CommandMailbox.SetMemoryMailbox.IOCTL_Opcode = DAC960_V2_SetMemoryMailbox; CommandMailbox.SetMemoryMailbox.HealthStatusBufferSizeKB = 1; CommandMailbox.SetMemoryMailbox.HealthStatusBufferBusAddress = Virtual_to_Bus(Controller->V2.HealthStatusBuffer); CommandMailbox.SetMemoryMailbox.FirstCommandMailboxBusAddress = Virtual_to_Bus(Controller->V2.FirstCommandMailbox); CommandMailbox.SetMemoryMailbox.FirstStatusMailboxBusAddress = Virtual_to_Bus(Controller->V2.FirstStatusMailbox); switch (Controller->HardwareType) { case DAC960_BA_Controller: while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress)) udelay(1); DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox); DAC960_BA_HardwareMailboxNewCommand(ControllerBaseAddress); while (!DAC960_BA_HardwareMailboxStatusAvailableP(ControllerBaseAddress)) udelay(1); CommandStatus = DAC960_BA_ReadCommandStatus(ControllerBaseAddress); DAC960_BA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); DAC960_BA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); break; case DAC960_LP_Controller: while (DAC960_LP_HardwareMailboxFullP(ControllerBaseAddress)) udelay(1); DAC960_LP_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox); DAC960_LP_HardwareMailboxNewCommand(ControllerBaseAddress); while (!DAC960_LP_HardwareMailboxStatusAvailableP(ControllerBaseAddress)) udelay(1); CommandStatus = DAC960_LP_ReadCommandStatus(ControllerBaseAddress); DAC960_LP_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); DAC960_LP_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); break; default: break; } return (CommandStatus == DAC960_V2_NormalCompletion);}/* DAC960_V1_ReadControllerConfiguration reads the Configuration Information from DAC960 V1 Firmware Controllers and initializes the Controller structure.*/static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T *Controller){ DAC960_V1_Enquiry2_T Enquiry2; DAC960_V1_Config2_T Config2; int LogicalDriveNumber, Channel, TargetID; if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry, &Controller->V1.Enquiry)) return DAC960_Failure(Controller, "ENQUIRY"); if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, &Enquiry2)) return DAC960_Failure(Controller, "ENQUIRY2"); if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, &Config2)) return DAC960_Failure(Controller, "READ CONFIG2"); if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_GetLogicalDriveInformation, &Controller->V1.LogicalDriveInformation)) return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION"); for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++) for (TargetID = 0; TargetID < Enquiry2.MaxTargets; TargetID++) if (!DAC960_V1_ExecuteType3D(Controller, DAC960_V1_GetDeviceState, Channel, TargetID, &Controller->V1.DeviceState [Channel][TargetID]))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -