14 #undef ScsiPortLogError
15 #undef ScsiPortMoveMemory
16 #undef ScsiPortWritePortBufferUchar
17 #undef ScsiPortWritePortBufferUlong
18 #undef ScsiPortWritePortBufferUshort
19 #undef ScsiPortWritePortUchar
20 #undef ScsiPortWritePortUlong
21 #undef ScsiPortWritePortUshort
22 #undef ScsiPortWriteRegisterBufferUchar
23 #undef ScsiPortWriteRegisterBufferUlong
24 #undef ScsiPortWriteRegisterBufferUshort
25 #undef ScsiPortWriteRegisterUchar
26 #undef ScsiPortWriteRegisterUlong
27 #undef ScsiPortWriteRegisterUshort
28 #undef ScsiPortReadPortBufferUchar
29 #undef ScsiPortReadPortBufferUlong
30 #undef ScsiPortReadPortBufferUshort
31 #undef ScsiPortReadPortUchar
32 #undef ScsiPortReadPortUlong
33 #undef ScsiPortReadPortUshort
34 #undef ScsiPortReadRegisterBufferUchar
35 #undef ScsiPortReadRegisterBufferUlong
36 #undef ScsiPortReadRegisterBufferUshort
37 #undef ScsiPortReadRegisterUchar
38 #undef ScsiPortReadRegisterUlong
39 #undef ScsiPortReadRegisterUshort
44 #define SCSI_PORT_NEXT_REQUEST_READY 0x0008
46 #define TAG_SCSI_DEVEXT 'DscS'
47 #define TAG_SCSI_ACCESS_RANGES 'AscS'
49 DBG_DEFAULT_CHANNEL(SCSIPORT
);
52 VOID NTAPI
HalpInitializePciStubs(VOID
);
53 VOID NTAPI
HalpInitBusHandler(VOID
);
58 PVOID NonCachedExtension
;
65 /* SRB extension stuff */
66 ULONG SrbExtensionSize
;
67 PVOID SrbExtensionBuffer
;
69 IO_SCSI_CAPABILITIES PortCapabilities
;
71 PHW_INITIALIZE HwInitialize
;
72 PHW_STARTIO HwStartIo
;
73 PHW_INTERRUPT HwInterrupt
;
74 PHW_RESET_BUS HwResetBus
;
76 /* DMA related stuff */
77 PADAPTER_OBJECT AdapterObject
;
79 ULONG CommonBufferLength
;
81 PVOID MiniPortDeviceExtension
;
82 } SCSI_PORT_DEVICE_EXTENSION
, *PSCSI_PORT_DEVICE_EXTENSION
;
84 PSCSI_PORT_DEVICE_EXTENSION ScsiDeviceExtensions
[SCSI_MAXIMUM_BUSES
];
91 PFOUR_BYTE Source
= (PFOUR_BYTE
)&Value
;
93 Dest
.Byte0
= Source
->Byte3
;
94 Dest
.Byte1
= Source
->Byte2
;
95 Dest
.Byte2
= Source
->Byte1
;
96 Dest
.Byte3
= Source
->Byte0
;
103 SpiSendSynchronousSrb(
104 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
105 IN PSCSI_REQUEST_BLOCK Srb
)
109 ASSERT(!(Srb
->SrbFlags
& SRB_FLAGS_IS_ACTIVE
));
111 /* HACK: handle lack of interrupts */
112 while (!(DeviceExtension
->InterruptFlags
& SCSI_PORT_NEXT_REQUEST_READY
))
114 KeStallExecutionProcessor(100 * 1000);
115 DeviceExtension
->HwInterrupt(DeviceExtension
->MiniPortDeviceExtension
);
118 DeviceExtension
->InterruptFlags
&= ~SCSI_PORT_NEXT_REQUEST_READY
;
119 Srb
->SrbFlags
|= SRB_FLAGS_IS_ACTIVE
;
121 if (!DeviceExtension
->HwStartIo(
122 DeviceExtension
->MiniPortDeviceExtension
,
129 /* HACK: handle lack of interrupts */
130 while (Srb
->SrbFlags
& SRB_FLAGS_IS_ACTIVE
)
132 KeStallExecutionProcessor(100 * 1000);
133 DeviceExtension
->HwInterrupt(DeviceExtension
->MiniPortDeviceExtension
);
136 ret
= SRB_STATUS(Srb
->SrbStatus
) == SRB_STATUS_SUCCESS
;
142 typedef struct tagDISKCONTEXT
145 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
150 /* Device characteristics */
152 ULONGLONG SectorOffset
;
153 ULONGLONG SectorCount
;
154 ULONGLONG SectorNumber
;
157 static ARC_STATUS
DiskClose(ULONG FileId
)
159 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
165 static ARC_STATUS
DiskGetFileInformation(ULONG FileId
, FILEINFORMATION
* Information
)
167 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
169 RtlZeroMemory(Information
, sizeof(FILEINFORMATION
));
170 Information
->EndingAddress
.QuadPart
= Context
->SectorCount
* Context
->SectorSize
;
171 Information
->CurrentAddress
.QuadPart
= Context
->SectorNumber
* Context
->SectorSize
;
176 static ARC_STATUS
DiskOpen(CHAR
* Path
, OPENMODE OpenMode
, ULONG
* FileId
)
178 PSCSI_REQUEST_BLOCK Srb
;
180 READ_CAPACITY_DATA ReadCapacityBuffer
;
182 DISKCONTEXT
* Context
;
183 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
184 ULONG ScsiBus
, PathId
, TargetId
, Lun
, Partition
, PathSyntax
;
186 ULONGLONG SectorOffset
= 0;
187 ULONGLONG SectorCount
;
190 if (!DissectArcPath2(Path
, &ScsiBus
, &TargetId
, &Lun
, &Partition
, &PathSyntax
))
192 if (PathSyntax
!= 0) /* scsi() format */
194 DeviceExtension
= ScsiDeviceExtensions
[ScsiBus
];
195 PathId
= ScsiBus
- DeviceExtension
->BusNum
;
197 /* Get disk capacity and sector size */
198 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
201 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
202 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
203 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
204 Srb
->PathId
= (UCHAR
)PathId
;
205 Srb
->TargetId
= (UCHAR
)TargetId
;
206 Srb
->Lun
= (UCHAR
)Lun
;
208 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
209 Srb
->DataTransferLength
= sizeof(READ_CAPACITY_DATA
);
210 Srb
->TimeOutValue
= 5; /* in seconds */
211 Srb
->DataBuffer
= &ReadCapacityBuffer
;
212 Cdb
= (PCDB
)Srb
->Cdb
;
213 Cdb
->CDB10
.OperationCode
= SCSIOP_READ_CAPACITY
;
214 if (!SpiSendSynchronousSrb(DeviceExtension
, Srb
))
219 /* Transform result to host endianness */
220 SectorCount
= ntohl(ReadCapacityBuffer
.LogicalBlockAddress
);
221 SectorSize
= ntohl(ReadCapacityBuffer
.BytesPerBlock
);
225 /* Need to offset start of disk and length */
230 Context
= ExAllocatePool(PagedPool
, sizeof(DISKCONTEXT
));
233 Context
->DeviceExtension
= DeviceExtension
;
234 Context
->PathId
= (UCHAR
)PathId
;
235 Context
->TargetId
= (UCHAR
)TargetId
;
236 Context
->Lun
= (UCHAR
)Lun
;
237 Context
->SectorSize
= SectorSize
;
238 Context
->SectorOffset
= SectorOffset
;
239 Context
->SectorCount
= SectorCount
;
240 Context
->SectorNumber
= 0;
241 FsSetDeviceSpecific(*FileId
, Context
);
246 static ARC_STATUS
DiskRead(ULONG FileId
, VOID
* Buffer
, ULONG N
, ULONG
* Count
)
248 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
249 PSCSI_REQUEST_BLOCK Srb
;
251 ULONG FullSectors
, NbSectors
;
259 FullSectors
= N
/ Context
->SectorSize
;
260 NbSectors
= (N
+ Context
->SectorSize
- 1) / Context
->SectorSize
;
261 if (Context
->SectorNumber
+ NbSectors
>= Context
->SectorCount
)
263 if (FullSectors
> 0xffff)
266 /* Read full sectors */
267 ASSERT(Context
->SectorNumber
< 0xFFFFFFFF);
268 Lba
= (ULONG
)Context
->SectorNumber
;
271 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
275 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
276 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
277 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
278 Srb
->PathId
= Context
->PathId
;
279 Srb
->TargetId
= Context
->TargetId
;
280 Srb
->Lun
= Context
->Lun
;
282 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
283 Srb
->DataTransferLength
= FullSectors
* Context
->SectorSize
;
284 Srb
->TimeOutValue
= 5; /* in seconds */
285 Srb
->DataBuffer
= Buffer
;
286 Cdb
= (PCDB
)Srb
->Cdb
;
287 Cdb
->CDB10
.OperationCode
= SCSIOP_READ
;
288 Cdb
->CDB10
.LogicalUnitNumber
= Srb
->Lun
;
289 Cdb
->CDB10
.LogicalBlockByte0
= (Lba
>> 24) & 0xff;
290 Cdb
->CDB10
.LogicalBlockByte1
= (Lba
>> 16) & 0xff;
291 Cdb
->CDB10
.LogicalBlockByte2
= (Lba
>> 8) & 0xff;
292 Cdb
->CDB10
.LogicalBlockByte3
= Lba
& 0xff;
293 Cdb
->CDB10
.TransferBlocksMsb
= (FullSectors
>> 8) & 0xff;
294 Cdb
->CDB10
.TransferBlocksLsb
= FullSectors
& 0xff;
295 if (!SpiSendSynchronousSrb(Context
->DeviceExtension
, Srb
))
299 Buffer
= (PUCHAR
)Buffer
+ FullSectors
* Context
->SectorSize
;
300 N
-= FullSectors
* Context
->SectorSize
;
301 *Count
+= FullSectors
* Context
->SectorSize
;
305 /* Read incomplete last sector */
310 Sector
= ExAllocatePool(PagedPool
, Context
->SectorSize
);
314 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
321 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
322 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
323 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
324 Srb
->PathId
= Context
->PathId
;
325 Srb
->TargetId
= Context
->TargetId
;
326 Srb
->Lun
= Context
->Lun
;
328 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
329 Srb
->DataTransferLength
= Context
->SectorSize
;
330 Srb
->TimeOutValue
= 5; /* in seconds */
331 Srb
->DataBuffer
= Sector
;
332 Cdb
= (PCDB
)Srb
->Cdb
;
333 Cdb
->CDB10
.OperationCode
= SCSIOP_READ
;
334 Cdb
->CDB10
.LogicalUnitNumber
= Srb
->Lun
;
335 Cdb
->CDB10
.LogicalBlockByte0
= (Lba
>> 24) & 0xff;
336 Cdb
->CDB10
.LogicalBlockByte1
= (Lba
>> 16) & 0xff;
337 Cdb
->CDB10
.LogicalBlockByte2
= (Lba
>> 8) & 0xff;
338 Cdb
->CDB10
.LogicalBlockByte3
= Lba
& 0xff;
339 Cdb
->CDB10
.TransferBlocksMsb
= 0;
340 Cdb
->CDB10
.TransferBlocksLsb
= 1;
341 if (!SpiSendSynchronousSrb(Context
->DeviceExtension
, Srb
))
346 RtlCopyMemory(Buffer
, Sector
, N
);
354 static ARC_STATUS
DiskSeek(ULONG FileId
, LARGE_INTEGER
* Position
, SEEKMODE SeekMode
)
356 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
358 if (SeekMode
!= SeekAbsolute
)
360 if (Position
->QuadPart
& (Context
->SectorSize
- 1))
363 Context
->SectorNumber
= Position
->QuadPart
/ Context
->SectorSize
;
367 static const DEVVTBL DiskVtbl
= {
369 DiskGetFileInformation
,
378 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
379 IN PHW_INITIALIZATION_DATA HwInitData
,
380 OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
381 IN BOOLEAN ZeroStruct
)
385 /* Zero out the struct if told so */
388 /* First zero the portconfig */
389 RtlZeroMemory(ConfigInfo
, sizeof(PORT_CONFIGURATION_INFORMATION
));
391 /* Initialize the struct */
392 ConfigInfo
->Length
= sizeof(PORT_CONFIGURATION_INFORMATION
);
393 ConfigInfo
->AdapterInterfaceType
= HwInitData
->AdapterInterfaceType
;
394 ConfigInfo
->InterruptMode
= Latched
;
395 ConfigInfo
->DmaChannel
= SP_UNINITIALIZED_VALUE
;
396 ConfigInfo
->DmaPort
= SP_UNINITIALIZED_VALUE
;
397 ConfigInfo
->MaximumTransferLength
= SP_UNINITIALIZED_VALUE
;
398 ConfigInfo
->MaximumNumberOfTargets
= SCSI_MAXIMUM_TARGETS_PER_BUS
;
400 /* Store parameters */
401 ConfigInfo
->NeedPhysicalAddresses
= HwInitData
->NeedPhysicalAddresses
;
402 ConfigInfo
->MapBuffers
= HwInitData
->MapBuffers
;
403 ConfigInfo
->AutoRequestSense
= HwInitData
->AutoRequestSense
;
404 ConfigInfo
->ReceiveEvent
= HwInitData
->ReceiveEvent
;
405 ConfigInfo
->TaggedQueuing
= HwInitData
->TaggedQueuing
;
406 ConfigInfo
->MultipleRequestPerLu
= HwInitData
->MultipleRequestPerLu
;
408 /* Get the disk usage */
409 ConfigInfo
->AtdiskPrimaryClaimed
= FALSE
; // FIXME
410 ConfigInfo
->AtdiskSecondaryClaimed
= FALSE
; // FIXME
412 /* Initiator bus id is not set */
413 for (Bus
= 0; Bus
< 8; Bus
++)
414 ConfigInfo
->InitiatorBusId
[Bus
] = (CCHAR
)SP_UNINITIALIZED_VALUE
;
417 ConfigInfo
->NumberOfPhysicalBreaks
= 17;
419 return STATUS_SUCCESS
;
425 IN ULONG DebugPrintLevel
,
426 IN PCCHAR DebugMessage
,
433 if (DebugPrintLevel
> 10)
436 va_start(ap
, DebugMessage
);
438 /* Construct a string */
439 Length
= _vsnprintf(Buffer
, 512, DebugMessage
, ap
);
441 /* Check if we went past the buffer */
442 if (Length
== MAXULONG
)
444 /* Terminate it if we went over-board */
445 Buffer
[sizeof(Buffer
) - 1] = '\0';
448 Length
= sizeof(Buffer
);
451 /* Print the message */
460 ScsiPortCompleteRequest(
461 IN PVOID HwDeviceExtension
,
471 #undef ScsiPortConvertPhysicalAddressToUlong
474 ScsiPortConvertPhysicalAddressToUlong(
475 IN SCSI_PHYSICAL_ADDRESS Address
)
477 return Address
.LowPart
;
480 SCSI_PHYSICAL_ADDRESS
482 ScsiPortConvertUlongToPhysicalAddress(
483 IN ULONG_PTR UlongAddress
)
485 SCSI_PHYSICAL_ADDRESS Address
;
487 Address
.QuadPart
= UlongAddress
;
494 IN PVOID DeviceExtension
)
502 ScsiPortFreeDeviceBase(
503 IN PVOID HwDeviceExtension
,
504 IN PVOID MappedAddress
)
512 IN PVOID DeviceExtension
,
513 IN ULONG BusDataType
,
514 IN ULONG SystemIoBusNumber
,
519 return HalGetBusDataByOffset(BusDataType
, SystemIoBusNumber
, SlotNumber
, Buffer
, 0, Length
);
524 ScsiPortGetDeviceBase(
525 IN PVOID HwDeviceExtension
,
526 IN INTERFACE_TYPE BusType
,
527 IN ULONG SystemIoBusNumber
,
528 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
529 IN ULONG NumberOfBytes
,
530 IN BOOLEAN InIoSpace
)
532 PHYSICAL_ADDRESS TranslatedAddress
;
535 AddressSpace
= (ULONG
)InIoSpace
;
536 if (HalTranslateBusAddress(BusType
,
540 &TranslatedAddress
) == FALSE
)
546 if (AddressSpace
!= 0)
547 return (PVOID
)TranslatedAddress
.u
.LowPart
;
551 return (PVOID
)IoAddress
.LowPart
;
556 ScsiPortGetLogicalUnit(
557 IN PVOID HwDeviceExtension
,
567 SCSI_PHYSICAL_ADDRESS
569 ScsiPortGetPhysicalAddress(
570 IN PVOID HwDeviceExtension
,
571 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
572 IN PVOID VirtualAddress
,
575 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
576 SCSI_PHYSICAL_ADDRESS PhysicalAddress
;
577 ULONG BufferLength
= 0;
580 TRACE("ScsiPortGetPhysicalAddress(%p %p %p %p)\n",
581 HwDeviceExtension
, Srb
, VirtualAddress
, Length
);
583 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
585 if (Srb
== NULL
|| Srb
->SenseInfoBuffer
== VirtualAddress
)
587 /* Simply look it up in the allocated common buffer */
588 Offset
= (PUCHAR
)VirtualAddress
- (PUCHAR
)DeviceExtension
->SrbExtensionBuffer
;
590 BufferLength
= DeviceExtension
->CommonBufferLength
- Offset
;
591 PhysicalAddress
.QuadPart
= Offset
;
597 PhysicalAddress
.QuadPart
= (LONGLONG
)(SP_UNINITIALIZED_VALUE
);
600 *Length
= BufferLength
;
601 return PhysicalAddress
;
607 IN PVOID DeviceExtension
,
620 SpiAllocateCommonBuffer(
621 IN OUT PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
622 IN ULONG NonCachedSize
)
625 ULONG CommonBufferLength
, BufSize
;
627 /* If size is 0, set it to 16 */
628 if (!DeviceExtension
->SrbExtensionSize
)
629 DeviceExtension
->SrbExtensionSize
= 16;
632 BufSize
= DeviceExtension
->SrbExtensionSize
;
635 BufSize
= (BufSize
+ sizeof(LONGLONG
) - 1) & ~(sizeof(LONGLONG
) - 1);
637 /* Sum up into the total common buffer length, and round it to page size */
639 ROUND_TO_PAGES(NonCachedSize
);
642 if (!DeviceExtension
->AdapterObject
)
644 /* From nonpaged pool if there is no DMA */
645 CommonBuffer
= ExAllocatePool(NonPagedPool
, CommonBufferLength
);
649 /* Perform a full request since we have a DMA adapter*/
654 /* Fail in case of error */
656 return STATUS_INSUFFICIENT_RESOURCES
;
659 RtlZeroMemory(CommonBuffer
, CommonBufferLength
);
661 /* Store its size in Device Extension */
662 DeviceExtension
->CommonBufferLength
= CommonBufferLength
;
664 /* SrbExtension buffer is located at the beginning of the buffer */
665 DeviceExtension
->SrbExtensionBuffer
= CommonBuffer
;
667 /* Non-cached extension buffer is located at the end of
671 CommonBufferLength
-= NonCachedSize
;
672 DeviceExtension
->NonCachedExtension
= (PUCHAR
)CommonBuffer
+ CommonBufferLength
;
676 DeviceExtension
->NonCachedExtension
= NULL
;
679 return STATUS_SUCCESS
;
684 ScsiPortGetUncachedExtension(
685 IN PVOID HwDeviceExtension
,
686 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
687 IN ULONG NumberOfBytes
)
689 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
690 DEVICE_DESCRIPTION DeviceDescription
;
691 ULONG MapRegistersCount
;
694 TRACE("ScsiPortGetUncachedExtension(%p %p %lu)\n",
695 HwDeviceExtension
, ConfigInfo
, NumberOfBytes
);
697 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
699 /* Check for allocated common DMA buffer */
700 if (DeviceExtension
->SrbExtensionBuffer
!= NULL
)
705 /* Check for DMA adapter object */
706 if (DeviceExtension
->AdapterObject
== NULL
)
708 /* Initialize DMA adapter description */
709 RtlZeroMemory(&DeviceDescription
, sizeof(DEVICE_DESCRIPTION
));
711 DeviceDescription
.Version
= DEVICE_DESCRIPTION_VERSION
;
712 DeviceDescription
.Master
= ConfigInfo
->Master
;
713 DeviceDescription
.ScatterGather
= ConfigInfo
->ScatterGather
;
714 DeviceDescription
.DemandMode
= ConfigInfo
->DemandMode
;
715 DeviceDescription
.Dma32BitAddresses
= ConfigInfo
->Dma32BitAddresses
;
716 DeviceDescription
.BusNumber
= ConfigInfo
->SystemIoBusNumber
;
717 DeviceDescription
.DmaChannel
= ConfigInfo
->DmaChannel
;
718 DeviceDescription
.InterfaceType
= ConfigInfo
->AdapterInterfaceType
;
719 DeviceDescription
.DmaWidth
= ConfigInfo
->DmaWidth
;
720 DeviceDescription
.DmaSpeed
= ConfigInfo
->DmaSpeed
;
721 DeviceDescription
.MaximumLength
= ConfigInfo
->MaximumTransferLength
;
722 DeviceDescription
.DmaPort
= ConfigInfo
->DmaPort
;
724 /* Get a DMA adapter object */
726 DeviceExtension
->AdapterObject
=
727 HalGetAdapter(&DeviceDescription
, &MapRegistersCount
);
729 /* Fail in case of error */
730 if (DeviceExtension
->AdapterObject
== NULL
)
735 MapRegistersCount
= 0;
738 /* Set number of physical breaks */
739 if (ConfigInfo
->NumberOfPhysicalBreaks
!= 0 &&
740 MapRegistersCount
> ConfigInfo
->NumberOfPhysicalBreaks
)
742 DeviceExtension
->PortCapabilities
.MaximumPhysicalPages
=
743 ConfigInfo
->NumberOfPhysicalBreaks
;
747 DeviceExtension
->PortCapabilities
.MaximumPhysicalPages
= MapRegistersCount
;
751 /* Update Srb extension size */
752 if (DeviceExtension
->SrbExtensionSize
!= ConfigInfo
->SrbExtensionSize
)
753 DeviceExtension
->SrbExtensionSize
= ConfigInfo
->SrbExtensionSize
;
755 /* Allocate a common DMA buffer */
756 Status
= SpiAllocateCommonBuffer(DeviceExtension
, NumberOfBytes
);
758 if (!NT_SUCCESS(Status
))
760 TRACE("SpiAllocateCommonBuffer() failed with Status = 0x%08X!\n", Status
);
764 return DeviceExtension
->NonCachedExtension
;
769 ScsiPortGetVirtualAddress(
770 IN PVOID HwDeviceExtension
,
771 IN SCSI_PHYSICAL_ADDRESS PhysicalAddress
)
781 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
790 struct _DRIVE_LAYOUT_INFORMATION
*PartitionBuffer
;
791 CHAR PartitionName
[64];
793 /* Register device with partition(0) suffix */
794 sprintf(PartitionName
, "%spartition(0)", ArcName
);
795 FsRegisterDevice(PartitionName
, &DiskVtbl
);
797 /* Read device partition table */
798 Status
= ArcOpen(PartitionName
, OpenReadOnly
, &FileId
);
799 if (Status
== ESUCCESS
)
801 ret
= HALDISPATCH
->HalIoReadPartitionTable((PDEVICE_OBJECT
)FileId
, 512, FALSE
, &PartitionBuffer
);
804 for (i
= 0; i
< PartitionBuffer
->PartitionCount
; i
++)
806 if (PartitionBuffer
->PartitionEntry
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
)
808 sprintf(PartitionName
, "%spartition(%lu)",
809 ArcName
, PartitionBuffer
->PartitionEntry
[i
].PartitionNumber
);
810 FsRegisterDevice(PartitionName
, &DiskVtbl
);
813 ExFreePool(PartitionBuffer
);
822 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
827 PSCSI_REQUEST_BLOCK Srb
;
829 INQUIRYDATA InquiryBuffer
;
833 if (!DeviceExtension
->HwResetBus(DeviceExtension
->MiniPortDeviceExtension
, PathId
))
838 /* Remember the extension */
839 ScsiDeviceExtensions
[ScsiBus
] = DeviceExtension
;
841 for (TargetId
= 0; TargetId
< DeviceExtension
->MaxTargedIds
; TargetId
++)
846 TRACE("Scanning SCSI device %d.%d.%d\n",
847 ScsiBus
, TargetId
, Lun
);
849 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
852 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
853 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
854 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
855 Srb
->PathId
= PathId
;
856 Srb
->TargetId
= TargetId
;
859 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
860 Srb
->DataTransferLength
= INQUIRYDATABUFFERSIZE
;
861 Srb
->TimeOutValue
= 5; /* in seconds */
862 Srb
->DataBuffer
= &InquiryBuffer
;
863 Cdb
= (PCDB
)Srb
->Cdb
;
864 Cdb
->CDB6INQUIRY
.OperationCode
= SCSIOP_INQUIRY
;
865 Cdb
->CDB6INQUIRY
.LogicalUnitNumber
= Srb
->Lun
;
866 Cdb
->CDB6INQUIRY
.AllocationLength
= (UCHAR
)Srb
->DataTransferLength
;
867 if (!SpiSendSynchronousSrb(DeviceExtension
, Srb
))
869 /* Don't check next LUNs */
873 /* Device exists, create its ARC name */
874 if (InquiryBuffer
.RemovableMedia
)
876 sprintf(ArcName
, "scsi(%ld)cdrom(%d)fdisk(%d)",
877 ScsiBus
, TargetId
, Lun
);
878 FsRegisterDevice(ArcName
, &DiskVtbl
);
882 sprintf(ArcName
, "scsi(%ld)disk(%d)rdisk(%d)",
883 ScsiBus
, TargetId
, Lun
);
884 /* Now, check if it has partitions */
885 SpiScanDevice(DeviceExtension
, ArcName
, PathId
, TargetId
, Lun
);
890 } while (Lun
< SCSI_MAXIMUM_LOGICAL_UNITS
);
897 IN PHW_INITIALIZATION_DATA HwInitializationData
,
898 IN PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor
,
899 IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig
)
901 PACCESS_RANGE AccessRange
;
902 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialData
;
908 /* Loop through all entries */
909 for (Index
= 0; Index
< ResourceDescriptor
->PartialResourceList
.Count
; Index
++)
911 PartialData
= &ResourceDescriptor
->PartialResourceList
.PartialDescriptors
[Index
];
913 switch (PartialData
->Type
)
915 case CmResourceTypePort
:
916 /* Copy access ranges */
917 if (RangeNumber
< HwInitializationData
->NumberOfAccessRanges
)
919 TRACE("Got port at 0x%I64x, len 0x%x\n",
920 PartialData
->u
.Port
.Start
.QuadPart
, PartialData
->u
.Port
.Length
);
921 AccessRange
= &((*(PortConfig
->AccessRanges
))[RangeNumber
]);
923 AccessRange
->RangeStart
= PartialData
->u
.Port
.Start
;
924 AccessRange
->RangeLength
= PartialData
->u
.Port
.Length
;
926 AccessRange
->RangeInMemory
= FALSE
;
931 case CmResourceTypeMemory
:
932 /* Copy access ranges */
933 if (RangeNumber
< HwInitializationData
->NumberOfAccessRanges
)
935 TRACE("Got memory at 0x%I64x, len 0x%x\n",
936 PartialData
->u
.Memory
.Start
.QuadPart
, PartialData
->u
.Memory
.Length
);
937 AccessRange
= &((*(PortConfig
->AccessRanges
))[RangeNumber
]);
939 AccessRange
->RangeStart
= PartialData
->u
.Memory
.Start
;
940 AccessRange
->RangeLength
= PartialData
->u
.Memory
.Length
;
942 AccessRange
->RangeInMemory
= TRUE
;
947 case CmResourceTypeInterrupt
:
948 /* Copy interrupt data */
949 TRACE("Got interrupt level %d, vector %d\n",
950 PartialData
->u
.Interrupt
.Level
, PartialData
->u
.Interrupt
.Vector
);
951 PortConfig
->BusInterruptLevel
= PartialData
->u
.Interrupt
.Level
;
952 PortConfig
->BusInterruptVector
= PartialData
->u
.Interrupt
.Vector
;
954 /* Set interrupt mode accordingly to the resource */
955 if (PartialData
->Flags
== CM_RESOURCE_INTERRUPT_LATCHED
)
957 PortConfig
->InterruptMode
= Latched
;
959 else if (PartialData
->Flags
== CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
)
961 PortConfig
->InterruptMode
= LevelSensitive
;
965 case CmResourceTypeDma
:
966 TRACE("Got DMA channel %d, port %d\n",
967 PartialData
->u
.Dma
.Channel
, PartialData
->u
.Dma
.Port
);
968 PortConfig
->DmaChannel
= PartialData
->u
.Dma
.Channel
;
969 PortConfig
->DmaPort
= PartialData
->u
.Dma
.Port
;
978 IN PHW_INITIALIZATION_DATA HwInitializationData
,
979 IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig
,
981 IN OUT PPCI_SLOT_NUMBER NextSlotNumber
)
983 PCI_COMMON_CONFIG PciConfig
;
984 PCI_SLOT_NUMBER SlotNumber
;
987 ULONG FunctionNumber
;
988 CHAR VendorIdString
[8];
989 CHAR DeviceIdString
[8];
990 PCM_RESOURCE_LIST ResourceList
= NULL
;
993 SlotNumber
.u
.AsULONG
= 0;
995 /* Loop through all devices */
996 for (DeviceNumber
= NextSlotNumber
->u
.bits
.DeviceNumber
; DeviceNumber
< PCI_MAX_DEVICES
; DeviceNumber
++)
998 SlotNumber
.u
.bits
.DeviceNumber
= DeviceNumber
;
1000 /* Loop through all functions */
1001 for (FunctionNumber
= NextSlotNumber
->u
.bits
.FunctionNumber
; FunctionNumber
< PCI_MAX_FUNCTION
; FunctionNumber
++)
1003 SlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
1005 /* Get PCI config bytes */
1006 DataSize
= HalGetBusDataByOffset(
1009 SlotNumber
.u
.AsULONG
,
1014 /* If result of HalGetBusData is 0, then the bus is wrong */
1018 /* If result is PCI_INVALID_VENDORID, then this device has no more
1020 if (PciConfig
.VendorID
== PCI_INVALID_VENDORID
)
1023 sprintf(VendorIdString
, "%04hx", PciConfig
.VendorID
);
1024 sprintf(DeviceIdString
, "%04hx", PciConfig
.DeviceID
);
1026 if (_strnicmp(VendorIdString
, HwInitializationData
->VendorId
, HwInitializationData
->VendorIdLength
) ||
1027 _strnicmp(DeviceIdString
, HwInitializationData
->DeviceId
, HwInitializationData
->DeviceIdLength
))
1029 /* It is not our device */
1033 TRACE( "Found device 0x%04hx 0x%04hx at %1lu %2lu %1lu\n",
1034 PciConfig
.VendorID
, PciConfig
.DeviceID
,
1036 SlotNumber
.u
.bits
.DeviceNumber
, SlotNumber
.u
.bits
.FunctionNumber
);
1038 Status
= HalAssignSlotResources(NULL
,
1044 SlotNumber
.u
.AsULONG
,
1047 if (!NT_SUCCESS(Status
))
1050 /* Create configuration information */
1051 SpiResourceToConfig(HwInitializationData
,
1055 /* Free the resource list */
1056 ExFreePool(ResourceList
);
1058 /* Set dev & fn numbers */
1059 NextSlotNumber
->u
.bits
.DeviceNumber
= DeviceNumber
;
1060 NextSlotNumber
->u
.bits
.FunctionNumber
= FunctionNumber
+ 1;
1062 /* Save the slot number */
1063 PortConfig
->SlotNumber
= SlotNumber
.u
.AsULONG
;
1067 NextSlotNumber
->u
.bits
.FunctionNumber
= 0;
1070 NextSlotNumber
->u
.bits
.DeviceNumber
= 0;
1080 IN PHW_INITIALIZATION_DATA HwInitializationData
,
1081 IN PVOID HwContext OPTIONAL
)
1083 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
1084 ULONG DeviceExtensionSize
;
1085 PORT_CONFIGURATION_INFORMATION PortConfig
;
1087 BOOLEAN FirstConfigCall
= TRUE
;
1088 PCI_SLOT_NUMBER SlotNumber
;
1092 if (HwInitializationData
->HwInitializationDataSize
!= sizeof(HW_INITIALIZATION_DATA
))
1094 return STATUS_INVALID_PARAMETER
;
1097 /* Check params for validity */
1098 if ((HwInitializationData
->HwInitialize
== NULL
) ||
1099 (HwInitializationData
->HwStartIo
== NULL
) ||
1100 (HwInitializationData
->HwInterrupt
== NULL
) ||
1101 (HwInitializationData
->HwFindAdapter
== NULL
) ||
1102 (HwInitializationData
->HwResetBus
== NULL
))
1104 return STATUS_INVALID_PARAMETER
;
1107 /* Zero starting slot number */
1108 SlotNumber
.u
.AsULONG
= 0;
1114 DeviceExtensionSize
= sizeof(SCSI_PORT_DEVICE_EXTENSION
) + HwInitializationData
->DeviceExtensionSize
;
1115 DeviceExtension
= FrLdrTempAlloc(DeviceExtensionSize
, TAG_SCSI_DEVEXT
);
1116 if (!DeviceExtension
)
1118 return STATUS_NO_MEMORY
;
1120 RtlZeroMemory(DeviceExtension
, DeviceExtensionSize
);
1121 DeviceExtension
->InterruptFlags
= SCSI_PORT_NEXT_REQUEST_READY
;
1122 DeviceExtension
->HwInitialize
= HwInitializationData
->HwInitialize
;
1123 DeviceExtension
->HwStartIo
= HwInitializationData
->HwStartIo
;
1124 DeviceExtension
->HwInterrupt
= HwInitializationData
->HwInterrupt
;
1125 DeviceExtension
->HwResetBus
= HwInitializationData
->HwResetBus
;
1126 DeviceExtension
->MiniPortDeviceExtension
= (PVOID
)(DeviceExtension
+ 1);
1128 Status
= SpiCreatePortConfig(DeviceExtension
,
1129 HwInitializationData
,
1132 if (Status
!= STATUS_SUCCESS
)
1134 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1138 PortConfig
.NumberOfAccessRanges
= HwInitializationData
->NumberOfAccessRanges
;
1139 PortConfig
.AccessRanges
= FrLdrTempAlloc(sizeof(ACCESS_RANGE
) * HwInitializationData
->NumberOfAccessRanges
,
1140 TAG_SCSI_ACCESS_RANGES
);
1141 if (!PortConfig
.AccessRanges
)
1143 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1144 return STATUS_NO_MEMORY
;
1146 RtlZeroMemory(PortConfig
.AccessRanges
, sizeof(ACCESS_RANGE
) * HwInitializationData
->NumberOfAccessRanges
);
1148 /* Search for matching PCI device */
1149 if ((HwInitializationData
->AdapterInterfaceType
== PCIBus
) &&
1150 (HwInitializationData
->VendorIdLength
> 0) &&
1151 (HwInitializationData
->VendorId
!= NULL
) &&
1152 (HwInitializationData
->DeviceIdLength
> 0) &&
1153 (HwInitializationData
->DeviceId
!= NULL
))
1155 PortConfig
.BusInterruptLevel
= 0;
1157 /* Get PCI device data */
1158 TRACE("VendorId '%.*s' DeviceId '%.*s'\n",
1159 HwInitializationData
->VendorIdLength
,
1160 HwInitializationData
->VendorId
,
1161 HwInitializationData
->DeviceIdLength
,
1162 HwInitializationData
->DeviceId
);
1164 if (!SpiGetPciConfigData(HwInitializationData
,
1169 /* Continue to the next bus, nothing here */
1170 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1171 return STATUS_INTERNAL_ERROR
;
1174 if (!PortConfig
.BusInterruptLevel
)
1176 /* Bypass this slot, because no interrupt was assigned */
1177 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1178 return STATUS_INTERNAL_ERROR
;
1182 if (HwInitializationData
->HwFindAdapter(
1183 DeviceExtension
->MiniPortDeviceExtension
,
1188 &Again
) != SP_RETURN_FOUND
)
1190 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1191 return STATUS_INTERNAL_ERROR
;
1194 /* Copy all stuff which we ever need from PortConfig to the DeviceExtension */
1195 if (PortConfig
.MaximumNumberOfTargets
> SCSI_MAXIMUM_TARGETS_PER_BUS
)
1196 DeviceExtension
->MaxTargedIds
= SCSI_MAXIMUM_TARGETS_PER_BUS
;
1198 DeviceExtension
->MaxTargedIds
= PortConfig
.MaximumNumberOfTargets
;
1200 DeviceExtension
->BusNum
= PortConfig
.SystemIoBusNumber
;
1202 TRACE("Adapter found: buses = %d, targets = %d\n",
1203 PortConfig
.NumberOfBuses
, DeviceExtension
->MaxTargedIds
);
1205 /* Initialize adapter */
1206 if (!DeviceExtension
->HwInitialize(DeviceExtension
->MiniPortDeviceExtension
))
1208 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1209 return STATUS_INTERNAL_ERROR
;
1213 for (ScsiBus
= 0; ScsiBus
< PortConfig
.NumberOfBuses
; ScsiBus
++)
1215 SpiScanAdapter(DeviceExtension
, PortConfig
.SystemIoBusNumber
, ScsiBus
);
1216 PortConfig
.SystemIoBusNumber
++;
1219 FirstConfigCall
= FALSE
;
1226 return STATUS_SUCCESS
;
1231 ScsiPortIoMapTransfer(
1232 IN PVOID HwDeviceExtension
,
1233 IN PSCSI_REQUEST_BLOCK Srb
,
1234 IN PVOID LogicalAddress
,
1244 IN PVOID HwDeviceExtension
,
1245 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
1259 IN PVOID WriteBuffer
,
1260 IN PVOID ReadBuffer
,
1263 RtlMoveMemory(WriteBuffer
, ReadBuffer
, Length
);
1268 ScsiPortNotification(
1269 IN SCSI_NOTIFICATION_TYPE NotificationType
,
1270 IN PVOID HwDeviceExtension
,
1273 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
1274 PSCSI_REQUEST_BLOCK Srb
;
1277 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
1279 va_start(ap
, HwDeviceExtension
);
1281 switch (NotificationType
)
1283 case RequestComplete
:
1284 /* Mask the SRB as completed */
1285 Srb
= va_arg(ap
, PSCSI_REQUEST_BLOCK
);
1286 Srb
->SrbFlags
&= ~SRB_FLAGS_IS_ACTIVE
;
1290 /* Say that device is ready */
1291 DeviceExtension
->InterruptFlags
|= SCSI_PORT_NEXT_REQUEST_READY
;
1304 ScsiPortReadPortBufferUchar(
1309 __inbytestring(H2I(Port
), Buffer
, Count
);
1314 ScsiPortReadPortBufferUlong(
1319 __indwordstring(H2I(Port
), Buffer
, Count
);
1324 ScsiPortReadPortBufferUshort(
1329 __inwordstring(H2I(Port
), Buffer
, Count
);
1334 ScsiPortReadPortUchar(
1337 TRACE("ScsiPortReadPortUchar(%p)\n", Port
);
1339 return READ_PORT_UCHAR(Port
);
1344 ScsiPortReadPortUlong(
1347 return READ_PORT_ULONG(Port
);
1352 ScsiPortReadPortUshort(
1355 return READ_PORT_USHORT(Port
);
1360 ScsiPortReadRegisterBufferUchar(
1371 ScsiPortReadRegisterBufferUlong(
1382 ScsiPortReadRegisterBufferUshort(
1383 IN PUSHORT Register
,
1393 ScsiPortReadRegisterUchar(
1396 return READ_REGISTER_UCHAR(Register
);
1401 ScsiPortReadRegisterUlong(
1404 return READ_REGISTER_ULONG(Register
);
1409 ScsiPortReadRegisterUshort(
1410 IN PUSHORT Register
)
1412 return READ_REGISTER_USHORT(Register
);
1417 ScsiPortSetBusDataByOffset(
1418 IN PVOID DeviceExtension
,
1419 IN ULONG BusDataType
,
1420 IN ULONG SystemIoBusNumber
,
1421 IN ULONG SlotNumber
,
1433 ScsiPortStallExecution(
1436 KeStallExecutionProcessor(Delay
);
1441 ScsiPortValidateRange(
1442 IN PVOID HwDeviceExtension
,
1443 IN INTERFACE_TYPE BusType
,
1444 IN ULONG SystemIoBusNumber
,
1445 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
1446 IN ULONG NumberOfBytes
,
1447 IN BOOLEAN InIoSpace
)
1461 ScsiPortWritePortBufferUchar(
1466 __outbytestring(H2I(Port
), Buffer
, Count
);
1471 ScsiPortWritePortBufferUlong(
1476 __outdwordstring(H2I(Port
), Buffer
, Count
);
1481 ScsiPortWritePortBufferUshort(
1486 __outwordstring(H2I(Port
), Buffer
, Count
);
1491 ScsiPortWritePortUchar(
1495 WRITE_PORT_UCHAR(Port
, Value
);
1500 ScsiPortWritePortUlong(
1504 WRITE_PORT_ULONG(Port
, Value
);
1509 ScsiPortWritePortUshort(
1513 WRITE_PORT_USHORT(Port
, Value
);
1518 ScsiPortWriteRegisterBufferUchar(
1529 ScsiPortWriteRegisterBufferUlong(
1540 ScsiPortWriteRegisterBufferUshort(
1541 IN PUSHORT Register
,
1551 ScsiPortWriteRegisterUchar(
1555 WRITE_REGISTER_UCHAR(Register
, Value
);
1560 ScsiPortWriteRegisterUlong(
1564 WRITE_REGISTER_ULONG(Register
, Value
);
1569 ScsiPortWriteRegisterUshort(
1570 IN PUSHORT Register
,
1573 WRITE_REGISTER_USHORT(Register
, Value
);
1576 extern char __ImageBase
;
1579 LoadBootDeviceDriver(VOID
)
1581 PIMAGE_NT_HEADERS NtHeaders
;
1582 LIST_ENTRY ModuleListHead
;
1583 PIMAGE_IMPORT_DESCRIPTOR ImportTable
;
1584 ULONG ImportTableSize
;
1585 PLDR_DATA_TABLE_ENTRY BootDdDTE
, FreeldrDTE
;
1586 CHAR NtBootDdPath
[MAX_PATH
];
1587 PVOID ImageBase
= NULL
;
1588 ULONG (NTAPI
*EntryPoint
)(IN PVOID DriverObject
, IN PVOID RegistryPath
);
1591 // FIXME: Must be done *INSIDE* the HAL!
1593 HalpInitializePciStubs();
1594 HalpInitBusHandler();
1597 /* Initialize the loaded module list */
1598 InitializeListHead(&ModuleListHead
);
1600 /* Create full ntbootdd.sys path */
1601 MachDiskGetBootPath(NtBootDdPath
, sizeof(NtBootDdPath
));
1602 strcat(NtBootDdPath
, "\\NTBOOTDD.SYS");
1605 Success
= WinLdrLoadImage(NtBootDdPath
, LoaderBootDriver
, &ImageBase
);
1608 /* That's OK. File simply doesn't exist */
1612 /* Allocate a DTE for ntbootdd */
1613 Success
= WinLdrAllocateDataTableEntry(&ModuleListHead
, "ntbootdd.sys",
1614 "NTBOOTDD.SYS", ImageBase
, &BootDdDTE
);
1618 /* Add the PE part of freeldr.sys to the list of loaded executables, it
1619 contains Scsiport* exports, imported by ntbootdd.sys */
1620 Success
= WinLdrAllocateDataTableEntry(&ModuleListHead
, "scsiport.sys",
1621 "FREELDR.SYS", &__ImageBase
, &FreeldrDTE
);
1624 RemoveEntryList(&BootDdDTE
->InLoadOrderLinks
);
1629 Success
= WinLdrScanImportDescriptorTable(&ModuleListHead
, "", BootDdDTE
);
1631 /* Now unlinkt the DTEs, they won't be valid later */
1632 RemoveEntryList(&BootDdDTE
->InLoadOrderLinks
);
1633 RemoveEntryList(&FreeldrDTE
->InLoadOrderLinks
);
1638 /* Change imports to PA */
1639 ImportTable
= (PIMAGE_IMPORT_DESCRIPTOR
)RtlImageDirectoryEntryToData(VaToPa(BootDdDTE
->DllBase
),
1640 TRUE
, IMAGE_DIRECTORY_ENTRY_IMPORT
, &ImportTableSize
);
1641 for (;(ImportTable
->Name
!= 0) && (ImportTable
->FirstThunk
!= 0);ImportTable
++)
1643 PIMAGE_THUNK_DATA ThunkData
= (PIMAGE_THUNK_DATA
)VaToPa(RVA(BootDdDTE
->DllBase
, ImportTable
->FirstThunk
));
1645 while (((PIMAGE_THUNK_DATA
)ThunkData
)->u1
.AddressOfData
!= 0)
1647 ThunkData
->u1
.Function
= (ULONG
)VaToPa((PVOID
)ThunkData
->u1
.Function
);
1652 /* Relocate image to PA */
1653 NtHeaders
= RtlImageNtHeader(VaToPa(BootDdDTE
->DllBase
));
1656 Success
= (BOOLEAN
)LdrRelocateImageWithBias(VaToPa(BootDdDTE
->DllBase
),
1657 NtHeaders
->OptionalHeader
.ImageBase
- (ULONG_PTR
)BootDdDTE
->DllBase
,
1660 TRUE
, /* in case of conflict still return success */
1665 /* Call the entrypoint */
1666 EntryPoint
= VaToPa(BootDdDTE
->EntryPoint
);
1667 (*EntryPoint
)(NULL
, NULL
);