⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dac960.c

📁 Linux块设备驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
}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 + -