3 * PROJECT: ReactOS PCI Bus driver
5 * PURPOSE: Driver entry
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * 10-09-2001 CSH Created
11 #include <ddk/ntddk.h>
22 // Make the initialization routines discardable, so that they
25 #pragma alloc_text(init, DriverEntry)
27 #endif /* ALLOC_PRAGMA */
29 /*** PUBLIC ******************************************************************/
32 /*** PRIVATE *****************************************************************/
36 PciDispatchDeviceControl(
37 IN PDEVICE_OBJECT DeviceObject
,
40 PIO_STACK_LOCATION IrpSp
;
43 DPRINT("Called. IRP is at (0x%X)\n", Irp
);
45 Irp
->IoStatus
.Information
= 0;
47 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
48 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
50 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
51 Status
= STATUS_NOT_IMPLEMENTED
;
55 if (Status
!= STATUS_PENDING
) {
56 Irp
->IoStatus
.Status
= Status
;
58 DPRINT("Completing IRP at 0x%X\n", Irp
);
60 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
63 DPRINT("Leaving. Status 0x%X\n", Status
);
72 IN PDEVICE_OBJECT DeviceObject
,
75 * FUNCTION: Handle Plug and Play IRPs
77 * DeviceObject = Pointer to PDO or FDO
78 * Irp = Pointer to IRP that should be handled
83 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
86 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
88 DPRINT("IsFDO %d\n", DeviceExtension
->IsFDO
);
90 if (DeviceExtension
->IsFDO
) {
91 Status
= FdoPnpControl(DeviceObject
, Irp
);
93 Status
= PdoPnpControl(DeviceObject
, Irp
);
103 IN PDEVICE_OBJECT DeviceObject
,
106 * FUNCTION: Handle power management IRPs
108 * DeviceObject = Pointer to PDO or FDO
109 * Irp = Pointer to IRP that should be handled
114 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
117 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
119 if (DeviceExtension
->IsFDO
) {
120 Status
= FdoPowerControl(DeviceObject
, Irp
);
122 Status
= PdoPowerControl(DeviceObject
, Irp
);
132 IN PDRIVER_OBJECT DriverObject
,
133 IN PDEVICE_OBJECT PhysicalDeviceObject
)
135 PFDO_DEVICE_EXTENSION DeviceExtension
;
141 Status
= IoCreateDevice(DriverObject
, sizeof(FDO_DEVICE_EXTENSION
),
142 NULL
, FILE_DEVICE_BUS_EXTENDER
, FILE_DEVICE_SECURE_OPEN
, TRUE
, &Fdo
);
143 if (!NT_SUCCESS(Status
)) {
144 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
148 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
150 RtlZeroMemory(DeviceExtension
, sizeof(FDO_DEVICE_EXTENSION
));
152 DeviceExtension
->Common
.IsFDO
= TRUE
;
154 DeviceExtension
->Ldo
=
155 IoAttachDeviceToDeviceStack(Fdo
, PhysicalDeviceObject
);
157 DeviceExtension
->State
= dsStopped
;
159 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
161 //Fdo->Flags |= DO_POWER_PAGABLE;
163 DPRINT("Done AddDevice\n");
165 return STATUS_SUCCESS
;
172 IN PDRIVER_OBJECT DriverObject
,
173 IN PUNICODE_STRING RegistryPath
)
175 DbgPrint("Peripheral Component Interconnect Bus Driver\n");
177 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = PciDispatchDeviceControl
;
178 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = PciPnpControl
;
179 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = PciPowerControl
;
180 DriverObject
->DriverExtension
->AddDevice
= PciAddDevice
;
182 return STATUS_SUCCESS
;
187 PciCreateUnicodeString(
188 PUNICODE_STRING Destination
,
196 RtlInitUnicodeString(Destination
, NULL
);
200 Length
= (wcslen(Source
) + 1) * sizeof(WCHAR
);
202 Destination
->Buffer
= ExAllocatePool(PoolType
, Length
);
204 if (Destination
->Buffer
== NULL
)
209 RtlCopyMemory(Destination
->Buffer
, Source
, Length
);
211 Destination
->MaximumLength
= Length
;
213 Destination
->Length
= Length
- sizeof(WCHAR
);
220 PciDuplicateUnicodeString(
221 PUNICODE_STRING Destination
,
222 PUNICODE_STRING Source
,
227 RtlInitUnicodeString(Destination
, NULL
);
228 return STATUS_SUCCESS
;
231 Destination
->Buffer
= ExAllocatePool(PoolType
, Source
->MaximumLength
);
232 if (Destination
->Buffer
== NULL
)
234 return STATUS_INSUFFICIENT_RESOURCES
;
237 Destination
->MaximumLength
= Source
->MaximumLength
;
238 Destination
->Length
= Source
->Length
;
239 RtlCopyMemory(Destination
->Buffer
, Source
->Buffer
, Source
->MaximumLength
);
241 return STATUS_SUCCESS
;
246 PciCreateDeviceIDString(PUNICODE_STRING DeviceID
,
252 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
253 Device
->PciConfig
.VendorID
,
254 Device
->PciConfig
.DeviceID
,
255 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
256 Device
->PciConfig
.u
.type0
.SubVendorID
,
257 Device
->PciConfig
.RevisionID
);
259 if (!PciCreateUnicodeString(DeviceID
, Buffer
, PagedPool
))
269 PciCreateInstanceIDString(PUNICODE_STRING InstanceID
,
277 Index
= swprintf(Buffer
,
280 (Device
->SlotNumber
.u
.bits
.DeviceNumber
<< 3) +
281 Device
->SlotNumber
.u
.bits
.FunctionNumber
);
283 Buffer
[Index
] = UNICODE_NULL
;
285 Length
= (Index
+ 1) * sizeof(WCHAR
);
286 InstanceID
->Buffer
= ExAllocatePool(PagedPool
, Length
);
287 if (InstanceID
->Buffer
== NULL
)
292 InstanceID
->Length
= Length
- sizeof(WCHAR
);
293 InstanceID
->MaximumLength
= Length
;
294 RtlCopyMemory(InstanceID
->Buffer
, Buffer
, Length
);
298 return PciCreateUnicodeString(InstanceID
, L
"0000", PagedPool
);
303 PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs
,
311 Index
+= swprintf(&Buffer
[Index
],
312 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
313 Device
->PciConfig
.VendorID
,
314 Device
->PciConfig
.DeviceID
,
315 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
316 Device
->PciConfig
.u
.type0
.SubVendorID
,
317 Device
->PciConfig
.RevisionID
);
320 Index
+= swprintf(&Buffer
[Index
],
321 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
322 Device
->PciConfig
.VendorID
,
323 Device
->PciConfig
.DeviceID
,
324 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
325 Device
->PciConfig
.u
.type0
.SubVendorID
);
328 Buffer
[Index
] = UNICODE_NULL
;
330 Length
= (Index
+ 1) * sizeof(WCHAR
);
331 HardwareIDs
->Buffer
= ExAllocatePool(PagedPool
, Length
);
332 if (HardwareIDs
->Buffer
== NULL
)
337 HardwareIDs
->Length
= Length
- sizeof(WCHAR
);
338 HardwareIDs
->MaximumLength
= Length
;
339 RtlCopyMemory(HardwareIDs
->Buffer
, Buffer
, Length
);
346 PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs
,
354 Index
+= swprintf(&Buffer
[Index
],
355 L
"PCI\\VEN_%04X&DEV_%04X&REV_%02X&CC_%02X%02X",
356 Device
->PciConfig
.VendorID
,
357 Device
->PciConfig
.DeviceID
,
358 Device
->PciConfig
.RevisionID
,
359 Device
->PciConfig
.BaseClass
,
360 Device
->PciConfig
.SubClass
);
363 Index
+= swprintf(&Buffer
[Index
],
364 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
365 Device
->PciConfig
.VendorID
,
366 Device
->PciConfig
.DeviceID
,
367 Device
->PciConfig
.BaseClass
,
368 Device
->PciConfig
.SubClass
,
369 Device
->PciConfig
.ProgIf
);
372 Index
+= swprintf(&Buffer
[Index
],
373 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
374 Device
->PciConfig
.VendorID
,
375 Device
->PciConfig
.DeviceID
,
376 Device
->PciConfig
.BaseClass
,
377 Device
->PciConfig
.SubClass
);
380 Index
+= swprintf(&Buffer
[Index
],
381 L
"PCI\\VEN_%04X&CC_%02X%02X%02X",
382 Device
->PciConfig
.VendorID
,
383 Device
->PciConfig
.BaseClass
,
384 Device
->PciConfig
.SubClass
,
385 Device
->PciConfig
.ProgIf
);
388 Index
+= swprintf(&Buffer
[Index
],
389 L
"PCI\\VEN_%04X&CC_%02X%02X",
390 Device
->PciConfig
.VendorID
,
391 Device
->PciConfig
.BaseClass
,
392 Device
->PciConfig
.SubClass
);
395 Index
+= swprintf(&Buffer
[Index
],
397 Device
->PciConfig
.VendorID
);
400 Index
+= swprintf(&Buffer
[Index
],
401 L
"PCI\\CC_%02X%02X%02X",
402 Device
->PciConfig
.BaseClass
,
403 Device
->PciConfig
.SubClass
,
404 Device
->PciConfig
.ProgIf
);
407 Index
+= swprintf(&Buffer
[Index
],
409 Device
->PciConfig
.BaseClass
,
410 Device
->PciConfig
.SubClass
);
413 Buffer
[Index
] = UNICODE_NULL
;
415 Length
= (Index
+ 1) * sizeof(WCHAR
);
416 CompatibleIDs
->Buffer
= ExAllocatePool(PagedPool
, Length
);
417 if (CompatibleIDs
->Buffer
== NULL
)
422 CompatibleIDs
->Length
= Length
- sizeof(WCHAR
);
423 CompatibleIDs
->MaximumLength
= Length
;
424 RtlCopyMemory(CompatibleIDs
->Buffer
, Buffer
, Length
);
431 PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription
,
437 switch (Device
->PciConfig
.BaseClass
)
439 case PCI_CLASS_PRE_20
:
440 switch (Device
->PciConfig
.SubClass
)
442 case PCI_SUBCLASS_PRE_20_VGA
:
443 Description
= L
"VGA device";
447 case PCI_SUBCLASS_PRE_20_NON_VGA
:
448 Description
= L
"PCI device";
453 case PCI_CLASS_MASS_STORAGE_CTLR
:
454 switch (Device
->PciConfig
.SubClass
)
456 case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR
:
457 Description
= L
"SCSI controller";
460 case PCI_SUBCLASS_MSC_IDE_CTLR
:
461 Description
= L
"IDE controller";
464 case PCI_SUBCLASS_MSC_FLOPPY_CTLR
:
465 Description
= L
"Floppy disk controller";
468 case PCI_SUBCLASS_MSC_IPI_CTLR
:
469 Description
= L
"IPI controller";
472 case PCI_SUBCLASS_MSC_RAID_CTLR
:
473 Description
= L
"RAID controller";
477 Description
= L
"Mass storage controller";
482 case PCI_CLASS_NETWORK_CTLR
:
483 switch (Device
->PciConfig
.SubClass
)
485 case PCI_SUBCLASS_NET_ETHERNET_CTLR
:
486 Description
= L
"Ethernet controller";
489 case PCI_SUBCLASS_NET_TOKEN_RING_CTLR
:
490 Description
= L
"Token-Ring controller";
493 case PCI_SUBCLASS_NET_FDDI_CTLR
:
494 Description
= L
"FDDI controller";
497 case PCI_SUBCLASS_NET_ATM_CTLR
:
498 Description
= L
"ATM controller";
502 Description
= L
"Network controller";
507 case PCI_CLASS_DISPLAY_CTLR
:
508 switch (Device
->PciConfig
.SubClass
)
510 case PCI_SUBCLASS_VID_VGA_CTLR
:
511 Description
= L
"VGA display controller";
514 case PCI_SUBCLASS_VID_XGA_CTLR
:
515 Description
= L
"XGA display controller";
518 case PCI_SUBLCASS_VID_3D_CTLR
:
519 Description
= L
"Multimedia display controller";
523 Description
= L
"Other display controller";
528 case PCI_CLASS_MULTIMEDIA_DEV
:
529 switch (Device
->PciConfig
.SubClass
)
531 case PCI_SUBCLASS_MM_VIDEO_DEV
:
532 Description
= L
"Multimedia video device";
535 case PCI_SUBCLASS_MM_AUDIO_DEV
:
536 Description
= L
"Multimedia audio device";
539 case PCI_SUBCLASS_MM_TELEPHONY_DEV
:
540 Description
= L
"Multimedia telephony device";
544 Description
= L
"Other multimedia device";
549 case PCI_CLASS_MEMORY_CTLR
:
550 switch (Device
->PciConfig
.SubClass
)
552 case PCI_SUBCLASS_MEM_RAM
:
553 Description
= L
"PCI Memory";
556 case PCI_SUBCLASS_MEM_FLASH
:
557 Description
= L
"PCI Flash Memory";
561 Description
= L
"Other memory controller";
566 case PCI_CLASS_BRIDGE_DEV
:
567 switch (Device
->PciConfig
.SubClass
)
569 case PCI_SUBCLASS_BR_HOST
:
570 Description
= L
"PCI-Host bridge";
573 case PCI_SUBCLASS_BR_ISA
:
574 Description
= L
"PCI-ISA bridge";
577 case PCI_SUBCLASS_BR_EISA
:
578 Description
= L
"PCI-EISA bridge";
581 case PCI_SUBCLASS_BR_MCA
:
582 Description
= L
"PCI-Micro Channel bridge";
585 case PCI_SUBCLASS_BR_PCI_TO_PCI
:
586 Description
= L
"PCI-PCI bridge";
589 case PCI_SUBCLASS_BR_PCMCIA
:
590 Description
= L
"PCI-PCMCIA bridge";
593 case PCI_SUBCLASS_BR_NUBUS
:
594 Description
= L
"PCI-NUBUS bridge";
597 case PCI_SUBCLASS_BR_CARDBUS
:
598 Description
= L
"PCI-CARDBUS bridge";
602 Description
= L
"Other bridge device";
607 case PCI_CLASS_SIMPLE_COMMS_CTLR
:
608 switch (Device
->PciConfig
.SubClass
)
612 Description
= L
"Communication device";
617 case PCI_CLASS_BASE_SYSTEM_DEV
:
618 switch (Device
->PciConfig
.SubClass
)
622 Description
= L
"System device";
627 case PCI_CLASS_INPUT_DEV
:
628 switch (Device
->PciConfig
.SubClass
)
632 Description
= L
"Input device";
637 case PCI_CLASS_DOCKING_STATION
:
638 switch (Device
->PciConfig
.SubClass
)
642 Description
= L
"Docking station";
647 case PCI_CLASS_PROCESSOR
:
648 switch (Device
->PciConfig
.SubClass
)
652 Description
= L
"Processor";
657 case PCI_CLASS_SERIAL_BUS_CTLR
:
658 switch (Device
->PciConfig
.SubClass
)
660 case PCI_SUBCLASS_SB_IEEE1394
:
661 Description
= L
"FireWire controller";
664 case PCI_SUBCLASS_SB_ACCESS
:
665 Description
= L
"ACCESS bus controller";
668 case PCI_SUBCLASS_SB_SSA
:
669 Description
= L
"SSA controller";
672 case PCI_SUBCLASS_SB_USB
:
673 Description
= L
"USB controller";
676 case PCI_SUBCLASS_SB_FIBRE_CHANNEL
:
677 Description
= L
"Fibre Channel controller";
681 Description
= L
"Other serial bus controller";
687 Description
= L
"Other PCI Device";
691 Length
= (wcslen(Description
) + 1) * sizeof(WCHAR
);
692 DeviceDescription
->Buffer
= ExAllocatePool(PagedPool
, Length
);
693 if (DeviceDescription
->Buffer
== NULL
)
698 DeviceDescription
->Length
= Length
- sizeof(WCHAR
);
699 DeviceDescription
->MaximumLength
= Length
;
700 RtlCopyMemory(DeviceDescription
->Buffer
, Description
, Length
);
707 PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation
,
715 Index
+= swprintf(&Buffer
[Index
],
716 L
"PCI-Bus %lu, Device %u, Function %u",
718 Device
->SlotNumber
.u
.bits
.DeviceNumber
,
719 Device
->SlotNumber
.u
.bits
.FunctionNumber
);
722 Buffer
[Index
] = UNICODE_NULL
;
724 Length
= (Index
+ 1) * sizeof(WCHAR
);
725 DeviceLocation
->Buffer
= ExAllocatePool(PagedPool
, Length
);
726 if (DeviceLocation
->Buffer
== NULL
)
731 DeviceLocation
->Length
= Length
- sizeof(WCHAR
);
732 DeviceLocation
->MaximumLength
= Length
;
733 RtlCopyMemory(DeviceLocation
->Buffer
, Buffer
, Length
);