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
);
53 PVOID NonCachedExtension
;
60 /* SRB extension stuff */
61 ULONG SrbExtensionSize
;
62 PVOID SrbExtensionBuffer
;
64 IO_SCSI_CAPABILITIES PortCapabilities
;
66 PHW_INITIALIZE HwInitialize
;
67 PHW_STARTIO HwStartIo
;
68 PHW_INTERRUPT HwInterrupt
;
69 PHW_RESET_BUS HwResetBus
;
71 /* DMA related stuff */
72 PADAPTER_OBJECT AdapterObject
;
74 ULONG CommonBufferLength
;
76 PVOID MiniPortDeviceExtension
;
77 } SCSI_PORT_DEVICE_EXTENSION
, *PSCSI_PORT_DEVICE_EXTENSION
;
79 PSCSI_PORT_DEVICE_EXTENSION ScsiDeviceExtensions
[SCSI_MAXIMUM_BUSES
];
86 PFOUR_BYTE Source
= (PFOUR_BYTE
)&Value
;
88 Dest
.Byte0
= Source
->Byte3
;
89 Dest
.Byte1
= Source
->Byte2
;
90 Dest
.Byte2
= Source
->Byte1
;
91 Dest
.Byte3
= Source
->Byte0
;
97 SpiSendSynchronousSrb(
98 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
99 IN PSCSI_REQUEST_BLOCK Srb
)
103 ASSERT(!(Srb
->SrbFlags
& SRB_FLAGS_IS_ACTIVE
));
105 /* HACK: handle lack of interrupts */
106 while (!(DeviceExtension
->InterruptFlags
& SCSI_PORT_NEXT_REQUEST_READY
))
108 KeStallExecutionProcessor(100 * 1000);
109 DeviceExtension
->HwInterrupt(DeviceExtension
->MiniPortDeviceExtension
);
112 DeviceExtension
->InterruptFlags
&= ~SCSI_PORT_NEXT_REQUEST_READY
;
113 Srb
->SrbFlags
|= SRB_FLAGS_IS_ACTIVE
;
115 if (!DeviceExtension
->HwStartIo(
116 DeviceExtension
->MiniPortDeviceExtension
,
123 /* HACK: handle lack of interrupts */
124 while (Srb
->SrbFlags
& SRB_FLAGS_IS_ACTIVE
)
126 KeStallExecutionProcessor(100 * 1000);
127 DeviceExtension
->HwInterrupt(DeviceExtension
->MiniPortDeviceExtension
);
130 ret
= SRB_STATUS(Srb
->SrbStatus
) == SRB_STATUS_SUCCESS
;
136 typedef struct tagDISKCONTEXT
139 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
144 /* Device characteristics */
146 ULONGLONG SectorOffset
;
147 ULONGLONG SectorCount
;
148 ULONGLONG SectorNumber
;
151 static LONG
DiskClose(ULONG FileId
)
153 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
159 static LONG
DiskGetFileInformation(ULONG FileId
, FILEINFORMATION
* Information
)
161 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
163 RtlZeroMemory(Information
, sizeof(FILEINFORMATION
));
164 Information
->EndingAddress
.QuadPart
= Context
->SectorCount
* Context
->SectorSize
;
165 Information
->CurrentAddress
.QuadPart
= Context
->SectorNumber
* Context
->SectorSize
;
170 static LONG
DiskOpen(CHAR
* Path
, OPENMODE OpenMode
, ULONG
* FileId
)
172 PSCSI_REQUEST_BLOCK Srb
;
174 READ_CAPACITY_DATA ReadCapacityBuffer
;
176 DISKCONTEXT
* Context
;
177 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
178 ULONG ScsiBus
, PathId
, TargetId
, Lun
, Partition
, PathSyntax
;
180 ULONGLONG SectorOffset
= 0;
181 ULONGLONG SectorCount
;
184 if (!DissectArcPath2(Path
, &ScsiBus
, &TargetId
, &Lun
, &Partition
, &PathSyntax
))
186 if (PathSyntax
!= 0) /* scsi() format */
188 DeviceExtension
= ScsiDeviceExtensions
[ScsiBus
];
189 PathId
= ScsiBus
- DeviceExtension
->BusNum
;
191 /* Get disk capacity and sector size */
192 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
195 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
196 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
197 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
198 Srb
->PathId
= (UCHAR
)PathId
;
199 Srb
->TargetId
= (UCHAR
)TargetId
;
200 Srb
->Lun
= (UCHAR
)Lun
;
202 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
203 Srb
->DataTransferLength
= sizeof(READ_CAPACITY_DATA
);
204 Srb
->TimeOutValue
= 5; /* in seconds */
205 Srb
->DataBuffer
= &ReadCapacityBuffer
;
206 Cdb
= (PCDB
)Srb
->Cdb
;
207 Cdb
->CDB10
.OperationCode
= SCSIOP_READ_CAPACITY
;
208 if (!SpiSendSynchronousSrb(DeviceExtension
, Srb
))
213 /* Transform result to host endianness */
214 SectorCount
= ntohl(ReadCapacityBuffer
.LogicalBlockAddress
);
215 SectorSize
= ntohl(ReadCapacityBuffer
.BytesPerBlock
);
219 /* Need to offset start of disk and length */
224 Context
= ExAllocatePool(PagedPool
, sizeof(DISKCONTEXT
));
227 Context
->DeviceExtension
= DeviceExtension
;
228 Context
->PathId
= (UCHAR
)PathId
;
229 Context
->TargetId
= (UCHAR
)TargetId
;
230 Context
->Lun
= (UCHAR
)Lun
;
231 Context
->SectorSize
= SectorSize
;
232 Context
->SectorOffset
= SectorOffset
;
233 Context
->SectorCount
= SectorCount
;
234 Context
->SectorNumber
= 0;
235 FsSetDeviceSpecific(*FileId
, Context
);
240 static LONG
DiskRead(ULONG FileId
, VOID
* Buffer
, ULONG N
, ULONG
* Count
)
242 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
243 PSCSI_REQUEST_BLOCK Srb
;
245 ULONG FullSectors
, NbSectors
;
253 FullSectors
= N
/ Context
->SectorSize
;
254 NbSectors
= (N
+ Context
->SectorSize
- 1) / Context
->SectorSize
;
255 if (Context
->SectorNumber
+ NbSectors
>= Context
->SectorCount
)
257 if (FullSectors
> 0xffff)
260 /* Read full sectors */
261 ASSERT(Context
->SectorNumber
< 0xFFFFFFFF);
262 Lba
= (ULONG
)Context
->SectorNumber
;
265 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
269 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
270 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
271 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
272 Srb
->PathId
= Context
->PathId
;
273 Srb
->TargetId
= Context
->TargetId
;
274 Srb
->Lun
= Context
->Lun
;
276 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
277 Srb
->DataTransferLength
= FullSectors
* Context
->SectorSize
;
278 Srb
->TimeOutValue
= 5; /* in seconds */
279 Srb
->DataBuffer
= Buffer
;
280 Cdb
= (PCDB
)Srb
->Cdb
;
281 Cdb
->CDB10
.OperationCode
= SCSIOP_READ
;
282 Cdb
->CDB10
.LogicalUnitNumber
= Srb
->Lun
;
283 Cdb
->CDB10
.LogicalBlockByte0
= (Lba
>> 24) & 0xff;
284 Cdb
->CDB10
.LogicalBlockByte1
= (Lba
>> 16) & 0xff;
285 Cdb
->CDB10
.LogicalBlockByte2
= (Lba
>> 8) & 0xff;
286 Cdb
->CDB10
.LogicalBlockByte3
= Lba
& 0xff;
287 Cdb
->CDB10
.TransferBlocksMsb
= (FullSectors
>> 8) & 0xff;
288 Cdb
->CDB10
.TransferBlocksLsb
= FullSectors
& 0xff;
289 if (!SpiSendSynchronousSrb(Context
->DeviceExtension
, Srb
))
293 Buffer
= (PUCHAR
)Buffer
+ FullSectors
* Context
->SectorSize
;
294 N
-= FullSectors
* Context
->SectorSize
;
295 *Count
+= FullSectors
* Context
->SectorSize
;
299 /* Read incomplete last sector */
304 Sector
= ExAllocatePool(PagedPool
, Context
->SectorSize
);
308 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
315 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
316 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
317 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
318 Srb
->PathId
= Context
->PathId
;
319 Srb
->TargetId
= Context
->TargetId
;
320 Srb
->Lun
= Context
->Lun
;
322 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
323 Srb
->DataTransferLength
= Context
->SectorSize
;
324 Srb
->TimeOutValue
= 5; /* in seconds */
325 Srb
->DataBuffer
= Sector
;
326 Cdb
= (PCDB
)Srb
->Cdb
;
327 Cdb
->CDB10
.OperationCode
= SCSIOP_READ
;
328 Cdb
->CDB10
.LogicalUnitNumber
= Srb
->Lun
;
329 Cdb
->CDB10
.LogicalBlockByte0
= (Lba
>> 24) & 0xff;
330 Cdb
->CDB10
.LogicalBlockByte1
= (Lba
>> 16) & 0xff;
331 Cdb
->CDB10
.LogicalBlockByte2
= (Lba
>> 8) & 0xff;
332 Cdb
->CDB10
.LogicalBlockByte3
= Lba
& 0xff;
333 Cdb
->CDB10
.TransferBlocksMsb
= 0;
334 Cdb
->CDB10
.TransferBlocksLsb
= 1;
335 if (!SpiSendSynchronousSrb(Context
->DeviceExtension
, Srb
))
340 RtlCopyMemory(Buffer
, Sector
, N
);
348 static LONG
DiskSeek(ULONG FileId
, LARGE_INTEGER
* Position
, SEEKMODE SeekMode
)
350 DISKCONTEXT
* Context
= FsGetDeviceSpecific(FileId
);
352 if (SeekMode
!= SeekAbsolute
)
354 if (Position
->QuadPart
& (Context
->SectorSize
- 1))
357 Context
->SectorNumber
= Position
->QuadPart
/ Context
->SectorSize
;
361 static const DEVVTBL DiskVtbl
= {
363 DiskGetFileInformation
,
371 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
372 IN PHW_INITIALIZATION_DATA HwInitData
,
373 OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
374 IN BOOLEAN ZeroStruct
)
378 /* Zero out the struct if told so */
381 /* First zero the portconfig */
382 RtlZeroMemory(ConfigInfo
, sizeof(PORT_CONFIGURATION_INFORMATION
));
384 /* Initialize the struct */
385 ConfigInfo
->Length
= sizeof(PORT_CONFIGURATION_INFORMATION
);
386 ConfigInfo
->AdapterInterfaceType
= HwInitData
->AdapterInterfaceType
;
387 ConfigInfo
->InterruptMode
= Latched
;
388 ConfigInfo
->DmaChannel
= SP_UNINITIALIZED_VALUE
;
389 ConfigInfo
->DmaPort
= SP_UNINITIALIZED_VALUE
;
390 ConfigInfo
->MaximumTransferLength
= SP_UNINITIALIZED_VALUE
;
391 ConfigInfo
->MaximumNumberOfTargets
= SCSI_MAXIMUM_TARGETS_PER_BUS
;
393 /* Store parameters */
394 ConfigInfo
->NeedPhysicalAddresses
= HwInitData
->NeedPhysicalAddresses
;
395 ConfigInfo
->MapBuffers
= HwInitData
->MapBuffers
;
396 ConfigInfo
->AutoRequestSense
= HwInitData
->AutoRequestSense
;
397 ConfigInfo
->ReceiveEvent
= HwInitData
->ReceiveEvent
;
398 ConfigInfo
->TaggedQueuing
= HwInitData
->TaggedQueuing
;
399 ConfigInfo
->MultipleRequestPerLu
= HwInitData
->MultipleRequestPerLu
;
401 /* Get the disk usage */
402 ConfigInfo
->AtdiskPrimaryClaimed
= FALSE
; // FIXME
403 ConfigInfo
->AtdiskSecondaryClaimed
= FALSE
; // FIXME
405 /* Initiator bus id is not set */
406 for (Bus
= 0; Bus
< 8; Bus
++)
407 ConfigInfo
->InitiatorBusId
[Bus
] = (CCHAR
)SP_UNINITIALIZED_VALUE
;
410 ConfigInfo
->NumberOfPhysicalBreaks
= 17;
412 return STATUS_SUCCESS
;
418 IN ULONG DebugPrintLevel
,
419 IN PCCHAR DebugMessage
,
426 if (DebugPrintLevel
> 10)
429 va_start(ap
, DebugMessage
);
431 /* Construct a string */
432 Length
= _vsnprintf(Buffer
, 512, DebugMessage
, ap
);
434 /* Check if we went past the buffer */
435 if (Length
== MAXULONG
)
437 /* Terminate it if we went over-board */
438 Buffer
[sizeof(Buffer
) - 1] = '\0';
441 Length
= sizeof(Buffer
);
444 /* Print the message */
453 ScsiPortCompleteRequest(
454 IN PVOID HwDeviceExtension
,
464 #undef ScsiPortConvertPhysicalAddressToUlong
467 ScsiPortConvertPhysicalAddressToUlong(
468 IN SCSI_PHYSICAL_ADDRESS Address
)
470 return Address
.LowPart
;
473 SCSI_PHYSICAL_ADDRESS
475 ScsiPortConvertUlongToPhysicalAddress(
476 IN ULONG_PTR UlongAddress
)
478 SCSI_PHYSICAL_ADDRESS Address
;
480 Address
.QuadPart
= UlongAddress
;
487 IN PVOID DeviceExtension
)
495 ScsiPortFreeDeviceBase(
496 IN PVOID HwDeviceExtension
,
497 IN PVOID MappedAddress
)
505 IN PVOID DeviceExtension
,
506 IN ULONG BusDataType
,
507 IN ULONG SystemIoBusNumber
,
512 return HalGetBusDataByOffset(BusDataType
, SystemIoBusNumber
, SlotNumber
, Buffer
, 0, Length
);
517 ScsiPortGetDeviceBase(
518 IN PVOID HwDeviceExtension
,
519 IN INTERFACE_TYPE BusType
,
520 IN ULONG SystemIoBusNumber
,
521 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
522 IN ULONG NumberOfBytes
,
523 IN BOOLEAN InIoSpace
)
525 PHYSICAL_ADDRESS TranslatedAddress
;
528 AddressSpace
= (ULONG
)InIoSpace
;
529 if (HalTranslateBusAddress(BusType
,
533 &TranslatedAddress
) == FALSE
)
539 if (AddressSpace
!= 0)
540 return (PVOID
)TranslatedAddress
.u
.LowPart
;
544 return (PVOID
)IoAddress
.LowPart
;
549 ScsiPortGetLogicalUnit(
550 IN PVOID HwDeviceExtension
,
560 SCSI_PHYSICAL_ADDRESS
562 ScsiPortGetPhysicalAddress(
563 IN PVOID HwDeviceExtension
,
564 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
565 IN PVOID VirtualAddress
,
568 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
569 SCSI_PHYSICAL_ADDRESS PhysicalAddress
;
570 ULONG BufferLength
= 0;
573 TRACE("ScsiPortGetPhysicalAddress(%p %p %p %p)\n",
574 HwDeviceExtension
, Srb
, VirtualAddress
, Length
);
576 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
578 if (Srb
== NULL
|| Srb
->SenseInfoBuffer
== VirtualAddress
)
580 /* Simply look it up in the allocated common buffer */
581 Offset
= (PUCHAR
)VirtualAddress
- (PUCHAR
)DeviceExtension
->SrbExtensionBuffer
;
583 BufferLength
= DeviceExtension
->CommonBufferLength
- Offset
;
584 PhysicalAddress
.QuadPart
= Offset
;
590 PhysicalAddress
.QuadPart
= (LONGLONG
)(SP_UNINITIALIZED_VALUE
);
593 *Length
= BufferLength
;
594 return PhysicalAddress
;
600 IN PVOID DeviceExtension
,
612 SpiAllocateCommonBuffer(
613 IN OUT PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
614 IN ULONG NonCachedSize
)
617 ULONG CommonBufferLength
, BufSize
;
619 /* If size is 0, set it to 16 */
620 if (!DeviceExtension
->SrbExtensionSize
)
621 DeviceExtension
->SrbExtensionSize
= 16;
624 BufSize
= DeviceExtension
->SrbExtensionSize
;
627 BufSize
= (BufSize
+ sizeof(LONGLONG
) - 1) & ~(sizeof(LONGLONG
) - 1);
629 /* Sum up into the total common buffer length, and round it to page size */
631 ROUND_TO_PAGES(NonCachedSize
);
634 if (!DeviceExtension
->AdapterObject
)
636 /* From nonpaged pool if there is no DMA */
637 CommonBuffer
= ExAllocatePool(NonPagedPool
, CommonBufferLength
);
641 /* Perform a full request since we have a DMA adapter*/
646 /* Fail in case of error */
648 return STATUS_INSUFFICIENT_RESOURCES
;
651 RtlZeroMemory(CommonBuffer
, CommonBufferLength
);
653 /* Store its size in Device Extension */
654 DeviceExtension
->CommonBufferLength
= CommonBufferLength
;
656 /* SrbExtension buffer is located at the beginning of the buffer */
657 DeviceExtension
->SrbExtensionBuffer
= CommonBuffer
;
659 /* Non-cached extension buffer is located at the end of
663 CommonBufferLength
-= NonCachedSize
;
664 DeviceExtension
->NonCachedExtension
= (PUCHAR
)CommonBuffer
+ CommonBufferLength
;
668 DeviceExtension
->NonCachedExtension
= NULL
;
671 return STATUS_SUCCESS
;
676 ScsiPortGetUncachedExtension(
677 IN PVOID HwDeviceExtension
,
678 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
,
679 IN ULONG NumberOfBytes
)
681 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
682 DEVICE_DESCRIPTION DeviceDescription
;
683 ULONG MapRegistersCount
;
686 TRACE("ScsiPortGetUncachedExtension(%p %p %lu)\n",
687 HwDeviceExtension
, ConfigInfo
, NumberOfBytes
);
689 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
691 /* Check for allocated common DMA buffer */
692 if (DeviceExtension
->SrbExtensionBuffer
!= NULL
)
697 /* Check for DMA adapter object */
698 if (DeviceExtension
->AdapterObject
== NULL
)
700 /* Initialize DMA adapter description */
701 RtlZeroMemory(&DeviceDescription
, sizeof(DEVICE_DESCRIPTION
));
703 DeviceDescription
.Version
= DEVICE_DESCRIPTION_VERSION
;
704 DeviceDescription
.Master
= ConfigInfo
->Master
;
705 DeviceDescription
.ScatterGather
= ConfigInfo
->ScatterGather
;
706 DeviceDescription
.DemandMode
= ConfigInfo
->DemandMode
;
707 DeviceDescription
.Dma32BitAddresses
= ConfigInfo
->Dma32BitAddresses
;
708 DeviceDescription
.BusNumber
= ConfigInfo
->SystemIoBusNumber
;
709 DeviceDescription
.DmaChannel
= ConfigInfo
->DmaChannel
;
710 DeviceDescription
.InterfaceType
= ConfigInfo
->AdapterInterfaceType
;
711 DeviceDescription
.DmaWidth
= ConfigInfo
->DmaWidth
;
712 DeviceDescription
.DmaSpeed
= ConfigInfo
->DmaSpeed
;
713 DeviceDescription
.MaximumLength
= ConfigInfo
->MaximumTransferLength
;
714 DeviceDescription
.DmaPort
= ConfigInfo
->DmaPort
;
716 /* Get a DMA adapter object */
718 DeviceExtension
->AdapterObject
=
719 HalGetAdapter(&DeviceDescription
, &MapRegistersCount
);
721 /* Fail in case of error */
722 if (DeviceExtension
->AdapterObject
== NULL
)
727 MapRegistersCount
= 0;
730 /* Set number of physical breaks */
731 if (ConfigInfo
->NumberOfPhysicalBreaks
!= 0 &&
732 MapRegistersCount
> ConfigInfo
->NumberOfPhysicalBreaks
)
734 DeviceExtension
->PortCapabilities
.MaximumPhysicalPages
=
735 ConfigInfo
->NumberOfPhysicalBreaks
;
739 DeviceExtension
->PortCapabilities
.MaximumPhysicalPages
= MapRegistersCount
;
743 /* Update Srb extension size */
744 if (DeviceExtension
->SrbExtensionSize
!= ConfigInfo
->SrbExtensionSize
)
745 DeviceExtension
->SrbExtensionSize
= ConfigInfo
->SrbExtensionSize
;
747 /* Allocate a common DMA buffer */
748 Status
= SpiAllocateCommonBuffer(DeviceExtension
, NumberOfBytes
);
750 if (!NT_SUCCESS(Status
))
752 TRACE("SpiAllocateCommonBuffer() failed with Status = 0x%08X!\n", Status
);
756 return DeviceExtension
->NonCachedExtension
;
761 ScsiPortGetVirtualAddress(
762 IN PVOID HwDeviceExtension
,
763 IN SCSI_PHYSICAL_ADDRESS PhysicalAddress
)
772 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
781 struct _DRIVE_LAYOUT_INFORMATION
*PartitionBuffer
;
782 CHAR PartitionName
[64];
784 /* Register device with partition(0) suffix */
785 sprintf(PartitionName
, "%spartition(0)", ArcName
);
786 FsRegisterDevice(PartitionName
, &DiskVtbl
);
788 /* Read device partition table */
789 Status
= ArcOpen(PartitionName
, OpenReadOnly
, &FileId
);
790 if (Status
== ESUCCESS
)
792 ret
= HALDISPATCH
->HalIoReadPartitionTable((PDEVICE_OBJECT
)FileId
, 512, FALSE
, &PartitionBuffer
);
795 for (i
= 0; i
< PartitionBuffer
->PartitionCount
; i
++)
797 if (PartitionBuffer
->PartitionEntry
[i
].PartitionType
!= PARTITION_ENTRY_UNUSED
)
799 sprintf(PartitionName
, "%spartition(%lu)",
800 ArcName
, PartitionBuffer
->PartitionEntry
[i
].PartitionNumber
);
801 FsRegisterDevice(PartitionName
, &DiskVtbl
);
804 ExFreePool(PartitionBuffer
);
812 IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
817 PSCSI_REQUEST_BLOCK Srb
;
819 INQUIRYDATA InquiryBuffer
;
823 if (!DeviceExtension
->HwResetBus(DeviceExtension
->MiniPortDeviceExtension
, PathId
))
828 /* Remember the extension */
829 ScsiDeviceExtensions
[ScsiBus
] = DeviceExtension
;
831 for (TargetId
= 0; TargetId
< DeviceExtension
->MaxTargedIds
; TargetId
++)
836 TRACE("Scanning SCSI device %d.%d.%d\n",
837 ScsiBus
, TargetId
, Lun
);
839 Srb
= ExAllocatePool(PagedPool
, sizeof(SCSI_REQUEST_BLOCK
));
842 RtlZeroMemory(Srb
, sizeof(SCSI_REQUEST_BLOCK
));
843 Srb
->Length
= sizeof(SCSI_REQUEST_BLOCK
);
844 Srb
->Function
= SRB_FUNCTION_EXECUTE_SCSI
;
845 Srb
->PathId
= PathId
;
846 Srb
->TargetId
= TargetId
;
849 Srb
->SrbFlags
= SRB_FLAGS_DATA_IN
;
850 Srb
->DataTransferLength
= INQUIRYDATABUFFERSIZE
;
851 Srb
->TimeOutValue
= 5; /* in seconds */
852 Srb
->DataBuffer
= &InquiryBuffer
;
853 Cdb
= (PCDB
)Srb
->Cdb
;
854 Cdb
->CDB6INQUIRY
.OperationCode
= SCSIOP_INQUIRY
;
855 Cdb
->CDB6INQUIRY
.LogicalUnitNumber
= Srb
->Lun
;
856 Cdb
->CDB6INQUIRY
.AllocationLength
= (UCHAR
)Srb
->DataTransferLength
;
857 if (!SpiSendSynchronousSrb(DeviceExtension
, Srb
))
859 /* Don't check next LUNs */
863 /* Device exists, create its ARC name */
864 if (InquiryBuffer
.RemovableMedia
)
866 sprintf(ArcName
, "scsi(%ld)cdrom(%d)fdisk(%d)",
867 ScsiBus
, TargetId
, Lun
);
868 FsRegisterDevice(ArcName
, &DiskVtbl
);
872 sprintf(ArcName
, "scsi(%ld)disk(%d)rdisk(%d)",
873 ScsiBus
, TargetId
, Lun
);
874 /* Now, check if it has partitions */
875 SpiScanDevice(DeviceExtension
, ArcName
, PathId
, TargetId
, Lun
);
880 } while (Lun
< SCSI_MAXIMUM_LOGICAL_UNITS
);
886 IN PHW_INITIALIZATION_DATA HwInitializationData
,
887 IN PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor
,
888 IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig
)
890 PACCESS_RANGE AccessRange
;
891 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialData
;
897 /* Loop through all entries */
898 for (Index
= 0; Index
< ResourceDescriptor
->PartialResourceList
.Count
; Index
++)
900 PartialData
= &ResourceDescriptor
->PartialResourceList
.PartialDescriptors
[Index
];
902 switch (PartialData
->Type
)
904 case CmResourceTypePort
:
905 /* Copy access ranges */
906 if (RangeNumber
< HwInitializationData
->NumberOfAccessRanges
)
908 TRACE("Got port at 0x%I64x, len 0x%x\n",
909 PartialData
->u
.Port
.Start
.QuadPart
, PartialData
->u
.Port
.Length
);
910 AccessRange
= &((*(PortConfig
->AccessRanges
))[RangeNumber
]);
912 AccessRange
->RangeStart
= PartialData
->u
.Port
.Start
;
913 AccessRange
->RangeLength
= PartialData
->u
.Port
.Length
;
915 AccessRange
->RangeInMemory
= FALSE
;
920 case CmResourceTypeMemory
:
921 /* Copy access ranges */
922 if (RangeNumber
< HwInitializationData
->NumberOfAccessRanges
)
924 TRACE("Got memory at 0x%I64x, len 0x%x\n",
925 PartialData
->u
.Memory
.Start
.QuadPart
, PartialData
->u
.Memory
.Length
);
926 AccessRange
= &((*(PortConfig
->AccessRanges
))[RangeNumber
]);
928 AccessRange
->RangeStart
= PartialData
->u
.Memory
.Start
;
929 AccessRange
->RangeLength
= PartialData
->u
.Memory
.Length
;
931 AccessRange
->RangeInMemory
= TRUE
;
936 case CmResourceTypeInterrupt
:
937 /* Copy interrupt data */
938 TRACE("Got interrupt level %d, vector %d\n",
939 PartialData
->u
.Interrupt
.Level
, PartialData
->u
.Interrupt
.Vector
);
940 PortConfig
->BusInterruptLevel
= PartialData
->u
.Interrupt
.Level
;
941 PortConfig
->BusInterruptVector
= PartialData
->u
.Interrupt
.Vector
;
943 /* Set interrupt mode accordingly to the resource */
944 if (PartialData
->Flags
== CM_RESOURCE_INTERRUPT_LATCHED
)
946 PortConfig
->InterruptMode
= Latched
;
948 else if (PartialData
->Flags
== CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
)
950 PortConfig
->InterruptMode
= LevelSensitive
;
954 case CmResourceTypeDma
:
955 TRACE("Got DMA channel %d, port %d\n",
956 PartialData
->u
.Dma
.Channel
, PartialData
->u
.Dma
.Port
);
957 PortConfig
->DmaChannel
= PartialData
->u
.Dma
.Channel
;
958 PortConfig
->DmaPort
= PartialData
->u
.Dma
.Port
;
966 IN
struct _HW_INITIALIZATION_DATA
*HwInitializationData
,
967 IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig
,
969 IN OUT PPCI_SLOT_NUMBER NextSlotNumber
)
971 PCI_COMMON_CONFIG PciConfig
;
972 PCI_SLOT_NUMBER SlotNumber
;
975 ULONG FunctionNumber
;
976 CHAR VendorIdString
[8];
977 CHAR DeviceIdString
[8];
978 PCM_RESOURCE_LIST ResourceList
= NULL
;
981 SlotNumber
.u
.AsULONG
= 0;
983 /* Loop through all devices */
984 for (DeviceNumber
= NextSlotNumber
->u
.bits
.DeviceNumber
; DeviceNumber
< PCI_MAX_DEVICES
; DeviceNumber
++)
986 SlotNumber
.u
.bits
.DeviceNumber
= DeviceNumber
;
988 /* Loop through all functions */
989 for (FunctionNumber
= NextSlotNumber
->u
.bits
.FunctionNumber
; FunctionNumber
< PCI_MAX_FUNCTION
; FunctionNumber
++)
991 SlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
993 /* Get PCI config bytes */
994 DataSize
= HalGetBusDataByOffset(
997 SlotNumber
.u
.AsULONG
,
1002 /* If result of HalGetBusData is 0, then the bus is wrong */
1006 /* If result is PCI_INVALID_VENDORID, then this device has no more
1008 if (PciConfig
.VendorID
== PCI_INVALID_VENDORID
)
1011 sprintf(VendorIdString
, "%04hx", PciConfig
.VendorID
);
1012 sprintf(DeviceIdString
, "%04hx", PciConfig
.DeviceID
);
1014 if (_strnicmp(VendorIdString
, HwInitializationData
->VendorId
, HwInitializationData
->VendorIdLength
) ||
1015 _strnicmp(DeviceIdString
, HwInitializationData
->DeviceId
, HwInitializationData
->DeviceIdLength
))
1017 /* It is not our device */
1021 TRACE( "Found device 0x%04hx 0x%04hx at %1lu %2lu %1lu\n",
1022 PciConfig
.VendorID
, PciConfig
.DeviceID
,
1024 SlotNumber
.u
.bits
.DeviceNumber
, SlotNumber
.u
.bits
.FunctionNumber
);
1026 Status
= HalAssignSlotResources(NULL
,
1032 SlotNumber
.u
.AsULONG
,
1035 if (!NT_SUCCESS(Status
))
1038 /* Create configuration information */
1039 SpiResourceToConfig(HwInitializationData
,
1043 /* Free the resource list */
1044 ExFreePool(ResourceList
);
1046 /* Set dev & fn numbers */
1047 NextSlotNumber
->u
.bits
.DeviceNumber
= DeviceNumber
;
1048 NextSlotNumber
->u
.bits
.FunctionNumber
= FunctionNumber
+ 1;
1050 /* Save the slot number */
1051 PortConfig
->SlotNumber
= SlotNumber
.u
.AsULONG
;
1055 NextSlotNumber
->u
.bits
.FunctionNumber
= 0;
1058 NextSlotNumber
->u
.bits
.DeviceNumber
= 0;
1068 IN
struct _HW_INITIALIZATION_DATA
*HwInitializationData
,
1069 IN PVOID HwContext OPTIONAL
)
1071 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
1072 ULONG DeviceExtensionSize
;
1073 PORT_CONFIGURATION_INFORMATION PortConfig
;
1075 BOOLEAN FirstConfigCall
= TRUE
;
1076 PCI_SLOT_NUMBER SlotNumber
;
1080 if (HwInitializationData
->HwInitializationDataSize
!= sizeof(HW_INITIALIZATION_DATA
))
1082 return STATUS_INVALID_PARAMETER
;
1085 /* Check params for validity */
1086 if ((HwInitializationData
->HwInitialize
== NULL
) ||
1087 (HwInitializationData
->HwStartIo
== NULL
) ||
1088 (HwInitializationData
->HwInterrupt
== NULL
) ||
1089 (HwInitializationData
->HwFindAdapter
== NULL
) ||
1090 (HwInitializationData
->HwResetBus
== NULL
))
1092 return STATUS_INVALID_PARAMETER
;
1095 /* Zero starting slot number */
1096 SlotNumber
.u
.AsULONG
= 0;
1102 DeviceExtensionSize
= sizeof(SCSI_PORT_DEVICE_EXTENSION
) + HwInitializationData
->DeviceExtensionSize
;
1103 DeviceExtension
= FrLdrTempAlloc(DeviceExtensionSize
, TAG_SCSI_DEVEXT
);
1104 if (!DeviceExtension
)
1106 return STATUS_NO_MEMORY
;
1108 RtlZeroMemory(DeviceExtension
, DeviceExtensionSize
);
1109 DeviceExtension
->InterruptFlags
= SCSI_PORT_NEXT_REQUEST_READY
;
1110 DeviceExtension
->HwInitialize
= HwInitializationData
->HwInitialize
;
1111 DeviceExtension
->HwStartIo
= HwInitializationData
->HwStartIo
;
1112 DeviceExtension
->HwInterrupt
= HwInitializationData
->HwInterrupt
;
1113 DeviceExtension
->HwResetBus
= HwInitializationData
->HwResetBus
;
1114 DeviceExtension
->MiniPortDeviceExtension
= (PVOID
)(DeviceExtension
+ 1);
1116 Status
= SpiCreatePortConfig(DeviceExtension
,
1117 HwInitializationData
,
1120 if (Status
!= STATUS_SUCCESS
)
1122 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1126 PortConfig
.NumberOfAccessRanges
= HwInitializationData
->NumberOfAccessRanges
;
1127 PortConfig
.AccessRanges
= FrLdrTempAlloc(sizeof(ACCESS_RANGE
) * HwInitializationData
->NumberOfAccessRanges
,
1128 TAG_SCSI_ACCESS_RANGES
);
1129 if (!PortConfig
.AccessRanges
)
1131 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1132 return STATUS_NO_MEMORY
;
1134 RtlZeroMemory(PortConfig
.AccessRanges
, sizeof(ACCESS_RANGE
) * HwInitializationData
->NumberOfAccessRanges
);
1136 /* Search for matching PCI device */
1137 if ((HwInitializationData
->AdapterInterfaceType
== PCIBus
) &&
1138 (HwInitializationData
->VendorIdLength
> 0) &&
1139 (HwInitializationData
->VendorId
!= NULL
) &&
1140 (HwInitializationData
->DeviceIdLength
> 0) &&
1141 (HwInitializationData
->DeviceId
!= NULL
))
1143 PortConfig
.BusInterruptLevel
= 0;
1145 /* Get PCI device data */
1146 TRACE("VendorId '%.*s' DeviceId '%.*s'\n",
1147 HwInitializationData
->VendorIdLength
,
1148 HwInitializationData
->VendorId
,
1149 HwInitializationData
->DeviceIdLength
,
1150 HwInitializationData
->DeviceId
);
1152 if (!SpiGetPciConfigData(HwInitializationData
,
1157 /* Continue to the next bus, nothing here */
1158 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1159 return STATUS_INTERNAL_ERROR
;
1162 if (!PortConfig
.BusInterruptLevel
)
1164 /* Bypass this slot, because no interrupt was assigned */
1165 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1166 return STATUS_INTERNAL_ERROR
;
1170 if (HwInitializationData
->HwFindAdapter(
1171 DeviceExtension
->MiniPortDeviceExtension
,
1176 &Again
) != SP_RETURN_FOUND
)
1178 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1179 return STATUS_INTERNAL_ERROR
;
1182 /* Copy all stuff which we ever need from PortConfig to the DeviceExtension */
1183 if (PortConfig
.MaximumNumberOfTargets
> SCSI_MAXIMUM_TARGETS_PER_BUS
)
1184 DeviceExtension
->MaxTargedIds
= SCSI_MAXIMUM_TARGETS_PER_BUS
;
1186 DeviceExtension
->MaxTargedIds
= PortConfig
.MaximumNumberOfTargets
;
1188 DeviceExtension
->BusNum
= PortConfig
.SystemIoBusNumber
;
1190 TRACE("Adapter found: buses = %d, targets = %d\n",
1191 PortConfig
.NumberOfBuses
, DeviceExtension
->MaxTargedIds
);
1193 /* Initialize adapter */
1194 if (!DeviceExtension
->HwInitialize(DeviceExtension
->MiniPortDeviceExtension
))
1196 FrLdrTempFree(DeviceExtension
, TAG_SCSI_DEVEXT
);
1197 return STATUS_INTERNAL_ERROR
;
1201 for (ScsiBus
= 0; ScsiBus
< PortConfig
.NumberOfBuses
; ScsiBus
++)
1203 SpiScanAdapter(DeviceExtension
, PortConfig
.SystemIoBusNumber
, ScsiBus
);
1204 PortConfig
.SystemIoBusNumber
++;
1207 FirstConfigCall
= FALSE
;
1214 return STATUS_SUCCESS
;
1219 ScsiPortIoMapTransfer(
1220 IN PVOID HwDeviceExtension
,
1221 IN PSCSI_REQUEST_BLOCK Srb
,
1222 IN PVOID LogicalAddress
,
1232 IN PVOID HwDeviceExtension
,
1233 IN PSCSI_REQUEST_BLOCK Srb OPTIONAL
,
1247 IN PVOID WriteBuffer
,
1248 IN PVOID ReadBuffer
,
1251 RtlMoveMemory(WriteBuffer
, ReadBuffer
, Length
);
1256 ScsiPortNotification(
1257 IN SCSI_NOTIFICATION_TYPE NotificationType
,
1258 IN PVOID HwDeviceExtension
,
1261 PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
;
1262 PSCSI_REQUEST_BLOCK Srb
;
1265 DeviceExtension
= ((PSCSI_PORT_DEVICE_EXTENSION
)HwDeviceExtension
) - 1;
1267 va_start(ap
, HwDeviceExtension
);
1269 switch (NotificationType
)
1271 case RequestComplete
:
1272 /* Mask the SRB as completed */
1273 Srb
= va_arg(ap
, PSCSI_REQUEST_BLOCK
);
1274 Srb
->SrbFlags
&= ~SRB_FLAGS_IS_ACTIVE
;
1278 /* Say that device is ready */
1279 DeviceExtension
->InterruptFlags
|= SCSI_PORT_NEXT_REQUEST_READY
;
1292 ScsiPortReadPortBufferUchar(
1297 __inbytestring(H2I(Port
), Buffer
, Count
);
1302 ScsiPortReadPortBufferUlong(
1307 __indwordstring(H2I(Port
), Buffer
, Count
);
1312 ScsiPortReadPortBufferUshort(
1317 __inwordstring(H2I(Port
), Buffer
, Count
);
1322 ScsiPortReadPortUchar(
1325 TRACE("ScsiPortReadPortUchar(%p)\n", Port
);
1327 return READ_PORT_UCHAR(Port
);
1332 ScsiPortReadPortUlong(
1335 return READ_PORT_ULONG(Port
);
1340 ScsiPortReadPortUshort(
1343 return READ_PORT_USHORT(Port
);
1348 ScsiPortReadRegisterBufferUchar(
1359 ScsiPortReadRegisterBufferUlong(
1370 ScsiPortReadRegisterBufferUshort(
1371 IN PUSHORT Register
,
1381 ScsiPortReadRegisterUchar(
1384 return READ_REGISTER_UCHAR(Register
);
1389 ScsiPortReadRegisterUlong(
1392 return READ_REGISTER_ULONG(Register
);
1397 ScsiPortReadRegisterUshort(
1398 IN PUSHORT Register
)
1400 return READ_REGISTER_USHORT(Register
);
1405 ScsiPortSetBusDataByOffset(
1406 IN PVOID DeviceExtension
,
1407 IN ULONG BusDataType
,
1408 IN ULONG SystemIoBusNumber
,
1409 IN ULONG SlotNumber
,
1421 ScsiPortStallExecution(
1424 KeStallExecutionProcessor(Delay
);
1429 ScsiPortValidateRange(
1430 IN PVOID HwDeviceExtension
,
1431 IN INTERFACE_TYPE BusType
,
1432 IN ULONG SystemIoBusNumber
,
1433 IN SCSI_PHYSICAL_ADDRESS IoAddress
,
1434 IN ULONG NumberOfBytes
,
1435 IN BOOLEAN InIoSpace
)
1449 ScsiPortWritePortBufferUchar(
1454 __outbytestring(H2I(Port
), Buffer
, Count
);
1459 ScsiPortWritePortBufferUlong(
1464 __outdwordstring(H2I(Port
), Buffer
, Count
);
1469 ScsiPortWritePortBufferUshort(
1474 __outwordstring(H2I(Port
), Buffer
, Count
);
1479 ScsiPortWritePortUchar(
1483 WRITE_PORT_UCHAR(Port
, Value
);
1488 ScsiPortWritePortUlong(
1492 WRITE_PORT_ULONG(Port
, Value
);
1497 ScsiPortWritePortUshort(
1501 WRITE_PORT_USHORT(Port
, Value
);
1506 ScsiPortWriteRegisterBufferUchar(
1517 ScsiPortWriteRegisterBufferUlong(
1528 ScsiPortWriteRegisterBufferUshort(
1529 IN PUSHORT Register
,
1539 ScsiPortWriteRegisterUchar(
1543 WRITE_REGISTER_UCHAR(Register
, Value
);
1548 ScsiPortWriteRegisterUlong(
1552 WRITE_REGISTER_ULONG(Register
, Value
);
1557 ScsiPortWriteRegisterUshort(
1558 IN PUSHORT Register
,
1561 WRITE_REGISTER_USHORT(Register
, Value
);
1564 extern char __ImageBase
;
1567 LoadBootDeviceDriver(VOID
)
1569 PIMAGE_NT_HEADERS NtHeaders
;
1570 LIST_ENTRY ModuleListHead
;
1571 PIMAGE_IMPORT_DESCRIPTOR ImportTable
;
1572 ULONG ImportTableSize
;
1573 PLDR_DATA_TABLE_ENTRY BootDdDTE
, FreeldrDTE
;
1574 CHAR NtBootDdPath
[MAX_PATH
];
1575 PVOID ImageBase
= NULL
;
1576 ULONG (NTAPI
*EntryPoint
)(IN PVOID DriverObject
, IN PVOID RegistryPath
);
1579 /* Initialize the loaded module list */
1580 InitializeListHead(&ModuleListHead
);
1582 /* Create full ntbootdd.sys path */
1583 MachDiskGetBootPath(NtBootDdPath
, sizeof(NtBootDdPath
));
1584 strcat(NtBootDdPath
, "\\NTBOOTDD.SYS");
1587 Status
= WinLdrLoadImage(NtBootDdPath
, LoaderBootDriver
, &ImageBase
);
1590 /* That's OK. File simply doesn't exist */
1594 /* Allocate a DTE for ntbootdd */
1595 Status
= WinLdrAllocateDataTableEntry(&ModuleListHead
, "ntbootdd.sys",
1596 "NTBOOTDD.SYS", ImageBase
, &BootDdDTE
);
1600 /* Add the PE part of freeldr.sys to the list of loaded executables, it
1601 contains Scsiport* exports, imported by ntbootdd.sys */
1602 Status
= WinLdrAllocateDataTableEntry(&ModuleListHead
, "scsiport.sys",
1603 "FREELDR.SYS", &__ImageBase
, &FreeldrDTE
);
1606 RemoveEntryList(&BootDdDTE
->InLoadOrderLinks
);
1611 Status
= WinLdrScanImportDescriptorTable(&ModuleListHead
, "", BootDdDTE
);
1613 /* Now unlinkt the DTEs, they won't be valid later */
1614 RemoveEntryList(&BootDdDTE
->InLoadOrderLinks
);
1615 RemoveEntryList(&FreeldrDTE
->InLoadOrderLinks
);
1620 /* Change imports to PA */
1621 ImportTable
= (PIMAGE_IMPORT_DESCRIPTOR
)RtlImageDirectoryEntryToData(VaToPa(BootDdDTE
->DllBase
),
1622 TRUE
, IMAGE_DIRECTORY_ENTRY_IMPORT
, &ImportTableSize
);
1623 for (;(ImportTable
->Name
!= 0) && (ImportTable
->FirstThunk
!= 0);ImportTable
++)
1625 PIMAGE_THUNK_DATA ThunkData
= (PIMAGE_THUNK_DATA
)VaToPa(RVA(BootDdDTE
->DllBase
, ImportTable
->FirstThunk
));
1627 while (((PIMAGE_THUNK_DATA
)ThunkData
)->u1
.AddressOfData
!= 0)
1629 ThunkData
->u1
.Function
= (ULONG
)VaToPa((PVOID
)ThunkData
->u1
.Function
);
1634 /* Relocate image to PA */
1635 NtHeaders
= RtlImageNtHeader(VaToPa(BootDdDTE
->DllBase
));
1638 Status
= (BOOLEAN
)LdrRelocateImageWithBias(
1639 VaToPa(BootDdDTE
->DllBase
),
1640 NtHeaders
->OptionalHeader
.ImageBase
- (ULONG_PTR
)BootDdDTE
->DllBase
,
1643 TRUE
, /* in case of conflict still return success */
1648 /* Call the entrypoint */
1649 EntryPoint
= VaToPa(BootDdDTE
->EntryPoint
);
1650 (*EntryPoint
)(NULL
, NULL
);