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
19 // Make the initialization routines discardable, so that they
22 #pragma alloc_text(init, DriverEntry)
24 #endif /* ALLOC_PRAGMA */
26 /*** PUBLIC ******************************************************************/
28 PPCI_DRIVER_EXTENSION DriverExtension
= NULL
;
30 /*** PRIVATE *****************************************************************/
34 PciDispatchDeviceControl(
35 IN PDEVICE_OBJECT DeviceObject
,
38 PIO_STACK_LOCATION IrpSp
;
41 DPRINT("Called. IRP is at (0x%X)\n", Irp
);
43 Irp
->IoStatus
.Information
= 0;
45 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
46 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
48 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
);
49 Status
= STATUS_NOT_IMPLEMENTED
;
53 if (Status
!= STATUS_PENDING
) {
54 Irp
->IoStatus
.Status
= Status
;
56 DPRINT("Completing IRP at 0x%X\n", Irp
);
58 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
61 DPRINT("Leaving. Status 0x%X\n", Status
);
70 IN PDEVICE_OBJECT DeviceObject
,
73 * FUNCTION: Handle Plug and Play IRPs
75 * DeviceObject = Pointer to PDO or FDO
76 * Irp = Pointer to IRP that should be handled
81 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
84 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
86 DPRINT("IsFDO %d\n", DeviceExtension
->IsFDO
);
88 if (DeviceExtension
->IsFDO
) {
89 Status
= FdoPnpControl(DeviceObject
, Irp
);
91 Status
= PdoPnpControl(DeviceObject
, Irp
);
101 IN PDEVICE_OBJECT DeviceObject
,
104 * FUNCTION: Handle power management IRPs
106 * DeviceObject = Pointer to PDO or FDO
107 * Irp = Pointer to IRP that should be handled
112 PCOMMON_DEVICE_EXTENSION DeviceExtension
;
115 DeviceExtension
= (PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
117 if (DeviceExtension
->IsFDO
) {
118 Status
= FdoPowerControl(DeviceObject
, Irp
);
120 Status
= PdoPowerControl(DeviceObject
, Irp
);
130 IN PDRIVER_OBJECT DriverObject
,
131 IN PDEVICE_OBJECT PhysicalDeviceObject
)
133 PFDO_DEVICE_EXTENSION DeviceExtension
;
139 Status
= IoCreateDevice(DriverObject
, sizeof(FDO_DEVICE_EXTENSION
),
140 NULL
, FILE_DEVICE_BUS_EXTENDER
, FILE_DEVICE_SECURE_OPEN
, TRUE
, &Fdo
);
141 if (!NT_SUCCESS(Status
)) {
142 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
146 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
148 RtlZeroMemory(DeviceExtension
, sizeof(FDO_DEVICE_EXTENSION
));
150 DeviceExtension
->Common
.IsFDO
= TRUE
;
152 DeviceExtension
->Ldo
=
153 IoAttachDeviceToDeviceStack(Fdo
, PhysicalDeviceObject
);
155 DeviceExtension
->State
= dsStopped
;
157 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
159 //Fdo->Flags |= DO_POWER_PAGABLE;
161 DPRINT("Done AddDevice\n");
163 return STATUS_SUCCESS
;
170 IN PDRIVER_OBJECT DriverObject
,
171 IN PUNICODE_STRING RegistryPath
)
175 DPRINT("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 Status
= IoAllocateDriverObjectExtension(
185 sizeof(PCI_DRIVER_EXTENSION
),
186 (PVOID
*)&DriverExtension
);
187 if (!NT_SUCCESS(Status
))
189 RtlZeroMemory(DriverExtension
, sizeof(PCI_DRIVER_EXTENSION
));
191 InitializeListHead(&DriverExtension
->BusListHead
);
192 KeInitializeSpinLock(&DriverExtension
->BusListLock
);
194 return STATUS_SUCCESS
;
199 PciCreateDeviceIDString(PUNICODE_STRING DeviceID
,
205 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
206 Device
->PciConfig
.VendorID
,
207 Device
->PciConfig
.DeviceID
,
208 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
209 Device
->PciConfig
.u
.type0
.SubVendorID
,
210 Device
->PciConfig
.RevisionID
);
212 return RtlCreateUnicodeString(DeviceID
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
217 PciCreateInstanceIDString(PUNICODE_STRING InstanceID
,
224 if (((PPDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
)->PciDevice
->BusNumber
!= 0)
226 /* FIXME: Copy InstanceID of parent PCI bus to Buffer */
227 // Index += swprintf(Buffer, ....);
230 swprintf(&Buffer
[Index
], L
"%02X", Device
->SlotNumber
.u
.AsULONG
& 0xff);
232 return RtlCreateUnicodeString(InstanceID
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
237 PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs
,
241 UNICODE_STRING BufferU
;
245 Index
+= swprintf(&Buffer
[Index
],
246 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
247 Device
->PciConfig
.VendorID
,
248 Device
->PciConfig
.DeviceID
,
249 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
250 Device
->PciConfig
.u
.type0
.SubVendorID
,
251 Device
->PciConfig
.RevisionID
);
254 Index
+= swprintf(&Buffer
[Index
],
255 L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
256 Device
->PciConfig
.VendorID
,
257 Device
->PciConfig
.DeviceID
,
258 (Device
->PciConfig
.u
.type0
.SubSystemID
<< 16) +
259 Device
->PciConfig
.u
.type0
.SubVendorID
);
262 Index
+= swprintf(&Buffer
[Index
],
263 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
264 Device
->PciConfig
.VendorID
,
265 Device
->PciConfig
.DeviceID
,
266 Device
->PciConfig
.BaseClass
,
267 Device
->PciConfig
.SubClass
,
268 Device
->PciConfig
.ProgIf
);
271 Index
+= swprintf(&Buffer
[Index
],
272 L
"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
273 Device
->PciConfig
.VendorID
,
274 Device
->PciConfig
.DeviceID
,
275 Device
->PciConfig
.BaseClass
,
276 Device
->PciConfig
.SubClass
);
279 Buffer
[Index
] = UNICODE_NULL
;
281 BufferU
.Length
= BufferU
.MaximumLength
= Index
* sizeof(WCHAR
);
282 BufferU
.Buffer
= Buffer
;
284 return RtlDuplicateUnicodeString(0, &BufferU
, HardwareIDs
);
289 PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs
,
293 UNICODE_STRING BufferU
;
297 Index
+= swprintf(&Buffer
[Index
],
298 L
"PCI\\VEN_%04X&DEV_%04X&REV_%02X",
299 Device
->PciConfig
.VendorID
,
300 Device
->PciConfig
.DeviceID
,
301 Device
->PciConfig
.RevisionID
);
304 Index
+= swprintf(&Buffer
[Index
],
305 L
"PCI\\VEN_%04X&DEV_%04X",
306 Device
->PciConfig
.VendorID
,
307 Device
->PciConfig
.DeviceID
);
310 Index
+= swprintf(&Buffer
[Index
],
311 L
"PCI\\VEN_%04X&CC_%02X%02X%02X",
312 Device
->PciConfig
.VendorID
,
313 Device
->PciConfig
.BaseClass
,
314 Device
->PciConfig
.SubClass
,
315 Device
->PciConfig
.ProgIf
);
318 Index
+= swprintf(&Buffer
[Index
],
319 L
"PCI\\VEN_%04X&CC_%02X%02X",
320 Device
->PciConfig
.VendorID
,
321 Device
->PciConfig
.BaseClass
,
322 Device
->PciConfig
.SubClass
);
325 Index
+= swprintf(&Buffer
[Index
],
327 Device
->PciConfig
.VendorID
);
330 Index
+= swprintf(&Buffer
[Index
],
331 L
"PCI\\CC_%02X%02X%02X",
332 Device
->PciConfig
.BaseClass
,
333 Device
->PciConfig
.SubClass
,
334 Device
->PciConfig
.ProgIf
);
337 Index
+= swprintf(&Buffer
[Index
],
339 Device
->PciConfig
.BaseClass
,
340 Device
->PciConfig
.SubClass
);
343 Buffer
[Index
] = UNICODE_NULL
;
345 BufferU
.Length
= BufferU
.MaximumLength
= Index
* sizeof(WCHAR
);
346 BufferU
.Buffer
= Buffer
;
348 return RtlDuplicateUnicodeString(0, &BufferU
, CompatibleIDs
);
353 PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription
,
358 switch (Device
->PciConfig
.BaseClass
)
360 case PCI_CLASS_PRE_20
:
361 switch (Device
->PciConfig
.SubClass
)
363 case PCI_SUBCLASS_PRE_20_VGA
:
364 Description
= L
"VGA device";
368 case PCI_SUBCLASS_PRE_20_NON_VGA
:
369 Description
= L
"PCI device";
374 case PCI_CLASS_MASS_STORAGE_CTLR
:
375 switch (Device
->PciConfig
.SubClass
)
377 case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR
:
378 Description
= L
"SCSI controller";
381 case PCI_SUBCLASS_MSC_IDE_CTLR
:
382 Description
= L
"IDE controller";
385 case PCI_SUBCLASS_MSC_FLOPPY_CTLR
:
386 Description
= L
"Floppy disk controller";
389 case PCI_SUBCLASS_MSC_IPI_CTLR
:
390 Description
= L
"IPI controller";
393 case PCI_SUBCLASS_MSC_RAID_CTLR
:
394 Description
= L
"RAID controller";
398 Description
= L
"Mass storage controller";
403 case PCI_CLASS_NETWORK_CTLR
:
404 switch (Device
->PciConfig
.SubClass
)
406 case PCI_SUBCLASS_NET_ETHERNET_CTLR
:
407 Description
= L
"Ethernet controller";
410 case PCI_SUBCLASS_NET_TOKEN_RING_CTLR
:
411 Description
= L
"Token-Ring controller";
414 case PCI_SUBCLASS_NET_FDDI_CTLR
:
415 Description
= L
"FDDI controller";
418 case PCI_SUBCLASS_NET_ATM_CTLR
:
419 Description
= L
"ATM controller";
423 Description
= L
"Network controller";
428 case PCI_CLASS_DISPLAY_CTLR
:
429 switch (Device
->PciConfig
.SubClass
)
431 case PCI_SUBCLASS_VID_VGA_CTLR
:
432 Description
= L
"VGA display controller";
435 case PCI_SUBCLASS_VID_XGA_CTLR
:
436 Description
= L
"XGA display controller";
439 case PCI_SUBLCASS_VID_3D_CTLR
:
440 Description
= L
"Multimedia display controller";
444 Description
= L
"Other display controller";
449 case PCI_CLASS_MULTIMEDIA_DEV
:
450 switch (Device
->PciConfig
.SubClass
)
452 case PCI_SUBCLASS_MM_VIDEO_DEV
:
453 Description
= L
"Multimedia video device";
456 case PCI_SUBCLASS_MM_AUDIO_DEV
:
457 Description
= L
"Multimedia audio device";
460 case PCI_SUBCLASS_MM_TELEPHONY_DEV
:
461 Description
= L
"Multimedia telephony device";
465 Description
= L
"Other multimedia device";
470 case PCI_CLASS_MEMORY_CTLR
:
471 switch (Device
->PciConfig
.SubClass
)
473 case PCI_SUBCLASS_MEM_RAM
:
474 Description
= L
"PCI Memory";
477 case PCI_SUBCLASS_MEM_FLASH
:
478 Description
= L
"PCI Flash Memory";
482 Description
= L
"Other memory controller";
487 case PCI_CLASS_BRIDGE_DEV
:
488 switch (Device
->PciConfig
.SubClass
)
490 case PCI_SUBCLASS_BR_HOST
:
491 Description
= L
"PCI-Host bridge";
494 case PCI_SUBCLASS_BR_ISA
:
495 Description
= L
"PCI-ISA bridge";
498 case PCI_SUBCLASS_BR_EISA
:
499 Description
= L
"PCI-EISA bridge";
502 case PCI_SUBCLASS_BR_MCA
:
503 Description
= L
"PCI-Micro Channel bridge";
506 case PCI_SUBCLASS_BR_PCI_TO_PCI
:
507 Description
= L
"PCI-PCI bridge";
510 case PCI_SUBCLASS_BR_PCMCIA
:
511 Description
= L
"PCI-PCMCIA bridge";
514 case PCI_SUBCLASS_BR_NUBUS
:
515 Description
= L
"PCI-NUBUS bridge";
518 case PCI_SUBCLASS_BR_CARDBUS
:
519 Description
= L
"PCI-CARDBUS bridge";
523 Description
= L
"Other bridge device";
528 case PCI_CLASS_SIMPLE_COMMS_CTLR
:
529 switch (Device
->PciConfig
.SubClass
)
533 Description
= L
"Communication device";
538 case PCI_CLASS_BASE_SYSTEM_DEV
:
539 switch (Device
->PciConfig
.SubClass
)
543 Description
= L
"System device";
548 case PCI_CLASS_INPUT_DEV
:
549 switch (Device
->PciConfig
.SubClass
)
553 Description
= L
"Input device";
558 case PCI_CLASS_DOCKING_STATION
:
559 switch (Device
->PciConfig
.SubClass
)
563 Description
= L
"Docking station";
568 case PCI_CLASS_PROCESSOR
:
569 switch (Device
->PciConfig
.SubClass
)
573 Description
= L
"Processor";
578 case PCI_CLASS_SERIAL_BUS_CTLR
:
579 switch (Device
->PciConfig
.SubClass
)
581 case PCI_SUBCLASS_SB_IEEE1394
:
582 Description
= L
"FireWire controller";
585 case PCI_SUBCLASS_SB_ACCESS
:
586 Description
= L
"ACCESS bus controller";
589 case PCI_SUBCLASS_SB_SSA
:
590 Description
= L
"SSA controller";
593 case PCI_SUBCLASS_SB_USB
:
594 Description
= L
"USB controller";
597 case PCI_SUBCLASS_SB_FIBRE_CHANNEL
:
598 Description
= L
"Fibre Channel controller";
602 Description
= L
"Other serial bus controller";
608 Description
= L
"Other PCI Device";
612 return RtlCreateUnicodeString(DeviceDescription
, Description
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;
617 PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation
,
623 L
"PCI-Bus %lu, Device %u, Function %u",
625 Device
->SlotNumber
.u
.bits
.DeviceNumber
,
626 Device
->SlotNumber
.u
.bits
.FunctionNumber
);
628 return RtlCreateUnicodeString(DeviceLocation
, Buffer
) ? STATUS_SUCCESS
: STATUS_INSUFFICIENT_RESOURCES
;