2 * PROJECT: ReactOS PCI Bus driver
4 * PURPOSE: Driver entry
5 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * 10-09-2001 CSH Created
18 static DRIVER_DISPATCH PciDispatchDeviceControl
;
19 static NTSTATUS NTAPI
PciDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
21 static DRIVER_ADD_DEVICE PciAddDevice
;
22 static NTSTATUS NTAPI
PciAddDevice(IN PDRIVER_OBJECT DriverObject
, IN PDEVICE_OBJECT PhysicalDeviceObject
);
24 static DRIVER_DISPATCH PciPowerControl
;
25 static NTSTATUS NTAPI
PciPowerControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
27 static DRIVER_DISPATCH PciPnpControl
;
28 static NTSTATUS NTAPI
PciPnpControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
33 // Make the initialization routines discardable, so that they
36 #pragma alloc_text(init, DriverEntry)
38 #endif /* ALLOC_PRAGMA */
40 /*** PUBLIC ******************************************************************/
42 PPCI_DRIVER_EXTENSION DriverExtension
= NULL
;
44 /*** PRIVATE *****************************************************************/
48 PciDispatchDeviceControl(
49 IN PDEVICE_OBJECT DeviceObject
,
52 PIO_STACK_LOCATION IrpSp
;
55 UNREFERENCED_PARAMETER(DeviceObject
);
56 DPRINT("Called. IRP is at (0x%X)\n", Irp
);
58 Irp
->IoStatus
.Information
= 0;
60 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
61 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
63 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
64 Status
= STATUS_NOT_IMPLEMENTED
;
68 if (Status
!= STATUS_PENDING
) {
69 Irp
->IoStatus
.Status
= Status
;
71 DPRINT("Completing IRP at 0x%X\n", Irp
);
73 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
76 DPRINT("Leaving. Status 0x%X\n", Status
);
85 IN PDEVICE_OBJECT DeviceObject
,
88 * FUNCTION: Handle Plug and Play IRPs
90 * DeviceObject = Pointer to PDO or FDO
91 * Irp = Pointer to IRP that should be handled
96 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
99 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
101 DPRINT("IsFDO %d\n", DeviceExtension
->IsFDO
);
103 if (DeviceExtension
->IsFDO
) {
104 Status
= FdoPnpControl(DeviceObject
, Irp
);
106 Status
= PdoPnpControl(DeviceObject
, Irp
);
116 IN PDEVICE_OBJECT DeviceObject
,
119 * FUNCTION: Handle power management IRPs
121 * DeviceObject = Pointer to PDO or FDO
122 * Irp = Pointer to IRP that should be handled
127 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
130 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
132 if (DeviceExtension
->IsFDO
) {
133 Status
= FdoPowerControl(DeviceObject
, Irp
);
135 Status
= PdoPowerControl(DeviceObject
, Irp
);
145 IN PDRIVER_OBJECT DriverObject
,
146 IN PDEVICE_OBJECT PhysicalDeviceObject
)
148 PFDO_DEVICE_EXTENSION DeviceExtension
;
153 if (PhysicalDeviceObject
== NULL
)
154 return STATUS_SUCCESS
;
156 Status
= IoCreateDevice(DriverObject
, sizeof(FDO_DEVICE_EXTENSION
),
157 NULL
, FILE_DEVICE_BUS_EXTENDER
, FILE_DEVICE_SECURE_OPEN
, TRUE
, &Fdo
);
158 if (!NT_SUCCESS(Status
)) {
159 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
163 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
165 RtlZeroMemory(DeviceExtension
, sizeof(FDO_DEVICE_EXTENSION
));
167 DeviceExtension
->Common
.IsFDO
= TRUE
;
169 DeviceExtension
->Ldo
=
170 IoAttachDeviceToDeviceStack(Fdo
, PhysicalDeviceObject
);
172 DeviceExtension
->State
= dsStopped
;
174 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
176 //Fdo->Flags |= DO_POWER_PAGABLE;
178 DPRINT("Done AddDevice\n");
180 return STATUS_SUCCESS
;
187 IN PDRIVER_OBJECT DriverObject
,
188 IN PUNICODE_STRING RegistryPath
)
192 UNREFERENCED_PARAMETER(RegistryPath
);
193 DPRINT("Peripheral Component Interconnect Bus Driver\n");
195 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = PciDispatchDeviceControl
;
196 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = PciPnpControl
;
197 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = PciPowerControl
;
198 DriverObject
->DriverExtension
->AddDevice
= PciAddDevice
;
200 Status
= IoAllocateDriverObjectExtension(
203 sizeof(PCI_DRIVER_EXTENSION
),
204 (PVOID
*)&DriverExtension
);
205 if (!NT_SUCCESS(Status
))
207 RtlZeroMemory(DriverExtension
, sizeof(PCI_DRIVER_EXTENSION
));
209 InitializeListHead(&DriverExtension
->BusListHead
);
210 KeInitializeSpinLock(&DriverExtension
->BusListLock
);
212 return STATUS_SUCCESS
;
217 PciCreateDeviceIDString(PUNICODE_STRING DeviceID
,
223 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
224 Device
->PciConfig
.VendorID
,
225 Device
->PciConfig
.DeviceID
,
226 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
227 Device
->PciConfig
.u
.type0
.SubVendorID
,
228 Device
->PciConfig
.RevisionID
);
230 return RtlCreateUnicodeString(DeviceID
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
235 PciCreateInstanceIDString(PUNICODE_STRING InstanceID
,
240 swprintf(Buffer
, L
"%02X", Device
->SlotNumber
.u
.AsULONG
& 0xff);
242 return RtlCreateUnicodeString(InstanceID
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
247 PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs
,
251 UNICODE_STRING BufferU
;
255 Index
+= swprintf(&Buffer
[Index
],
256 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
257 Device
->PciConfig
.VendorID
,
258 Device
->PciConfig
.DeviceID
,
259 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
260 Device
->PciConfig
.u
.type0
.SubVendorID
,
261 Device
->PciConfig
.RevisionID
);
264 Index
+= swprintf(&Buffer
[Index
],
265 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
266 Device
->PciConfig
.VendorID
,
267 Device
->PciConfig
.DeviceID
,
268 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
269 Device
->PciConfig
.u
.type0
.SubVendorID
);
272 Index
+= swprintf(&Buffer
[Index
],
273 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
274 Device
->PciConfig
.VendorID
,
275 Device
->PciConfig
.DeviceID
,
276 Device
->PciConfig
.BaseClass
,
277 Device
->PciConfig
.SubClass
,
278 Device
->PciConfig
.ProgIf
);
281 Index
+= swprintf(&Buffer
[Index
],
282 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
283 Device
->PciConfig
.VendorID
,
284 Device
->PciConfig
.DeviceID
,
285 Device
->PciConfig
.BaseClass
,
286 Device
->PciConfig
.SubClass
);
289 Buffer
[Index
] = UNICODE_NULL
;
291 BufferU
.Length
= BufferU
.MaximumLength
= (USHORT
) Index
* sizeof(WCHAR
);
292 BufferU
.Buffer
= Buffer
;
294 return PciDuplicateUnicodeString(0, &BufferU
, HardwareIDs
);
299 PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs
,
303 UNICODE_STRING BufferU
;
307 Index
+= swprintf(&Buffer
[Index
],
308 L
"PCI\\VEN_%04X&DEV_%04X&REV_%02X",
309 Device
->PciConfig
.VendorID
,
310 Device
->PciConfig
.DeviceID
,
311 Device
->PciConfig
.RevisionID
);
314 Index
+= swprintf(&Buffer
[Index
],
315 L
"PCI\\VEN_%04X&DEV_%04X",
316 Device
->PciConfig
.VendorID
,
317 Device
->PciConfig
.DeviceID
);
320 Index
+= swprintf(&Buffer
[Index
],
321 L
"PCI\\VEN_%04X&CC_%02X%02X%02X",
322 Device
->PciConfig
.VendorID
,
323 Device
->PciConfig
.BaseClass
,
324 Device
->PciConfig
.SubClass
,
325 Device
->PciConfig
.ProgIf
);
328 Index
+= swprintf(&Buffer
[Index
],
329 L
"PCI\\VEN_%04X&CC_%02X%02X",
330 Device
->PciConfig
.VendorID
,
331 Device
->PciConfig
.BaseClass
,
332 Device
->PciConfig
.SubClass
);
335 Index
+= swprintf(&Buffer
[Index
],
337 Device
->PciConfig
.VendorID
);
340 Index
+= swprintf(&Buffer
[Index
],
341 L
"PCI\\CC_%02X%02X%02X",
342 Device
->PciConfig
.BaseClass
,
343 Device
->PciConfig
.SubClass
,
344 Device
->PciConfig
.ProgIf
);
347 Index
+= swprintf(&Buffer
[Index
],
349 Device
->PciConfig
.BaseClass
,
350 Device
->PciConfig
.SubClass
);
353 Buffer
[Index
] = UNICODE_NULL
;
355 BufferU
.Length
= BufferU
.MaximumLength
= (USHORT
)Index
* sizeof(WCHAR
);
356 BufferU
.Buffer
= Buffer
;
358 return PciDuplicateUnicodeString(0, &BufferU
, CompatibleIDs
);
363 PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription
,
368 switch (Device
->PciConfig
.BaseClass
)
370 case PCI_CLASS_PRE_20
:
371 switch (Device
->PciConfig
.SubClass
)
373 case PCI_SUBCLASS_PRE_20_VGA
:
374 Description
= L
"VGA device";
378 case PCI_SUBCLASS_PRE_20_NON_VGA
:
379 Description
= L
"PCI device";
384 case PCI_CLASS_MASS_STORAGE_CTLR
:
385 switch (Device
->PciConfig
.SubClass
)
387 case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR
:
388 Description
= L
"SCSI controller";
391 case PCI_SUBCLASS_MSC_IDE_CTLR
:
392 Description
= L
"IDE controller";
395 case PCI_SUBCLASS_MSC_FLOPPY_CTLR
:
396 Description
= L
"Floppy disk controller";
399 case PCI_SUBCLASS_MSC_IPI_CTLR
:
400 Description
= L
"IPI controller";
403 case PCI_SUBCLASS_MSC_RAID_CTLR
:
404 Description
= L
"RAID controller";
408 Description
= L
"Mass storage controller";
413 case PCI_CLASS_NETWORK_CTLR
:
414 switch (Device
->PciConfig
.SubClass
)
416 case PCI_SUBCLASS_NET_ETHERNET_CTLR
:
417 Description
= L
"Ethernet controller";
420 case PCI_SUBCLASS_NET_TOKEN_RING_CTLR
:
421 Description
= L
"Token-Ring controller";
424 case PCI_SUBCLASS_NET_FDDI_CTLR
:
425 Description
= L
"FDDI controller";
428 case PCI_SUBCLASS_NET_ATM_CTLR
:
429 Description
= L
"ATM controller";
433 Description
= L
"Network controller";
438 case PCI_CLASS_DISPLAY_CTLR
:
439 switch (Device
->PciConfig
.SubClass
)
441 case PCI_SUBCLASS_VID_VGA_CTLR
:
442 Description
= L
"VGA display controller";
445 case PCI_SUBCLASS_VID_XGA_CTLR
:
446 Description
= L
"XGA display controller";
449 case PCI_SUBCLASS_VID_3D_CTLR
:
450 Description
= L
"Multimedia display controller";
454 Description
= L
"Other display controller";
459 case PCI_CLASS_MULTIMEDIA_DEV
:
460 switch (Device
->PciConfig
.SubClass
)
462 case PCI_SUBCLASS_MM_VIDEO_DEV
:
463 Description
= L
"Multimedia video device";
466 case PCI_SUBCLASS_MM_AUDIO_DEV
:
467 Description
= L
"Multimedia audio device";
470 case PCI_SUBCLASS_MM_TELEPHONY_DEV
:
471 Description
= L
"Multimedia telephony device";
475 Description
= L
"Other multimedia device";
480 case PCI_CLASS_MEMORY_CTLR
:
481 switch (Device
->PciConfig
.SubClass
)
483 case PCI_SUBCLASS_MEM_RAM
:
484 Description
= L
"PCI Memory";
487 case PCI_SUBCLASS_MEM_FLASH
:
488 Description
= L
"PCI Flash Memory";
492 Description
= L
"Other memory controller";
497 case PCI_CLASS_BRIDGE_DEV
:
498 switch (Device
->PciConfig
.SubClass
)
500 case PCI_SUBCLASS_BR_HOST
:
501 Description
= L
"PCI-Host bridge";
504 case PCI_SUBCLASS_BR_ISA
:
505 Description
= L
"PCI-ISA bridge";
508 case PCI_SUBCLASS_BR_EISA
:
509 Description
= L
"PCI-EISA bridge";
512 case PCI_SUBCLASS_BR_MCA
:
513 Description
= L
"PCI-Micro Channel bridge";
516 case PCI_SUBCLASS_BR_PCI_TO_PCI
:
517 Description
= L
"PCI-PCI bridge";
520 case PCI_SUBCLASS_BR_PCMCIA
:
521 Description
= L
"PCI-PCMCIA bridge";
524 case PCI_SUBCLASS_BR_NUBUS
:
525 Description
= L
"PCI-NUBUS bridge";
528 case PCI_SUBCLASS_BR_CARDBUS
:
529 Description
= L
"PCI-CARDBUS bridge";
533 Description
= L
"Other bridge device";
538 case PCI_CLASS_SIMPLE_COMMS_CTLR
:
539 switch (Device
->PciConfig
.SubClass
)
543 Description
= L
"Communication device";
548 case PCI_CLASS_BASE_SYSTEM_DEV
:
549 switch (Device
->PciConfig
.SubClass
)
553 Description
= L
"System device";
558 case PCI_CLASS_INPUT_DEV
:
559 switch (Device
->PciConfig
.SubClass
)
563 Description
= L
"Input device";
568 case PCI_CLASS_DOCKING_STATION
:
569 switch (Device
->PciConfig
.SubClass
)
573 Description
= L
"Docking station";
578 case PCI_CLASS_PROCESSOR
:
579 switch (Device
->PciConfig
.SubClass
)
583 Description
= L
"Processor";
588 case PCI_CLASS_SERIAL_BUS_CTLR
:
589 switch (Device
->PciConfig
.SubClass
)
591 case PCI_SUBCLASS_SB_IEEE1394
:
592 Description
= L
"FireWire controller";
595 case PCI_SUBCLASS_SB_ACCESS
:
596 Description
= L
"ACCESS bus controller";
599 case PCI_SUBCLASS_SB_SSA
:
600 Description
= L
"SSA controller";
603 case PCI_SUBCLASS_SB_USB
:
604 Description
= L
"USB controller";
607 case PCI_SUBCLASS_SB_FIBRE_CHANNEL
:
608 Description
= L
"Fibre Channel controller";
611 case PCI_SUBCLASS_SB_SMBUS
:
612 Description
= L
"SMBus controller";
616 Description
= L
"Other serial bus controller";
622 Description
= L
"Other PCI Device";
626 return RtlCreateUnicodeString(DeviceDescription
, Description
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
631 PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation
,
637 L
"PCI-Bus %lu, Device %u, Function %u",
639 Device
->SlotNumber
.u
.bits
.DeviceNumber
,
640 Device
->SlotNumber
.u
.bits
.FunctionNumber
);
642 return RtlCreateUnicodeString(DeviceLocation
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
646 PciDuplicateUnicodeString(
648 IN PCUNICODE_STRING SourceString
,
649 OUT PUNICODE_STRING DestinationString
)
651 if (SourceString
== NULL
|| DestinationString
== NULL
652 || SourceString
->Length
> SourceString
->MaximumLength
653 || (SourceString
->Length
== 0 && SourceString
->MaximumLength
> 0 && SourceString
->Buffer
== NULL
)
654 || Flags
== RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING
|| Flags
>= 4)
656 return STATUS_INVALID_PARAMETER
;
660 if ((SourceString
->Length
== 0)
661 && (Flags
!= (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
|
662 RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING
)))
664 DestinationString
->Length
= 0;
665 DestinationString
->MaximumLength
= 0;
666 DestinationString
->Buffer
= NULL
;
670 USHORT DestMaxLength
= SourceString
->Length
;
672 if (Flags
& RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
)
673 DestMaxLength
+= sizeof(UNICODE_NULL
);
675 DestinationString
->Buffer
= ExAllocatePoolWithTag(PagedPool
, DestMaxLength
, TAG_PCI
);
676 if (DestinationString
->Buffer
== NULL
)
677 return STATUS_NO_MEMORY
;
679 RtlCopyMemory(DestinationString
->Buffer
, SourceString
->Buffer
, SourceString
->Length
);
680 DestinationString
->Length
= SourceString
->Length
;
681 DestinationString
->MaximumLength
= DestMaxLength
;
683 if (Flags
& RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
)
684 DestinationString
->Buffer
[DestinationString
->Length
/ sizeof(WCHAR
)] = 0;
687 return STATUS_SUCCESS
;