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

📄 buslogic.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
				true);  CCB = HostAdapter->Free_CCBs;  if (CCB == NULL) return NULL;  CCB->SerialNumber = ++SerialNumber;  HostAdapter->Free_CCBs = CCB->Next;  CCB->Next = NULL;  return CCB;}/*  BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's  free list.  The Host Adapter's Lock should already have been acquired by the  caller.*/static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB){  BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;  CCB->Command = NULL;  CCB->Status = BusLogic_CCB_Free;  CCB->Next = HostAdapter->Free_CCBs;  HostAdapter->Free_CCBs = CCB;}/*  BusLogic_Command sends the command OperationCode to HostAdapter, optionally  providing ParameterLength bytes of ParameterData and receiving at most  ReplyLength bytes of ReplyData; any excess reply data is received but  discarded.  On success, this function returns the number of reply bytes read from  the Host Adapter (including any discarded data); on failure, it returns  -1 if the command was invalid, or -2 if a timeout occurred.  BusLogic_Command is called exclusively during host adapter detection and  initialization, so performance and latency are not critical, and exclusive  access to the Host Adapter hardware is assumed.  Once the host adapter and  driver are initialized, the only Host Adapter command that is issued is the  single byte Execute Mailbox Command operation code, which does not require  waiting for the Host Adapter Ready bit to be set in the Status Register.*/static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,			    BusLogic_OperationCode_T OperationCode,			    void *ParameterData,			    int ParameterLength,			    void *ReplyData,			    int ReplyLength){  unsigned char *ParameterPointer = (unsigned char *) ParameterData;  unsigned char *ReplyPointer = (unsigned char *) ReplyData;  BusLogic_StatusRegister_T StatusRegister;  BusLogic_InterruptRegister_T InterruptRegister;  ProcessorFlags_T ProcessorFlags = 0;  int ReplyBytes = 0, Result;  long TimeoutCounter;  /*    Clear out the Reply Data if provided.  */  if (ReplyLength > 0)    memset(ReplyData, 0, ReplyLength);  /*    If the IRQ Channel has not yet been acquired, then interrupts must be    disabled while issuing host adapter commands since a Command Complete    interrupt could occur if the IRQ Channel was previously enabled by another    BusLogic Host Adapter or another driver sharing the same IRQ Channel.  */  if (!HostAdapter->IRQ_ChannelAcquired)    {      save_flags(ProcessorFlags);      cli();    }  /*    Wait for the Host Adapter Ready bit to be set and the Command/Parameter    Register Busy bit to be reset in the Status Register.  */  TimeoutCounter = 10000;  while (--TimeoutCounter >= 0)    {      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);      if (StatusRegister.Bits.HostAdapterReady &&	  !StatusRegister.Bits.CommandParameterRegisterBusy)	break;      udelay(100);    }  if (TimeoutCounter < 0)    {      BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";      Result = -2;      goto Done;    }  /*    Write the OperationCode to the Command/Parameter Register.  */  HostAdapter->HostAdapterCommandCompleted = false;  BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);  /*    Write any additional Parameter Bytes.  */  TimeoutCounter = 10000;  while (ParameterLength > 0 && --TimeoutCounter >= 0)    {      /*	Wait 100 microseconds to give the Host Adapter enough time to determine	whether the last value written to the Command/Parameter Register was	valid or not.  If the Command Complete bit is set in the Interrupt	Register, then the Command Invalid bit in the Status Register will be	reset if the Operation Code or Parameter was valid and the command	has completed, or set if the Operation Code or Parameter was invalid.	If the Data In Register Ready bit is set in the Status Register, then	the Operation Code was valid, and data is waiting to be read back	from the Host Adapter.  Otherwise, wait for the Command/Parameter	Register Busy bit in the Status Register to be reset.      */      udelay(100);      InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);      if (InterruptRegister.Bits.CommandComplete) break;      if (HostAdapter->HostAdapterCommandCompleted) break;      if (StatusRegister.Bits.DataInRegisterReady) break;      if (StatusRegister.Bits.CommandParameterRegisterBusy) continue;      BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);      ParameterLength--;    }  if (TimeoutCounter < 0)    {      BusLogic_CommandFailureReason =	"Timeout waiting for Parameter Acceptance";      Result = -2;      goto Done;    }  /*    The Modify I/O Address command does not cause a Command Complete Interrupt.  */  if (OperationCode == BusLogic_ModifyIOAddress)    {      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);      if (StatusRegister.Bits.CommandInvalid)	{	  BusLogic_CommandFailureReason = "Modify I/O Address Invalid";	  Result = -1;	  goto Done;	}      if (BusLogic_GlobalOptions.TraceConfiguration)	BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: "			"(Modify I/O Address)\n", HostAdapter,			OperationCode, StatusRegister.All);      Result = 0;      goto Done;    }  /*    Select an appropriate timeout value for awaiting command completion.  */  switch (OperationCode)    {    case BusLogic_InquireInstalledDevicesID0to7:    case BusLogic_InquireInstalledDevicesID8to15:    case BusLogic_InquireTargetDevices:      /* Approximately 60 seconds. */      TimeoutCounter = 60*10000;      break;    default:      /* Approximately 1 second. */      TimeoutCounter = 10000;      break;    }  /*    Receive any Reply Bytes, waiting for either the Command Complete bit to    be set in the Interrupt Register, or for the Interrupt Handler to set the    Host Adapter Command Completed bit in the Host Adapter structure.  */  while (--TimeoutCounter >= 0)    {      InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);      if (InterruptRegister.Bits.CommandComplete) break;      if (HostAdapter->HostAdapterCommandCompleted) break;      if (StatusRegister.Bits.DataInRegisterReady)	{	  if (++ReplyBytes <= ReplyLength)	    *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);	  else BusLogic_ReadDataInRegister(HostAdapter);	}      if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&	  StatusRegister.Bits.HostAdapterReady) break;      udelay(100);    }  if (TimeoutCounter < 0)    {      BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";      Result = -2;      goto Done;    }  /*    Clear any pending Command Complete Interrupt.  */  BusLogic_InterruptReset(HostAdapter);  /*    Provide tracing information if requested.  */  if (BusLogic_GlobalOptions.TraceConfiguration)    {      int i;      BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",		      HostAdapter, OperationCode,		      StatusRegister.All, ReplyLength, ReplyBytes);      if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;      for (i = 0; i < ReplyLength; i++)	BusLogic_Notice(" %02X", HostAdapter,			((unsigned char *) ReplyData)[i]);      BusLogic_Notice("\n", HostAdapter);    }  /*    Process Command Invalid conditions.  */  if (StatusRegister.Bits.CommandInvalid)    {      /*	Some early BusLogic Host Adapters may not recover properly from	a Command Invalid condition, so if this appears to be the case,	a Soft Reset is issued to the Host Adapter.  Potentially invalid	commands are never attempted after Mailbox Initialization is	performed, so there should be no Host Adapter state lost by a	Soft Reset in response to a Command Invalid condition.      */      udelay(1000);      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);      if (StatusRegister.Bits.CommandInvalid ||	  StatusRegister.Bits.Reserved ||	  StatusRegister.Bits.DataInRegisterReady ||	  StatusRegister.Bits.CommandParameterRegisterBusy ||	  !StatusRegister.Bits.HostAdapterReady ||	  !StatusRegister.Bits.InitializationRequired ||	  StatusRegister.Bits.DiagnosticActive ||	  StatusRegister.Bits.DiagnosticFailure)	{	  BusLogic_SoftReset(HostAdapter);	  udelay(1000);	}      BusLogic_CommandFailureReason = "Command Invalid";      Result = -1;      goto Done;    }  /*    Handle Excess Parameters Supplied conditions.  */  if (ParameterLength > 0)    {      BusLogic_CommandFailureReason = "Excess Parameters Supplied";      Result = -1;      goto Done;    }  /*    Indicate the command completed successfully.  */  BusLogic_CommandFailureReason = NULL;  Result = ReplyBytes;  /*    Restore the interrupt status if necessary and return.  */Done:  if (!HostAdapter->IRQ_ChannelAcquired)    restore_flags(ProcessorFlags);  return Result;}/*  BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list  of I/O Address and Bus Probe Information to be checked for potential BusLogic  Host Adapters.*/static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address){  BusLogic_ProbeInfo_T *ProbeInfo;  if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return;  ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];  ProbeInfo->HostAdapterType = BusLogic_MultiMaster;  ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;  ProbeInfo->IO_Address = IO_Address;}/*  BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and  Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters  only from the list of standard BusLogic MultiMaster ISA I/O Addresses.*/static void BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T						*PrototypeHostAdapter){  /*    If BusLogic Driver Options specifications requested that ISA Bus Probes    be inhibited, do not proceed further.  */  if (BusLogic_ProbeOptions.NoProbeISA) return;  /*    Append the list of standard BusLogic MultiMaster ISA I/O Addresses.  */  if (BusLogic_ProbeOptions.LimitedProbeISA      ? BusLogic_ProbeOptions.Probe330      : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)    BusLogic_AppendProbeAddressISA(0x330);  if (BusLogic_ProbeOptions.LimitedProbeISA      ? BusLogic_ProbeOptions.Probe334      : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)    BusLogic_AppendProbeAddressISA(0x334);  if (BusLogic_ProbeOptions.LimitedProbeISA      ? BusLogic_ProbeOptions.Probe230      : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)    BusLogic_AppendProbeAddressISA(0x230);  if (BusLogic_ProbeOptions.LimitedProbeISA      ? BusLogic_ProbeOptions.Probe234      : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)    BusLogic_AppendProbeAddressISA(0x234);  if (BusLogic_ProbeOptions.LimitedProbeISA      ? BusLogic_ProbeOptions.Probe130      : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)    BusLogic_AppendProbeAddressISA(0x130);  if (BusLogic_ProbeOptions.LimitedProbeISA      ? BusLogic_ProbeOptions.Probe134      : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)    BusLogic_AppendProbeAddressISA(0x134);}#ifdef CONFIG_PCI/*  BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order  of increasing PCI Bus and Device Number.*/static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList,				   int ProbeInfoCount){  int LastInterchange = ProbeInfoCount-1, Bound, j;  while (LastInterchange > 0)    {      Bound = LastInterchange;      LastInterchange = 0;      for (j = 0; j < Bound; j++)	{	  BusLogic_ProbeInfo_T *ProbeInfo1 = &ProbeInfoList[j];	  BusLogic_ProbeInfo_T *ProbeInfo2 = &ProbeInfoList[j+1];	  if (ProbeInfo1->Bus > ProbeInfo2->Bus ||	      (ProbeInfo1->Bus == ProbeInfo2->Bus &&	       (ProbeInfo1->Device > ProbeInfo2->Device)))	    {	      BusLogic_ProbeInfo_T TempProbeInfo;	      memcpy(&TempProbeInfo, ProbeInfo1, sizeof(BusLogic_ProbeInfo_T));	      memcpy(ProbeInfo1, ProbeInfo2, sizeof(BusLogic_ProbeInfo_T));	      memcpy(ProbeInfo2, &TempProbeInfo, sizeof(BusLogic_ProbeInfo_T));	      LastInterchange = j;	    }	}

⌨️ 快捷键说明

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