Implement InterfacePciDevicePresent(Ex) of PCI_DEVICE_PRESENT_INTERFACE
[reactos.git] / reactos / drivers / bus / pci / pci.c
index 58b2f2d..34d0cbd 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: pci.c,v 1.5 2003/12/12 21:54:42 ekohl Exp $
- *
+/*
  * PROJECT:         ReactOS PCI Bus driver
  * FILE:            pci.c
  * PURPOSE:         Driver entry
@@ -9,6 +8,8 @@
  */
 
 #include <ddk/ntddk.h>
+#include <ddk/ntifs.h>
+#include <stdio.h>
 
 #include "pcidef.h"
 #include "pci.h"
@@ -19,7 +20,7 @@
 
 #ifdef  ALLOC_PRAGMA
 
-// Make the initialization routines discardable, so that they 
+// Make the initialization routines discardable, so that they
 // don't waste space
 
 #pragma  alloc_text(init, DriverEntry)
 
 /*** PUBLIC ******************************************************************/
 
+PPCI_DRIVER_EXTENSION DriverExtension = NULL;
 
 /*** PRIVATE *****************************************************************/
 
-NTSTATUS
+static NTSTATUS
 STDCALL
 PciDispatchDeviceControl(
-  IN PDEVICE_OBJECT DeviceObject, 
-  IN PIRP Irp) 
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PIRP Irp)
 {
   PIO_STACK_LOCATION IrpSp;
   NTSTATUS Status;
@@ -66,7 +68,7 @@ PciDispatchDeviceControl(
 }
 
 
-NTSTATUS
+static NTSTATUS
 STDCALL
 PciPnpControl(
   IN PDEVICE_OBJECT DeviceObject,
@@ -97,7 +99,7 @@ PciPnpControl(
 }
 
 
-NTSTATUS
+static NTSTATUS
 STDCALL
 PciPowerControl(
   IN PDEVICE_OBJECT DeviceObject,
@@ -126,7 +128,7 @@ PciPowerControl(
 }
 
 
-NTSTATUS
+static NTSTATUS
 STDCALL
 PciAddDevice(
   IN PDRIVER_OBJECT DriverObject,
@@ -172,47 +174,462 @@ DriverEntry(
   IN PDRIVER_OBJECT DriverObject,
   IN PUNICODE_STRING RegistryPath)
 {
-  DbgPrint("Peripheral Component Interconnect Bus Driver\n");
+  NTSTATUS Status;
 
-  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH) PciDispatchDeviceControl;
-  DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH) PciPnpControl;
-  DriverObject->MajorFunction[IRP_MJ_POWER] = (PDRIVER_DISPATCH) PciPowerControl;
+  DPRINT("Peripheral Component Interconnect Bus Driver\n");
+
+  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PciDispatchDeviceControl;
+  DriverObject->MajorFunction[IRP_MJ_PNP] = PciPnpControl;
+  DriverObject->MajorFunction[IRP_MJ_POWER] = PciPowerControl;
   DriverObject->DriverExtension->AddDevice = PciAddDevice;
 
+  Status = IoAllocateDriverObjectExtension(
+    DriverObject,
+    DriverObject,
+    sizeof(PCI_DRIVER_EXTENSION),
+    (PVOID*)&DriverExtension);
+  if (!NT_SUCCESS(Status))
+    return Status;
+  RtlZeroMemory(DriverExtension, sizeof(PCI_DRIVER_EXTENSION));
+
+  InitializeListHead(&DriverExtension->BusListHead);
+  KeInitializeSpinLock(&DriverExtension->BusListLock);
+
   return STATUS_SUCCESS;
 }
 
 
-BOOLEAN
-PciCreateUnicodeString(
-  PUNICODE_STRING      Destination,
-  PWSTR Source,
-  POOL_TYPE PoolType)
+NTSTATUS
+PciCreateDeviceIDString(PUNICODE_STRING DeviceID,
+                        PPCI_DEVICE Device)
+{
+  WCHAR Buffer[256];
+
+  swprintf(Buffer,
+           L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
+           Device->PciConfig.VendorID,
+           Device->PciConfig.DeviceID,
+           (Device->PciConfig.u.type0.SubSystemID << 16) +
+           Device->PciConfig.u.type0.SubVendorID,
+           Device->PciConfig.RevisionID);
+
+  return RtlCreateUnicodeString(DeviceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
+}
+
+
+NTSTATUS
+PciCreateInstanceIDString(PUNICODE_STRING InstanceID,
+                          PPCI_DEVICE Device)
 {
-  ULONG Length;
+  WCHAR Buffer[32];
+  ULONG Index;
 
-  if (!Source)
+  Index = 0;
+  if (((PPDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension)->PciDevice->BusNumber != 0)
   {
-    RtlInitUnicodeString(Destination, NULL);
-    return TRUE;
+    /* FIXME: Copy InstanceID of parent PCI bus to Buffer */
+    // Index += swprintf(Buffer, ....);
   }
 
-  Length = (wcslen(Source) + 1) * sizeof(WCHAR);
+  swprintf(&Buffer[Index], L"%02X", Device->SlotNumber.u.AsULONG & 0xff);
+
+  return RtlCreateUnicodeString(InstanceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
+}
+
+
+NTSTATUS
+PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs,
+                           PPCI_DEVICE Device)
+{
+  WCHAR Buffer[256];
+  UNICODE_STRING BufferU;
+  ULONG Index;
+
+  Index = 0;
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
+           Device->PciConfig.VendorID,
+           Device->PciConfig.DeviceID,
+           (Device->PciConfig.u.type0.SubSystemID << 16) +
+           Device->PciConfig.u.type0.SubVendorID,
+           Device->PciConfig.RevisionID);
+  Index++;
+
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
+           Device->PciConfig.VendorID,
+           Device->PciConfig.DeviceID,
+           (Device->PciConfig.u.type0.SubSystemID << 16) +
+           Device->PciConfig.u.type0.SubVendorID);
+  Index++;
+
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
+           Device->PciConfig.VendorID,
+           Device->PciConfig.DeviceID,
+           Device->PciConfig.BaseClass,
+           Device->PciConfig.SubClass,
+           Device->PciConfig.ProgIf);
+  Index++;
+
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
+           Device->PciConfig.VendorID,
+           Device->PciConfig.DeviceID,
+           Device->PciConfig.BaseClass,
+           Device->PciConfig.SubClass);
+  Index++;
+
+  Buffer[Index] = UNICODE_NULL;
+  
+  BufferU.Length = BufferU.MaximumLength = Index * sizeof(WCHAR);
+  BufferU.Buffer = Buffer;
+
+  return RtlDuplicateUnicodeString(0, &BufferU, HardwareIDs);
+}
 
-  Destination->Buffer = ExAllocatePool(PoolType, Length);
 
-  if (Destination->Buffer == NULL)
+NTSTATUS
+PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs,
+                             PPCI_DEVICE Device)
+{
+  WCHAR Buffer[256];
+  UNICODE_STRING BufferU;
+  ULONG Index;
+
+  Index = 0;
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\VEN_%04X&DEV_%04X&REV_%02X",
+           Device->PciConfig.VendorID,
+           Device->PciConfig.DeviceID,
+           Device->PciConfig.RevisionID);
+  Index++;
+
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\VEN_%04X&DEV_%04X",
+           Device->PciConfig.VendorID,
+           Device->PciConfig.DeviceID);
+  Index++;
+
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\VEN_%04X&CC_%02X%02X%02X",
+           Device->PciConfig.VendorID,
+           Device->PciConfig.BaseClass,
+           Device->PciConfig.SubClass,
+           Device->PciConfig.ProgIf);
+  Index++;
+
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\VEN_%04X&CC_%02X%02X",
+           Device->PciConfig.VendorID,
+           Device->PciConfig.BaseClass,
+           Device->PciConfig.SubClass);
+  Index++;
+
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\VEN_%04X",
+           Device->PciConfig.VendorID);
+  Index++;
+
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\CC_%02X%02X%02X",
+           Device->PciConfig.BaseClass,
+           Device->PciConfig.SubClass,
+           Device->PciConfig.ProgIf);
+  Index++;
+
+  Index += swprintf(&Buffer[Index],
+           L"PCI\\CC_%02X%02X",
+           Device->PciConfig.BaseClass,
+           Device->PciConfig.SubClass);
+  Index++;
+
+  Buffer[Index] = UNICODE_NULL;
+
+  BufferU.Length = BufferU.MaximumLength = Index * sizeof(WCHAR);
+  BufferU.Buffer = Buffer;
+
+  return RtlDuplicateUnicodeString(0, &BufferU, CompatibleIDs);
+}
+
+
+NTSTATUS
+PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription,
+                                 PPCI_DEVICE Device)
+{
+  PCWSTR Description;
+
+  switch (Device->PciConfig.BaseClass)
   {
-    return FALSE;
+    case PCI_CLASS_PRE_20:
+      switch (Device->PciConfig.SubClass)
+      {
+        case PCI_SUBCLASS_PRE_20_VGA:
+          Description = L"VGA device";
+          break;
+
+        default:
+        case PCI_SUBCLASS_PRE_20_NON_VGA:
+          Description = L"PCI device";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_MASS_STORAGE_CTLR:
+      switch (Device->PciConfig.SubClass)
+      {
+        case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR:
+          Description = L"SCSI controller";
+          break;
+
+        case PCI_SUBCLASS_MSC_IDE_CTLR:
+          Description = L"IDE controller";
+          break;
+
+        case PCI_SUBCLASS_MSC_FLOPPY_CTLR:
+          Description = L"Floppy disk controller";
+          break;
+
+        case PCI_SUBCLASS_MSC_IPI_CTLR:
+          Description = L"IPI controller";
+          break;
+
+        case PCI_SUBCLASS_MSC_RAID_CTLR:
+          Description = L"RAID controller";
+          break;
+
+        default:
+          Description = L"Mass storage controller";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_NETWORK_CTLR:
+      switch (Device->PciConfig.SubClass)
+      {
+        case PCI_SUBCLASS_NET_ETHERNET_CTLR:
+          Description = L"Ethernet controller";
+          break;
+
+        case PCI_SUBCLASS_NET_TOKEN_RING_CTLR:
+          Description = L"Token-Ring controller";
+          break;
+
+        case PCI_SUBCLASS_NET_FDDI_CTLR:
+          Description = L"FDDI controller";
+          break;
+
+        case PCI_SUBCLASS_NET_ATM_CTLR:
+          Description = L"ATM controller";
+          break;
+
+        default:
+          Description = L"Network controller";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_DISPLAY_CTLR:
+      switch (Device->PciConfig.SubClass)
+      {
+        case PCI_SUBCLASS_VID_VGA_CTLR:
+          Description = L"VGA display controller";
+          break;
+
+        case PCI_SUBCLASS_VID_XGA_CTLR:
+          Description = L"XGA display controller";
+          break;
+
+        case PCI_SUBLCASS_VID_3D_CTLR:
+          Description = L"Multimedia display controller";
+          break;
+
+        default:
+          Description = L"Other display controller";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_MULTIMEDIA_DEV:
+      switch (Device->PciConfig.SubClass)
+      {
+        case PCI_SUBCLASS_MM_VIDEO_DEV:
+          Description = L"Multimedia video device";
+          break;
+
+        case PCI_SUBCLASS_MM_AUDIO_DEV:
+          Description = L"Multimedia audio device";
+          break;
+
+        case PCI_SUBCLASS_MM_TELEPHONY_DEV:
+          Description = L"Multimedia telephony device";
+          break;
+
+        default:
+          Description = L"Other multimedia device";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_MEMORY_CTLR:
+      switch (Device->PciConfig.SubClass)
+      {
+        case PCI_SUBCLASS_MEM_RAM:
+          Description = L"PCI Memory";
+          break;
+
+        case PCI_SUBCLASS_MEM_FLASH:
+          Description = L"PCI Flash Memory";
+          break;
+
+        default:
+          Description = L"Other memory controller";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_BRIDGE_DEV:
+      switch (Device->PciConfig.SubClass)
+      {
+        case PCI_SUBCLASS_BR_HOST:
+          Description = L"PCI-Host bridge";
+          break;
+
+        case PCI_SUBCLASS_BR_ISA:
+          Description = L"PCI-ISA bridge";
+          break;
+
+        case PCI_SUBCLASS_BR_EISA:
+          Description = L"PCI-EISA bridge";
+          break;
+
+        case PCI_SUBCLASS_BR_MCA:
+          Description = L"PCI-Micro Channel bridge";
+          break;
+
+        case PCI_SUBCLASS_BR_PCI_TO_PCI:
+          Description = L"PCI-PCI bridge";
+          break;
+
+        case PCI_SUBCLASS_BR_PCMCIA:
+          Description = L"PCI-PCMCIA bridge";
+          break;
+
+        case PCI_SUBCLASS_BR_NUBUS:
+          Description = L"PCI-NUBUS bridge";
+          break;
+
+        case PCI_SUBCLASS_BR_CARDBUS:
+          Description = L"PCI-CARDBUS bridge";
+          break;
+
+        default:
+          Description = L"Other bridge device";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_SIMPLE_COMMS_CTLR:
+      switch (Device->PciConfig.SubClass)
+      {
+
+        default:
+          Description = L"Communication device";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_BASE_SYSTEM_DEV:
+      switch (Device->PciConfig.SubClass)
+      {
+
+        default:
+          Description = L"System device";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_INPUT_DEV:
+      switch (Device->PciConfig.SubClass)
+      {
+
+        default:
+          Description = L"Input device";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_DOCKING_STATION:
+      switch (Device->PciConfig.SubClass)
+      {
+
+        default:
+          Description = L"Docking station";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_PROCESSOR:
+      switch (Device->PciConfig.SubClass)
+      {
+
+        default:
+          Description = L"Processor";
+          break;
+      }
+      break;
+
+    case PCI_CLASS_SERIAL_BUS_CTLR:
+      switch (Device->PciConfig.SubClass)
+      {
+        case PCI_SUBCLASS_SB_IEEE1394:
+          Description = L"FireWire controller";
+          break;
+
+        case PCI_SUBCLASS_SB_ACCESS:
+          Description = L"ACCESS bus controller";
+          break;
+
+        case PCI_SUBCLASS_SB_SSA:
+          Description = L"SSA controller";
+          break;
+
+        case PCI_SUBCLASS_SB_USB:
+          Description = L"USB controller";
+          break;
+
+        case PCI_SUBCLASS_SB_FIBRE_CHANNEL:
+          Description = L"Fibre Channel controller";
+          break;
+
+        default:
+          Description = L"Other serial bus controller";
+          break;
+      }
+      break;
+
+    default:
+      Description = L"Other PCI Device";
+      break;
   }
 
-  RtlCopyMemory(Destination->Buffer, Source, Length);
+  return RtlCreateUnicodeString(DeviceDescription, Description) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
+}
+
 
-  Destination->MaximumLength = Length;
+NTSTATUS
+PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation,
+                              PPCI_DEVICE Device)
+{
+  WCHAR Buffer[256];
 
-  Destination->Length = Length - sizeof(WCHAR);
+  swprintf(Buffer,
+           L"PCI-Bus %lu, Device %u, Function %u",
+           Device->BusNumber,
+           Device->SlotNumber.u.bits.DeviceNumber,
+           Device->SlotNumber.u.bits.FunctionNumber);
 
-  return TRUE;
+  return RtlCreateUnicodeString(DeviceLocation, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
 }
 
 /* EOF */