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
54 #define SCSI_PORT_NEXT_REQUEST_READY 0x0008
56 #define TAG_SCSI_DEVEXT 'DscS'
57 #define TAG_SCSI_ACCESS_RANGES 'AscS'
59 DBG_DEFAULT_CHANNEL(SCSIPORT
);
61 /* GLOBALS ********************************************************************/
64 VOID NTAPI
HalpInitializePciStubs(VOID
);
65 VOID NTAPI
HalpInitBusHandler(VOID
);
70 PVOID NonCachedExtension
;
77 /* SRB extension stuff */
78 ULONG SrbExtensionSize
;
79 PVOID SrbExtensionBuffer
;
81 IO_SCSI_CAPABILITIES PortCapabilities
;
83 PHW_INITIALIZE HwInitialize
;
84 PHW_STARTIO HwStartIo
;
85 PHW_INTERRUPT HwInterrupt
;
86 PHW_RESET_BUS HwResetBus
;
88 /* DMA related stuff */
89 PADAPTER_OBJECT AdapterObject
;
91 ULONG CommonBufferLength
;
93 PVOID MiniPortDeviceExtension
;
94 } SCSI_PORT_DEVICE_EXTENSION
, *PSCSI_PORT_DEVICE_EXTENSION
;
96 typedef struct tagDISKCONTEXT
99 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
104 /* Device characteristics */
106 ULONGLONG SectorOffset
;
107 ULONGLONG SectorCount
;
108 ULONGLONG SectorNumber
;
111 PSCSI_PORT_DEVICE_EXTENSION ScsiDeviceExtensions
[SCSI_MAXIMUM_BUSES
];
113 /* FUNCTIONS ******************************************************************/
120 PFOUR_BYTE Source
= (PFOUR_BYTE
)&Value
;
122 Dest
.Byte0
= Source
->Byte3
;
123 Dest
.Byte1
= Source
->Byte2
;
124 Dest
.Byte2
= Source
->Byte1
;
125 Dest
.Byte3
= Source
->Byte0
;
132 SpiSendSynchronousSrb(
133 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
134 IN PSCSI_REQUEST_BLOCK Srb
)
138 ASSERT(!(Srb
->SrbFlags
& SRB_FLAGS_IS_ACTIVE
));
140 /* HACK: handle lack of interrupts */
141 while (!(DeviceExtension
->InterruptFlags
& SCSI_PORT_NEXT_REQUEST_READY
))
143 KeStallExecutionProcessor(100 * 1000);
144 DeviceExtension
->HwInterrupt(DeviceExtension
->MiniPortDeviceExtension
);
147 DeviceExtension
->InterruptFlags
&= ~SCSI_PORT_NEXT_REQUEST_READY
;
148 Srb
->SrbFlags
|= SRB_FLAGS_IS_ACTIVE
;
150 if (!DeviceExtension
->HwStartIo(
151 DeviceExtension
->MiniPortDeviceExtension
,
158 /* HACK: handle lack of interrupts */
159 while (Srb
->SrbFlags
& SRB_FLAGS_IS_ACTIVE
)
161 KeStallExecutionProcessor(100 * 1000);
162 DeviceExtension
->HwInterrupt(DeviceExtension
->MiniPortDeviceExtension
);
165 ret
= SRB_STATUS(Srb
->SrbStatus
) == SRB_STATUS_SUCCESS
;
171 static ARC_STATUS
DiskClose(ULONG FileId
)
173 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
179 static ARC_STATUS
DiskGetFileInformation(ULONG FileId
, FILEINFORMATION
* Information
)
181 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
183 RtlZeroMemory(Information
, sizeof(FILEINFORMATION
));
184 Information
->EndingAddress
.QuadPart
= Context
->SectorCount
* Context
->SectorSize
;
185 Information
->CurrentAddress
.QuadPart
= Context
->SectorNumber
* Context
->SectorSize
;
190 static ARC_STATUS
DiskOpen(CHAR
* Path
, OPENMODE OpenMode
, ULONG
* FileId
)
192 PSCSI_REQUEST_BLOCK Srb
;
194 READ_CAPACITY_DATA ReadCapacityBuffer
;
196 DISKCONTEXT
* Context
;
197 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
198 ULONG ScsiBus
, PathId
, TargetId
, Lun
, Partition
, PathSyntax
;
200 ULONGLONG SectorOffset
= 0;
201 ULONGLONG SectorCount
;
204 if (!DissectArcPath2(Path
, &ScsiBus
, &TargetId
, &Lun
, &Partition
, &PathSyntax
))
206 if (PathSyntax
!= 0) /* scsi() format */
208 DeviceExtension
= ScsiDeviceExtensions
[ScsiBus
];
209 PathId
= ScsiBus
- DeviceExtension
->BusNum
;
211 /* Get disk capacity and sector size */
212 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
215 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
216 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
217 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
218 Srb
->PathId
= (UCHAR
)PathId
;
219 Srb
->TargetId
= (UCHAR
)TargetId
;
220 Srb
->Lun
= (UCHAR
)Lun
;
222 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
223 Srb
->DataTransferLength
= sizeof(READ_CAPACITY_DATA
);
224 Srb
->TimeOutValue
= 5; /* in seconds */
225 Srb
->DataBuffer
= &ReadCapacityBuffer
;
226 Cdb
= (PCDB
)Srb
->Cdb
;
227 Cdb
->CDB10
.OperationCode
= SCSIOP_READ_CAPACITY
;
228 if (!SpiSendSynchronousSrb(DeviceExtension
, Srb
))
233 /* Transform result to host endianness */
234 SectorCount
= ntohl(ReadCapacityBuffer
.LogicalBlockAddress
);
235 SectorSize
= ntohl(ReadCapacityBuffer
.BytesPerBlock
);
239 /* Need to offset start of disk and length */
244 Context
= ExAllocatePool(PagedPool
, sizeof(DISKCONTEXT
));
247 Context
->DeviceExtension
= DeviceExtension
;
248 Context
->PathId
= (UCHAR
)PathId
;
249 Context
->TargetId
= (UCHAR
)TargetId
;
250 Context
->Lun
= (UCHAR
)Lun
;
251 Context
->SectorSize
= SectorSize
;
252 Context
->SectorOffset
= SectorOffset
;
253 Context
->SectorCount
= SectorCount
;
254 Context
->SectorNumber
= 0;
255 FsSetDeviceSpecific(*FileId
, Context
);
260 static ARC_STATUS
DiskRead(ULONG FileId
, VOID
* Buffer
, ULONG N
, ULONG
* Count
)
262 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
263 PSCSI_REQUEST_BLOCK Srb
;
265 ULONG FullSectors
, NbSectors
;
273 FullSectors
= N
/ Context
->SectorSize
;
274 NbSectors
= (N
+ Context
->SectorSize
- 1) / Context
->SectorSize
;
275 if (Context
->SectorNumber
+ NbSectors
>= Context
->SectorCount
)
277 if (FullSectors
> 0xffff)
280 /* Read full sectors */
281 ASSERT(Context
->SectorNumber
< 0xFFFFFFFF);
282 Lba
= (ULONG
)Context
->SectorNumber
;
285 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
289 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
290 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
291 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
292 Srb
->PathId
= Context
->PathId
;
293 Srb
->TargetId
= Context
->TargetId
;
294 Srb
->Lun
= Context
->Lun
;
296 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
297 Srb
->DataTransferLength
= FullSectors
* Context
->SectorSize
;
298 Srb
->TimeOutValue
= 5; /* in seconds */
299 Srb
->DataBuffer
= Buffer
;
300 Cdb
= (PCDB
)Srb
->Cdb
;
301 Cdb
->CDB10
.OperationCode
= SCSIOP_READ
;
302 Cdb
->CDB10
.LogicalUnitNumber
= Srb
->Lun
;
303 Cdb
->CDB10
.LogicalBlockByte0
= (Lba
>> 24) & 0xff;
304 Cdb
->CDB10
.LogicalBlockByte1
= (Lba
>> 16) & 0xff;
305 Cdb
->CDB10
.LogicalBlockByte2
= (Lba
>> 8) & 0xff;
306 Cdb
->CDB10
.LogicalBlockByte3
= Lba
& 0xff;
307 Cdb
->CDB10
.TransferBlocksMsb
= (FullSectors
>> 8) & 0xff;
308 Cdb
->CDB10
.TransferBlocksLsb
= FullSectors
& 0xff;
309 if (!SpiSendSynchronousSrb(Context
->DeviceExtension
, Srb
))
313 Buffer
= (PUCHAR
)Buffer
+ FullSectors
* Context
->SectorSize
;
314 N
-= FullSectors
* Context
->SectorSize
;
315 *Count
+= FullSectors
* Context
->SectorSize
;
319 /* Read incomplete last sector */
324 Sector
= ExAllocatePool(PagedPool
, Context
->SectorSize
);
328 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
335 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
336 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
337 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
338 Srb
->PathId
= Context
->PathId
;
339 Srb
->TargetId
= Context
->TargetId
;
340 Srb
->Lun
= Context
->Lun
;
342 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
343 Srb
->DataTransferLength
= Context
->SectorSize
;
344 Srb
->TimeOutValue
= 5; /* in seconds */
345 Srb
->DataBuffer
= Sector
;
346 Cdb
= (PCDB
)Srb
->Cdb
;
347 Cdb
->CDB10
.OperationCode
= SCSIOP_READ
;
348 Cdb
->CDB10
.LogicalUnitNumber
= Srb
->Lun
;
349 Cdb
->CDB10
.LogicalBlockByte0
= (Lba
>> 24) & 0xff;
350 Cdb
->CDB10
.LogicalBlockByte1
= (Lba
>> 16) & 0xff;
351 Cdb
->CDB10
.LogicalBlockByte2
= (Lba
>> 8) & 0xff;
352 Cdb
->CDB10
.LogicalBlockByte3
= Lba
& 0xff;
353 Cdb
->CDB10
.TransferBlocksMsb
= 0;
354 Cdb
->CDB10
.TransferBlocksLsb
= 1;
355 if (!SpiSendSynchronousSrb(Context
->DeviceExtension
, Srb
))
360 RtlCopyMemory(Buffer
, Sector
, N
);
368 static ARC_STATUS
DiskSeek(ULONG FileId
, LARGE_INTEGER
* Position
, SEEKMODE SeekMode
)
370 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
372 if (SeekMode
!= SeekAbsolute
)
374 if (Position
->QuadPart
& (Context
->SectorSize
- 1))
377 Context
->SectorNumber
= Position
->QuadPart
/ Context
->SectorSize
;
381 static const DEVVTBL DiskVtbl
= {
383 DiskGetFileInformation
,
392 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
393 IN PHW_INITIALIZATION_DATA HwInitData
,
394 OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
395 IN BOOLEAN ZeroStruct
)
399 /* Zero out the struct if told so */
402 /* First zero the portconfig */
403 RtlZeroMemory(ConfigInfo
, sizeof(PORT_CONFIGURATION_INFORMATION
));
405 /* Initialize the struct */
406 ConfigInfo
->Length
= sizeof(PORT_CONFIGURATION_INFORMATION
);
407 ConfigInfo
->AdapterInterfaceType
= HwInitData
->AdapterInterfaceType
;
408 ConfigInfo
->InterruptMode
= Latched
;
409 ConfigInfo
->DmaChannel
= SP_UNINITIALIZED_VALUE
;
410 ConfigInfo
->DmaPort
= SP_UNINITIALIZED_VALUE
;
411 ConfigInfo
->MaximumTransferLength
= SP_UNINITIALIZED_VALUE
;
412 ConfigInfo
->MaximumNumberOfTargets
= SCSI_MAXIMUM_TARGETS_PER_BUS
;
414 /* Store parameters */
415 ConfigInfo
->NeedPhysicalAddresses
= HwInitData
->NeedPhysicalAddresses
;
416 ConfigInfo
->MapBuffers
= HwInitData
->MapBuffers
;
417 ConfigInfo
->AutoRequestSense
= HwInitData
->AutoRequestSense
;
418 ConfigInfo
->ReceiveEvent
= HwInitData
->ReceiveEvent
;
419 ConfigInfo
->TaggedQueuing
= HwInitData
->TaggedQueuing
;
420 ConfigInfo
->MultipleRequestPerLu
= HwInitData
->MultipleRequestPerLu
;
422 /* Get the disk usage */
423 ConfigInfo
->AtdiskPrimaryClaimed
= FALSE
; // FIXME
424 ConfigInfo
->AtdiskSecondaryClaimed
= FALSE
; // FIXME
426 /* Initiator bus id is not set */
427 for (Bus
= 0; Bus
< 8; Bus
++)
428 ConfigInfo
->InitiatorBusId
[Bus
] = (CCHAR
)SP_UNINITIALIZED_VALUE
;
431 ConfigInfo
->NumberOfPhysicalBreaks
= 17;
433 return STATUS_SUCCESS
;
439 IN ULONG DebugPrintLevel
,
440 IN PCCHAR DebugMessage
,
447 if (DebugPrintLevel
> 10)
450 va_start(ap
, DebugMessage
);
452 /* Construct a string */
453 Length
= _vsnprintf(Buffer
, 512, DebugMessage
, ap
);
455 /* Check if we went past the buffer */
456 if (Length
== MAXULONG
)
458 /* Terminate it if we went over-board */
459 Buffer
[sizeof(Buffer
) - 1] = '\0';
462 Length
= sizeof(Buffer
);
465 /* Print the message */
474 ScsiPortCompleteRequest(
475 IN PVOID HwDeviceExtension
,
485 #undef ScsiPortConvertPhysicalAddressToUlong
488 ScsiPortConvertPhysicalAddressToUlong(
489 IN SCSI_PHYSICAL_ADDRESS Address
)
491 return Address
.LowPart
;
494 SCSI_PHYSICAL_ADDRESS
496 ScsiPortConvertUlongToPhysicalAddress(
497 IN ULONG_PTR UlongAddress
)
499 SCSI_PHYSICAL_ADDRESS Address
;
501 Address
.QuadPart
= UlongAddress
;
508 IN PVOID DeviceExtension
)
516 ScsiPortFreeDeviceBase(
517 IN PVOID HwDeviceExtension
,
518 IN PVOID MappedAddress
)
526 IN PVOID DeviceExtension
,
527 IN ULONG BusDataType
,
528 IN ULONG SystemIoBusNumber
,
533 return HalGetBusDataByOffset(BusDataType
, SystemIoBusNumber
, SlotNumber
, Buffer
, 0, Length
);
538 ScsiPortGetDeviceBase(
539 IN PVOID HwDeviceExtension
,
540 IN INTERFACE_TYPE BusType
,
541 IN ULONG SystemIoBusNumber
,
542 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
543 IN ULONG NumberOfBytes
,
544 IN BOOLEAN InIoSpace
)
546 PHYSICAL_ADDRESS TranslatedAddress
;
549 AddressSpace
= (ULONG
)InIoSpace
;
550 if (HalTranslateBusAddress(BusType
,
554 &TranslatedAddress
) == FALSE
)
560 if (AddressSpace
!= 0)
561 return (PVOID
)TranslatedAddress
.u
.LowPart
;
565 return (PVOID
)IoAddress
.LowPart
;
570 ScsiPortGetLogicalUnit(
571 IN PVOID HwDeviceExtension
,
581 SCSI_PHYSICAL_ADDRESS
583 ScsiPortGetPhysicalAddress(
584 IN PVOID HwDeviceExtension
,
585 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
586 IN PVOID VirtualAddress
,
589 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
590 SCSI_PHYSICAL_ADDRESS PhysicalAddress
;
591 ULONG BufferLength
= 0;
594 TRACE("ScsiPortGetPhysicalAddress(%p %p %p %p)\n",
595 HwDeviceExtension
, Srb
, VirtualAddress
, Length
);
597 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
599 if (Srb
== NULL
|| Srb
->SenseInfoBuffer
== VirtualAddress
)
601 /* Simply look it up in the allocated common buffer */
602 Offset
= (PUCHAR
)VirtualAddress
- (PUCHAR
)DeviceExtension
->SrbExtensionBuffer
;
604 BufferLength
= DeviceExtension
->CommonBufferLength
- Offset
;
605 PhysicalAddress
.QuadPart
= Offset
;
611 PhysicalAddress
.QuadPart
= (LONGLONG
)(SP_UNINITIALIZED_VALUE
);
614 *Length
= BufferLength
;
615 return PhysicalAddress
;
621 IN PVOID DeviceExtension
,
634 SpiAllocateCommonBuffer(
635 IN OUT PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
636 IN ULONG NonCachedSize
)
639 ULONG CommonBufferLength
, BufSize
;
641 /* If size is 0, set it to 16 */
642 if (!DeviceExtension
->SrbExtensionSize
)
643 DeviceExtension
->SrbExtensionSize
= 16;
646 BufSize
= DeviceExtension
->SrbExtensionSize
;
649 BufSize
= (BufSize
+ sizeof(LONGLONG
) - 1) & ~(sizeof(LONGLONG
) - 1);
651 /* Sum up into the total common buffer length, and round it to page size */
653 ROUND_TO_PAGES(NonCachedSize
);
656 if (!DeviceExtension
->AdapterObject
)
658 /* From nonpaged pool if there is no DMA */
659 CommonBuffer
= ExAllocatePool(NonPagedPool
, CommonBufferLength
);
663 /* Perform a full request since we have a DMA adapter*/
668 /* Fail in case of error */
670 return STATUS_INSUFFICIENT_RESOURCES
;
673 RtlZeroMemory(CommonBuffer
, CommonBufferLength
);
675 /* Store its size in Device Extension */
676 DeviceExtension
->CommonBufferLength
= CommonBufferLength
;
678 /* SrbExtension buffer is located at the beginning of the buffer */
679 DeviceExtension
->SrbExtensionBuffer
= CommonBuffer
;
681 /* Non-cached extension buffer is located at the end of
685 CommonBufferLength
-= NonCachedSize
;
686 DeviceExtension
->NonCachedExtension
= (PUCHAR
)CommonBuffer
+ CommonBufferLength
;
690 DeviceExtension
->NonCachedExtension
= NULL
;
693 return STATUS_SUCCESS
;
698 ScsiPortGetUncachedExtension(
699 IN PVOID HwDeviceExtension
,
700 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
701 IN ULONG NumberOfBytes
)
703 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
704 DEVICE_DESCRIPTION DeviceDescription
;
705 ULONG MapRegistersCount
;
708 TRACE("ScsiPortGetUncachedExtension(%p %p %lu)\n",
709 HwDeviceExtension
, ConfigInfo
, NumberOfBytes
);
711 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
713 /* Check for allocated common DMA buffer */
714 if (DeviceExtension
->SrbExtensionBuffer
!= NULL
)
719 /* Check for DMA adapter object */
720 if (DeviceExtension
->AdapterObject
== NULL
)
722 /* Initialize DMA adapter description */
723 RtlZeroMemory(&DeviceDescription
, sizeof(DEVICE_DESCRIPTION
));
725 DeviceDescription
.Version
= DEVICE_DESCRIPTION_VERSION
;
726 DeviceDescription
.Master
= ConfigInfo
->Master
;
727 DeviceDescription
.ScatterGather
= ConfigInfo
->ScatterGather
;
728 DeviceDescription
.DemandMode
= ConfigInfo
->DemandMode
;
729 DeviceDescription
.Dma32BitAddresses
= ConfigInfo
->Dma32BitAddresses
;
730 DeviceDescription
.BusNumber
= ConfigInfo
->SystemIoBusNumber
;
731 DeviceDescription
.DmaChannel
= ConfigInfo
->DmaChannel
;
732 DeviceDescription
.InterfaceType
= ConfigInfo
->AdapterInterfaceType
;
733 DeviceDescription
.DmaWidth
= ConfigInfo
->DmaWidth
;
734 DeviceDescription
.DmaSpeed
= ConfigInfo
->DmaSpeed
;
735 DeviceDescription
.MaximumLength
= ConfigInfo
->MaximumTransferLength
;
736 DeviceDescription
.DmaPort
= ConfigInfo
->DmaPort
;
738 /* Get a DMA adapter object */
740 DeviceExtension
->AdapterObject
=
741 HalGetAdapter(&DeviceDescription
, &MapRegistersCount
);
743 /* Fail in case of error */
744 if (DeviceExtension
->AdapterObject
== NULL
)
749 MapRegistersCount
= 0;
752 /* Set number of physical breaks */
753 if (ConfigInfo
->NumberOfPhysicalBreaks
!= 0 &&
754 MapRegistersCount
> ConfigInfo
->NumberOfPhysicalBreaks
)
756 DeviceExtension
->PortCapabilities
.MaximumPhysicalPages
=
757 ConfigInfo
->NumberOfPhysicalBreaks
;
761 DeviceExtension
->PortCapabilities
.MaximumPhysicalPages
= MapRegistersCount
;
765 /* Update Srb extension size */
766 if (DeviceExtension
->SrbExtensionSize
!= ConfigInfo
->SrbExtensionSize
)
767 DeviceExtension
->SrbExtensionSize
= ConfigInfo
->SrbExtensionSize
;
769 /* Allocate a common DMA buffer */
770 Status
= SpiAllocateCommonBuffer(DeviceExtension
, NumberOfBytes
);
772 if (!NT_SUCCESS(Status
))
774 TRACE("SpiAllocateCommonBuffer() failed with Status = 0x%08X!\n", Status
);
778 return DeviceExtension
->NonCachedExtension
;
783 ScsiPortGetVirtualAddress(
784 IN PVOID HwDeviceExtension
,
785 IN SCSI_PHYSICAL_ADDRESS PhysicalAddress
)
795 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
804 struct _DRIVE_LAYOUT_INFORMATION
*PartitionBuffer
;
805 CHAR PartitionName
[64];
807 /* Register device with partition(0) suffix */
808 sprintf(PartitionName
, "%spartition(0)", ArcName
);
809 FsRegisterDevice(PartitionName
, &DiskVtbl
);
811 /* Read device partition table */
812 Status
= ArcOpen(PartitionName
, OpenReadOnly
, &FileId
);
813 if (Status
== ESUCCESS
)
815 ret
= HALDISPATCH
->HalIoReadPartitionTable((PDEVICE_OBJECT
)FileId
, 512, FALSE
, &PartitionBuffer
);
818 for (i
= 0; i
< PartitionBuffer
->PartitionCount
; i
++)
820 if (PartitionBuffer
->PartitionEntry
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
)
822 sprintf(PartitionName
, "%spartition(%lu)",
823 ArcName
, PartitionBuffer
->PartitionEntry
[i
].PartitionNumber
);
824 FsRegisterDevice(PartitionName
, &DiskVtbl
);
827 ExFreePool(PartitionBuffer
);
836 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
841 PSCSI_REQUEST_BLOCK Srb
;
843 INQUIRYDATA InquiryBuffer
;
847 if (!DeviceExtension
->HwResetBus(DeviceExtension
->MiniPortDeviceExtension
, PathId
))
852 /* Remember the extension */
853 ScsiDeviceExtensions
[ScsiBus
] = DeviceExtension
;
855 for (TargetId
= 0; TargetId
< DeviceExtension
->MaxTargedIds
; TargetId
++)
860 TRACE("Scanning SCSI device %d.%d.%d\n",
861 ScsiBus
, TargetId
, Lun
);
863 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
866 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
867 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
868 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
869 Srb
->PathId
= PathId
;
870 Srb
->TargetId
= TargetId
;
873 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
874 Srb
->DataTransferLength
= INQUIRYDATABUFFERSIZE
;
875 Srb
->TimeOutValue
= 5; /* in seconds */
876 Srb
->DataBuffer
= &InquiryBuffer
;
877 Cdb
= (PCDB
)Srb
->Cdb
;
878 Cdb
->CDB6INQUIRY
.OperationCode
= SCSIOP_INQUIRY
;
879 Cdb
->CDB6INQUIRY
.LogicalUnitNumber
= Srb
->Lun
;
880 Cdb
->CDB6INQUIRY
.AllocationLength
= (UCHAR
)Srb
->DataTransferLength
;
881 if (!SpiSendSynchronousSrb(DeviceExtension
, Srb
))
883 /* Don't check next LUNs */
887 /* Device exists, create its ARC name */
888 if (InquiryBuffer
.RemovableMedia
)
890 sprintf(ArcName
, "scsi(%ld)cdrom(%d)fdisk(%d)",
891 ScsiBus
, TargetId
, Lun
);
892 FsRegisterDevice(ArcName
, &DiskVtbl
);
896 sprintf(ArcName
, "scsi(%ld)disk(%d)rdisk(%d)",
897 ScsiBus
, TargetId
, Lun
);
898 /* Now, check if it has partitions */
899 SpiScanDevice(DeviceExtension
, ArcName
, PathId
, TargetId
, Lun
);
904 } while (Lun
< SCSI_MAXIMUM_LOGICAL_UNITS
);
911 IN PHW_INITIALIZATION_DATA HwInitializationData
,
912 IN PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor
,
913 IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig
)
915 PACCESS_RANGE AccessRange
;
916 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialData
;
922 /* Loop through all entries */
923 for (Index
= 0; Index
< ResourceDescriptor
->PartialResourceList
.Count
; Index
++)
925 PartialData
= &ResourceDescriptor
->PartialResourceList
.PartialDescriptors
[Index
];
927 switch (PartialData
->Type
)
929 case CmResourceTypePort
:
930 /* Copy access ranges */
931 if (RangeNumber
< HwInitializationData
->NumberOfAccessRanges
)
933 TRACE("Got port at 0x%I64x, len 0x%x\n",
934 PartialData
->u
.Port
.Start
.QuadPart
, PartialData
->u
.Port
.Length
);
935 AccessRange
= &((*(PortConfig
->AccessRanges
))[RangeNumber
]);
937 AccessRange
->RangeStart
= PartialData
->u
.Port
.Start
;
938 AccessRange
->RangeLength
= PartialData
->u
.Port
.Length
;
940 AccessRange
->RangeInMemory
= FALSE
;
945 case CmResourceTypeMemory
:
946 /* Copy access ranges */
947 if (RangeNumber
< HwInitializationData
->NumberOfAccessRanges
)
949 TRACE("Got memory at 0x%I64x, len 0x%x\n",
950 PartialData
->u
.Memory
.Start
.QuadPart
, PartialData
->u
.Memory
.Length
);
951 AccessRange
= &((*(PortConfig
->AccessRanges
))[RangeNumber
]);
953 AccessRange
->RangeStart
= PartialData
->u
.Memory
.Start
;
954 AccessRange
->RangeLength
= PartialData
->u
.Memory
.Length
;
956 AccessRange
->RangeInMemory
= TRUE
;
961 case CmResourceTypeInterrupt
:
962 /* Copy interrupt data */
963 TRACE("Got interrupt level %d, vector %d\n",
964 PartialData
->u
.Interrupt
.Level
, PartialData
->u
.Interrupt
.Vector
);
965 PortConfig
->BusInterruptLevel
= PartialData
->u
.Interrupt
.Level
;
966 PortConfig
->BusInterruptVector
= PartialData
->u
.Interrupt
.Vector
;
968 /* Set interrupt mode accordingly to the resource */
969 if (PartialData
->Flags
== CM_RESOURCE_INTERRUPT_LATCHED
)
971 PortConfig
->InterruptMode
= Latched
;
973 else if (PartialData
->Flags
== CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
)
975 PortConfig
->InterruptMode
= LevelSensitive
;
979 case CmResourceTypeDma
:
980 TRACE("Got DMA channel %d, port %d\n",
981 PartialData
->u
.Dma
.Channel
, PartialData
->u
.Dma
.Port
);
982 PortConfig
->DmaChannel
= PartialData
->u
.Dma
.Channel
;
983 PortConfig
->DmaPort
= PartialData
->u
.Dma
.Port
;
992 IN PHW_INITIALIZATION_DATA HwInitializationData
,
993 IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig
,
995 IN OUT PPCI_SLOT_NUMBER NextSlotNumber
)
997 PCI_COMMON_CONFIG PciConfig
;
998 PCI_SLOT_NUMBER SlotNumber
;
1001 ULONG FunctionNumber
;
1002 CHAR VendorIdString
[8];
1003 CHAR DeviceIdString
[8];
1004 PCM_RESOURCE_LIST ResourceList
= NULL
;
1007 SlotNumber
.u
.AsULONG
= 0;
1009 /* Loop through all devices */
1010 for (DeviceNumber
= NextSlotNumber
->u
.bits
.DeviceNumber
; DeviceNumber
< PCI_MAX_DEVICES
; DeviceNumber
++)
1012 SlotNumber
.u
.bits
.DeviceNumber
= DeviceNumber
;
1014 /* Loop through all functions */
1015 for (FunctionNumber
= NextSlotNumber
->u
.bits
.FunctionNumber
; FunctionNumber
< PCI_MAX_FUNCTION
; FunctionNumber
++)
1017 SlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
1019 /* Get PCI config bytes */
1020 DataSize
= HalGetBusDataByOffset(
1023 SlotNumber
.u
.AsULONG
,
1028 /* If result of HalGetBusData is 0, then the bus is wrong */
1032 /* If result is PCI_INVALID_VENDORID, then this device has no more
1034 if (PciConfig
.VendorID
== PCI_INVALID_VENDORID
)
1037 sprintf(VendorIdString
, "%04hx", PciConfig
.VendorID
);
1038 sprintf(DeviceIdString
, "%04hx", PciConfig
.DeviceID
);
1040 if (_strnicmp(VendorIdString
, HwInitializationData
->VendorId
, HwInitializationData
->VendorIdLength
) ||
1041 _strnicmp(DeviceIdString
, HwInitializationData
->DeviceId
, HwInitializationData
->DeviceIdLength
))
1043 /* It is not our device */
1047 TRACE( "Found device 0x%04hx 0x%04hx at %1lu %2lu %1lu\n",
1048 PciConfig
.VendorID
, PciConfig
.DeviceID
,
1050 SlotNumber
.u
.bits
.DeviceNumber
, SlotNumber
.u
.bits
.FunctionNumber
);
1052 Status
= HalAssignSlotResources(NULL
,
1058 SlotNumber
.u
.AsULONG
,
1061 if (!NT_SUCCESS(Status
))
1064 /* Create configuration information */
1065 SpiResourceToConfig(HwInitializationData
,
1069 /* Free the resource list */
1070 ExFreePool(ResourceList
);
1072 /* Set dev & fn numbers */
1073 NextSlotNumber
->u
.bits
.DeviceNumber
= DeviceNumber
;
1074 NextSlotNumber
->u
.bits
.FunctionNumber
= FunctionNumber
+ 1;
1076 /* Save the slot number */
1077 PortConfig
->SlotNumber
= SlotNumber
.u
.AsULONG
;
1081 NextSlotNumber
->u
.bits
.FunctionNumber
= 0;
1084 NextSlotNumber
->u
.bits
.DeviceNumber
= 0;
1094 IN PHW_INITIALIZATION_DATA HwInitializationData
,
1095 IN PVOID HwContext OPTIONAL
)
1097 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
1098 ULONG DeviceExtensionSize
;
1099 PORT_CONFIGURATION_INFORMATION PortConfig
;
1101 BOOLEAN FirstConfigCall
= TRUE
;
1102 PCI_SLOT_NUMBER SlotNumber
;
1106 if (HwInitializationData
->HwInitializationDataSize
!= sizeof(HW_INITIALIZATION_DATA
))
1108 return STATUS_INVALID_PARAMETER
;
1111 /* Check params for validity */
1112 if ((HwInitializationData
->HwInitialize
== NULL
) ||
1113 (HwInitializationData
->HwStartIo
== NULL
) ||
1114 (HwInitializationData
->HwInterrupt
== NULL
) ||
1115 (HwInitializationData
->HwFindAdapter
== NULL
) ||
1116 (HwInitializationData
->HwResetBus
== NULL
))
1118 return STATUS_INVALID_PARAMETER
;
1121 /* Zero starting slot number */
1122 SlotNumber
.u
.AsULONG
= 0;
1128 DeviceExtensionSize
= sizeof(SCSI_PORT_DEVICE_EXTENSION
) + HwInitializationData
->DeviceExtensionSize
;
1129 DeviceExtension
= FrLdrTempAlloc(DeviceExtensionSize
, TAG_SCSI_DEVEXT
);
1130 if (!DeviceExtension
)
1132 return STATUS_NO_MEMORY
;
1134 RtlZeroMemory(DeviceExtension
, DeviceExtensionSize
);
1135 DeviceExtension
->InterruptFlags
= SCSI_PORT_NEXT_REQUEST_READY
;
1136 DeviceExtension
->HwInitialize
= HwInitializationData
->HwInitialize
;
1137 DeviceExtension
->HwStartIo
= HwInitializationData
->HwStartIo
;
1138 DeviceExtension
->HwInterrupt
= HwInitializationData
->HwInterrupt
;
1139 DeviceExtension
->HwResetBus
= HwInitializationData
->HwResetBus
;
1140 DeviceExtension
->MiniPortDeviceExtension
= (PVOID
)(DeviceExtension
+ 1);
1142 Status
= SpiCreatePortConfig(DeviceExtension
,
1143 HwInitializationData
,
1146 if (Status
!= STATUS_SUCCESS
)
1148 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1152 PortConfig
.NumberOfAccessRanges
= HwInitializationData
->NumberOfAccessRanges
;
1153 PortConfig
.AccessRanges
= FrLdrTempAlloc(sizeof(ACCESS_RANGE
) * HwInitializationData
->NumberOfAccessRanges
,
1154 TAG_SCSI_ACCESS_RANGES
);
1155 if (!PortConfig
.AccessRanges
)
1157 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1158 return STATUS_NO_MEMORY
;
1160 RtlZeroMemory(PortConfig
.AccessRanges
, sizeof(ACCESS_RANGE
) * HwInitializationData
->NumberOfAccessRanges
);
1162 /* Search for matching PCI device */
1163 if ((HwInitializationData
->AdapterInterfaceType
== PCIBus
) &&
1164 (HwInitializationData
->VendorIdLength
> 0) &&
1165 (HwInitializationData
->VendorId
!= NULL
) &&
1166 (HwInitializationData
->DeviceIdLength
> 0) &&
1167 (HwInitializationData
->DeviceId
!= NULL
))
1169 PortConfig
.BusInterruptLevel
= 0;
1171 /* Get PCI device data */
1172 TRACE("VendorId '%.*s' DeviceId '%.*s'\n",
1173 HwInitializationData
->VendorIdLength
,
1174 HwInitializationData
->VendorId
,
1175 HwInitializationData
->DeviceIdLength
,
1176 HwInitializationData
->DeviceId
);
1178 if (!SpiGetPciConfigData(HwInitializationData
,
1183 /* Continue to the next bus, nothing here */
1184 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1185 return STATUS_INTERNAL_ERROR
;
1188 if (!PortConfig
.BusInterruptLevel
)
1190 /* Bypass this slot, because no interrupt was assigned */
1191 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1192 return STATUS_INTERNAL_ERROR
;
1196 if (HwInitializationData
->HwFindAdapter(
1197 DeviceExtension
->MiniPortDeviceExtension
,
1202 &Again
) != SP_RETURN_FOUND
)
1204 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1205 return STATUS_INTERNAL_ERROR
;
1208 /* Copy all stuff which we ever need from PortConfig to the DeviceExtension */
1209 if (PortConfig
.MaximumNumberOfTargets
> SCSI_MAXIMUM_TARGETS_PER_BUS
)
1210 DeviceExtension
->MaxTargedIds
= SCSI_MAXIMUM_TARGETS_PER_BUS
;
1212 DeviceExtension
->MaxTargedIds
= PortConfig
.MaximumNumberOfTargets
;
1214 DeviceExtension
->BusNum
= PortConfig
.SystemIoBusNumber
;
1216 TRACE("Adapter found: buses = %d, targets = %d\n",
1217 PortConfig
.NumberOfBuses
, DeviceExtension
->MaxTargedIds
);
1219 /* Initialize adapter */
1220 if (!DeviceExtension
->HwInitialize(DeviceExtension
->MiniPortDeviceExtension
))
1222 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1223 return STATUS_INTERNAL_ERROR
;
1227 for (ScsiBus
= 0; ScsiBus
< PortConfig
.NumberOfBuses
; ScsiBus
++)
1229 SpiScanAdapter(DeviceExtension
, PortConfig
.SystemIoBusNumber
, ScsiBus
);
1230 PortConfig
.SystemIoBusNumber
++;
1233 FirstConfigCall
= FALSE
;
1240 return STATUS_SUCCESS
;
1245 ScsiPortIoMapTransfer(
1246 IN PVOID HwDeviceExtension
,
1247 IN PSCSI_REQUEST_BLOCK Srb
,
1248 IN PVOID LogicalAddress
,
1258 IN PVOID HwDeviceExtension
,
1259 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
1273 IN PVOID WriteBuffer
,
1274 IN PVOID ReadBuffer
,
1277 RtlMoveMemory(WriteBuffer
, ReadBuffer
, Length
);
1282 ScsiPortNotification(
1283 IN SCSI_NOTIFICATION_TYPE NotificationType
,
1284 IN PVOID HwDeviceExtension
,
1287 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
1288 PSCSI_REQUEST_BLOCK Srb
;
1291 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
1293 va_start(ap
, HwDeviceExtension
);
1295 switch (NotificationType
)
1297 case RequestComplete
:
1298 /* Mask the SRB as completed */
1299 Srb
= va_arg(ap
, PSCSI_REQUEST_BLOCK
);
1300 Srb
->SrbFlags
&= ~SRB_FLAGS_IS_ACTIVE
;
1304 /* Say that device is ready */
1305 DeviceExtension
->InterruptFlags
|= SCSI_PORT_NEXT_REQUEST_READY
;
1318 ScsiPortReadPortBufferUchar(
1323 __inbytestring(H2I(Port
), Buffer
, Count
);
1328 ScsiPortReadPortBufferUlong(
1333 __indwordstring(H2I(Port
), Buffer
, Count
);
1338 ScsiPortReadPortBufferUshort(
1343 __inwordstring(H2I(Port
), Buffer
, Count
);
1348 ScsiPortReadPortUchar(
1351 TRACE("ScsiPortReadPortUchar(%p)\n", Port
);
1353 return READ_PORT_UCHAR(Port
);
1358 ScsiPortReadPortUlong(
1361 return READ_PORT_ULONG(Port
);
1366 ScsiPortReadPortUshort(
1369 return READ_PORT_USHORT(Port
);
1374 ScsiPortReadRegisterBufferUchar(
1385 ScsiPortReadRegisterBufferUlong(
1396 ScsiPortReadRegisterBufferUshort(
1397 IN PUSHORT Register
,
1407 ScsiPortReadRegisterUchar(
1410 return READ_REGISTER_UCHAR(Register
);
1415 ScsiPortReadRegisterUlong(
1418 return READ_REGISTER_ULONG(Register
);
1423 ScsiPortReadRegisterUshort(
1424 IN PUSHORT Register
)
1426 return READ_REGISTER_USHORT(Register
);
1431 ScsiPortSetBusDataByOffset(
1432 IN PVOID DeviceExtension
,
1433 IN ULONG BusDataType
,
1434 IN ULONG SystemIoBusNumber
,
1435 IN ULONG SlotNumber
,
1447 ScsiPortStallExecution(
1450 KeStallExecutionProcessor(Delay
);
1455 ScsiPortValidateRange(
1456 IN PVOID HwDeviceExtension
,
1457 IN INTERFACE_TYPE BusType
,
1458 IN ULONG SystemIoBusNumber
,
1459 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
1460 IN ULONG NumberOfBytes
,
1461 IN BOOLEAN InIoSpace
)
1475 ScsiPortWritePortBufferUchar(
1480 __outbytestring(H2I(Port
), Buffer
, Count
);
1485 ScsiPortWritePortBufferUlong(
1490 __outdwordstring(H2I(Port
), Buffer
, Count
);
1495 ScsiPortWritePortBufferUshort(
1500 __outwordstring(H2I(Port
), Buffer
, Count
);
1505 ScsiPortWritePortUchar(
1509 WRITE_PORT_UCHAR(Port
, Value
);
1514 ScsiPortWritePortUlong(
1518 WRITE_PORT_ULONG(Port
, Value
);
1523 ScsiPortWritePortUshort(
1527 WRITE_PORT_USHORT(Port
, Value
);
1532 ScsiPortWriteRegisterBufferUchar(
1543 ScsiPortWriteRegisterBufferUlong(
1554 ScsiPortWriteRegisterBufferUshort(
1555 IN PUSHORT Register
,
1565 ScsiPortWriteRegisterUchar(
1569 WRITE_REGISTER_UCHAR(Register
, Value
);
1574 ScsiPortWriteRegisterUlong(
1578 WRITE_REGISTER_ULONG(Register
, Value
);
1583 ScsiPortWriteRegisterUshort(
1584 IN PUSHORT Register
,
1587 WRITE_REGISTER_USHORT(Register
, Value
);
1590 extern char __ImageBase
;
1593 LoadBootDeviceDriver(VOID
)
1595 PIMAGE_NT_HEADERS NtHeaders
;
1596 LIST_ENTRY ModuleListHead
;
1597 PIMAGE_IMPORT_DESCRIPTOR ImportTable
;
1598 ULONG ImportTableSize
;
1599 PLDR_DATA_TABLE_ENTRY BootDdDTE
, FreeldrDTE
;
1600 CHAR NtBootDdPath
[MAX_PATH
];
1601 PVOID ImageBase
= NULL
;
1602 ULONG (NTAPI
*EntryPoint
)(IN PVOID DriverObject
, IN PVOID RegistryPath
);
1605 // FIXME: Must be done *INSIDE* the HAL!
1607 HalpInitializePciStubs();
1608 HalpInitBusHandler();
1611 /* Initialize the loaded module list */
1612 InitializeListHead(&ModuleListHead
);
1614 /* Create full ntbootdd.sys path */
1615 MachDiskGetBootPath(NtBootDdPath
, sizeof(NtBootDdPath
));
1616 strcat(NtBootDdPath
, "\\NTBOOTDD.SYS");
1619 Success
= WinLdrLoadImage(NtBootDdPath
, LoaderBootDriver
, &ImageBase
);
1622 /* That's OK. File simply doesn't exist */
1626 /* Allocate a DTE for ntbootdd */
1627 Success
= WinLdrAllocateDataTableEntry(&ModuleListHead
, "ntbootdd.sys",
1628 "NTBOOTDD.SYS", ImageBase
, &BootDdDTE
);
1632 /* Add the PE part of freeldr.sys to the list of loaded executables, it
1633 contains Scsiport* exports, imported by ntbootdd.sys */
1634 Success
= WinLdrAllocateDataTableEntry(&ModuleListHead
, "scsiport.sys",
1635 "FREELDR.SYS", &__ImageBase
, &FreeldrDTE
);
1638 RemoveEntryList(&BootDdDTE
->InLoadOrderLinks
);
1643 Success
= WinLdrScanImportDescriptorTable(&ModuleListHead
, "", BootDdDTE
);
1645 /* Now unlinkt the DTEs, they won't be valid later */
1646 RemoveEntryList(&BootDdDTE
->InLoadOrderLinks
);
1647 RemoveEntryList(&FreeldrDTE
->InLoadOrderLinks
);
1652 /* Change imports to PA */
1653 ImportTable
= (PIMAGE_IMPORT_DESCRIPTOR
)RtlImageDirectoryEntryToData(VaToPa(BootDdDTE
->DllBase
),
1654 TRUE
, IMAGE_DIRECTORY_ENTRY_IMPORT
, &ImportTableSize
);
1655 for (;(ImportTable
->Name
!= 0) && (ImportTable
->FirstThunk
!= 0);ImportTable
++)
1657 PIMAGE_THUNK_DATA ThunkData
= (PIMAGE_THUNK_DATA
)VaToPa(RVA(BootDdDTE
->DllBase
, ImportTable
->FirstThunk
));
1659 while (((PIMAGE_THUNK_DATA
)ThunkData
)->u1
.AddressOfData
!= 0)
1661 ThunkData
->u1
.Function
= (ULONG
)VaToPa((PVOID
)ThunkData
->u1
.Function
);
1666 /* Relocate image to PA */
1667 NtHeaders
= RtlImageNtHeader(VaToPa(BootDdDTE
->DllBase
));
1670 Success
= (BOOLEAN
)LdrRelocateImageWithBias(VaToPa(BootDdDTE
->DllBase
),
1671 NtHeaders
->OptionalHeader
.ImageBase
- (ULONG_PTR
)BootDdDTE
->DllBase
,
1674 TRUE
, /* in case of conflict still return success */
1679 /* Call the entrypoint */
1680 EntryPoint
= VaToPa(BootDdDTE
->EntryPoint
);
1681 (*EntryPoint
)(NULL
, NULL
);