atapi.c

来自「一个类似windows」· C语言 代码 · 共 2,047 行 · 第 1/5 页

C
2,047
字号

  /* Search the ISA bus for ide controllers */
#ifdef ENABLE_ISA
  InitData.HwFindAdapter = AtapiFindIsaBusController;
  InitData.NumberOfAccessRanges = 2;
  InitData.AdapterInterfaceType = Isa;

  InitData.VendorId = NULL;
  InitData.VendorIdLength = 0;
  InitData.DeviceId = NULL;
  InitData.DeviceIdLength = 0;

  Status = ScsiPortInitialize(DriverObject,
			      RegistryPath,
			      &InitData,
			      NULL);
//      if (newStatus < statusToReturn)
//        statusToReturn = newStatus;
#endif

  DPRINT("Returning from DriverEntry\n");

  return(Status);
}


BOOLEAN
AtapiClaimHwResources(PATAPI_MINIPORT_EXTENSION DevExt,
		      PPORT_CONFIGURATION_INFORMATION ConfigInfo,
		      INTERFACE_TYPE InterfaceType,
		      ULONG CommandPortBase,
		      ULONG ControlPortBase,
		      ULONG BusMasterPortBase,
		      ULONG InterruptVector)
{
   SCSI_PHYSICAL_ADDRESS IoAddress;
   PVOID IoBase;
#ifdef ENABLE_DMA
   ULONG Length;
#endif
   IoAddress = ScsiPortConvertUlongToPhysicalAddress(CommandPortBase);
   IoBase = ScsiPortGetDeviceBase((PVOID)DevExt,
                                  InterfaceType,
				  ConfigInfo->SystemIoBusNumber,
				  IoAddress,
				  8,
				  TRUE);
   if (IoBase == NULL)
   {
      return FALSE;
   }
   DevExt->Handler = NULL;
   DevExt->CommandPortBase = (ULONG)IoBase;
   (*ConfigInfo->AccessRanges)[0].RangeStart = IoAddress;
   (*ConfigInfo->AccessRanges)[0].RangeLength = 8;
   (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;

   if (ControlPortBase)
   {
      IoAddress = ScsiPortConvertUlongToPhysicalAddress(ControlPortBase + 2);
      IoBase = ScsiPortGetDeviceBase((PVOID)DevExt,
                                     InterfaceType,
				     ConfigInfo->SystemIoBusNumber,
				     IoAddress,
				     1,
				     TRUE);
      if (IoBase == NULL)
      {
         ScsiPortFreeDeviceBase((PVOID)DevExt,
	                        (PVOID)DevExt->CommandPortBase);
         return FALSE;
      }
      DevExt->ControlPortBase = (ULONG)IoBase;
      (*ConfigInfo->AccessRanges)[1].RangeStart = IoAddress;
      (*ConfigInfo->AccessRanges)[1].RangeLength = 1;
      (*ConfigInfo->AccessRanges)[1].RangeInMemory = FALSE;
   }
   if (BusMasterPortBase)
   {
      IoAddress = ScsiPortConvertUlongToPhysicalAddress(BusMasterPortBase);
      IoBase = ScsiPortGetDeviceBase((PVOID)DevExt,
                                     InterfaceType,
				     ConfigInfo->SystemIoBusNumber,
				     IoAddress,
				     8,
				     TRUE);
      if (IoBase == NULL)
      {
         ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->CommandPortBase);
         ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->ControlPortBase);
         return FALSE;
      }
      DevExt->BusMasterRegisterBase = (ULONG)IoBase;
      (*ConfigInfo->AccessRanges)[2].RangeStart = IoAddress;
      (*ConfigInfo->AccessRanges)[2].RangeLength = 8;
      (*ConfigInfo->AccessRanges)[2].RangeInMemory = FALSE;
#ifdef ENABLE_DMA
//      ConfigInfo->DmaChannel = SP_UNINITIALIZED_VALUE;
//      ConfigInfo->DmaPort = SP_UNINITIALIZED_VALUE;
      ConfigInfo->DmaWidth = Width32Bits;
//      ConfigInfo->DmaSpeed = Compatible;
      ConfigInfo->ScatterGather = TRUE;
      ConfigInfo->Master = TRUE;
      ConfigInfo->NumberOfPhysicalBreaks = 0x10000 / PAGE_SIZE + 1;
      ConfigInfo->Dma32BitAddresses = TRUE;
      ConfigInfo->NeedPhysicalAddresses = TRUE;
      ConfigInfo->MapBuffers = TRUE;

      DevExt->PRDMaxCount = PAGE_SIZE / sizeof(PRD);
      DevExt->PRDTable = ScsiPortGetUncachedExtension(DevExt, ConfigInfo, sizeof(PRD) * DevExt->PRDMaxCount);
      if (DevExt->PRDTable != NULL)
        {
	  DevExt->PRDTablePhysicalAddress = ScsiPortGetPhysicalAddress(DevExt, NULL, DevExt->PRDTable, &Length);
	}
      if (DevExt->PRDTable == NULL ||
	  DevExt->PRDTablePhysicalAddress.QuadPart == 0LL ||
	  Length < sizeof(PRD) * DevExt->PRDMaxCount)
      {
         ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->CommandPortBase);
         ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->ControlPortBase);
         ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->BusMasterRegisterBase);
	 return FALSE;
      }
#endif
   }
   ConfigInfo->BusInterruptLevel = InterruptVector;
   ConfigInfo->BusInterruptVector = InterruptVector;
   ConfigInfo->InterruptMode = (InterfaceType == Isa) ? Latched : LevelSensitive;

   if ((CommandPortBase == 0x1F0 || ControlPortBase == 0x3F4) && !ConfigInfo->AtdiskPrimaryClaimed)
   {
      ConfigInfo->AtdiskPrimaryClaimed = TRUE;
   }
   if ((CommandPortBase == 0x170 || ControlPortBase == 0x374) && !ConfigInfo->AtdiskSecondaryClaimed)
   {
      ConfigInfo->AtdiskSecondaryClaimed = TRUE;
   }
   return TRUE;
}


#ifdef ENABLE_PCI
static ULONG STDCALL
AtapiFindCompatiblePciController(PVOID DeviceExtension,
				 PVOID HwContext,
				 PVOID BusInformation,
				 PCHAR ArgumentString,
				 PPORT_CONFIGURATION_INFORMATION ConfigInfo,
				 PBOOLEAN Again)
{
  PATAPI_MINIPORT_EXTENSION DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension;
  PCI_SLOT_NUMBER SlotNumber;
  PCI_COMMON_CONFIG PciConfig;
  ULONG DataSize;
  ULONG StartDeviceNumber;
  ULONG DeviceNumber;
  ULONG StartFunctionNumber;
  ULONG FunctionNumber;
  BOOLEAN ChannelFound;
  BOOLEAN DeviceFound;
  ULONG BusMasterBasePort = 0;

  DPRINT("AtapiFindCompatiblePciController() Bus: %lu  Slot: %lu\n",
	  ConfigInfo->SystemIoBusNumber,
	  ConfigInfo->SlotNumber);

  *Again = FALSE;

  /* both channels were claimed: exit */
  if (ConfigInfo->AtdiskPrimaryClaimed == TRUE &&
      ConfigInfo->AtdiskSecondaryClaimed == TRUE)
    return(SP_RETURN_NOT_FOUND);

  SlotNumber.u.AsULONG = ConfigInfo->SlotNumber;
  StartDeviceNumber = SlotNumber.u.bits.DeviceNumber;
  StartFunctionNumber = SlotNumber.u.bits.FunctionNumber;
  for (DeviceNumber = StartDeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
  {
     SlotNumber.u.bits.DeviceNumber = DeviceNumber;
     for (FunctionNumber = StartFunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
     {
	SlotNumber.u.bits.FunctionNumber = FunctionNumber;
	ChannelFound = FALSE;
	DeviceFound = FALSE;

        DataSize = ScsiPortGetBusData(DeviceExtension,
				      PCIConfiguration,
				      ConfigInfo->SystemIoBusNumber,
				      SlotNumber.u.AsULONG,
				      &PciConfig,
				      PCI_COMMON_HDR_LENGTH);
        if (DataSize != PCI_COMMON_HDR_LENGTH)
	{
	   if (FunctionNumber == 0)
	   {
	      break;
	   }
	   else
	   {
	      continue;
	   }
	}

	DPRINT("%x %x\n", PciConfig.BaseClass, PciConfig.SubClass);
	if (PciConfig.BaseClass == 0x01 &&
	    PciConfig.SubClass == 0x01) // &&
//	    (PciConfig.ProgIf & 0x05) == 0)
	{
	   /* both channels are in compatibility mode */
	   DPRINT("Bus %1lu  Device %2lu  Func %1lu  VenID 0x%04hx  DevID 0x%04hx\n",
		  ConfigInfo->SystemIoBusNumber,
		  SlotNumber.u.bits.DeviceNumber,
		  SlotNumber.u.bits.FunctionNumber,
		  PciConfig.VendorID,
		  PciConfig.DeviceID);
	   DPRINT("ProgIF 0x%02hx\n", PciConfig.ProgIf);

	   DPRINT("Found IDE controller in compatibility mode!\n");

	   ConfigInfo->NumberOfBuses = 1;
	   ConfigInfo->MaximumNumberOfTargets = 2;
	   ConfigInfo->MaximumTransferLength = 0x10000; /* max 64Kbyte */

	   if (PciConfig.ProgIf & 0x80)
	   {
	      DPRINT("Found IDE Bus Master controller!\n");
	      if (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE)
	      {
		  BusMasterBasePort = PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_ADDRESS_MASK;
		  DPRINT("  IDE Bus Master Registers at IO %lx\n", BusMasterBasePort);
	      }
	   }
	   if (ConfigInfo->AtdiskPrimaryClaimed == FALSE)
	   {
	      /* Both channels unclaimed: Claim primary channel */
	      DPRINT("Primary channel!\n");
              ChannelFound = AtapiClaimHwResources(DevExt,
		                                   ConfigInfo,
		                                   PCIBus,
		                                   0x1F0,
			                           0x3F4,
			                           BusMasterBasePort,
			                           14);
              *Again = TRUE;
	   }
	   else if (ConfigInfo->AtdiskSecondaryClaimed == FALSE)
	   {
	      /* Primary channel already claimed: claim secondary channel */
	      DPRINT("Secondary channel!\n");

              ChannelFound = AtapiClaimHwResources(DevExt,
		                                   ConfigInfo,
		                                   PCIBus,
		                                   0x170,
			                           0x374,
						   BusMasterBasePort ? BusMasterBasePort + 8 : 0,
			                           15);
	      *Again = FALSE;
	   }
	   /* Find attached devices */
	   if (ChannelFound)
	   {
	      DeviceFound = AtapiFindDevices(DevExt, ConfigInfo);
	      ConfigInfo->SlotNumber = SlotNumber.u.AsULONG;
	      DPRINT("AtapiFindCompatiblePciController() returns: SP_RETURN_FOUND\n");
	      return(SP_RETURN_FOUND);
	   }
	}
	if (FunctionNumber == 0 && !(PciConfig.HeaderType & PCI_MULTIFUNCTION))
	{
	   break;
	}
     }
     StartFunctionNumber = 0;
  }
  DPRINT("AtapiFindCompatiblePciController() returns: SP_RETURN_NOT_FOUND\n");

  return(SP_RETURN_NOT_FOUND);
}
#endif


#ifdef ENABLE_ISA
static ULONG STDCALL
AtapiFindIsaBusController(PVOID DeviceExtension,
			  PVOID HwContext,
			  PVOID BusInformation,
			  PCHAR ArgumentString,
			  PPORT_CONFIGURATION_INFORMATION ConfigInfo,
			  PBOOLEAN Again)
{
  PATAPI_MINIPORT_EXTENSION DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension;
  BOOLEAN ChannelFound = FALSE;
  BOOLEAN DeviceFound = FALSE;

  DPRINT("AtapiFindIsaBusController() called!\n");

  *Again = FALSE;

  ConfigInfo->NumberOfBuses = 1;
  ConfigInfo->MaximumNumberOfTargets = 2;
  ConfigInfo->MaximumTransferLength = 0x10000; /* max 64Kbyte */

  if (ConfigInfo->AtdiskPrimaryClaimed == FALSE)
    {
      /* Both channels unclaimed: Claim primary channel */
      DPRINT("Primary channel!\n");

      ChannelFound = AtapiClaimHwResources(DevExt,
		                           ConfigInfo,
		                           Isa,
		                           0x1F0,
			                   0x3F4,
			                   0,
			                   14);
      *Again = TRUE;
    }
  else if (ConfigInfo->AtdiskSecondaryClaimed == FALSE)
    {
      /* Primary channel already claimed: claim secondary channel */
      DPRINT("Secondary channel!\n");

      ChannelFound = AtapiClaimHwResources(DevExt,
		                           ConfigInfo,
		                           Isa,
		                           0x170,
			                   0x374,
			                   0,
			                   15);
      *Again = FALSE;
    }
  else
    {
      DPRINT("AtapiFindIsaBusController() both channels claimed. Returns: SP_RETURN_NOT_FOUND\n");
      *Again = FALSE;
      return(SP_RETURN_NOT_FOUND);
    }

  /* Find attached devices */
  if (ChannelFound)
    {
      DeviceFound = AtapiFindDevices(DevExt,
				     ConfigInfo);
      DPRINT("AtapiFindIsaBusController() returns: SP_RETURN_FOUND\n");
      return(SP_RETURN_FOUND);
    }
  *Again = FALSE;
  return SP_RETURN_NOT_FOUND;
}
#endif


#ifdef ENABLE_NATIVE_PCI
static ULONG STDCALL
AtapiFindNativePciController(PVOID DeviceExtension,
			     PVOID HwContext,
			     PVOID BusInformation,
			     PCHAR ArgumentString,
			     PPORT_CONFIGURATION_INFORMATION ConfigInfo,
			     PBOOLEAN Again)
{
  PATAPI_MINIPORT_EXTENSION DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension;
  PCI_COMMON_CONFIG PciConfig;
  PCI_SLOT_NUMBER SlotNumber;
  ULONG DataSize;
  ULONG DeviceNumber;
  ULONG StartDeviceNumber;
  ULONG FunctionNumber;
  ULONG StartFunctionNumber;
  ULONG BusMasterBasePort;
  ULONG Count;
  BOOLEAN ChannelFound;

  DPRINT("AtapiFindNativePciController() called!\n");

  SlotNumber.u.AsULONG = ConfigInfo->SlotNumber;
  StartDeviceNumber = SlotNumber.u.bits.DeviceNumber;
  StartFunctionNumber = SlotNumber.u.bits.FunctionNumber;
  for (DeviceNumber = StartDeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
  {
     SlotNumber.u.bits.DeviceNumber = DeviceNumber;
     for (FunctionNumber = StartFunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
     {
	SlotNumber.u.bits.FunctionNumber = FunctionNumber;
	DataSize = ScsiPortGetBusData(DeviceExtension,
				      PCIConfiguration,
				      ConfigInfo->SystemIoBusNumber,
				      SlotNumber.u.AsULONG,
				      &PciConfig,
				      PCI_COMMON_HDR_LENGTH);
	if (DataSize != PCI_COMMON_HDR_LENGTH)
	{
	   break;
	}
	for (Count = 0; Count < sizeof(PciNativeController)/sizeof(PCI_NATIVE_CONTROLLER); Count++)
	{
	   if (PciConfig.VendorID == PciNativeController[Count].VendorID &&
	       PciConfig.DeviceID == PciNativeController[Count].DeviceID)
	   {
	      break;
	   }
	}
	if (Count < sizeof(PciNativeController)/sizeof(PCI_NATIVE_CONTROLLER))
	{
	   /* We have found a known native pci ide controller */
	   if ((PciConfig.ProgIf & 0x80) && (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE))
	   {
	      DPRINT("Found IDE Bus Master controller!\n");
	      BusMasterBasePort = PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_ADDRESS_MASK;
	      DPRINT("  IDE Bus Master Registers at IO %lx\n", BusMasterBasePort);

⌨️ 快捷键说明

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