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>
23 // Make the initialization routines discardable, so that they
26 #pragma alloc_text(init, DriverEntry)
28 #endif /* ALLOC_PRAGMA */
30 /*** PUBLIC ******************************************************************/
33 /*** PRIVATE *****************************************************************/
37 PciDispatchDeviceControl(
38 IN PDEVICE_OBJECT DeviceObject
,
41 PIO_STACK_LOCATION IrpSp
;
44 DPRINT("Called. IRP is at (0x%X)\n", Irp
);
46 Irp
->IoStatus
.Information
= 0;
48 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
49 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
51 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
52 Status
= STATUS_NOT_IMPLEMENTED
;
56 if (Status
!= STATUS_PENDING
) {
57 Irp
->IoStatus
.Status
= Status
;
59 DPRINT("Completing IRP at 0x%X\n", Irp
);
61 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
64 DPRINT("Leaving. Status 0x%X\n", Status
);
73 IN PDEVICE_OBJECT DeviceObject
,
76 * FUNCTION: Handle Plug and Play IRPs
78 * DeviceObject = Pointer to PDO or FDO
79 * Irp = Pointer to IRP that should be handled
84 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
87 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
89 DPRINT("IsFDO %d\n", DeviceExtension
->IsFDO
);
91 if (DeviceExtension
->IsFDO
) {
92 Status
= FdoPnpControl(DeviceObject
, Irp
);
94 Status
= PdoPnpControl(DeviceObject
, Irp
);
104 IN PDEVICE_OBJECT DeviceObject
,
107 * FUNCTION: Handle power management IRPs
109 * DeviceObject = Pointer to PDO or FDO
110 * Irp = Pointer to IRP that should be handled
115 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
118 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
120 if (DeviceExtension
->IsFDO
) {
121 Status
= FdoPowerControl(DeviceObject
, Irp
);
123 Status
= PdoPowerControl(DeviceObject
, Irp
);
133 IN PDRIVER_OBJECT DriverObject
,
134 IN PDEVICE_OBJECT PhysicalDeviceObject
)
136 PFDO_DEVICE_EXTENSION DeviceExtension
;
142 Status
= IoCreateDevice(DriverObject
, sizeof(FDO_DEVICE_EXTENSION
),
143 NULL
, FILE_DEVICE_BUS_EXTENDER
, FILE_DEVICE_SECURE_OPEN
, TRUE
, &Fdo
);
144 if (!NT_SUCCESS(Status
)) {
145 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
149 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
151 RtlZeroMemory(DeviceExtension
, sizeof(FDO_DEVICE_EXTENSION
));
153 DeviceExtension
->Common
.IsFDO
= TRUE
;
155 DeviceExtension
->Ldo
=
156 IoAttachDeviceToDeviceStack(Fdo
, PhysicalDeviceObject
);
158 DeviceExtension
->State
= dsStopped
;
160 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
162 //Fdo->Flags |= DO_POWER_PAGABLE;
164 DPRINT("Done AddDevice\n");
166 return STATUS_SUCCESS
;
173 IN PDRIVER_OBJECT DriverObject
,
174 IN PUNICODE_STRING RegistryPath
)
176 DPRINT("Peripheral Component Interconnect Bus Driver\n");
178 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = PciDispatchDeviceControl
;
179 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = PciPnpControl
;
180 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = PciPowerControl
;
181 DriverObject
->DriverExtension
->AddDevice
= PciAddDevice
;
183 return STATUS_SUCCESS
;
188 PciCreateUnicodeString(
189 PUNICODE_STRING Destination
,
197 RtlInitUnicodeString(Destination
, NULL
);
201 Length
= (wcslen(Source
) + 1) * sizeof(WCHAR
);
203 Destination
->Buffer
= ExAllocatePool(PoolType
, Length
);
205 if (Destination
->Buffer
== NULL
)
210 RtlCopyMemory(Destination
->Buffer
, Source
, Length
);
212 Destination
->MaximumLength
= Length
;
214 Destination
->Length
= Length
- sizeof(WCHAR
);
221 PciDuplicateUnicodeString(
222 PUNICODE_STRING Destination
,
223 PUNICODE_STRING Source
,
228 RtlInitUnicodeString(Destination
, NULL
);
229 return STATUS_SUCCESS
;
232 Destination
->Buffer
= ExAllocatePool(PoolType
, Source
->MaximumLength
);
233 if (Destination
->Buffer
== NULL
)
235 return STATUS_INSUFFICIENT_RESOURCES
;
238 Destination
->MaximumLength
= Source
->MaximumLength
;
239 Destination
->Length
= Source
->Length
;
240 RtlCopyMemory(Destination
->Buffer
, Source
->Buffer
, Source
->MaximumLength
);
242 return STATUS_SUCCESS
;
247 PciCreateDeviceIDString(PUNICODE_STRING DeviceID
,
253 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
254 Device
->PciConfig
.VendorID
,
255 Device
->PciConfig
.DeviceID
,
256 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
257 Device
->PciConfig
.u
.type0
.SubVendorID
,
258 Device
->PciConfig
.RevisionID
);
260 if (!PciCreateUnicodeString(DeviceID
, Buffer
, PagedPool
))
270 PciCreateInstanceIDString(PUNICODE_STRING InstanceID
,
278 Index
= swprintf(Buffer
,
281 (Device
->SlotNumber
.u
.bits
.DeviceNumber
<< 3) +
282 Device
->SlotNumber
.u
.bits
.FunctionNumber
);
284 Buffer
[Index
] = UNICODE_NULL
;
286 Length
= (Index
+ 1) * sizeof(WCHAR
);
287 InstanceID
->Buffer
= ExAllocatePool(PagedPool
, Length
);
288 if (InstanceID
->Buffer
== NULL
)
293 InstanceID
->Length
= Length
- sizeof(WCHAR
);
294 InstanceID
->MaximumLength
= Length
;
295 RtlCopyMemory(InstanceID
->Buffer
, Buffer
, Length
);
302 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
303 Device
->PciConfig
.VendorID
,
304 Device
->PciConfig
.DeviceID
,
305 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
306 Device
->PciConfig
.u
.type0
.SubVendorID
,
307 Device
->PciConfig
.RevisionID
);
310 if (!wcscmp(L
"PCI\\VEN_10DE&DEV_01C2&SUBSYS_00000000&REV_D4", Buffer
))
312 //DPRINT("xbox ohci controler found at bus 0x%lX, dev num %d, func num %d\n", Device->BusNumber, Device->SlotNumber.u.bits.DeviceNumber, Device->SlotNumber.u.bits.FunctionNumber);
313 if (Device
->SlotNumber
.u
.bits
.DeviceNumber
== 2)
314 return PciCreateUnicodeString(InstanceID
, L
"0000", PagedPool
);
316 return PciCreateUnicodeString(InstanceID
, L
"0001", PagedPool
);
319 return PciCreateUnicodeString(InstanceID
, L
"0000", PagedPool
);
324 PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs
,
332 Index
+= swprintf(&Buffer
[Index
],
333 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
334 Device
->PciConfig
.VendorID
,
335 Device
->PciConfig
.DeviceID
,
336 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
337 Device
->PciConfig
.u
.type0
.SubVendorID
,
338 Device
->PciConfig
.RevisionID
);
341 Index
+= swprintf(&Buffer
[Index
],
342 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
343 Device
->PciConfig
.VendorID
,
344 Device
->PciConfig
.DeviceID
,
345 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
346 Device
->PciConfig
.u
.type0
.SubVendorID
);
349 Buffer
[Index
] = UNICODE_NULL
;
351 Length
= (Index
+ 1) * sizeof(WCHAR
);
352 HardwareIDs
->Buffer
= ExAllocatePool(PagedPool
, Length
);
353 if (HardwareIDs
->Buffer
== NULL
)
358 HardwareIDs
->Length
= Length
- sizeof(WCHAR
);
359 HardwareIDs
->MaximumLength
= Length
;
360 RtlCopyMemory(HardwareIDs
->Buffer
, Buffer
, Length
);
367 PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs
,
375 Index
+= swprintf(&Buffer
[Index
],
376 L
"PCI\\VEN_%04X&DEV_%04X&REV_%02X&CC_%02X%02X",
377 Device
->PciConfig
.VendorID
,
378 Device
->PciConfig
.DeviceID
,
379 Device
->PciConfig
.RevisionID
,
380 Device
->PciConfig
.BaseClass
,
381 Device
->PciConfig
.SubClass
);
384 Index
+= swprintf(&Buffer
[Index
],
385 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
386 Device
->PciConfig
.VendorID
,
387 Device
->PciConfig
.DeviceID
,
388 Device
->PciConfig
.BaseClass
,
389 Device
->PciConfig
.SubClass
,
390 Device
->PciConfig
.ProgIf
);
393 Index
+= swprintf(&Buffer
[Index
],
394 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
395 Device
->PciConfig
.VendorID
,
396 Device
->PciConfig
.DeviceID
,
397 Device
->PciConfig
.BaseClass
,
398 Device
->PciConfig
.SubClass
);
401 Index
+= swprintf(&Buffer
[Index
],
402 L
"PCI\\VEN_%04X&CC_%02X%02X%02X",
403 Device
->PciConfig
.VendorID
,
404 Device
->PciConfig
.BaseClass
,
405 Device
->PciConfig
.SubClass
,
406 Device
->PciConfig
.ProgIf
);
409 Index
+= swprintf(&Buffer
[Index
],
410 L
"PCI\\VEN_%04X&CC_%02X%02X",
411 Device
->PciConfig
.VendorID
,
412 Device
->PciConfig
.BaseClass
,
413 Device
->PciConfig
.SubClass
);
416 Index
+= swprintf(&Buffer
[Index
],
418 Device
->PciConfig
.VendorID
);
421 Index
+= swprintf(&Buffer
[Index
],
422 L
"PCI\\CC_%02X%02X%02X",
423 Device
->PciConfig
.BaseClass
,
424 Device
->PciConfig
.SubClass
,
425 Device
->PciConfig
.ProgIf
);
428 Index
+= swprintf(&Buffer
[Index
],
430 Device
->PciConfig
.BaseClass
,
431 Device
->PciConfig
.SubClass
);
434 Buffer
[Index
] = UNICODE_NULL
;
436 Length
= (Index
+ 1) * sizeof(WCHAR
);
437 CompatibleIDs
->Buffer
= ExAllocatePool(PagedPool
, Length
);
438 if (CompatibleIDs
->Buffer
== NULL
)
443 CompatibleIDs
->Length
= Length
- sizeof(WCHAR
);
444 CompatibleIDs
->MaximumLength
= Length
;
445 RtlCopyMemory(CompatibleIDs
->Buffer
, Buffer
, Length
);
452 PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription
,
458 switch (Device
->PciConfig
.BaseClass
)
460 case PCI_CLASS_PRE_20
:
461 switch (Device
->PciConfig
.SubClass
)
463 case PCI_SUBCLASS_PRE_20_VGA
:
464 Description
= L
"VGA device";
468 case PCI_SUBCLASS_PRE_20_NON_VGA
:
469 Description
= L
"PCI device";
474 case PCI_CLASS_MASS_STORAGE_CTLR
:
475 switch (Device
->PciConfig
.SubClass
)
477 case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR
:
478 Description
= L
"SCSI controller";
481 case PCI_SUBCLASS_MSC_IDE_CTLR
:
482 Description
= L
"IDE controller";
485 case PCI_SUBCLASS_MSC_FLOPPY_CTLR
:
486 Description
= L
"Floppy disk controller";
489 case PCI_SUBCLASS_MSC_IPI_CTLR
:
490 Description
= L
"IPI controller";
493 case PCI_SUBCLASS_MSC_RAID_CTLR
:
494 Description
= L
"RAID controller";
498 Description
= L
"Mass storage controller";
503 case PCI_CLASS_NETWORK_CTLR
:
504 switch (Device
->PciConfig
.SubClass
)
506 case PCI_SUBCLASS_NET_ETHERNET_CTLR
:
507 Description
= L
"Ethernet controller";
510 case PCI_SUBCLASS_NET_TOKEN_RING_CTLR
:
511 Description
= L
"Token-Ring controller";
514 case PCI_SUBCLASS_NET_FDDI_CTLR
:
515 Description
= L
"FDDI controller";
518 case PCI_SUBCLASS_NET_ATM_CTLR
:
519 Description
= L
"ATM controller";
523 Description
= L
"Network controller";
528 case PCI_CLASS_DISPLAY_CTLR
:
529 switch (Device
->PciConfig
.SubClass
)
531 case PCI_SUBCLASS_VID_VGA_CTLR
:
532 Description
= L
"VGA display controller";
535 case PCI_SUBCLASS_VID_XGA_CTLR
:
536 Description
= L
"XGA display controller";
539 case PCI_SUBLCASS_VID_3D_CTLR
:
540 Description
= L
"Multimedia display controller";
544 Description
= L
"Other display controller";
549 case PCI_CLASS_MULTIMEDIA_DEV
:
550 switch (Device
->PciConfig
.SubClass
)
552 case PCI_SUBCLASS_MM_VIDEO_DEV
:
553 Description
= L
"Multimedia video device";
556 case PCI_SUBCLASS_MM_AUDIO_DEV
:
557 Description
= L
"Multimedia audio device";
560 case PCI_SUBCLASS_MM_TELEPHONY_DEV
:
561 Description
= L
"Multimedia telephony device";
565 Description
= L
"Other multimedia device";
570 case PCI_CLASS_MEMORY_CTLR
:
571 switch (Device
->PciConfig
.SubClass
)
573 case PCI_SUBCLASS_MEM_RAM
:
574 Description
= L
"PCI Memory";
577 case PCI_SUBCLASS_MEM_FLASH
:
578 Description
= L
"PCI Flash Memory";
582 Description
= L
"Other memory controller";
587 case PCI_CLASS_BRIDGE_DEV
:
588 switch (Device
->PciConfig
.SubClass
)
590 case PCI_SUBCLASS_BR_HOST
:
591 Description
= L
"PCI-Host bridge";
594 case PCI_SUBCLASS_BR_ISA
:
595 Description
= L
"PCI-ISA bridge";
598 case PCI_SUBCLASS_BR_EISA
:
599 Description
= L
"PCI-EISA bridge";
602 case PCI_SUBCLASS_BR_MCA
:
603 Description
= L
"PCI-Micro Channel bridge";
606 case PCI_SUBCLASS_BR_PCI_TO_PCI
:
607 Description
= L
"PCI-PCI bridge";
610 case PCI_SUBCLASS_BR_PCMCIA
:
611 Description
= L
"PCI-PCMCIA bridge";
614 case PCI_SUBCLASS_BR_NUBUS
:
615 Description
= L
"PCI-NUBUS bridge";
618 case PCI_SUBCLASS_BR_CARDBUS
:
619 Description
= L
"PCI-CARDBUS bridge";
623 Description
= L
"Other bridge device";
628 case PCI_CLASS_SIMPLE_COMMS_CTLR
:
629 switch (Device
->PciConfig
.SubClass
)
633 Description
= L
"Communication device";
638 case PCI_CLASS_BASE_SYSTEM_DEV
:
639 switch (Device
->PciConfig
.SubClass
)
643 Description
= L
"System device";
648 case PCI_CLASS_INPUT_DEV
:
649 switch (Device
->PciConfig
.SubClass
)
653 Description
= L
"Input device";
658 case PCI_CLASS_DOCKING_STATION
:
659 switch (Device
->PciConfig
.SubClass
)
663 Description
= L
"Docking station";
668 case PCI_CLASS_PROCESSOR
:
669 switch (Device
->PciConfig
.SubClass
)
673 Description
= L
"Processor";
678 case PCI_CLASS_SERIAL_BUS_CTLR
:
679 switch (Device
->PciConfig
.SubClass
)
681 case PCI_SUBCLASS_SB_IEEE1394
:
682 Description
= L
"FireWire controller";
685 case PCI_SUBCLASS_SB_ACCESS
:
686 Description
= L
"ACCESS bus controller";
689 case PCI_SUBCLASS_SB_SSA
:
690 Description
= L
"SSA controller";
693 case PCI_SUBCLASS_SB_USB
:
694 Description
= L
"USB controller";
697 case PCI_SUBCLASS_SB_FIBRE_CHANNEL
:
698 Description
= L
"Fibre Channel controller";
702 Description
= L
"Other serial bus controller";
708 Description
= L
"Other PCI Device";
712 Length
= (wcslen(Description
) + 1) * sizeof(WCHAR
);
713 DeviceDescription
->Buffer
= ExAllocatePool(PagedPool
, Length
);
714 if (DeviceDescription
->Buffer
== NULL
)
719 DeviceDescription
->Length
= Length
- sizeof(WCHAR
);
720 DeviceDescription
->MaximumLength
= Length
;
721 RtlCopyMemory(DeviceDescription
->Buffer
, Description
, Length
);
728 PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation
,
736 Index
+= swprintf(&Buffer
[Index
],
737 L
"PCI-Bus %lu, Device %u, Function %u",
739 Device
->SlotNumber
.u
.bits
.DeviceNumber
,
740 Device
->SlotNumber
.u
.bits
.FunctionNumber
);
743 Buffer
[Index
] = UNICODE_NULL
;
745 Length
= (Index
+ 1) * sizeof(WCHAR
);
746 DeviceLocation
->Buffer
= ExAllocatePool(PagedPool
, Length
);
747 if (DeviceLocation
->Buffer
== NULL
)
752 DeviceLocation
->Length
= Length
- sizeof(WCHAR
);
753 DeviceLocation
->MaximumLength
= Length
;
754 RtlCopyMemory(DeviceLocation
->Buffer
, Buffer
, Length
);