dac960.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,755 行 · 第 1/5 页

C
1,755
字号
			     .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 =    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);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?