📄 dac960.c
字号:
CommandMailboxesSize + StatusMailboxesSize + sizeof(DAC960_V2_HealthStatusBuffer_T) + sizeof(DAC960_V2_ControllerInfo_T) + sizeof(DAC960_V2_LogicalDeviceInfo_T) + sizeof(DAC960_V2_PhysicalDeviceInfo_T) + sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T) + sizeof(DAC960_V2_Event_T) + sizeof(DAC960_V2_PhysicalToLogicalDevice_T); if (!init_dma_loaf(PCI_Device, DmaPages, DmaPagesSize)) { pci_free_consistent(PCI_Device, sizeof(DAC960_V2_CommandMailbox_T), CommandMailbox, CommandMailboxDMA); return false; } CommandMailboxesMemory = slice_dma_loaf(DmaPages, CommandMailboxesSize, &CommandMailboxesMemoryDMA); /* These are the base addresses for the command memory mailbox array */ Controller->V2.FirstCommandMailbox = CommandMailboxesMemory; Controller->V2.FirstCommandMailboxDMA = CommandMailboxesMemoryDMA; 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; /* These are the base addresses for the status memory mailbox array */ StatusMailboxesMemory = slice_dma_loaf(DmaPages, StatusMailboxesSize, &StatusMailboxesMemoryDMA); Controller->V2.FirstStatusMailbox = StatusMailboxesMemory; Controller->V2.FirstStatusMailboxDMA = StatusMailboxesMemoryDMA; StatusMailboxesMemory += DAC960_V2_StatusMailboxCount - 1; Controller->V2.LastStatusMailbox = StatusMailboxesMemory; Controller->V2.NextStatusMailbox = Controller->V2.FirstStatusMailbox; Controller->V2.HealthStatusBuffer = slice_dma_loaf(DmaPages, sizeof(DAC960_V2_HealthStatusBuffer_T), &Controller->V2.HealthStatusBufferDMA); Controller->V2.NewControllerInformation = slice_dma_loaf(DmaPages, sizeof(DAC960_V2_ControllerInfo_T), &Controller->V2.NewControllerInformationDMA); Controller->V2.NewLogicalDeviceInformation = slice_dma_loaf(DmaPages, sizeof(DAC960_V2_LogicalDeviceInfo_T), &Controller->V2.NewLogicalDeviceInformationDMA); Controller->V2.NewPhysicalDeviceInformation = slice_dma_loaf(DmaPages, sizeof(DAC960_V2_PhysicalDeviceInfo_T), &Controller->V2.NewPhysicalDeviceInformationDMA); Controller->V2.NewInquiryUnitSerialNumber = slice_dma_loaf(DmaPages, sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), &Controller->V2.NewInquiryUnitSerialNumberDMA); Controller->V2.Event = slice_dma_loaf(DmaPages, sizeof(DAC960_V2_Event_T), &Controller->V2.EventDMA); Controller->V2.PhysicalToLogicalDevice = slice_dma_loaf(DmaPages, sizeof(DAC960_V2_PhysicalToLogicalDevice_T), &Controller->V2.PhysicalToLogicalDeviceDMA); /* Enable the Memory Mailbox Interface. I don't know why we can't just use one of the memory mailboxes we just allocated to do this, instead of using this temporary one. Try this change later. */ 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 = Controller->V2.HealthStatusBufferDMA; CommandMailbox->SetMemoryMailbox.FirstCommandMailboxBusAddress = Controller->V2.FirstCommandMailboxDMA; CommandMailbox->SetMemoryMailbox.FirstStatusMailboxBusAddress = Controller->V2.FirstStatusMailboxDMA; switch (Controller->HardwareType) { case DAC960_GEM_Controller: while (DAC960_GEM_HardwareMailboxFullP(ControllerBaseAddress)) udelay(1); DAC960_GEM_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA); DAC960_GEM_HardwareMailboxNewCommand(ControllerBaseAddress); while (!DAC960_GEM_HardwareMailboxStatusAvailableP(ControllerBaseAddress)) udelay(1); CommandStatus = DAC960_GEM_ReadCommandStatus(ControllerBaseAddress); DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); DAC960_GEM_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); break; case DAC960_BA_Controller: while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress)) udelay(1); DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA); 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, CommandMailboxDMA); 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: DAC960_Failure(Controller, "Unknown Controller Type\n"); CommandStatus = DAC960_V2_AbormalCompletion; break; } pci_free_consistent(PCI_Device, sizeof(DAC960_V2_CommandMailbox_T), CommandMailbox, CommandMailboxDMA); 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; dma_addr_t Enquiry2DMA; DAC960_V1_Config2_T *Config2; dma_addr_t Config2DMA; int LogicalDriveNumber, Channel, TargetID; struct dma_loaf local_dma; if (!init_dma_loaf(Controller->PCIDevice, &local_dma, sizeof(DAC960_V1_Enquiry2_T) + sizeof(DAC960_V1_Config2_T))) return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION"); Enquiry2 = slice_dma_loaf(&local_dma, sizeof(DAC960_V1_Enquiry2_T), &Enquiry2DMA); Config2 = slice_dma_loaf(&local_dma, sizeof(DAC960_V1_Config2_T), &Config2DMA); if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry, Controller->V1.NewEnquiryDMA)) { free_dma_loaf(Controller->PCIDevice, &local_dma); return DAC960_Failure(Controller, "ENQUIRY"); } memcpy(&Controller->V1.Enquiry, Controller->V1.NewEnquiry, sizeof(DAC960_V1_Enquiry_T)); if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, Enquiry2DMA)) { free_dma_loaf(Controller->PCIDevice, &local_dma); return DAC960_Failure(Controller, "ENQUIRY2"); } if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, Config2DMA)) { free_dma_loaf(Controller->PCIDevice, &local_dma); return DAC960_Failure(Controller, "READ CONFIG2"); } if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_GetLogicalDriveInformation, Controller->V1.NewLogicalDriveInformationDMA)) { free_dma_loaf(Controller->PCIDevice, &local_dma); return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION"); } memcpy(&Controller->V1.LogicalDriveInformation, Controller->V1.NewLogicalDriveInformation, sizeof(DAC960_V1_LogicalDriveInformationArray_T)); 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.NewDeviceStateDMA)) { free_dma_loaf(Controller->PCIDevice, &local_dma); return DAC960_Failure(Controller, "GET DEVICE STATE"); } memcpy(&Controller->V1.DeviceState[Channel][TargetID], Controller->V1.NewDeviceState, sizeof(DAC960_V1_DeviceState_T)); } /* Initialize the Controller Model Name and Full Model Name fields. */ switch (Enquiry2->HardwareID.SubModel) { case DAC960_V1_P_PD_PU: if (Enquiry2->SCSICapability.BusSpeed == DAC960_V1_Ultra) strcpy(Controller->ModelName, "DAC960PU"); else strcpy(Controller->ModelName, "DAC960PD"); break; case DAC960_V1_PL: strcpy(Controller->ModelName, "DAC960PL"); break; case DAC960_V1_PG: strcpy(Controller->ModelName, "DAC960PG"); break; case DAC960_V1_PJ: strcpy(Controller->ModelName, "DAC960PJ"); break; case DAC960_V1_PR: strcpy(Controller->ModelName, "DAC960PR"); break; case DAC960_V1_PT: strcpy(Controller->ModelName, "DAC960PT"); break; case DAC960_V1_PTL0: strcpy(Controller->ModelName, "DAC960PTL0"); break; case DAC960_V1_PRL: strcpy(Controller->ModelName, "DAC960PRL"); break; case DAC960_V1_PTL1: strcpy(Controller->ModelName, "DAC960PTL1"); break; case DAC960_V1_1164P: strcpy(Controller->ModelName, "DAC1164P"); break; default: free_dma_loaf(Controller->PCIDevice, &local_dma); return DAC960_Failure(Controller, "MODEL VERIFICATION"); } strcpy(Controller->FullModelName, "Mylex "); strcat(Controller->FullModelName, Controller->ModelName); /* Initialize the Controller Firmware Version field and verify that it is a supported firmware version. The supported firmware versions are: DAC1164P 5.06 and above DAC960PTL/PRL/PJ/PG 4.06 and above DAC960PU/PD/PL 3.51 and above DAC960PU/PD/PL/P 2.73 and above */#if defined(CONFIG_ALPHA) /* DEC Alpha machines were often equipped with DAC960 cards that were OEMed from Mylex, and had their own custom firmware. Version 2.70, the last custom FW revision to be released by DEC for these older controllers, appears to work quite well with this driver. Cards tested successfully were several versions each of the PD and PU, called by DEC the KZPSC and KZPAC, respectively, and having the Manufacturer Numbers (from Mylex), usually on a sticker on the back of the board, of: KZPSC: D040347 (1-channel) or D040348 (2-channel) or D040349 (3-channel) KZPAC: D040395 (1-channel) or D040396 (2-channel) or D040397 (3-channel) */# define FIRMWARE_27X "2.70"#else# define FIRMWARE_27X "2.73"#endif if (Enquiry2->FirmwareID.MajorVersion == 0) { Enquiry2->FirmwareID.MajorVersion = Controller->V1.Enquiry.MajorFirmwareVersion; Enquiry2->FirmwareID.MinorVersion = Controller->V1.Enquiry.MinorFirmwareVersion; Enquiry2->FirmwareID.FirmwareType = '0'; Enquiry2->FirmwareID.TurnID = 0; } sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d", Enquiry2->FirmwareID.MajorVersion, Enquiry2->FirmwareID.MinorVersion, Enquiry2->FirmwareID.FirmwareType, Enquiry2->FirmwareID.TurnID); if (!((Controller->FirmwareVersion[0] == '5' && strcmp(Controller->FirmwareVersion, "5.06") >= 0) || (Controller->FirmwareVersion[0] == '4' && strcmp(Controller->FirmwareVersion, "4.06") >= 0) || (Controller->FirmwareVersion[0] == '3' && strcmp(Controller->FirmwareVersion, "3.51") >= 0) || (Controller->FirmwareVersion[0] == '2' && strcmp(Controller->FirmwareVersion, FIRMWARE_27X) >= 0))) { DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION"); DAC960_Error("Firmware Version = '%s'\n", Controller, Controller->FirmwareVersion); free_dma_loaf(Controller->PCIDevice, &local_dma); return false; } /* Initialize the Controller Channels, Targets, Memory Size, and SAF-TE Enclosure Management Enabled fields. */ Controller->Channels = Enquiry2->ActualChannels; Controller->Targets = Enquiry2->MaxTargets; Controller->MemorySize = Enquiry2->MemorySize >> 20; Controller->V1.SAFTE_EnclosureManagementEnabled = (Enquiry2->FaultManagementType == DAC960_V1_SAFTE); /* Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and Driver Scatter/Gather Limit. The Driver Queue Depth must be at most one less than the Controller Queue Depth to allow for an automatic drive rebuild operation. */ Controller->ControllerQueueDepth = Controller->V1.Enquiry.MaxCommands; Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1; if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth) Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth; Controller->LogicalDriveCount = Controller->V1.Enquiry.NumberOfLogicalDrives; Controller->MaxBlocksPerCommand = Enquiry2->MaxBlocksPerCommand; Controller->ControllerScatterGatherLimit = Enquiry2->MaxScatterGatherEntries; Controller->DriverScatterGatherLimit = Controller->ControllerScatterGatherLimit; if (Controller->DriverScatterGatherLimit > DAC960_V1_ScatterGatherLimit) Controller->DriverScatterGatherLimit = DAC960_V1_ScatterGatherLimit; /* Initialize the Stripe Size, Segment Size, and Geometry Translation. */ Controller->V1.StripeSize = Config2->BlocksPerStripe * Config2->BlockFactor >> (10 - DAC960_BlockSizeBits); Controller->V1.SegmentSize = Config2->BlocksPerCacheLine * Config2->BlockFactor >> (10 - DAC960_BlockSizeBits); switch (Config2->DriveGeometry) { case DAC960_V1_Geometry_128_32: Controller->V1.GeometryTranslationHeads = 128; Controller->V1.GeometryTranslationSectors = 32; break; case DAC960_V1_Geometry_255_63: Controller->V1.GeometryTranslationHeads = 255; Controller->V1.GeometryTranslationSectors = 63; break; default: free_dma_loaf(Controller->PCIDevice, &local_dma); return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -