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 STDCALL
PciDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
21 static DRIVER_ADD_DEVICE PciAddDevice
;
22 static NTSTATUS STDCALL
PciAddDevice(IN PDRIVER_OBJECT DriverObject
, IN PDEVICE_OBJECT PhysicalDeviceObject
);
24 static DRIVER_DISPATCH PciPowerControl
;
25 static NTSTATUS STDCALL
PciPowerControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
);
27 static DRIVER_DISPATCH PciPnpControl
;
28 static NTSTATUS STDCALL
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 DPRINT("Called. IRP is at (0x%X)\n", Irp
);
57 Irp
->IoStatus
.Information
= 0;
59 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
60 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
62 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
63 Status
= STATUS_NOT_IMPLEMENTED
;
67 if (Status
!= STATUS_PENDING
) {
68 Irp
->IoStatus
.Status
= Status
;
70 DPRINT("Completing IRP at 0x%X\n", Irp
);
72 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
75 DPRINT("Leaving. Status 0x%X\n", Status
);
84 IN PDEVICE_OBJECT DeviceObject
,
87 * FUNCTION: Handle Plug and Play IRPs
89 * DeviceObject = Pointer to PDO or FDO
90 * Irp = Pointer to IRP that should be handled
95 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
98 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
100 DPRINT("IsFDO %d\n", DeviceExtension
->IsFDO
);
102 if (DeviceExtension
->IsFDO
) {
103 Status
= FdoPnpControl(DeviceObject
, Irp
);
105 Status
= PdoPnpControl(DeviceObject
, Irp
);
115 IN PDEVICE_OBJECT DeviceObject
,
118 * FUNCTION: Handle power management IRPs
120 * DeviceObject = Pointer to PDO or FDO
121 * Irp = Pointer to IRP that should be handled
126 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
129 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
131 if (DeviceExtension
->IsFDO
) {
132 Status
= FdoPowerControl(DeviceObject
, Irp
);
134 Status
= PdoPowerControl(DeviceObject
, Irp
);
144 IN PDRIVER_OBJECT DriverObject
,
145 IN PDEVICE_OBJECT PhysicalDeviceObject
)
147 PFDO_DEVICE_EXTENSION DeviceExtension
;
152 if (PhysicalDeviceObject
== NULL
)
153 return STATUS_SUCCESS
;
155 Status
= IoCreateDevice(DriverObject
, sizeof(FDO_DEVICE_EXTENSION
),
156 NULL
, FILE_DEVICE_BUS_EXTENDER
, FILE_DEVICE_SECURE_OPEN
, TRUE
, &Fdo
);
157 if (!NT_SUCCESS(Status
)) {
158 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
162 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
164 RtlZeroMemory(DeviceExtension
, sizeof(FDO_DEVICE_EXTENSION
));
166 DeviceExtension
->Common
.IsFDO
= TRUE
;
168 DeviceExtension
->Ldo
=
169 IoAttachDeviceToDeviceStack(Fdo
, PhysicalDeviceObject
);
171 DeviceExtension
->State
= dsStopped
;
173 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
175 //Fdo->Flags |= DO_POWER_PAGABLE;
177 DPRINT("Done AddDevice\n");
179 return STATUS_SUCCESS
;
186 IN PDRIVER_OBJECT DriverObject
,
187 IN PUNICODE_STRING RegistryPath
)
191 DPRINT("Peripheral Component Interconnect Bus Driver\n");
193 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = PciDispatchDeviceControl
;
194 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = PciPnpControl
;
195 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = PciPowerControl
;
196 DriverObject
->DriverExtension
->AddDevice
= PciAddDevice
;
198 Status
= IoAllocateDriverObjectExtension(
201 sizeof(PCI_DRIVER_EXTENSION
),
202 (PVOID
*)&DriverExtension
);
203 if (!NT_SUCCESS(Status
))
205 RtlZeroMemory(DriverExtension
, sizeof(PCI_DRIVER_EXTENSION
));
207 InitializeListHead(&DriverExtension
->BusListHead
);
208 KeInitializeSpinLock(&DriverExtension
->BusListLock
);
210 return STATUS_SUCCESS
;
215 PciCreateDeviceIDString(PUNICODE_STRING DeviceID
,
221 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
222 Device
->PciConfig
.VendorID
,
223 Device
->PciConfig
.DeviceID
,
224 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
225 Device
->PciConfig
.u
.type0
.SubVendorID
,
226 Device
->PciConfig
.RevisionID
);
228 return RtlCreateUnicodeString(DeviceID
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
233 PciCreateInstanceIDString(PUNICODE_STRING InstanceID
,
238 swprintf(Buffer
, L
"%02X", Device
->SlotNumber
.u
.AsULONG
& 0xff);
240 return RtlCreateUnicodeString(InstanceID
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
245 PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs
,
249 UNICODE_STRING BufferU
;
253 Index
+= swprintf(&Buffer
[Index
],
254 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
255 Device
->PciConfig
.VendorID
,
256 Device
->PciConfig
.DeviceID
,
257 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
258 Device
->PciConfig
.u
.type0
.SubVendorID
,
259 Device
->PciConfig
.RevisionID
);
262 Index
+= swprintf(&Buffer
[Index
],
263 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
264 Device
->PciConfig
.VendorID
,
265 Device
->PciConfig
.DeviceID
,
266 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
267 Device
->PciConfig
.u
.type0
.SubVendorID
);
270 Index
+= swprintf(&Buffer
[Index
],
271 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
272 Device
->PciConfig
.VendorID
,
273 Device
->PciConfig
.DeviceID
,
274 Device
->PciConfig
.BaseClass
,
275 Device
->PciConfig
.SubClass
,
276 Device
->PciConfig
.ProgIf
);
279 Index
+= swprintf(&Buffer
[Index
],
280 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
281 Device
->PciConfig
.VendorID
,
282 Device
->PciConfig
.DeviceID
,
283 Device
->PciConfig
.BaseClass
,
284 Device
->PciConfig
.SubClass
);
287 Buffer
[Index
] = UNICODE_NULL
;
289 BufferU
.Length
= BufferU
.MaximumLength
= (USHORT
) Index
* sizeof(WCHAR
);
290 BufferU
.Buffer
= Buffer
;
292 return PciDuplicateUnicodeString(0, &BufferU
, HardwareIDs
);
297 PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs
,
301 UNICODE_STRING BufferU
;
305 Index
+= swprintf(&Buffer
[Index
],
306 L
"PCI\\VEN_%04X&DEV_%04X&REV_%02X",
307 Device
->PciConfig
.VendorID
,
308 Device
->PciConfig
.DeviceID
,
309 Device
->PciConfig
.RevisionID
);
312 Index
+= swprintf(&Buffer
[Index
],
313 L
"PCI\\VEN_%04X&DEV_%04X",
314 Device
->PciConfig
.VendorID
,
315 Device
->PciConfig
.DeviceID
);
318 Index
+= swprintf(&Buffer
[Index
],
319 L
"PCI\\VEN_%04X&CC_%02X%02X%02X",
320 Device
->PciConfig
.VendorID
,
321 Device
->PciConfig
.BaseClass
,
322 Device
->PciConfig
.SubClass
,
323 Device
->PciConfig
.ProgIf
);
326 Index
+= swprintf(&Buffer
[Index
],
327 L
"PCI\\VEN_%04X&CC_%02X%02X",
328 Device
->PciConfig
.VendorID
,
329 Device
->PciConfig
.BaseClass
,
330 Device
->PciConfig
.SubClass
);
333 Index
+= swprintf(&Buffer
[Index
],
335 Device
->PciConfig
.VendorID
);
338 Index
+= swprintf(&Buffer
[Index
],
339 L
"PCI\\CC_%02X%02X%02X",
340 Device
->PciConfig
.BaseClass
,
341 Device
->PciConfig
.SubClass
,
342 Device
->PciConfig
.ProgIf
);
345 Index
+= swprintf(&Buffer
[Index
],
347 Device
->PciConfig
.BaseClass
,
348 Device
->PciConfig
.SubClass
);
351 Buffer
[Index
] = UNICODE_NULL
;
353 BufferU
.Length
= BufferU
.MaximumLength
= (USHORT
)Index
* sizeof(WCHAR
);
354 BufferU
.Buffer
= Buffer
;
356 return PciDuplicateUnicodeString(0, &BufferU
, CompatibleIDs
);
361 PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription
,
366 switch (Device
->PciConfig
.BaseClass
)
368 case PCI_CLASS_PRE_20
:
369 switch (Device
->PciConfig
.SubClass
)
371 case PCI_SUBCLASS_PRE_20_VGA
:
372 Description
= L
"VGA device";
376 case PCI_SUBCLASS_PRE_20_NON_VGA
:
377 Description
= L
"PCI device";
382 case PCI_CLASS_MASS_STORAGE_CTLR
:
383 switch (Device
->PciConfig
.SubClass
)
385 case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR
:
386 Description
= L
"SCSI controller";
389 case PCI_SUBCLASS_MSC_IDE_CTLR
:
390 Description
= L
"IDE controller";
393 case PCI_SUBCLASS_MSC_FLOPPY_CTLR
:
394 Description
= L
"Floppy disk controller";
397 case PCI_SUBCLASS_MSC_IPI_CTLR
:
398 Description
= L
"IPI controller";
401 case PCI_SUBCLASS_MSC_RAID_CTLR
:
402 Description
= L
"RAID controller";
406 Description
= L
"Mass storage controller";
411 case PCI_CLASS_NETWORK_CTLR
:
412 switch (Device
->PciConfig
.SubClass
)
414 case PCI_SUBCLASS_NET_ETHERNET_CTLR
:
415 Description
= L
"Ethernet controller";
418 case PCI_SUBCLASS_NET_TOKEN_RING_CTLR
:
419 Description
= L
"Token-Ring controller";
422 case PCI_SUBCLASS_NET_FDDI_CTLR
:
423 Description
= L
"FDDI controller";
426 case PCI_SUBCLASS_NET_ATM_CTLR
:
427 Description
= L
"ATM controller";
431 Description
= L
"Network controller";
436 case PCI_CLASS_DISPLAY_CTLR
:
437 switch (Device
->PciConfig
.SubClass
)
439 case PCI_SUBCLASS_VID_VGA_CTLR
:
440 Description
= L
"VGA display controller";
443 case PCI_SUBCLASS_VID_XGA_CTLR
:
444 Description
= L
"XGA display controller";
447 case PCI_SUBCLASS_VID_3D_CTLR
:
448 Description
= L
"Multimedia display controller";
452 Description
= L
"Other display controller";
457 case PCI_CLASS_MULTIMEDIA_DEV
:
458 switch (Device
->PciConfig
.SubClass
)
460 case PCI_SUBCLASS_MM_VIDEO_DEV
:
461 Description
= L
"Multimedia video device";
464 case PCI_SUBCLASS_MM_AUDIO_DEV
:
465 Description
= L
"Multimedia audio device";
468 case PCI_SUBCLASS_MM_TELEPHONY_DEV
:
469 Description
= L
"Multimedia telephony device";
473 Description
= L
"Other multimedia device";
478 case PCI_CLASS_MEMORY_CTLR
:
479 switch (Device
->PciConfig
.SubClass
)
481 case PCI_SUBCLASS_MEM_RAM
:
482 Description
= L
"PCI Memory";
485 case PCI_SUBCLASS_MEM_FLASH
:
486 Description
= L
"PCI Flash Memory";
490 Description
= L
"Other memory controller";
495 case PCI_CLASS_BRIDGE_DEV
:
496 switch (Device
->PciConfig
.SubClass
)
498 case PCI_SUBCLASS_BR_HOST
:
499 Description
= L
"PCI-Host bridge";
502 case PCI_SUBCLASS_BR_ISA
:
503 Description
= L
"PCI-ISA bridge";
506 case PCI_SUBCLASS_BR_EISA
:
507 Description
= L
"PCI-EISA bridge";
510 case PCI_SUBCLASS_BR_MCA
:
511 Description
= L
"PCI-Micro Channel bridge";
514 case PCI_SUBCLASS_BR_PCI_TO_PCI
:
515 Description
= L
"PCI-PCI bridge";
518 case PCI_SUBCLASS_BR_PCMCIA
:
519 Description
= L
"PCI-PCMCIA bridge";
522 case PCI_SUBCLASS_BR_NUBUS
:
523 Description
= L
"PCI-NUBUS bridge";
526 case PCI_SUBCLASS_BR_CARDBUS
:
527 Description
= L
"PCI-CARDBUS bridge";
531 Description
= L
"Other bridge device";
536 case PCI_CLASS_SIMPLE_COMMS_CTLR
:
537 switch (Device
->PciConfig
.SubClass
)
541 Description
= L
"Communication device";
546 case PCI_CLASS_BASE_SYSTEM_DEV
:
547 switch (Device
->PciConfig
.SubClass
)
551 Description
= L
"System device";
556 case PCI_CLASS_INPUT_DEV
:
557 switch (Device
->PciConfig
.SubClass
)
561 Description
= L
"Input device";
566 case PCI_CLASS_DOCKING_STATION
:
567 switch (Device
->PciConfig
.SubClass
)
571 Description
= L
"Docking station";
576 case PCI_CLASS_PROCESSOR
:
577 switch (Device
->PciConfig
.SubClass
)
581 Description
= L
"Processor";
586 case PCI_CLASS_SERIAL_BUS_CTLR
:
587 switch (Device
->PciConfig
.SubClass
)
589 case PCI_SUBCLASS_SB_IEEE1394
:
590 Description
= L
"FireWire controller";
593 case PCI_SUBCLASS_SB_ACCESS
:
594 Description
= L
"ACCESS bus controller";
597 case PCI_SUBCLASS_SB_SSA
:
598 Description
= L
"SSA controller";
601 case PCI_SUBCLASS_SB_USB
:
602 Description
= L
"USB controller";
605 case PCI_SUBCLASS_SB_FIBRE_CHANNEL
:
606 Description
= L
"Fibre Channel controller";
610 Description
= L
"Other serial bus controller";
616 Description
= L
"Other PCI Device";
620 return RtlCreateUnicodeString(DeviceDescription
, Description
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
625 PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation
,
631 L
"PCI-Bus %lu, Device %u, Function %u",
633 Device
->SlotNumber
.u
.bits
.DeviceNumber
,
634 Device
->SlotNumber
.u
.bits
.FunctionNumber
);
636 return RtlCreateUnicodeString(DeviceLocation
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
640 PciDuplicateUnicodeString(
642 IN PCUNICODE_STRING SourceString
,
643 OUT PUNICODE_STRING DestinationString
)
645 if (SourceString
== NULL
|| DestinationString
== NULL
646 || SourceString
->Length
> SourceString
->MaximumLength
647 || (SourceString
->Length
== 0 && SourceString
->MaximumLength
> 0 && SourceString
->Buffer
== NULL
)
648 || Flags
== RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING
|| Flags
>= 4)
650 return STATUS_INVALID_PARAMETER
;
654 if ((SourceString
->Length
== 0)
655 && (Flags
!= (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
|
656 RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING
)))
658 DestinationString
->Length
= 0;
659 DestinationString
->MaximumLength
= 0;
660 DestinationString
->Buffer
= NULL
;
664 USHORT DestMaxLength
= SourceString
->Length
;
666 if (Flags
& RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
)
667 DestMaxLength
+= sizeof(UNICODE_NULL
);
669 DestinationString
->Buffer
= ExAllocatePoolWithTag(PagedPool
, DestMaxLength
, TAG_PCI
);
670 if (DestinationString
->Buffer
== NULL
)
671 return STATUS_NO_MEMORY
;
673 RtlCopyMemory(DestinationString
->Buffer
, SourceString
->Buffer
, SourceString
->Length
);
674 DestinationString
->Length
= SourceString
->Length
;
675 DestinationString
->MaximumLength
= DestMaxLength
;
677 if (Flags
& RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
)
678 DestinationString
->Buffer
[DestinationString
->Length
/ sizeof(WCHAR
)] = 0;
681 return STATUS_SUCCESS
;