📄 dac960.c
字号:
}static void DAC960_V2_ConstructNewUnitSerialNumber( DAC960_Controller_T *Controller, DAC960_V2_CommandMailbox_T *CommandMailbox, int Channel, int TargetID, int LogicalUnit){ CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10_Passthru; CommandMailbox->SCSI_10.CommandControlBits .DataTransferControllerToHost = true; CommandMailbox->SCSI_10.CommandControlBits .NoAutoRequestSense = true; CommandMailbox->SCSI_10.DataTransferSize = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T); CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit = LogicalUnit; CommandMailbox->SCSI_10.PhysicalDevice.TargetID = TargetID; CommandMailbox->SCSI_10.PhysicalDevice.Channel = 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 = Controller->V2.NewInquiryUnitSerialNumberDMA; CommandMailbox->SCSI_10.DataTransferMemoryAddress .ScatterGatherSegments[0] .SegmentByteCount = CommandMailbox->SCSI_10.DataTransferSize;}/* DAC960_V2_NewUnitSerialNumber executes an SCSI pass-through Inquiry command to a SCSI device identified by Channel number, Target id, Logical Unit Number. This function Waits for completion of the command. The return data includes Unit Serial Number information for the specified device. Data is stored in the controller's V2.NewPhysicalDeviceInfo dma-able memory buffer.*/static boolean DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Controller, int Channel, int TargetID, int LogicalUnit){ DAC960_Command_T *Command; DAC960_V2_CommandMailbox_T *CommandMailbox; DAC960_V2_CommandStatus_T CommandStatus; Command = DAC960_AllocateCommand(Controller); CommandMailbox = &Command->V2.CommandMailbox; DAC960_V2_ClearCommand(Command); Command->CommandType = DAC960_ImmediateCommand; DAC960_V2_ConstructNewUnitSerialNumber(Controller, CommandMailbox, Channel, TargetID, LogicalUnit); 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. PD and P controller types have no memory mailbox, but still need the other dma mapped memory.*/static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T *Controller){ void __iomem *ControllerBaseAddress = Controller->BaseAddress; DAC960_HardwareType_T hw_type = Controller->HardwareType; struct pci_dev *PCI_Device = Controller->PCIDevice; struct dma_loaf *DmaPages = &Controller->DmaPages; size_t DmaPagesSize; size_t CommandMailboxesSize; size_t StatusMailboxesSize; DAC960_V1_CommandMailbox_T *CommandMailboxesMemory; dma_addr_t CommandMailboxesMemoryDMA; DAC960_V1_StatusMailbox_T *StatusMailboxesMemory; dma_addr_t StatusMailboxesMemoryDMA; DAC960_V1_CommandMailbox_T CommandMailbox; DAC960_V1_CommandStatus_T CommandStatus; int TimeoutCounter; int i; if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V1_PciDmaMask)) return DAC960_Failure(Controller, "DMA mask out of range"); Controller->BounceBufferLimit = DAC690_V1_PciDmaMask; if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) { CommandMailboxesSize = 0; StatusMailboxesSize = 0; } else { CommandMailboxesSize = DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T); StatusMailboxesSize = DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T); } DmaPagesSize = CommandMailboxesSize + StatusMailboxesSize + sizeof(DAC960_V1_DCDB_T) + sizeof(DAC960_V1_Enquiry_T) + sizeof(DAC960_V1_ErrorTable_T) + sizeof(DAC960_V1_EventLogEntry_T) + sizeof(DAC960_V1_RebuildProgress_T) + sizeof(DAC960_V1_LogicalDriveInformationArray_T) + sizeof(DAC960_V1_BackgroundInitializationStatus_T) + sizeof(DAC960_V1_DeviceState_T) + sizeof(DAC960_SCSI_Inquiry_T) + sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T); if (!init_dma_loaf(PCI_Device, DmaPages, DmaPagesSize)) return false; if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) goto skip_mailboxes; CommandMailboxesMemory = slice_dma_loaf(DmaPages, CommandMailboxesSize, &CommandMailboxesMemoryDMA); /* These are the base addresses for the command memory mailbox array */ Controller->V1.FirstCommandMailbox = CommandMailboxesMemory; Controller->V1.FirstCommandMailboxDMA = CommandMailboxesMemoryDMA; CommandMailboxesMemory += DAC960_V1_CommandMailboxCount - 1; Controller->V1.LastCommandMailbox = CommandMailboxesMemory; Controller->V1.NextCommandMailbox = Controller->V1.FirstCommandMailbox; Controller->V1.PreviousCommandMailbox1 = Controller->V1.LastCommandMailbox; Controller->V1.PreviousCommandMailbox2 = Controller->V1.LastCommandMailbox - 1; /* These are the base addresses for the status memory mailbox array */ StatusMailboxesMemory = slice_dma_loaf(DmaPages, StatusMailboxesSize, &StatusMailboxesMemoryDMA); Controller->V1.FirstStatusMailbox = StatusMailboxesMemory; Controller->V1.FirstStatusMailboxDMA = StatusMailboxesMemoryDMA; StatusMailboxesMemory += DAC960_V1_StatusMailboxCount - 1; Controller->V1.LastStatusMailbox = StatusMailboxesMemory; Controller->V1.NextStatusMailbox = Controller->V1.FirstStatusMailbox;skip_mailboxes: Controller->V1.MonitoringDCDB = slice_dma_loaf(DmaPages, sizeof(DAC960_V1_DCDB_T), &Controller->V1.MonitoringDCDB_DMA); Controller->V1.NewEnquiry = slice_dma_loaf(DmaPages, sizeof(DAC960_V1_Enquiry_T), &Controller->V1.NewEnquiryDMA); Controller->V1.NewErrorTable = slice_dma_loaf(DmaPages, sizeof(DAC960_V1_ErrorTable_T), &Controller->V1.NewErrorTableDMA); Controller->V1.EventLogEntry = slice_dma_loaf(DmaPages, sizeof(DAC960_V1_EventLogEntry_T), &Controller->V1.EventLogEntryDMA); Controller->V1.RebuildProgress = slice_dma_loaf(DmaPages, sizeof(DAC960_V1_RebuildProgress_T), &Controller->V1.RebuildProgressDMA); Controller->V1.NewLogicalDriveInformation = slice_dma_loaf(DmaPages, sizeof(DAC960_V1_LogicalDriveInformationArray_T), &Controller->V1.NewLogicalDriveInformationDMA); Controller->V1.BackgroundInitializationStatus = slice_dma_loaf(DmaPages, sizeof(DAC960_V1_BackgroundInitializationStatus_T), &Controller->V1.BackgroundInitializationStatusDMA); Controller->V1.NewDeviceState = slice_dma_loaf(DmaPages, sizeof(DAC960_V1_DeviceState_T), &Controller->V1.NewDeviceStateDMA); Controller->V1.NewInquiryStandardData = slice_dma_loaf(DmaPages, sizeof(DAC960_SCSI_Inquiry_T), &Controller->V1.NewInquiryStandardDataDMA); Controller->V1.NewInquiryUnitSerialNumber = slice_dma_loaf(DmaPages, sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), &Controller->V1.NewInquiryUnitSerialNumberDMA); if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) 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 = Controller->V1.FirstCommandMailboxDMA; CommandMailbox.TypeX.StatusMailboxesBusAddress = Controller->V1.FirstStatusMailboxDMA;#define TIMEOUT_COUNT 1000000 for (i = 0; i < 2; i++) switch (Controller->HardwareType) { case DAC960_LA_Controller: TimeoutCounter = TIMEOUT_COUNT; 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); TimeoutCounter = TIMEOUT_COUNT; 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: TimeoutCounter = TIMEOUT_COUNT; 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); TimeoutCounter = TIMEOUT_COUNT; 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: DAC960_Failure(Controller, "Unknown Controller Type\n"); break; } return false;}/* DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface for DAC960 V2 Firmware Controllers. Aggregate the space needed for the controller's memory mailbox and the other data structures that will be targets of dma transfers with the controller. Allocate a dma-mapped region of memory to hold these structures. Then, save CPU pointers and dma_addr_t values to reference the structures that are contained in that region.*/static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T *Controller){ void __iomem *ControllerBaseAddress = Controller->BaseAddress; struct pci_dev *PCI_Device = Controller->PCIDevice; struct dma_loaf *DmaPages = &Controller->DmaPages; size_t DmaPagesSize; size_t CommandMailboxesSize; size_t StatusMailboxesSize; DAC960_V2_CommandMailbox_T *CommandMailboxesMemory; dma_addr_t CommandMailboxesMemoryDMA; DAC960_V2_StatusMailbox_T *StatusMailboxesMemory; dma_addr_t StatusMailboxesMemoryDMA; DAC960_V2_CommandMailbox_T *CommandMailbox; dma_addr_t CommandMailboxDMA; DAC960_V2_CommandStatus_T CommandStatus; if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V2_PciDmaMask)) return DAC960_Failure(Controller, "DMA mask out of range"); Controller->BounceBufferLimit = DAC690_V2_PciDmaMask; /* This is a temporary dma mapping, used only in the scope of this function */ CommandMailbox = (DAC960_V2_CommandMailbox_T *)pci_alloc_consistent( PCI_Device, sizeof(DAC960_V2_CommandMailbox_T), &CommandMailboxDMA); if (CommandMailbox == NULL) return false; CommandMailboxesSize = DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T); StatusMailboxesSize = DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T); DmaPagesSize =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -