2 * PROJECT: ReactOS Boot Loader (FreeLDR)
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: boot/freeldr/freeldr/disk/scsiport.c
5 * PURPOSE: Interface for SCSI Emulation
6 * PROGRAMMERS: Hervé Poussineau <hpoussin@reactos.org>
9 /* INCLUDES *******************************************************************/
24 #undef ScsiPortLogError
25 #undef ScsiPortMoveMemory
26 #undef ScsiPortWritePortBufferUchar
27 #undef ScsiPortWritePortBufferUlong
28 #undef ScsiPortWritePortBufferUshort
29 #undef ScsiPortWritePortUchar
30 #undef ScsiPortWritePortUlong
31 #undef ScsiPortWritePortUshort
32 #undef ScsiPortWriteRegisterBufferUchar
33 #undef ScsiPortWriteRegisterBufferUlong
34 #undef ScsiPortWriteRegisterBufferUshort
35 #undef ScsiPortWriteRegisterUchar
36 #undef ScsiPortWriteRegisterUlong
37 #undef ScsiPortWriteRegisterUshort
38 #undef ScsiPortReadPortBufferUchar
39 #undef ScsiPortReadPortBufferUlong
40 #undef ScsiPortReadPortBufferUshort
41 #undef ScsiPortReadPortUchar
42 #undef ScsiPortReadPortUlong
43 #undef ScsiPortReadPortUshort
44 #undef ScsiPortReadRegisterBufferUchar
45 #undef ScsiPortReadRegisterBufferUlong
46 #undef ScsiPortReadRegisterBufferUshort
47 #undef ScsiPortReadRegisterUchar
48 #undef ScsiPortReadRegisterUlong
49 #undef ScsiPortReadRegisterUshort
53 #define SCSI_PORT_NEXT_REQUEST_READY 0x0008
55 #define TAG_SCSI_DEVEXT 'DscS'
56 #define TAG_SCSI_ACCESS_RANGES 'AscS'
58 DBG_DEFAULT_CHANNEL(SCSIPORT
);
60 /* GLOBALS ********************************************************************/
63 VOID NTAPI
HalpInitializePciStubs(VOID
);
64 VOID NTAPI
HalpInitBusHandler(VOID
);
69 PVOID NonCachedExtension
;
76 /* SRB extension stuff */
77 ULONG SrbExtensionSize
;
78 PVOID SrbExtensionBuffer
;
80 IO_SCSI_CAPABILITIES PortCapabilities
;
82 PHW_INITIALIZE HwInitialize
;
83 PHW_STARTIO HwStartIo
;
84 PHW_INTERRUPT HwInterrupt
;
85 PHW_RESET_BUS HwResetBus
;
87 /* DMA related stuff */
88 PADAPTER_OBJECT AdapterObject
;
90 ULONG CommonBufferLength
;
92 PVOID MiniPortDeviceExtension
;
93 } SCSI_PORT_DEVICE_EXTENSION
, *PSCSI_PORT_DEVICE_EXTENSION
;
95 typedef struct tagDISKCONTEXT
98 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
103 /* Device characteristics */
105 ULONGLONG SectorOffset
;
106 ULONGLONG SectorCount
;
107 ULONGLONG SectorNumber
;
110 PSCSI_PORT_DEVICE_EXTENSION ScsiDeviceExtensions
[SCSI_MAXIMUM_BUSES
];
112 /* FUNCTIONS ******************************************************************/
119 PFOUR_BYTE Source
= (PFOUR_BYTE
)&Value
;
121 Dest
.Byte0
= Source
->Byte3
;
122 Dest
.Byte1
= Source
->Byte2
;
123 Dest
.Byte2
= Source
->Byte1
;
124 Dest
.Byte3
= Source
->Byte0
;
131 SpiSendSynchronousSrb(
132 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
133 IN PSCSI_REQUEST_BLOCK Srb
)
137 ASSERT(!(Srb
->SrbFlags
& SRB_FLAGS_IS_ACTIVE
));
139 /* HACK: handle lack of interrupts */
140 while (!(DeviceExtension
->InterruptFlags
& SCSI_PORT_NEXT_REQUEST_READY
))
142 KeStallExecutionProcessor(100 * 1000);
143 DeviceExtension
->HwInterrupt(DeviceExtension
->MiniPortDeviceExtension
);
146 DeviceExtension
->InterruptFlags
&= ~SCSI_PORT_NEXT_REQUEST_READY
;
147 Srb
->SrbFlags
|= SRB_FLAGS_IS_ACTIVE
;
149 if (!DeviceExtension
->HwStartIo(
150 DeviceExtension
->MiniPortDeviceExtension
,
157 /* HACK: handle lack of interrupts */
158 while (Srb
->SrbFlags
& SRB_FLAGS_IS_ACTIVE
)
160 KeStallExecutionProcessor(100 * 1000);
161 DeviceExtension
->HwInterrupt(DeviceExtension
->MiniPortDeviceExtension
);
164 ret
= SRB_STATUS(Srb
->SrbStatus
) == SRB_STATUS_SUCCESS
;
170 static ARC_STATUS
DiskClose(ULONG FileId
)
172 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
178 static ARC_STATUS
DiskGetFileInformation(ULONG FileId
, FILEINFORMATION
* Information
)
180 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
182 RtlZeroMemory(Information
, sizeof(FILEINFORMATION
));
183 Information
->EndingAddress
.QuadPart
= Context
->SectorCount
* Context
->SectorSize
;
184 Information
->CurrentAddress
.QuadPart
= Context
->SectorNumber
* Context
->SectorSize
;
189 static ARC_STATUS
DiskOpen(CHAR
* Path
, OPENMODE OpenMode
, ULONG
* FileId
)
191 PSCSI_REQUEST_BLOCK Srb
;
193 READ_CAPACITY_DATA ReadCapacityBuffer
;
195 DISKCONTEXT
* Context
;
196 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
197 ULONG ScsiBus
, PathId
, TargetId
, Lun
, Partition
, PathSyntax
;
199 ULONGLONG SectorOffset
= 0;
200 ULONGLONG SectorCount
;
203 if (!DissectArcPath2(Path
, &ScsiBus
, &TargetId
, &Lun
, &Partition
, &PathSyntax
))
205 if (PathSyntax
!= 0) /* scsi() format */
207 DeviceExtension
= ScsiDeviceExtensions
[ScsiBus
];
208 PathId
= ScsiBus
- DeviceExtension
->BusNum
;
210 /* Get disk capacity and sector size */
211 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
214 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
215 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
216 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
217 Srb
->PathId
= (UCHAR
)PathId
;
218 Srb
->TargetId
= (UCHAR
)TargetId
;
219 Srb
->Lun
= (UCHAR
)Lun
;
221 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
222 Srb
->DataTransferLength
= sizeof(READ_CAPACITY_DATA
);
223 Srb
->TimeOutValue
= 5; /* in seconds */
224 Srb
->DataBuffer
= &ReadCapacityBuffer
;
225 Cdb
= (PCDB
)Srb
->Cdb
;
226 Cdb
->CDB10
.OperationCode
= SCSIOP_READ_CAPACITY
;
227 if (!SpiSendSynchronousSrb(DeviceExtension
, Srb
))
232 /* Transform result to host endianness */
233 SectorCount
= ntohl(ReadCapacityBuffer
.LogicalBlockAddress
);
234 SectorSize
= ntohl(ReadCapacityBuffer
.BytesPerBlock
);
238 /* Need to offset start of disk and length */
243 Context
= ExAllocatePool(PagedPool
, sizeof(DISKCONTEXT
));
246 Context
->DeviceExtension
= DeviceExtension
;
247 Context
->PathId
= (UCHAR
)PathId
;
248 Context
->TargetId
= (UCHAR
)TargetId
;
249 Context
->Lun
= (UCHAR
)Lun
;
250 Context
->SectorSize
= SectorSize
;
251 Context
->SectorOffset
= SectorOffset
;
252 Context
->SectorCount
= SectorCount
;
253 Context
->SectorNumber
= 0;
254 FsSetDeviceSpecific(*FileId
, Context
);
259 static ARC_STATUS
DiskRead(ULONG FileId
, VOID
* Buffer
, ULONG N
, ULONG
* Count
)
261 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
262 PSCSI_REQUEST_BLOCK Srb
;
264 ULONG FullSectors
, NbSectors
;
272 FullSectors
= N
/ Context
->SectorSize
;
273 NbSectors
= (N
+ Context
->SectorSize
- 1) / Context
->SectorSize
;
274 if (Context
->SectorNumber
+ NbSectors
>= Context
->SectorCount
)
276 if (FullSectors
> 0xffff)
279 /* Read full sectors */
280 ASSERT(Context
->SectorNumber
< 0xFFFFFFFF);
281 Lba
= (ULONG
)Context
->SectorNumber
;
284 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
288 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
289 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
290 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
291 Srb
->PathId
= Context
->PathId
;
292 Srb
->TargetId
= Context
->TargetId
;
293 Srb
->Lun
= Context
->Lun
;
295 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
296 Srb
->DataTransferLength
= FullSectors
* Context
->SectorSize
;
297 Srb
->TimeOutValue
= 5; /* in seconds */
298 Srb
->DataBuffer
= Buffer
;
299 Cdb
= (PCDB
)Srb
->Cdb
;
300 Cdb
->CDB10
.OperationCode
= SCSIOP_READ
;
301 Cdb
->CDB10
.LogicalUnitNumber
= Srb
->Lun
;
302 Cdb
->CDB10
.LogicalBlockByte0
= (Lba
>> 24) & 0xff;
303 Cdb
->CDB10
.LogicalBlockByte1
= (Lba
>> 16) & 0xff;
304 Cdb
->CDB10
.LogicalBlockByte2
= (Lba
>> 8) & 0xff;
305 Cdb
->CDB10
.LogicalBlockByte3
= Lba
& 0xff;
306 Cdb
->CDB10
.TransferBlocksMsb
= (FullSectors
>> 8) & 0xff;
307 Cdb
->CDB10
.TransferBlocksLsb
= FullSectors
& 0xff;
308 if (!SpiSendSynchronousSrb(Context
->DeviceExtension
, Srb
))
312 Buffer
= (PUCHAR
)Buffer
+ FullSectors
* Context
->SectorSize
;
313 N
-= FullSectors
* Context
->SectorSize
;
314 *Count
+= FullSectors
* Context
->SectorSize
;
318 /* Read incomplete last sector */
323 Sector
= ExAllocatePool(PagedPool
, Context
->SectorSize
);
327 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
334 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
335 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
336 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
337 Srb
->PathId
= Context
->PathId
;
338 Srb
->TargetId
= Context
->TargetId
;
339 Srb
->Lun
= Context
->Lun
;
341 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
342 Srb
->DataTransferLength
= Context
->SectorSize
;
343 Srb
->TimeOutValue
= 5; /* in seconds */
344 Srb
->DataBuffer
= Sector
;
345 Cdb
= (PCDB
)Srb
->Cdb
;
346 Cdb
->CDB10
.OperationCode
= SCSIOP_READ
;
347 Cdb
->CDB10
.LogicalUnitNumber
= Srb
->Lun
;
348 Cdb
->CDB10
.LogicalBlockByte0
= (Lba
>> 24) & 0xff;
349 Cdb
->CDB10
.LogicalBlockByte1
= (Lba
>> 16) & 0xff;
350 Cdb
->CDB10
.LogicalBlockByte2
= (Lba
>> 8) & 0xff;
351 Cdb
->CDB10
.LogicalBlockByte3
= Lba
& 0xff;
352 Cdb
->CDB10
.TransferBlocksMsb
= 0;
353 Cdb
->CDB10
.TransferBlocksLsb
= 1;
354 if (!SpiSendSynchronousSrb(Context
->DeviceExtension
, Srb
))
359 RtlCopyMemory(Buffer
, Sector
, N
);
367 static ARC_STATUS
DiskSeek(ULONG FileId
, LARGE_INTEGER
* Position
, SEEKMODE SeekMode
)
369 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
371 if (SeekMode
!= SeekAbsolute
)
373 if (Position
->QuadPart
& (Context
->SectorSize
- 1))
376 Context
->SectorNumber
= Position
->QuadPart
/ Context
->SectorSize
;
380 static const DEVVTBL DiskVtbl
= {
382 DiskGetFileInformation
,
391 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
392 IN PHW_INITIALIZATION_DATA HwInitData
,
393 OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
394 IN BOOLEAN ZeroStruct
)
398 /* Zero out the struct if told so */
401 /* First zero the portconfig */
402 RtlZeroMemory(ConfigInfo
, sizeof(PORT_CONFIGURATION_INFORMATION
));
404 /* Initialize the struct */
405 ConfigInfo
->Length
= sizeof(PORT_CONFIGURATION_INFORMATION
);
406 ConfigInfo
->AdapterInterfaceType
= HwInitData
->AdapterInterfaceType
;
407 ConfigInfo
->InterruptMode
= Latched
;
408 ConfigInfo
->DmaChannel
= SP_UNINITIALIZED_VALUE
;
409 ConfigInfo
->DmaPort
= SP_UNINITIALIZED_VALUE
;
410 ConfigInfo
->MaximumTransferLength
= SP_UNINITIALIZED_VALUE
;
411 ConfigInfo
->MaximumNumberOfTargets
= SCSI_MAXIMUM_TARGETS_PER_BUS
;
413 /* Store parameters */
414 ConfigInfo
->NeedPhysicalAddresses
= HwInitData
->NeedPhysicalAddresses
;
415 ConfigInfo
->MapBuffers
= HwInitData
->MapBuffers
;
416 ConfigInfo
->AutoRequestSense
= HwInitData
->AutoRequestSense
;
417 ConfigInfo
->ReceiveEvent
= HwInitData
->ReceiveEvent
;
418 ConfigInfo
->TaggedQueuing
= HwInitData
->TaggedQueuing
;
419 ConfigInfo
->MultipleRequestPerLu
= HwInitData
->MultipleRequestPerLu
;
421 /* Get the disk usage */
422 ConfigInfo
->AtdiskPrimaryClaimed
= FALSE
; // FIXME
423 ConfigInfo
->AtdiskSecondaryClaimed
= FALSE
; // FIXME
425 /* Initiator bus id is not set */
426 for (Bus
= 0; Bus
< 8; Bus
++)
427 ConfigInfo
->InitiatorBusId
[Bus
] = (CCHAR
)SP_UNINITIALIZED_VALUE
;
430 ConfigInfo
->NumberOfPhysicalBreaks
= 17;
432 return STATUS_SUCCESS
;
438 IN ULONG DebugPrintLevel
,
439 IN PCCHAR DebugMessage
,
446 if (DebugPrintLevel
> 10)
449 va_start(ap
, DebugMessage
);
451 /* Construct a string */
452 Length
= _vsnprintf(Buffer
, 512, DebugMessage
, ap
);
454 /* Check if we went past the buffer */
455 if (Length
== MAXULONG
)
457 /* Terminate it if we went over-board */
458 Buffer
[sizeof(Buffer
) - 1] = '\0';
461 Length
= sizeof(Buffer
);
464 /* Print the message */
473 ScsiPortCompleteRequest(
474 IN PVOID HwDeviceExtension
,
484 #undef ScsiPortConvertPhysicalAddressToUlong
487 ScsiPortConvertPhysicalAddressToUlong(
488 IN SCSI_PHYSICAL_ADDRESS Address
)
490 return Address
.LowPart
;
493 SCSI_PHYSICAL_ADDRESS
495 ScsiPortConvertUlongToPhysicalAddress(
496 IN ULONG_PTR UlongAddress
)
498 SCSI_PHYSICAL_ADDRESS Address
;
500 Address
.QuadPart
= UlongAddress
;
507 IN PVOID DeviceExtension
)
515 ScsiPortFreeDeviceBase(
516 IN PVOID HwDeviceExtension
,
517 IN PVOID MappedAddress
)
525 IN PVOID DeviceExtension
,
526 IN ULONG BusDataType
,
527 IN ULONG SystemIoBusNumber
,
532 return HalGetBusDataByOffset(BusDataType
, SystemIoBusNumber
, SlotNumber
, Buffer
, 0, Length
);
537 ScsiPortGetDeviceBase(
538 IN PVOID HwDeviceExtension
,
539 IN INTERFACE_TYPE BusType
,
540 IN ULONG SystemIoBusNumber
,
541 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
542 IN ULONG NumberOfBytes
,
543 IN BOOLEAN InIoSpace
)
545 PHYSICAL_ADDRESS TranslatedAddress
;
548 AddressSpace
= (ULONG
)InIoSpace
;
549 if (HalTranslateBusAddress(BusType
,
553 &TranslatedAddress
) == FALSE
)
559 if (AddressSpace
!= 0)
560 return (PVOID
)TranslatedAddress
.u
.LowPart
;
564 return (PVOID
)IoAddress
.LowPart
;
569 ScsiPortGetLogicalUnit(
570 IN PVOID HwDeviceExtension
,
580 SCSI_PHYSICAL_ADDRESS
582 ScsiPortGetPhysicalAddress(
583 IN PVOID HwDeviceExtension
,
584 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
585 IN PVOID VirtualAddress
,
588 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
589 SCSI_PHYSICAL_ADDRESS PhysicalAddress
;
590 ULONG BufferLength
= 0;
593 TRACE("ScsiPortGetPhysicalAddress(%p %p %p %p)\n",
594 HwDeviceExtension
, Srb
, VirtualAddress
, Length
);
596 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
598 if (Srb
== NULL
|| Srb
->SenseInfoBuffer
== VirtualAddress
)
600 /* Simply look it up in the allocated common buffer */
601 Offset
= (PUCHAR
)VirtualAddress
- (PUCHAR
)DeviceExtension
->SrbExtensionBuffer
;
603 BufferLength
= DeviceExtension
->CommonBufferLength
- Offset
;
604 PhysicalAddress
.QuadPart
= Offset
;
609 PhysicalAddress
.QuadPart
= (LONGLONG
)(SP_UNINITIALIZED_VALUE
);
612 *Length
= BufferLength
;
613 return PhysicalAddress
;
619 IN PVOID DeviceExtension
,
632 SpiAllocateCommonBuffer(
633 IN OUT PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
634 IN ULONG NonCachedSize
)
637 ULONG CommonBufferLength
, BufSize
;
639 /* If size is 0, set it to 16 */
640 if (!DeviceExtension
->SrbExtensionSize
)
641 DeviceExtension
->SrbExtensionSize
= 16;
644 BufSize
= DeviceExtension
->SrbExtensionSize
;
647 BufSize
= (BufSize
+ sizeof(LONGLONG
) - 1) & ~(sizeof(LONGLONG
) - 1);
649 /* Sum up into the total common buffer length, and round it to page size */
651 ROUND_TO_PAGES(NonCachedSize
);
654 if (!DeviceExtension
->AdapterObject
)
656 /* From nonpaged pool if there is no DMA */
657 CommonBuffer
= ExAllocatePool(NonPagedPool
, CommonBufferLength
);
661 /* Perform a full request since we have a DMA adapter*/
666 /* Fail in case of error */
668 return STATUS_INSUFFICIENT_RESOURCES
;
671 RtlZeroMemory(CommonBuffer
, CommonBufferLength
);
673 /* Store its size in Device Extension */
674 DeviceExtension
->CommonBufferLength
= CommonBufferLength
;
676 /* SrbExtension buffer is located at the beginning of the buffer */
677 DeviceExtension
->SrbExtensionBuffer
= CommonBuffer
;
679 /* Non-cached extension buffer is located at the end of
683 CommonBufferLength
-= NonCachedSize
;
684 DeviceExtension
->NonCachedExtension
= (PUCHAR
)CommonBuffer
+ CommonBufferLength
;
688 DeviceExtension
->NonCachedExtension
= NULL
;
691 return STATUS_SUCCESS
;
696 ScsiPortGetUncachedExtension(
697 IN PVOID HwDeviceExtension
,
698 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
699 IN ULONG NumberOfBytes
)
701 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
702 DEVICE_DESCRIPTION DeviceDescription
;
703 ULONG MapRegistersCount
;
706 TRACE("ScsiPortGetUncachedExtension(%p %p %lu)\n",
707 HwDeviceExtension
, ConfigInfo
, NumberOfBytes
);
709 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
711 /* Check for allocated common DMA buffer */
712 if (DeviceExtension
->SrbExtensionBuffer
!= NULL
)
717 /* Check for DMA adapter object */
718 if (DeviceExtension
->AdapterObject
== NULL
)
720 /* Initialize DMA adapter description */
721 RtlZeroMemory(&DeviceDescription
, sizeof(DEVICE_DESCRIPTION
));
723 DeviceDescription
.Version
= DEVICE_DESCRIPTION_VERSION
;
724 DeviceDescription
.Master
= ConfigInfo
->Master
;
725 DeviceDescription
.ScatterGather
= ConfigInfo
->ScatterGather
;
726 DeviceDescription
.DemandMode
= ConfigInfo
->DemandMode
;
727 DeviceDescription
.Dma32BitAddresses
= ConfigInfo
->Dma32BitAddresses
;
728 DeviceDescription
.BusNumber
= ConfigInfo
->SystemIoBusNumber
;
729 DeviceDescription
.DmaChannel
= ConfigInfo
->DmaChannel
;
730 DeviceDescription
.InterfaceType
= ConfigInfo
->AdapterInterfaceType
;
731 DeviceDescription
.DmaWidth
= ConfigInfo
->DmaWidth
;
732 DeviceDescription
.DmaSpeed
= ConfigInfo
->DmaSpeed
;
733 DeviceDescription
.MaximumLength
= ConfigInfo
->MaximumTransferLength
;
734 DeviceDescription
.DmaPort
= ConfigInfo
->DmaPort
;
736 /* Get a DMA adapter object */
738 DeviceExtension
->AdapterObject
=
739 HalGetAdapter(&DeviceDescription
, &MapRegistersCount
);
741 /* Fail in case of error */
742 if (DeviceExtension
->AdapterObject
== NULL
)
747 MapRegistersCount
= 0;
750 /* Set number of physical breaks */
751 if (ConfigInfo
->NumberOfPhysicalBreaks
!= 0 &&
752 MapRegistersCount
> ConfigInfo
->NumberOfPhysicalBreaks
)
754 DeviceExtension
->PortCapabilities
.MaximumPhysicalPages
=
755 ConfigInfo
->NumberOfPhysicalBreaks
;
759 DeviceExtension
->PortCapabilities
.MaximumPhysicalPages
= MapRegistersCount
;
763 /* Update Srb extension size */
764 if (DeviceExtension
->SrbExtensionSize
!= ConfigInfo
->SrbExtensionSize
)
765 DeviceExtension
->SrbExtensionSize
= ConfigInfo
->SrbExtensionSize
;
767 /* Allocate a common DMA buffer */
768 Status
= SpiAllocateCommonBuffer(DeviceExtension
, NumberOfBytes
);
770 if (!NT_SUCCESS(Status
))
772 TRACE("SpiAllocateCommonBuffer() failed with Status = 0x%08X!\n", Status
);
776 return DeviceExtension
->NonCachedExtension
;
781 ScsiPortGetVirtualAddress(
782 IN PVOID HwDeviceExtension
,
783 IN SCSI_PHYSICAL_ADDRESS PhysicalAddress
)
793 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
802 struct _DRIVE_LAYOUT_INFORMATION
*PartitionBuffer
;
803 CHAR PartitionName
[64];
805 /* Register device with partition(0) suffix */
806 sprintf(PartitionName
, "%spartition(0)", ArcName
);
807 FsRegisterDevice(PartitionName
, &DiskVtbl
);
809 /* Read device partition table */
810 Status
= ArcOpen(PartitionName
, OpenReadOnly
, &FileId
);
811 if (Status
== ESUCCESS
)
813 ret
= HALDISPATCH
->HalIoReadPartitionTable((PDEVICE_OBJECT
)FileId
, 512, FALSE
, &PartitionBuffer
);
816 for (i
= 0; i
< PartitionBuffer
->PartitionCount
; i
++)
818 if (PartitionBuffer
->PartitionEntry
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
)
820 sprintf(PartitionName
, "%spartition(%lu)",
821 ArcName
, PartitionBuffer
->PartitionEntry
[i
].PartitionNumber
);
822 FsRegisterDevice(PartitionName
, &DiskVtbl
);
825 ExFreePool(PartitionBuffer
);
834 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
839 PSCSI_REQUEST_BLOCK Srb
;
841 INQUIRYDATA InquiryBuffer
;
845 if (!DeviceExtension
->HwResetBus(DeviceExtension
->MiniPortDeviceExtension
, PathId
))
850 /* Remember the extension */
851 ScsiDeviceExtensions
[ScsiBus
] = DeviceExtension
;
853 for (TargetId
= 0; TargetId
< DeviceExtension
->MaxTargedIds
; TargetId
++)
858 TRACE("Scanning SCSI device %d.%d.%d\n",
859 ScsiBus
, TargetId
, Lun
);
861 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
864 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
865 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
866 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
867 Srb
->PathId
= PathId
;
868 Srb
->TargetId
= TargetId
;
871 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
872 Srb
->DataTransferLength
= INQUIRYDATABUFFERSIZE
;
873 Srb
->TimeOutValue
= 5; /* in seconds */
874 Srb
->DataBuffer
= &InquiryBuffer
;
875 Cdb
= (PCDB
)Srb
->Cdb
;
876 Cdb
->CDB6INQUIRY
.OperationCode
= SCSIOP_INQUIRY
;
877 Cdb
->CDB6INQUIRY
.LogicalUnitNumber
= Srb
->Lun
;
878 Cdb
->CDB6INQUIRY
.AllocationLength
= (UCHAR
)Srb
->DataTransferLength
;
879 if (!SpiSendSynchronousSrb(DeviceExtension
, Srb
))
881 /* Don't check next LUNs */
885 /* Device exists, create its ARC name */
886 if (InquiryBuffer
.RemovableMedia
)
888 sprintf(ArcName
, "scsi(%ld)cdrom(%d)fdisk(%d)",
889 ScsiBus
, TargetId
, Lun
);
890 FsRegisterDevice(ArcName
, &DiskVtbl
);
894 sprintf(ArcName
, "scsi(%ld)disk(%d)rdisk(%d)",
895 ScsiBus
, TargetId
, Lun
);
896 /* Now, check if it has partitions */
897 SpiScanDevice(DeviceExtension
, ArcName
, PathId
, TargetId
, Lun
);
902 } while (Lun
< SCSI_MAXIMUM_LOGICAL_UNITS
);
909 IN PHW_INITIALIZATION_DATA HwInitializationData
,
910 IN PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor
,
911 IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig
)
913 PACCESS_RANGE AccessRange
;
914 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialData
;
920 /* Loop through all entries */
921 for (Index
= 0; Index
< ResourceDescriptor
->PartialResourceList
.Count
; Index
++)
923 PartialData
= &ResourceDescriptor
->PartialResourceList
.PartialDescriptors
[Index
];
925 switch (PartialData
->Type
)
927 case CmResourceTypePort
:
928 /* Copy access ranges */
929 if (RangeNumber
< HwInitializationData
->NumberOfAccessRanges
)
931 TRACE("Got port at 0x%I64x, len 0x%x\n",
932 PartialData
->u
.Port
.Start
.QuadPart
, PartialData
->u
.Port
.Length
);
933 AccessRange
= &((*(PortConfig
->AccessRanges
))[RangeNumber
]);
935 AccessRange
->RangeStart
= PartialData
->u
.Port
.Start
;
936 AccessRange
->RangeLength
= PartialData
->u
.Port
.Length
;
938 AccessRange
->RangeInMemory
= FALSE
;
943 case CmResourceTypeMemory
:
944 /* Copy access ranges */
945 if (RangeNumber
< HwInitializationData
->NumberOfAccessRanges
)
947 TRACE("Got memory at 0x%I64x, len 0x%x\n",
948 PartialData
->u
.Memory
.Start
.QuadPart
, PartialData
->u
.Memory
.Length
);
949 AccessRange
= &((*(PortConfig
->AccessRanges
))[RangeNumber
]);
951 AccessRange
->RangeStart
= PartialData
->u
.Memory
.Start
;
952 AccessRange
->RangeLength
= PartialData
->u
.Memory
.Length
;
954 AccessRange
->RangeInMemory
= TRUE
;
959 case CmResourceTypeInterrupt
:
960 /* Copy interrupt data */
961 TRACE("Got interrupt level %d, vector %d\n",
962 PartialData
->u
.Interrupt
.Level
, PartialData
->u
.Interrupt
.Vector
);
963 PortConfig
->BusInterruptLevel
= PartialData
->u
.Interrupt
.Level
;
964 PortConfig
->BusInterruptVector
= PartialData
->u
.Interrupt
.Vector
;
966 /* Set interrupt mode accordingly to the resource */
967 if (PartialData
->Flags
== CM_RESOURCE_INTERRUPT_LATCHED
)
969 PortConfig
->InterruptMode
= Latched
;
971 else if (PartialData
->Flags
== CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
)
973 PortConfig
->InterruptMode
= LevelSensitive
;
977 case CmResourceTypeDma
:
978 TRACE("Got DMA channel %d, port %d\n",
979 PartialData
->u
.Dma
.Channel
, PartialData
->u
.Dma
.Port
);
980 PortConfig
->DmaChannel
= PartialData
->u
.Dma
.Channel
;
981 PortConfig
->DmaPort
= PartialData
->u
.Dma
.Port
;
990 IN PHW_INITIALIZATION_DATA HwInitializationData
,
991 IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig
,
993 IN OUT PPCI_SLOT_NUMBER NextSlotNumber
)
995 PCI_COMMON_CONFIG PciConfig
;
996 PCI_SLOT_NUMBER SlotNumber
;
999 ULONG FunctionNumber
;
1000 CHAR VendorIdString
[8];
1001 CHAR DeviceIdString
[8];
1002 PCM_RESOURCE_LIST ResourceList
= NULL
;
1005 SlotNumber
.u
.AsULONG
= 0;
1007 /* Loop through all devices */
1008 for (DeviceNumber
= NextSlotNumber
->u
.bits
.DeviceNumber
; DeviceNumber
< PCI_MAX_DEVICES
; DeviceNumber
++)
1010 SlotNumber
.u
.bits
.DeviceNumber
= DeviceNumber
;
1012 /* Loop through all functions */
1013 for (FunctionNumber
= NextSlotNumber
->u
.bits
.FunctionNumber
; FunctionNumber
< PCI_MAX_FUNCTION
; FunctionNumber
++)
1015 SlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
1017 /* Get PCI config bytes */
1018 DataSize
= HalGetBusDataByOffset(
1021 SlotNumber
.u
.AsULONG
,
1026 /* If result of HalGetBusData is 0, then the bus is wrong */
1030 /* If result is PCI_INVALID_VENDORID, then this device has no more
1032 if (PciConfig
.VendorID
== PCI_INVALID_VENDORID
)
1035 sprintf(VendorIdString
, "%04hx", PciConfig
.VendorID
);
1036 sprintf(DeviceIdString
, "%04hx", PciConfig
.DeviceID
);
1038 if (_strnicmp(VendorIdString
, HwInitializationData
->VendorId
, HwInitializationData
->VendorIdLength
) ||
1039 _strnicmp(DeviceIdString
, HwInitializationData
->DeviceId
, HwInitializationData
->DeviceIdLength
))
1041 /* It is not our device */
1045 TRACE( "Found device 0x%04hx 0x%04hx at %1lu %2lu %1lu\n",
1046 PciConfig
.VendorID
, PciConfig
.DeviceID
,
1048 SlotNumber
.u
.bits
.DeviceNumber
, SlotNumber
.u
.bits
.FunctionNumber
);
1050 Status
= HalAssignSlotResources(NULL
,
1056 SlotNumber
.u
.AsULONG
,
1059 if (!NT_SUCCESS(Status
))
1062 /* Create configuration information */
1063 SpiResourceToConfig(HwInitializationData
,
1067 /* Free the resource list */
1068 ExFreePool(ResourceList
);
1070 /* Set dev & fn numbers */
1071 NextSlotNumber
->u
.bits
.DeviceNumber
= DeviceNumber
;
1072 NextSlotNumber
->u
.bits
.FunctionNumber
= FunctionNumber
+ 1;
1074 /* Save the slot number */
1075 PortConfig
->SlotNumber
= SlotNumber
.u
.AsULONG
;
1079 NextSlotNumber
->u
.bits
.FunctionNumber
= 0;
1082 NextSlotNumber
->u
.bits
.DeviceNumber
= 0;
1092 IN PHW_INITIALIZATION_DATA HwInitializationData
,
1093 IN PVOID HwContext OPTIONAL
)
1095 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
1096 ULONG DeviceExtensionSize
;
1097 PORT_CONFIGURATION_INFORMATION PortConfig
;
1099 BOOLEAN FirstConfigCall
= TRUE
;
1100 PCI_SLOT_NUMBER SlotNumber
;
1104 if (HwInitializationData
->HwInitializationDataSize
!= sizeof(HW_INITIALIZATION_DATA
))
1106 return STATUS_INVALID_PARAMETER
;
1109 /* Check params for validity */
1110 if ((HwInitializationData
->HwInitialize
== NULL
) ||
1111 (HwInitializationData
->HwStartIo
== NULL
) ||
1112 (HwInitializationData
->HwInterrupt
== NULL
) ||
1113 (HwInitializationData
->HwFindAdapter
== NULL
) ||
1114 (HwInitializationData
->HwResetBus
== NULL
))
1116 return STATUS_INVALID_PARAMETER
;
1119 /* Zero starting slot number */
1120 SlotNumber
.u
.AsULONG
= 0;
1126 DeviceExtensionSize
= sizeof(SCSI_PORT_DEVICE_EXTENSION
) + HwInitializationData
->DeviceExtensionSize
;
1127 DeviceExtension
= FrLdrTempAlloc(DeviceExtensionSize
, TAG_SCSI_DEVEXT
);
1128 if (!DeviceExtension
)
1130 return STATUS_NO_MEMORY
;
1132 RtlZeroMemory(DeviceExtension
, DeviceExtensionSize
);
1133 DeviceExtension
->InterruptFlags
= SCSI_PORT_NEXT_REQUEST_READY
;
1134 DeviceExtension
->HwInitialize
= HwInitializationData
->HwInitialize
;
1135 DeviceExtension
->HwStartIo
= HwInitializationData
->HwStartIo
;
1136 DeviceExtension
->HwInterrupt
= HwInitializationData
->HwInterrupt
;
1137 DeviceExtension
->HwResetBus
= HwInitializationData
->HwResetBus
;
1138 DeviceExtension
->MiniPortDeviceExtension
= (PVOID
)(DeviceExtension
+ 1);
1140 Status
= SpiCreatePortConfig(DeviceExtension
,
1141 HwInitializationData
,
1144 if (Status
!= STATUS_SUCCESS
)
1146 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1150 PortConfig
.NumberOfAccessRanges
= HwInitializationData
->NumberOfAccessRanges
;
1151 PortConfig
.AccessRanges
= FrLdrTempAlloc(sizeof(ACCESS_RANGE
) * HwInitializationData
->NumberOfAccessRanges
,
1152 TAG_SCSI_ACCESS_RANGES
);
1153 if (!PortConfig
.AccessRanges
)
1155 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1156 return STATUS_NO_MEMORY
;
1158 RtlZeroMemory(PortConfig
.AccessRanges
, sizeof(ACCESS_RANGE
) * HwInitializationData
->NumberOfAccessRanges
);
1160 /* Search for matching PCI device */
1161 if ((HwInitializationData
->AdapterInterfaceType
== PCIBus
) &&
1162 (HwInitializationData
->VendorIdLength
> 0) &&
1163 (HwInitializationData
->VendorId
!= NULL
) &&
1164 (HwInitializationData
->DeviceIdLength
> 0) &&
1165 (HwInitializationData
->DeviceId
!= NULL
))
1167 PortConfig
.BusInterruptLevel
= 0;
1169 /* Get PCI device data */
1170 TRACE("VendorId '%.*s' DeviceId '%.*s'\n",
1171 HwInitializationData
->VendorIdLength
,
1172 HwInitializationData
->VendorId
,
1173 HwInitializationData
->DeviceIdLength
,
1174 HwInitializationData
->DeviceId
);
1176 if (!SpiGetPciConfigData(HwInitializationData
,
1181 /* Continue to the next bus, nothing here */
1182 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1183 return STATUS_INTERNAL_ERROR
;
1186 if (!PortConfig
.BusInterruptLevel
)
1188 /* Bypass this slot, because no interrupt was assigned */
1189 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1190 return STATUS_INTERNAL_ERROR
;
1194 if (HwInitializationData
->HwFindAdapter(
1195 DeviceExtension
->MiniPortDeviceExtension
,
1200 &Again
) != SP_RETURN_FOUND
)
1202 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1203 return STATUS_INTERNAL_ERROR
;
1206 /* Copy all stuff which we ever need from PortConfig to the DeviceExtension */
1207 if (PortConfig
.MaximumNumberOfTargets
> SCSI_MAXIMUM_TARGETS_PER_BUS
)
1208 DeviceExtension
->MaxTargedIds
= SCSI_MAXIMUM_TARGETS_PER_BUS
;
1210 DeviceExtension
->MaxTargedIds
= PortConfig
.MaximumNumberOfTargets
;
1212 DeviceExtension
->BusNum
= PortConfig
.SystemIoBusNumber
;
1214 TRACE("Adapter found: buses = %d, targets = %d\n",
1215 PortConfig
.NumberOfBuses
, DeviceExtension
->MaxTargedIds
);
1217 /* Initialize adapter */
1218 if (!DeviceExtension
->HwInitialize(DeviceExtension
->MiniPortDeviceExtension
))
1220 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1221 return STATUS_INTERNAL_ERROR
;
1225 for (ScsiBus
= 0; ScsiBus
< PortConfig
.NumberOfBuses
; ScsiBus
++)
1227 SpiScanAdapter(DeviceExtension
, PortConfig
.SystemIoBusNumber
, ScsiBus
);
1228 PortConfig
.SystemIoBusNumber
++;
1231 FirstConfigCall
= FALSE
;
1238 return STATUS_SUCCESS
;
1243 ScsiPortIoMapTransfer(
1244 IN PVOID HwDeviceExtension
,
1245 IN PSCSI_REQUEST_BLOCK Srb
,
1246 IN PVOID LogicalAddress
,
1256 IN PVOID HwDeviceExtension
,
1257 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
1271 IN PVOID WriteBuffer
,
1272 IN PVOID ReadBuffer
,
1275 RtlMoveMemory(WriteBuffer
, ReadBuffer
, Length
);
1280 ScsiPortNotification(
1281 IN SCSI_NOTIFICATION_TYPE NotificationType
,
1282 IN PVOID HwDeviceExtension
,
1285 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
1286 PSCSI_REQUEST_BLOCK Srb
;
1289 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
1291 va_start(ap
, HwDeviceExtension
);
1293 switch (NotificationType
)
1295 case RequestComplete
:
1296 /* Mask the SRB as completed */
1297 Srb
= va_arg(ap
, PSCSI_REQUEST_BLOCK
);
1298 Srb
->SrbFlags
&= ~SRB_FLAGS_IS_ACTIVE
;
1302 /* Say that device is ready */
1303 DeviceExtension
->InterruptFlags
|= SCSI_PORT_NEXT_REQUEST_READY
;
1316 ScsiPortReadPortBufferUchar(
1321 __inbytestring(H2I(Port
), Buffer
, Count
);
1326 ScsiPortReadPortBufferUlong(
1331 __indwordstring(H2I(Port
), Buffer
, Count
);
1336 ScsiPortReadPortBufferUshort(
1341 __inwordstring(H2I(Port
), Buffer
, Count
);
1346 ScsiPortReadPortUchar(
1349 TRACE("ScsiPortReadPortUchar(%p)\n", Port
);
1351 return READ_PORT_UCHAR(Port
);
1356 ScsiPortReadPortUlong(
1359 return READ_PORT_ULONG(Port
);
1364 ScsiPortReadPortUshort(
1367 return READ_PORT_USHORT(Port
);
1372 ScsiPortReadRegisterBufferUchar(
1383 ScsiPortReadRegisterBufferUlong(
1394 ScsiPortReadRegisterBufferUshort(
1395 IN PUSHORT Register
,
1405 ScsiPortReadRegisterUchar(
1408 return READ_REGISTER_UCHAR(Register
);
1413 ScsiPortReadRegisterUlong(
1416 return READ_REGISTER_ULONG(Register
);
1421 ScsiPortReadRegisterUshort(
1422 IN PUSHORT Register
)
1424 return READ_REGISTER_USHORT(Register
);
1429 ScsiPortSetBusDataByOffset(
1430 IN PVOID DeviceExtension
,
1431 IN ULONG BusDataType
,
1432 IN ULONG SystemIoBusNumber
,
1433 IN ULONG SlotNumber
,
1445 ScsiPortStallExecution(
1448 KeStallExecutionProcessor(Delay
);
1453 ScsiPortValidateRange(
1454 IN PVOID HwDeviceExtension
,
1455 IN INTERFACE_TYPE BusType
,
1456 IN ULONG SystemIoBusNumber
,
1457 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
1458 IN ULONG NumberOfBytes
,
1459 IN BOOLEAN InIoSpace
)
1473 ScsiPortWritePortBufferUchar(
1478 __outbytestring(H2I(Port
), Buffer
, Count
);
1483 ScsiPortWritePortBufferUlong(
1488 __outdwordstring(H2I(Port
), Buffer
, Count
);
1493 ScsiPortWritePortBufferUshort(
1498 __outwordstring(H2I(Port
), Buffer
, Count
);
1503 ScsiPortWritePortUchar(
1507 WRITE_PORT_UCHAR(Port
, Value
);
1512 ScsiPortWritePortUlong(
1516 WRITE_PORT_ULONG(Port
, Value
);
1521 ScsiPortWritePortUshort(
1525 WRITE_PORT_USHORT(Port
, Value
);
1530 ScsiPortWriteRegisterBufferUchar(
1541 ScsiPortWriteRegisterBufferUlong(
1552 ScsiPortWriteRegisterBufferUshort(
1553 IN PUSHORT Register
,
1563 ScsiPortWriteRegisterUchar(
1567 WRITE_REGISTER_UCHAR(Register
, Value
);
1572 ScsiPortWriteRegisterUlong(
1576 WRITE_REGISTER_ULONG(Register
, Value
);
1581 ScsiPortWriteRegisterUshort(
1582 IN PUSHORT Register
,
1585 WRITE_REGISTER_USHORT(Register
, Value
);
1588 extern char __ImageBase
;
1591 LoadBootDeviceDriver(VOID
)
1593 PIMAGE_NT_HEADERS NtHeaders
;
1594 LIST_ENTRY ModuleListHead
;
1595 PIMAGE_IMPORT_DESCRIPTOR ImportTable
;
1596 ULONG ImportTableSize
;
1597 PLDR_DATA_TABLE_ENTRY BootDdDTE
, FreeldrDTE
;
1598 CHAR NtBootDdPath
[MAX_PATH
];
1599 PVOID ImageBase
= NULL
;
1600 ULONG (NTAPI
*EntryPoint
)(IN PVOID DriverObject
, IN PVOID RegistryPath
);
1603 // FIXME: Must be done *INSIDE* the HAL!
1605 HalpInitializePciStubs();
1606 HalpInitBusHandler();
1609 /* Initialize the loaded module list */
1610 InitializeListHead(&ModuleListHead
);
1612 /* Create full ntbootdd.sys path */
1613 MachDiskGetBootPath(NtBootDdPath
, sizeof(NtBootDdPath
));
1614 strcat(NtBootDdPath
, "\\NTBOOTDD.SYS");
1617 Success
= WinLdrLoadImage(NtBootDdPath
, LoaderBootDriver
, &ImageBase
);
1620 /* That's OK. File simply doesn't exist */
1624 /* Allocate a DTE for ntbootdd */
1625 Success
= WinLdrAllocateDataTableEntry(&ModuleListHead
, "ntbootdd.sys",
1626 "NTBOOTDD.SYS", ImageBase
, &BootDdDTE
);
1630 /* Add the PE part of freeldr.sys to the list of loaded executables, it
1631 contains Scsiport* exports, imported by ntbootdd.sys */
1632 Success
= WinLdrAllocateDataTableEntry(&ModuleListHead
, "scsiport.sys",
1633 "FREELDR.SYS", &__ImageBase
, &FreeldrDTE
);
1636 RemoveEntryList(&BootDdDTE
->InLoadOrderLinks
);
1641 Success
= WinLdrScanImportDescriptorTable(&ModuleListHead
, "", BootDdDTE
);
1643 /* Now unlinkt the DTEs, they won't be valid later */
1644 RemoveEntryList(&BootDdDTE
->InLoadOrderLinks
);
1645 RemoveEntryList(&FreeldrDTE
->InLoadOrderLinks
);
1650 /* Change imports to PA */
1651 ImportTable
= (PIMAGE_IMPORT_DESCRIPTOR
)RtlImageDirectoryEntryToData(VaToPa(BootDdDTE
->DllBase
),
1652 TRUE
, IMAGE_DIRECTORY_ENTRY_IMPORT
, &ImportTableSize
);
1653 for (;(ImportTable
->Name
!= 0) && (ImportTable
->FirstThunk
!= 0);ImportTable
++)
1655 PIMAGE_THUNK_DATA ThunkData
= (PIMAGE_THUNK_DATA
)VaToPa(RVA(BootDdDTE
->DllBase
, ImportTable
->FirstThunk
));
1657 while (((PIMAGE_THUNK_DATA
)ThunkData
)->u1
.AddressOfData
!= 0)
1659 ThunkData
->u1
.Function
= (ULONG
)VaToPa((PVOID
)ThunkData
->u1
.Function
);
1664 /* Relocate image to PA */
1665 NtHeaders
= RtlImageNtHeader(VaToPa(BootDdDTE
->DllBase
));
1668 Success
= (BOOLEAN
)LdrRelocateImageWithBias(VaToPa(BootDdDTE
->DllBase
),
1669 NtHeaders
->OptionalHeader
.ImageBase
- (ULONG_PTR
)BootDdDTE
->DllBase
,
1672 TRUE
, /* in case of conflict still return success */
1677 /* Call the entrypoint */
1678 EntryPoint
= VaToPa(BootDdDTE
->EntryPoint
);
1679 (*EntryPoint
)(NULL
, NULL
);