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
18 // Make the initialization routines discardable, so that they
21 #pragma alloc_text(init, DriverEntry)
23 #endif /* ALLOC_PRAGMA */
25 /*** PUBLIC ******************************************************************/
27 PCI_BUS_TYPE PciBusConfigType = pbtUnknown;
30 /*** PRIVATE *****************************************************************/
33 PciReadConfigUchar(UCHAR Bus,
38 switch (PciBusConfigType)
41 WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
42 *Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3));
43 return STATUS_SUCCESS;
46 WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
47 WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
48 *Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset)));
49 WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
50 return STATUS_SUCCESS;
52 return STATUS_UNSUCCESSFUL;
57 PciReadConfigUshort(UCHAR Bus,
62 if ((Offset & 1) != 0)
64 return STATUS_INVALID_PARAMETER;
67 switch (PciBusConfigType)
70 WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
71 *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2));
72 return STATUS_SUCCESS;
75 WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
76 WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
77 *Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)));
78 WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
79 return STATUS_SUCCESS;
81 return STATUS_UNSUCCESSFUL;
86 PciReadConfigUlong(UCHAR Bus,
91 if ((Offset & 3) != 0)
93 return STATUS_INVALID_PARAMETER;
96 switch (PciBusConfigType)
99 WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
100 *Value = READ_PORT_ULONG((PULONG)0xCFC);
101 return STATUS_SUCCESS;
104 WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
105 WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
106 *Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)));
107 WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
108 return STATUS_SUCCESS;
110 return STATUS_UNSUCCESSFUL;
115 PciWriteConfigUchar(UCHAR Bus,
120 switch (PciBusConfigType)
123 WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
124 WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value);
125 return STATUS_SUCCESS;
128 WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
129 WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
130 WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value);
131 WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
132 return STATUS_SUCCESS;
134 return STATUS_UNSUCCESSFUL;
139 PciWriteConfigUshort(UCHAR Bus,
144 if ((Offset & 1) != 0)
146 return STATUS_INVALID_PARAMETER;
149 switch (PciBusConfigType)
152 WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
153 WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2), Value);
154 return STATUS_SUCCESS;
157 WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
158 WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
159 WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value);
160 WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
161 return STATUS_SUCCESS;
163 return STATUS_UNSUCCESSFUL;
168 PciWriteConfigUlong(UCHAR Bus,
173 if ((Offset & 3) != 0)
175 return STATUS_INVALID_PARAMETER;
178 switch (PciBusConfigType)
181 WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
182 WRITE_PORT_ULONG((PULONG)0xCFC, Value);
183 return STATUS_SUCCESS;
186 WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
187 WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
188 WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value);
189 WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
190 return STATUS_SUCCESS;
192 return STATUS_UNSUCCESSFUL;
197 PciGetBusData(ULONG BusNumber,
204 ULONG Address = Offset;
210 DPRINT(" BusNumber %lu\n", BusNumber);
211 DPRINT(" SlotNumber %lu\n", SlotNumber);
212 DPRINT(" Offset 0x%lx\n", Offset);
213 DPRINT(" Length 0x%lx\n", Length);
216 if ((Length == 0) || (PciBusConfigType == 0))
219 /* 0E=PCI_HEADER_TYPE */
220 PciReadConfigUchar(BusNumber,
224 if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0))
227 PciReadConfigUlong(BusNumber,
231 /* some broken boards return 0 if a slot is empty: */
232 if (Vendor == 0xFFFFFFFF || Vendor == 0)
235 if ((Address & 1) && (Len >= 1))
237 PciReadConfigUchar(BusNumber,
246 if ((Address & 2) && (Len >= 2))
248 PciReadConfigUshort(BusNumber,
259 PciReadConfigUlong(BusNumber,
270 PciReadConfigUshort(BusNumber,
281 PciReadConfigUchar(BusNumber,
295 PciSetBusData(ULONG BusNumber,
302 ULONG Address = Offset;
308 DPRINT(" BusNumber %lu\n", BusNumber);
309 DPRINT(" SlotNumber %lu\n", SlotNumber);
310 DPRINT(" Offset 0x%lx\n", Offset);
311 DPRINT(" Length 0x%lx\n", Length);
314 if ((Length == 0) || (PciBusConfigType == 0))
317 /* 0E=PCI_HEADER_TYPE */
318 PciReadConfigUchar(BusNumber,
322 if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0))
325 PciReadConfigUlong(BusNumber,
329 /* some broken boards return 0 if a slot is empty: */
330 if (Vendor == 0xFFFFFFFF || Vendor == 0)
333 if ((Address & 1) && (Len >= 1))
335 PciWriteConfigUchar(BusNumber,
344 if ((Address & 2) && (Len >= 2))
346 PciWriteConfigUshort(BusNumber,
357 PciWriteConfigUlong(BusNumber,
368 PciWriteConfigUshort(BusNumber,
379 PciWriteConfigUchar(BusNumber,
393 PciGetBusConfigType(VOID)
399 DPRINT("Checking configuration type 1:\n");
400 WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01);
401 Value = READ_PORT_ULONG((PULONG)0xCF8);
402 WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000);
403 if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000)
405 WRITE_PORT_ULONG((PULONG)0xCF8, Value);
406 DPRINT(" Success!\n");
409 WRITE_PORT_ULONG((PULONG)0xCF8, Value);
410 DPRINT(" Unsuccessful!\n");
412 DPRINT("Checking configuration type 2:\n");
413 WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00);
414 WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00);
415 WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00);
416 if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 &&
417 READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00)
419 DPRINT(" Success!\n");
422 DPRINT(" Unsuccessful!\n");
424 DPRINT("No pci bus found!\n");
431 PciDispatchDeviceControl(
432 IN PDEVICE_OBJECT DeviceObject,
435 PIO_STACK_LOCATION IrpSp;
438 DPRINT("Called. IRP is at (0x%X)\n", Irp);
440 Irp->IoStatus.Information = 0;
442 IrpSp = IoGetCurrentIrpStackLocation(Irp);
443 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
445 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
446 Status = STATUS_NOT_IMPLEMENTED;
450 if (Status != STATUS_PENDING) {
451 Irp->IoStatus.Status = Status;
453 DPRINT("Completing IRP at 0x%X\n", Irp);
455 IoCompleteRequest(Irp, IO_NO_INCREMENT);
458 DPRINT("Leaving. Status 0x%X\n", Status);
467 IN PDEVICE_OBJECT DeviceObject,
470 * FUNCTION: Handle Plug and Play IRPs
472 * DeviceObject = Pointer to PDO or FDO
473 * Irp = Pointer to IRP that should be handled
478 PCOMMON_DEVICE_EXTENSION DeviceExtension;
481 DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
483 DPRINT("IsFDO %d\n", DeviceExtension->IsFDO);
485 if (DeviceExtension->IsFDO) {
486 Status = FdoPnpControl(DeviceObject, Irp);
488 Status = PdoPnpControl(DeviceObject, Irp);
498 IN PDEVICE_OBJECT DeviceObject,
501 * FUNCTION: Handle power management IRPs
503 * DeviceObject = Pointer to PDO or FDO
504 * Irp = Pointer to IRP that should be handled
509 PCOMMON_DEVICE_EXTENSION DeviceExtension;
512 DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
514 if (DeviceExtension->IsFDO) {
515 Status = FdoPowerControl(DeviceObject, Irp);
517 Status = PdoPowerControl(DeviceObject, Irp);
527 IN PDRIVER_OBJECT DriverObject,
528 IN PDEVICE_OBJECT PhysicalDeviceObject)
530 PFDO_DEVICE_EXTENSION DeviceExtension;
536 Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION),
537 NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo);
538 if (!NT_SUCCESS(Status)) {
539 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
543 DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
545 RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
547 DeviceExtension->Common.IsFDO = TRUE;
549 DeviceExtension->Ldo =
550 IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject);
552 DeviceExtension->State = dsStopped;
554 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
556 //Fdo->Flags |= DO_POWER_PAGABLE;
558 DPRINT("Done AddDevice\n");
560 return STATUS_SUCCESS;
567 IN PDRIVER_OBJECT DriverObject,
568 IN PUNICODE_STRING RegistryPath)
570 DbgPrint("Peripheral Component Interconnect Bus Driver\n");
572 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH) PciDispatchDeviceControl;
573 DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH) PciPnpControl;
574 DriverObject->MajorFunction[IRP_MJ_POWER] = (PDRIVER_DISPATCH) PciPowerControl;
575 DriverObject->DriverExtension->AddDevice = PciAddDevice;
577 return STATUS_SUCCESS;
582 PciCreateUnicodeString(
583 PUNICODE_STRING Destination,
591 RtlInitUnicodeString(Destination, NULL);
595 Length = (wcslen(Source) + 1) * sizeof(WCHAR);
597 Destination->Buffer = ExAllocatePool(PoolType, Length);
599 if (Destination->Buffer == NULL)
604 RtlCopyMemory(Destination->Buffer, Source, Length);
606 Destination->MaximumLength = Length;
608 Destination->Length = Length - sizeof(WCHAR);