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
)
189 /* The driver object extension is destroyed by the I/O manager */
195 IN PDRIVER_OBJECT DriverObject
,
196 IN PUNICODE_STRING RegistryPath
)
200 UNREFERENCED_PARAMETER(RegistryPath
);
201 DPRINT("Peripheral Component Interconnect Bus Driver\n");
203 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = PciDispatchDeviceControl
;
204 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = PciPnpControl
;
205 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = PciPowerControl
;
206 DriverObject
->DriverExtension
->AddDevice
= PciAddDevice
;
207 DriverObject
->DriverUnload
= PciUnload
;
209 Status
= IoAllocateDriverObjectExtension(
212 sizeof(PCI_DRIVER_EXTENSION
),
213 (PVOID
*)&DriverExtension
);
214 if (!NT_SUCCESS(Status
))
216 RtlZeroMemory(DriverExtension
, sizeof(PCI_DRIVER_EXTENSION
));
218 InitializeListHead(&DriverExtension
->BusListHead
);
219 KeInitializeSpinLock(&DriverExtension
->BusListLock
);
221 return STATUS_SUCCESS
;
226 PciCreateDeviceIDString(PUNICODE_STRING DeviceID
,
232 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
233 Device
->PciConfig
.VendorID
,
234 Device
->PciConfig
.DeviceID
,
235 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
236 Device
->PciConfig
.u
.type0
.SubVendorID
,
237 Device
->PciConfig
.RevisionID
);
239 return RtlCreateUnicodeString(DeviceID
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
244 PciCreateInstanceIDString(PUNICODE_STRING InstanceID
,
249 swprintf(Buffer
, L
"%02X", Device
->SlotNumber
.u
.AsULONG
& 0xff);
251 return RtlCreateUnicodeString(InstanceID
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
256 PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs
,
260 UNICODE_STRING BufferU
;
264 Index
+= swprintf(&Buffer
[Index
],
265 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
266 Device
->PciConfig
.VendorID
,
267 Device
->PciConfig
.DeviceID
,
268 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
269 Device
->PciConfig
.u
.type0
.SubVendorID
,
270 Device
->PciConfig
.RevisionID
);
273 Index
+= swprintf(&Buffer
[Index
],
274 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
275 Device
->PciConfig
.VendorID
,
276 Device
->PciConfig
.DeviceID
,
277 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
278 Device
->PciConfig
.u
.type0
.SubVendorID
);
281 Index
+= swprintf(&Buffer
[Index
],
282 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
283 Device
->PciConfig
.VendorID
,
284 Device
->PciConfig
.DeviceID
,
285 Device
->PciConfig
.BaseClass
,
286 Device
->PciConfig
.SubClass
,
287 Device
->PciConfig
.ProgIf
);
290 Index
+= swprintf(&Buffer
[Index
],
291 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
292 Device
->PciConfig
.VendorID
,
293 Device
->PciConfig
.DeviceID
,
294 Device
->PciConfig
.BaseClass
,
295 Device
->PciConfig
.SubClass
);
298 Buffer
[Index
] = UNICODE_NULL
;
300 BufferU
.Length
= BufferU
.MaximumLength
= (USHORT
) Index
* sizeof(WCHAR
);
301 BufferU
.Buffer
= Buffer
;
303 return PciDuplicateUnicodeString(0, &BufferU
, HardwareIDs
);
308 PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs
,
312 UNICODE_STRING BufferU
;
316 Index
+= swprintf(&Buffer
[Index
],
317 L
"PCI\\VEN_%04X&DEV_%04X&REV_%02X",
318 Device
->PciConfig
.VendorID
,
319 Device
->PciConfig
.DeviceID
,
320 Device
->PciConfig
.RevisionID
);
323 Index
+= swprintf(&Buffer
[Index
],
324 L
"PCI\\VEN_%04X&DEV_%04X",
325 Device
->PciConfig
.VendorID
,
326 Device
->PciConfig
.DeviceID
);
329 Index
+= swprintf(&Buffer
[Index
],
330 L
"PCI\\VEN_%04X&CC_%02X%02X%02X",
331 Device
->PciConfig
.VendorID
,
332 Device
->PciConfig
.BaseClass
,
333 Device
->PciConfig
.SubClass
,
334 Device
->PciConfig
.ProgIf
);
337 Index
+= swprintf(&Buffer
[Index
],
338 L
"PCI\\VEN_%04X&CC_%02X%02X",
339 Device
->PciConfig
.VendorID
,
340 Device
->PciConfig
.BaseClass
,
341 Device
->PciConfig
.SubClass
);
344 Index
+= swprintf(&Buffer
[Index
],
346 Device
->PciConfig
.VendorID
);
349 Index
+= swprintf(&Buffer
[Index
],
350 L
"PCI\\CC_%02X%02X%02X",
351 Device
->PciConfig
.BaseClass
,
352 Device
->PciConfig
.SubClass
,
353 Device
->PciConfig
.ProgIf
);
356 Index
+= swprintf(&Buffer
[Index
],
358 Device
->PciConfig
.BaseClass
,
359 Device
->PciConfig
.SubClass
);
362 Buffer
[Index
] = UNICODE_NULL
;
364 BufferU
.Length
= BufferU
.MaximumLength
= (USHORT
)Index
* sizeof(WCHAR
);
365 BufferU
.Buffer
= Buffer
;
367 return PciDuplicateUnicodeString(0, &BufferU
, CompatibleIDs
);
372 PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription
,
377 switch (Device
->PciConfig
.BaseClass
)
379 case PCI_CLASS_PRE_20
:
380 switch (Device
->PciConfig
.SubClass
)
382 case PCI_SUBCLASS_PRE_20_VGA
:
383 Description
= L
"VGA device";
387 case PCI_SUBCLASS_PRE_20_NON_VGA
:
388 Description
= L
"PCI device";
393 case PCI_CLASS_MASS_STORAGE_CTLR
:
394 switch (Device
->PciConfig
.SubClass
)
396 case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR
:
397 Description
= L
"SCSI controller";
400 case PCI_SUBCLASS_MSC_IDE_CTLR
:
401 Description
= L
"IDE controller";
404 case PCI_SUBCLASS_MSC_FLOPPY_CTLR
:
405 Description
= L
"Floppy disk controller";
408 case PCI_SUBCLASS_MSC_IPI_CTLR
:
409 Description
= L
"IPI controller";
412 case PCI_SUBCLASS_MSC_RAID_CTLR
:
413 Description
= L
"RAID controller";
417 Description
= L
"Mass storage controller";
422 case PCI_CLASS_NETWORK_CTLR
:
423 switch (Device
->PciConfig
.SubClass
)
425 case PCI_SUBCLASS_NET_ETHERNET_CTLR
:
426 Description
= L
"Ethernet controller";
429 case PCI_SUBCLASS_NET_TOKEN_RING_CTLR
:
430 Description
= L
"Token-Ring controller";
433 case PCI_SUBCLASS_NET_FDDI_CTLR
:
434 Description
= L
"FDDI controller";
437 case PCI_SUBCLASS_NET_ATM_CTLR
:
438 Description
= L
"ATM controller";
442 Description
= L
"Network controller";
447 case PCI_CLASS_DISPLAY_CTLR
:
448 switch (Device
->PciConfig
.SubClass
)
450 case PCI_SUBCLASS_VID_VGA_CTLR
:
451 Description
= L
"VGA display controller";
454 case PCI_SUBCLASS_VID_XGA_CTLR
:
455 Description
= L
"XGA display controller";
458 case PCI_SUBCLASS_VID_3D_CTLR
:
459 Description
= L
"Multimedia display controller";
463 Description
= L
"Other display controller";
468 case PCI_CLASS_MULTIMEDIA_DEV
:
469 switch (Device
->PciConfig
.SubClass
)
471 case PCI_SUBCLASS_MM_VIDEO_DEV
:
472 Description
= L
"Multimedia video device";
475 case PCI_SUBCLASS_MM_AUDIO_DEV
:
476 Description
= L
"Multimedia audio device";
479 case PCI_SUBCLASS_MM_TELEPHONY_DEV
:
480 Description
= L
"Multimedia telephony device";
484 Description
= L
"Other multimedia device";
489 case PCI_CLASS_MEMORY_CTLR
:
490 switch (Device
->PciConfig
.SubClass
)
492 case PCI_SUBCLASS_MEM_RAM
:
493 Description
= L
"PCI Memory";
496 case PCI_SUBCLASS_MEM_FLASH
:
497 Description
= L
"PCI Flash Memory";
501 Description
= L
"Other memory controller";
506 case PCI_CLASS_BRIDGE_DEV
:
507 switch (Device
->PciConfig
.SubClass
)
509 case PCI_SUBCLASS_BR_HOST
:
510 Description
= L
"PCI-Host bridge";
513 case PCI_SUBCLASS_BR_ISA
:
514 Description
= L
"PCI-ISA bridge";
517 case PCI_SUBCLASS_BR_EISA
:
518 Description
= L
"PCI-EISA bridge";
521 case PCI_SUBCLASS_BR_MCA
:
522 Description
= L
"PCI-Micro Channel bridge";
525 case PCI_SUBCLASS_BR_PCI_TO_PCI
:
526 Description
= L
"PCI-PCI bridge";
529 case PCI_SUBCLASS_BR_PCMCIA
:
530 Description
= L
"PCI-PCMCIA bridge";
533 case PCI_SUBCLASS_BR_NUBUS
:
534 Description
= L
"PCI-NUBUS bridge";
537 case PCI_SUBCLASS_BR_CARDBUS
:
538 Description
= L
"PCI-CARDBUS bridge";
542 Description
= L
"Other bridge device";
547 case PCI_CLASS_SIMPLE_COMMS_CTLR
:
548 switch (Device
->PciConfig
.SubClass
)
552 Description
= L
"Communication device";
557 case PCI_CLASS_BASE_SYSTEM_DEV
:
558 switch (Device
->PciConfig
.SubClass
)
562 Description
= L
"System device";
567 case PCI_CLASS_INPUT_DEV
:
568 switch (Device
->PciConfig
.SubClass
)
572 Description
= L
"Input device";
577 case PCI_CLASS_DOCKING_STATION
:
578 switch (Device
->PciConfig
.SubClass
)
582 Description
= L
"Docking station";
587 case PCI_CLASS_PROCESSOR
:
588 switch (Device
->PciConfig
.SubClass
)
592 Description
= L
"Processor";
597 case PCI_CLASS_SERIAL_BUS_CTLR
:
598 switch (Device
->PciConfig
.SubClass
)
600 case PCI_SUBCLASS_SB_IEEE1394
:
601 Description
= L
"FireWire controller";
604 case PCI_SUBCLASS_SB_ACCESS
:
605 Description
= L
"ACCESS bus controller";
608 case PCI_SUBCLASS_SB_SSA
:
609 Description
= L
"SSA controller";
612 case PCI_SUBCLASS_SB_USB
:
613 Description
= L
"USB controller";
616 case PCI_SUBCLASS_SB_FIBRE_CHANNEL
:
617 Description
= L
"Fibre Channel controller";
620 case PCI_SUBCLASS_SB_SMBUS
:
621 Description
= L
"SMBus controller";
625 Description
= L
"Other serial bus controller";
631 Description
= L
"Other PCI Device";
635 return RtlCreateUnicodeString(DeviceDescription
, Description
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
640 PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation
,
646 L
"PCI-Bus %lu, Device %u, Function %u",
648 Device
->SlotNumber
.u
.bits
.DeviceNumber
,
649 Device
->SlotNumber
.u
.bits
.FunctionNumber
);
651 return RtlCreateUnicodeString(DeviceLocation
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
655 PciDuplicateUnicodeString(
657 IN PCUNICODE_STRING SourceString
,
658 OUT PUNICODE_STRING DestinationString
)
660 if (SourceString
== NULL
|| DestinationString
== NULL
661 || SourceString
->Length
> SourceString
->MaximumLength
662 || (SourceString
->Length
== 0 && SourceString
->MaximumLength
> 0 && SourceString
->Buffer
== NULL
)
663 || Flags
== RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING
|| Flags
>= 4)
665 return STATUS_INVALID_PARAMETER
;
669 if ((SourceString
->Length
== 0)
670 && (Flags
!= (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
|
671 RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING
)))
673 DestinationString
->Length
= 0;
674 DestinationString
->MaximumLength
= 0;
675 DestinationString
->Buffer
= NULL
;
679 USHORT DestMaxLength
= SourceString
->Length
;
681 if (Flags
& RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
)
682 DestMaxLength
+= sizeof(UNICODE_NULL
);
684 DestinationString
->Buffer
= ExAllocatePoolWithTag(PagedPool
, DestMaxLength
, TAG_PCI
);
685 if (DestinationString
->Buffer
== NULL
)
686 return STATUS_NO_MEMORY
;
688 RtlCopyMemory(DestinationString
->Buffer
, SourceString
->Buffer
, SourceString
->Length
);
689 DestinationString
->Length
= SourceString
->Length
;
690 DestinationString
->MaximumLength
= DestMaxLength
;
692 if (Flags
& RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
)
693 DestinationString
->Buffer
[DestinationString
->Length
/ sizeof(WCHAR
)] = 0;
696 return STATUS_SUCCESS
;