-/* $Id: pci.c,v 1.1 2001/09/16 13:18:24 chorns Exp $
+/* $Id: pci.c,v 1.7 2004/06/09 14:22:53 ekohl Exp $
*
* PROJECT: ReactOS PCI Bus driver
* FILE: pci.c
* UPDATE HISTORY:
* 10-09-2001 CSH Created
*/
-#include <pci.h>
+
+#include <ddk/ntddk.h>
+
+#include "pcidef.h"
+#include "pci.h"
#define NDEBUG
#include <debug.h>
/*** PUBLIC ******************************************************************/
-PCI_BUS_TYPE PciBusConfigType = pbtUnknown;
-
/*** PRIVATE *****************************************************************/
-static NTSTATUS
-PciReadConfigUchar(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- PUCHAR Value)
-{
- switch (PciBusConfigType)
- {
- case pbtType1:
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- *Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3));
- return STATUS_SUCCESS;
-
- case pbtType2:
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- *Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset)));
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS
-PciReadConfigUshort(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- PUSHORT Value)
-{
- if ((Offset & 1) != 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- switch (PciBusConfigType)
- {
- case pbtType1:
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 1));
- return STATUS_SUCCESS;
-
- case pbtType2:
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- *Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)));
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS
-PciReadConfigUlong(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- PULONG Value)
-{
- if ((Offset & 3) != 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- switch (PciBusConfigType)
- {
- case pbtType1:
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- *Value = READ_PORT_ULONG((PULONG)0xCFC);
- return STATUS_SUCCESS;
-
- case pbtType2:
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- *Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)));
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS
-PciWriteConfigUchar(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- UCHAR Value)
-{
- switch (PciBusConfigType)
- {
- case pbtType1:
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value);
- return STATUS_SUCCESS;
-
- case pbtType2:
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS
-PciWriteConfigUshort(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- USHORT Value)
-{
- if ((Offset & 1) != 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- switch (PciBusConfigType)
- {
- case pbtType1:
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 1), Value);
- return STATUS_SUCCESS;
-
- case pbtType2:
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS
-PciWriteConfigUlong(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- ULONG Value)
-{
- if ((Offset & 3) != 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- switch (PciBusConfigType)
- {
- case pbtType1:
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- WRITE_PORT_ULONG((PULONG)0xCFC, Value);
- return STATUS_SUCCESS;
-
- case pbtType2:
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-ULONG
-PciGetBusData(ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Offset,
- ULONG Length)
-{
- PVOID Ptr = Buffer;
- ULONG Address = Offset;
- ULONG Len = Length;
- ULONG Vendor;
- UCHAR HeaderType;
-
-#if 0
- DPRINT(" BusNumber %lu\n", BusNumber);
- DPRINT(" SlotNumber %lu\n", SlotNumber);
- DPRINT(" Offset 0x%lx\n", Offset);
- DPRINT(" Length 0x%lx\n", Length);
-#endif
-
- if ((Length == 0) || (PciBusConfigType == 0))
- return 0;
-
- /* 0E=PCI_HEADER_TYPE */
- PciReadConfigUchar(BusNumber,
- SlotNumber & 0xF8,
- 0x0E,
- &HeaderType);
- if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0))
- return 0;
-
- PciReadConfigUlong(BusNumber,
- SlotNumber,
- 0x00,
- &Vendor);
- /* some broken boards return 0 if a slot is empty: */
- if (Vendor == 0xFFFFFFFF || Vendor == 0)
- return 0;
-
- if ((Address & 1) && (Len >= 1))
- {
- PciReadConfigUchar(BusNumber,
- SlotNumber,
- Address,
- Ptr);
- Ptr = Ptr + 1;
- Address++;
- Len--;
- }
-
- if ((Address & 2) && (Len >= 2))
- {
- PciReadConfigUshort(BusNumber,
- SlotNumber,
- Address,
- Ptr);
- Ptr = Ptr + 2;
- Address += 2;
- Len -= 2;
- }
-
- while (Len >= 4)
- {
- PciReadConfigUlong(BusNumber,
- SlotNumber,
- Address,
- Ptr);
- Ptr = Ptr + 4;
- Address += 4;
- Len -= 4;
- }
-
- if (Len >= 2)
- {
- PciReadConfigUshort(BusNumber,
- SlotNumber,
- Address,
- Ptr);
- Ptr = Ptr + 2;
- Address += 2;
- Len -= 2;
- }
-
- if (Len >= 1)
- {
- PciReadConfigUchar(BusNumber,
- SlotNumber,
- Address,
- Ptr);
- Ptr = Ptr + 1;
- Address++;
- Len--;
- }
-
- return Length - Len;
-}
-
-
-ULONG
-PciSetBusData(ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Offset,
- ULONG Length)
-{
- PVOID Ptr = Buffer;
- ULONG Address = Offset;
- ULONG Len = Length;
- ULONG Vendor;
- UCHAR HeaderType;
-
-#if 0
- DPRINT(" BusNumber %lu\n", BusNumber);
- DPRINT(" SlotNumber %lu\n", SlotNumber);
- DPRINT(" Offset 0x%lx\n", Offset);
- DPRINT(" Length 0x%lx\n", Length);
-#endif
-
- if ((Length == 0) || (PciBusConfigType == 0))
- return 0;
-
- /* 0E=PCI_HEADER_TYPE */
- PciReadConfigUchar(BusNumber,
- SlotNumber & 0xF8,
- 0x0E,
- &HeaderType);
- if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0))
- return 0;
-
- PciReadConfigUlong(BusNumber,
- SlotNumber,
- 0x00,
- &Vendor);
- /* some broken boards return 0 if a slot is empty: */
- if (Vendor == 0xFFFFFFFF || Vendor == 0)
- return 0;
-
- if ((Address & 1) && (Len >= 1))
- {
- PciWriteConfigUchar(BusNumber,
- SlotNumber,
- Address,
- *(PUCHAR)Ptr);
- Ptr = Ptr + 1;
- Address++;
- Len--;
- }
-
- if ((Address & 2) && (Len >= 2))
- {
- PciWriteConfigUshort(BusNumber,
- SlotNumber,
- Address,
- *(PUSHORT)Ptr);
- Ptr = Ptr + 2;
- Address += 2;
- Len -= 2;
- }
-
- while (Len >= 4)
- {
- PciWriteConfigUlong(BusNumber,
- SlotNumber,
- Address,
- *(PULONG)Ptr);
- Ptr = Ptr + 4;
- Address += 4;
- Len -= 4;
- }
-
- if (Len >= 2)
- {
- PciWriteConfigUshort(BusNumber,
- SlotNumber,
- Address,
- *(PUSHORT)Ptr);
- Ptr = Ptr + 2;
- Address += 2;
- Len -= 2;
- }
-
- if (Len >= 1)
- {
- PciWriteConfigUchar(BusNumber,
- SlotNumber,
- Address,
- *(PUCHAR)Ptr);
- Ptr = Ptr + 1;
- Address++;
- Len--;
- }
-
- return Length - Len;
-}
-
-
-PCI_BUS_TYPE
-PciGetBusConfigType(VOID)
-{
- ULONG Value;
-
- DPRINT("Called\n");
-
- DPRINT("Checking configuration type 1:\n");
- WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01);
- Value = READ_PORT_ULONG((PULONG)0xCF8);
- WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000);
- if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000)
- {
- WRITE_PORT_ULONG((PULONG)0xCF8, Value);
- DPRINT(" Success!\n");
- return pbtType1;
- }
- WRITE_PORT_ULONG((PULONG)0xCF8, Value);
- DPRINT(" Unsuccessful!\n");
-
- DPRINT("Checking configuration type 2:\n");
- WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00);
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00);
- if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 &&
- READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00)
- {
- DPRINT(" Success!\n");
- return pbtType2;
- }
- DPRINT(" Unsuccessful!\n");
-
- DPRINT("No pci bus found!\n");
- return pbtUnknown;
-}
-
-
NTSTATUS
STDCALL
PciDispatchDeviceControl(
RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
- DeviceExtension->IsFDO = TRUE;
+ DeviceExtension->Common.IsFDO = TRUE;
DeviceExtension->Ldo =
IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject);
BOOLEAN
PciCreateUnicodeString(
- PUNICODE_STRING Destination,
+ PUNICODE_STRING Destination,
PWSTR Source,
POOL_TYPE PoolType)
{
return TRUE;
}
+
+NTSTATUS
+PciDuplicateUnicodeString(
+ PUNICODE_STRING Destination,
+ PUNICODE_STRING Source,
+ POOL_TYPE PoolType)
+{
+ if (Source == NULL)
+ {
+ RtlInitUnicodeString(Destination, NULL);
+ return STATUS_SUCCESS;
+ }
+
+ Destination->Buffer = ExAllocatePool(PoolType, Source->MaximumLength);
+ if (Destination->Buffer == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Destination->MaximumLength = Source->MaximumLength;
+ Destination->Length = Source->Length;
+ RtlCopyMemory(Destination->Buffer, Source->Buffer, Source->MaximumLength);
+
+ return STATUS_SUCCESS;
+}
+
+
+BOOLEAN
+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);
+
+ if (!PciCreateUnicodeString(DeviceID, Buffer, PagedPool))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN
+PciCreateInstanceIDString(PUNICODE_STRING DeviceID,
+ PPCI_DEVICE Device)
+{
+ /* FIXME */
+
+#if 0
+ swprintf(Buffer,
+ L"%02lx&%04lx",
+ Device->BusNumber,
+ Device->SlotNumber.SlotNumber.u.AsULONG);
+#endif
+
+ return PciCreateUnicodeString(DeviceID, L"0000", PagedPool);
+}
+
+
+BOOLEAN
+PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs,
+ PPCI_DEVICE Device)
+{
+ WCHAR Buffer[256];
+ ULONG Length;
+ 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++;
+
+ Buffer[Index] = UNICODE_NULL;
+
+ Length = (Index + 1) * sizeof(WCHAR);
+ HardwareIDs->Buffer = ExAllocatePool(PagedPool, Length);
+ if (Buffer == NULL)
+ {
+ return FALSE;
+ }
+
+ HardwareIDs->Length = Length - sizeof(WCHAR);
+ HardwareIDs->MaximumLength = Length;
+ RtlCopyMemory(HardwareIDs->Buffer, Buffer, Length);
+
+ return TRUE;
+}
+
+
+BOOLEAN
+PciCreateCompatibleIDsString(PUNICODE_STRING HardwareIDs,
+ PPCI_DEVICE Device)
+{
+ WCHAR Buffer[256];
+ ULONG Length;
+ ULONG Index;
+
+ Index = 0;
+ Index += swprintf(&Buffer[Index],
+ L"PCI\\VEN_%04X&DEV_%04X&REV_%02X&CC_%02X%02X",
+ Device->PciConfig.VendorID,
+ Device->PciConfig.DeviceID,
+ Device->PciConfig.RevisionID,
+ Device->PciConfig.BaseClass,
+ Device->PciConfig.SubClass);
+ 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++;
+
+ 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;
+
+ Length = (Index + 1) * sizeof(WCHAR);
+ HardwareIDs->Buffer = ExAllocatePool(PagedPool, Length);
+ if (Buffer == NULL)
+ {
+ return FALSE;
+ }
+
+ HardwareIDs->Length = Length - sizeof(WCHAR);
+ HardwareIDs->MaximumLength = Length;
+ RtlCopyMemory(HardwareIDs->Buffer, Buffer, Length);
+
+ return TRUE;
+}
+
/* EOF */