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
17 static DRIVER_DISPATCH PciDispatchDeviceControl
;
18 static NTSTATUS NTAPI
PciDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
20 static DRIVER_ADD_DEVICE PciAddDevice
;
21 static NTSTATUS NTAPI
PciAddDevice(IN PDRIVER_OBJECT DriverObject
, IN PDEVICE_OBJECT PhysicalDeviceObject
);
23 static DRIVER_DISPATCH PciPowerControl
;
24 static NTSTATUS NTAPI
PciPowerControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
26 static DRIVER_DISPATCH PciPnpControl
;
27 static NTSTATUS NTAPI
PciPnpControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
32 // Make the initialization routines discardable, so that they
35 #pragma alloc_text(init, DriverEntry)
37 #endif /* ALLOC_PRAGMA */
39 /*** PUBLIC ******************************************************************/
41 PPCI_DRIVER_EXTENSION DriverExtension
= NULL
;
43 /*** PRIVATE *****************************************************************/
47 PciDispatchDeviceControl(
48 IN PDEVICE_OBJECT DeviceObject
,
51 PIO_STACK_LOCATION IrpSp
;
54 UNREFERENCED_PARAMETER(DeviceObject
);
55 DPRINT("Called. IRP is at (0x%p)\n", Irp
);
57 Irp
->IoStatus
.Information
= 0;
59 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
60 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
)
70 Irp
->IoStatus
.Status
= Status
;
72 DPRINT("Completing IRP at 0x%p\n", Irp
);
74 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
77 DPRINT("Leaving. Status 0x%X\n", Status
);
86 IN PDEVICE_OBJECT DeviceObject
,
89 * FUNCTION: Handle Plug and Play IRPs
91 * DeviceObject = Pointer to PDO or FDO
92 * Irp = Pointer to IRP that should be handled
97 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
100 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
102 DPRINT("IsFDO %u\n", DeviceExtension
->IsFDO
);
104 if (DeviceExtension
->IsFDO
)
106 Status
= FdoPnpControl(DeviceObject
, Irp
);
110 Status
= PdoPnpControl(DeviceObject
, Irp
);
120 IN PDEVICE_OBJECT DeviceObject
,
123 * FUNCTION: Handle power management IRPs
125 * DeviceObject = Pointer to PDO or FDO
126 * Irp = Pointer to IRP that should be handled
131 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
134 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
136 if (DeviceExtension
->IsFDO
)
138 Status
= FdoPowerControl(DeviceObject
, Irp
);
142 Status
= PdoPowerControl(DeviceObject
, Irp
);
152 IN PDRIVER_OBJECT DriverObject
,
153 IN PDEVICE_OBJECT PhysicalDeviceObject
)
155 PFDO_DEVICE_EXTENSION DeviceExtension
;
160 if (PhysicalDeviceObject
== NULL
)
161 return STATUS_SUCCESS
;
163 Status
= IoCreateDevice(DriverObject
,
164 sizeof(FDO_DEVICE_EXTENSION
),
166 FILE_DEVICE_BUS_EXTENDER
,
167 FILE_DEVICE_SECURE_OPEN
,
170 if (!NT_SUCCESS(Status
))
172 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
176 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
178 RtlZeroMemory(DeviceExtension
, sizeof(FDO_DEVICE_EXTENSION
));
180 DeviceExtension
->Common
.IsFDO
= TRUE
;
182 DeviceExtension
->Ldo
= IoAttachDeviceToDeviceStack(Fdo
,
183 PhysicalDeviceObject
);
185 DeviceExtension
->State
= dsStopped
;
187 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
189 //Fdo->Flags |= DO_POWER_PAGABLE;
191 DPRINT("Done AddDevice\n");
193 return STATUS_SUCCESS
;
196 DRIVER_UNLOAD PciUnload
;
201 IN PDRIVER_OBJECT DriverObject
)
203 /* The driver object extension is destroyed by the I/O manager */
204 UNREFERENCED_PARAMETER(DriverObject
);
210 IN PDRIVER_OBJECT DriverObject
,
211 IN PUNICODE_STRING RegistryPath
)
215 UNREFERENCED_PARAMETER(RegistryPath
);
216 DPRINT("Peripheral Component Interconnect Bus Driver\n");
218 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = PciDispatchDeviceControl
;
219 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = PciPnpControl
;
220 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = PciPowerControl
;
221 DriverObject
->DriverExtension
->AddDevice
= PciAddDevice
;
222 DriverObject
->DriverUnload
= PciUnload
;
224 Status
= IoAllocateDriverObjectExtension(DriverObject
,
226 sizeof(PCI_DRIVER_EXTENSION
),
227 (PVOID
*)&DriverExtension
);
228 if (!NT_SUCCESS(Status
))
231 RtlZeroMemory(DriverExtension
, sizeof(PCI_DRIVER_EXTENSION
));
233 InitializeListHead(&DriverExtension
->BusListHead
);
234 KeInitializeSpinLock(&DriverExtension
->BusListLock
);
236 return STATUS_SUCCESS
;
241 PciCreateDeviceIDString(PUNICODE_STRING DeviceID
,
247 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
248 Device
->PciConfig
.VendorID
,
249 Device
->PciConfig
.DeviceID
,
250 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
251 Device
->PciConfig
.u
.type0
.SubVendorID
,
252 Device
->PciConfig
.RevisionID
);
254 return RtlCreateUnicodeString(DeviceID
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
259 PciCreateInstanceIDString(PUNICODE_STRING InstanceID
,
264 swprintf(Buffer
, L
"%02X", Device
->SlotNumber
.u
.AsULONG
& 0xff);
266 return RtlCreateUnicodeString(InstanceID
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
271 PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs
,
275 UNICODE_STRING BufferU
;
279 Index
+= swprintf(&Buffer
[Index
],
280 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
281 Device
->PciConfig
.VendorID
,
282 Device
->PciConfig
.DeviceID
,
283 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
284 Device
->PciConfig
.u
.type0
.SubVendorID
,
285 Device
->PciConfig
.RevisionID
);
288 Index
+= swprintf(&Buffer
[Index
],
289 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
290 Device
->PciConfig
.VendorID
,
291 Device
->PciConfig
.DeviceID
,
292 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
293 Device
->PciConfig
.u
.type0
.SubVendorID
);
296 Index
+= swprintf(&Buffer
[Index
],
297 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
298 Device
->PciConfig
.VendorID
,
299 Device
->PciConfig
.DeviceID
,
300 Device
->PciConfig
.BaseClass
,
301 Device
->PciConfig
.SubClass
,
302 Device
->PciConfig
.ProgIf
);
305 Index
+= swprintf(&Buffer
[Index
],
306 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
307 Device
->PciConfig
.VendorID
,
308 Device
->PciConfig
.DeviceID
,
309 Device
->PciConfig
.BaseClass
,
310 Device
->PciConfig
.SubClass
);
313 Buffer
[Index
] = UNICODE_NULL
;
315 BufferU
.Length
= BufferU
.MaximumLength
= (USHORT
) Index
* sizeof(WCHAR
);
316 BufferU
.Buffer
= Buffer
;
318 return PciDuplicateUnicodeString(0, &BufferU
, HardwareIDs
);
323 PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs
,
327 UNICODE_STRING BufferU
;
331 Index
+= swprintf(&Buffer
[Index
],
332 L
"PCI\\VEN_%04X&DEV_%04X&REV_%02X",
333 Device
->PciConfig
.VendorID
,
334 Device
->PciConfig
.DeviceID
,
335 Device
->PciConfig
.RevisionID
);
338 Index
+= swprintf(&Buffer
[Index
],
339 L
"PCI\\VEN_%04X&DEV_%04X",
340 Device
->PciConfig
.VendorID
,
341 Device
->PciConfig
.DeviceID
);
344 Index
+= swprintf(&Buffer
[Index
],
345 L
"PCI\\VEN_%04X&CC_%02X%02X%02X",
346 Device
->PciConfig
.VendorID
,
347 Device
->PciConfig
.BaseClass
,
348 Device
->PciConfig
.SubClass
,
349 Device
->PciConfig
.ProgIf
);
352 Index
+= swprintf(&Buffer
[Index
],
353 L
"PCI\\VEN_%04X&CC_%02X%02X",
354 Device
->PciConfig
.VendorID
,
355 Device
->PciConfig
.BaseClass
,
356 Device
->PciConfig
.SubClass
);
359 Index
+= swprintf(&Buffer
[Index
],
361 Device
->PciConfig
.VendorID
);
364 Index
+= swprintf(&Buffer
[Index
],
365 L
"PCI\\CC_%02X%02X%02X",
366 Device
->PciConfig
.BaseClass
,
367 Device
->PciConfig
.SubClass
,
368 Device
->PciConfig
.ProgIf
);
371 Index
+= swprintf(&Buffer
[Index
],
373 Device
->PciConfig
.BaseClass
,
374 Device
->PciConfig
.SubClass
);
377 Buffer
[Index
] = UNICODE_NULL
;
379 BufferU
.Length
= BufferU
.MaximumLength
= (USHORT
)Index
* sizeof(WCHAR
);
380 BufferU
.Buffer
= Buffer
;
382 return PciDuplicateUnicodeString(0, &BufferU
, CompatibleIDs
);
387 PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription
,
392 switch (Device
->PciConfig
.BaseClass
)
394 case PCI_CLASS_PRE_20
:
395 switch (Device
->PciConfig
.SubClass
)
397 case PCI_SUBCLASS_PRE_20_VGA
:
398 Description
= L
"VGA device";
402 case PCI_SUBCLASS_PRE_20_NON_VGA
:
403 Description
= L
"PCI device";
408 case PCI_CLASS_MASS_STORAGE_CTLR
:
409 switch (Device
->PciConfig
.SubClass
)
411 case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR
:
412 Description
= L
"SCSI controller";
415 case PCI_SUBCLASS_MSC_IDE_CTLR
:
416 Description
= L
"IDE controller";
419 case PCI_SUBCLASS_MSC_FLOPPY_CTLR
:
420 Description
= L
"Floppy disk controller";
423 case PCI_SUBCLASS_MSC_IPI_CTLR
:
424 Description
= L
"IPI controller";
427 case PCI_SUBCLASS_MSC_RAID_CTLR
:
428 Description
= L
"RAID controller";
432 Description
= L
"Mass storage controller";
437 case PCI_CLASS_NETWORK_CTLR
:
438 switch (Device
->PciConfig
.SubClass
)
440 case PCI_SUBCLASS_NET_ETHERNET_CTLR
:
441 Description
= L
"Ethernet controller";
444 case PCI_SUBCLASS_NET_TOKEN_RING_CTLR
:
445 Description
= L
"Token-Ring controller";
448 case PCI_SUBCLASS_NET_FDDI_CTLR
:
449 Description
= L
"FDDI controller";
452 case PCI_SUBCLASS_NET_ATM_CTLR
:
453 Description
= L
"ATM controller";
457 Description
= L
"Network controller";
462 case PCI_CLASS_DISPLAY_CTLR
:
463 switch (Device
->PciConfig
.SubClass
)
465 case PCI_SUBCLASS_VID_VGA_CTLR
:
466 Description
= L
"VGA display controller";
469 case PCI_SUBCLASS_VID_XGA_CTLR
:
470 Description
= L
"XGA display controller";
473 case PCI_SUBCLASS_VID_3D_CTLR
:
474 Description
= L
"Multimedia display controller";
478 Description
= L
"Other display controller";
483 case PCI_CLASS_MULTIMEDIA_DEV
:
484 switch (Device
->PciConfig
.SubClass
)
486 case PCI_SUBCLASS_MM_VIDEO_DEV
:
487 Description
= L
"Multimedia video device";
490 case PCI_SUBCLASS_MM_AUDIO_DEV
:
491 Description
= L
"Multimedia audio device";
494 case PCI_SUBCLASS_MM_TELEPHONY_DEV
:
495 Description
= L
"Multimedia telephony device";
499 Description
= L
"Other multimedia device";
504 case PCI_CLASS_MEMORY_CTLR
:
505 switch (Device
->PciConfig
.SubClass
)
507 case PCI_SUBCLASS_MEM_RAM
:
508 Description
= L
"PCI Memory";
511 case PCI_SUBCLASS_MEM_FLASH
:
512 Description
= L
"PCI Flash Memory";
516 Description
= L
"Other memory controller";
521 case PCI_CLASS_BRIDGE_DEV
:
522 switch (Device
->PciConfig
.SubClass
)
524 case PCI_SUBCLASS_BR_HOST
:
525 Description
= L
"PCI-Host bridge";
528 case PCI_SUBCLASS_BR_ISA
:
529 Description
= L
"PCI-ISA bridge";
532 case PCI_SUBCLASS_BR_EISA
:
533 Description
= L
"PCI-EISA bridge";
536 case PCI_SUBCLASS_BR_MCA
:
537 Description
= L
"PCI-Micro Channel bridge";
540 case PCI_SUBCLASS_BR_PCI_TO_PCI
:
541 Description
= L
"PCI-PCI bridge";
544 case PCI_SUBCLASS_BR_PCMCIA
:
545 Description
= L
"PCI-PCMCIA bridge";
548 case PCI_SUBCLASS_BR_NUBUS
:
549 Description
= L
"PCI-NUBUS bridge";
552 case PCI_SUBCLASS_BR_CARDBUS
:
553 Description
= L
"PCI-CARDBUS bridge";
557 Description
= L
"Other bridge device";
562 case PCI_CLASS_SIMPLE_COMMS_CTLR
:
563 switch (Device
->PciConfig
.SubClass
)
567 Description
= L
"Communication device";
572 case PCI_CLASS_BASE_SYSTEM_DEV
:
573 switch (Device
->PciConfig
.SubClass
)
577 Description
= L
"System device";
582 case PCI_CLASS_INPUT_DEV
:
583 switch (Device
->PciConfig
.SubClass
)
587 Description
= L
"Input device";
592 case PCI_CLASS_DOCKING_STATION
:
593 switch (Device
->PciConfig
.SubClass
)
597 Description
= L
"Docking station";
602 case PCI_CLASS_PROCESSOR
:
603 switch (Device
->PciConfig
.SubClass
)
607 Description
= L
"Processor";
612 case PCI_CLASS_SERIAL_BUS_CTLR
:
613 switch (Device
->PciConfig
.SubClass
)
615 case PCI_SUBCLASS_SB_IEEE1394
:
616 Description
= L
"FireWire controller";
619 case PCI_SUBCLASS_SB_ACCESS
:
620 Description
= L
"ACCESS bus controller";
623 case PCI_SUBCLASS_SB_SSA
:
624 Description
= L
"SSA controller";
627 case PCI_SUBCLASS_SB_USB
:
628 Description
= L
"USB controller";
631 case PCI_SUBCLASS_SB_FIBRE_CHANNEL
:
632 Description
= L
"Fibre Channel controller";
635 case PCI_SUBCLASS_SB_SMBUS
:
636 Description
= L
"SMBus controller";
640 Description
= L
"Other serial bus controller";
646 Description
= L
"Other PCI Device";
650 return RtlCreateUnicodeString(DeviceDescription
, Description
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
655 PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation
,
661 L
"PCI-Bus %lu, Device %u, Function %u",
663 Device
->SlotNumber
.u
.bits
.DeviceNumber
,
664 Device
->SlotNumber
.u
.bits
.FunctionNumber
);
666 return RtlCreateUnicodeString(DeviceLocation
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
670 PciDuplicateUnicodeString(
672 IN PCUNICODE_STRING SourceString
,
673 OUT PUNICODE_STRING DestinationString
)
675 if (SourceString
== NULL
||
676 DestinationString
== NULL
||
677 SourceString
->Length
> SourceString
->MaximumLength
||
678 (SourceString
->Length
== 0 && SourceString
->MaximumLength
> 0 && SourceString
->Buffer
== NULL
) ||
679 Flags
== RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING
||
682 return STATUS_INVALID_PARAMETER
;
685 if ((SourceString
->Length
== 0) &&
686 (Flags
!= (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
|
687 RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING
)))
689 DestinationString
->Length
= 0;
690 DestinationString
->MaximumLength
= 0;
691 DestinationString
->Buffer
= NULL
;
695 USHORT DestMaxLength
= SourceString
->Length
;
697 if (Flags
& RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
)
698 DestMaxLength
+= sizeof(UNICODE_NULL
);
700 DestinationString
->Buffer
= ExAllocatePoolWithTag(PagedPool
, DestMaxLength
, TAG_PCI
);
701 if (DestinationString
->Buffer
== NULL
)
702 return STATUS_NO_MEMORY
;
704 RtlCopyMemory(DestinationString
->Buffer
, SourceString
->Buffer
, SourceString
->Length
);
705 DestinationString
->Length
= SourceString
->Length
;
706 DestinationString
->MaximumLength
= DestMaxLength
;
708 if (Flags
& RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
)
709 DestinationString
->Buffer
[DestinationString
->Length
/ sizeof(WCHAR
)] = 0;
712 return STATUS_SUCCESS
;