1c2c66affSColin Finck /*
2c2c66affSColin Finck * PROJECT: ReactOS PCI Bus driver
3c2c66affSColin Finck * FILE: pci.c
4c2c66affSColin Finck * PURPOSE: Driver entry
5c2c66affSColin Finck * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
6c2c66affSColin Finck * UPDATE HISTORY:
7c2c66affSColin Finck * 10-09-2001 CSH Created
8c2c66affSColin Finck */
9c2c66affSColin Finck
10c2c66affSColin Finck #include "pci.h"
11c2c66affSColin Finck
12c2c66affSColin Finck #include <stdio.h>
13c2c66affSColin Finck
14c2c66affSColin Finck #define NDEBUG
15c2c66affSColin Finck #include <debug.h>
16c2c66affSColin Finck
17c2c66affSColin Finck static DRIVER_DISPATCH PciDispatchDeviceControl;
18c2c66affSColin Finck static NTSTATUS NTAPI PciDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
19c2c66affSColin Finck
20c2c66affSColin Finck static DRIVER_ADD_DEVICE PciAddDevice;
21c2c66affSColin Finck static NTSTATUS NTAPI PciAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject);
22c2c66affSColin Finck
23c2c66affSColin Finck static DRIVER_DISPATCH PciPowerControl;
24c2c66affSColin Finck static NTSTATUS NTAPI PciPowerControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
25c2c66affSColin Finck
26c2c66affSColin Finck static DRIVER_DISPATCH PciPnpControl;
27c2c66affSColin Finck static NTSTATUS NTAPI PciPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
28c2c66affSColin Finck
29c2c66affSColin Finck /*** PUBLIC ******************************************************************/
30c2c66affSColin Finck
31c2c66affSColin Finck PPCI_DRIVER_EXTENSION DriverExtension = NULL;
32*734cd5e8SDmitry Borisov BOOLEAN HasDebuggingDevice = FALSE;
33*734cd5e8SDmitry Borisov PCI_TYPE1_CFG_CYCLE_BITS PciDebuggingDevice[2] = {0};
34c2c66affSColin Finck
35c2c66affSColin Finck /*** PRIVATE *****************************************************************/
36c2c66affSColin Finck
37c2c66affSColin Finck static NTSTATUS
38c2c66affSColin Finck NTAPI
PciDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)39c2c66affSColin Finck PciDispatchDeviceControl(
40c2c66affSColin Finck IN PDEVICE_OBJECT DeviceObject,
41c2c66affSColin Finck IN PIRP Irp)
42c2c66affSColin Finck {
43c2c66affSColin Finck PIO_STACK_LOCATION IrpSp;
44c2c66affSColin Finck NTSTATUS Status;
45c2c66affSColin Finck
46c2c66affSColin Finck UNREFERENCED_PARAMETER(DeviceObject);
47c2c66affSColin Finck DPRINT("Called. IRP is at (0x%p)\n", Irp);
48c2c66affSColin Finck
49c2c66affSColin Finck Irp->IoStatus.Information = 0;
50c2c66affSColin Finck
51c2c66affSColin Finck IrpSp = IoGetCurrentIrpStackLocation(Irp);
52c2c66affSColin Finck switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
53c2c66affSColin Finck {
54c2c66affSColin Finck default:
55c2c66affSColin Finck DPRINT("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
56c2c66affSColin Finck Status = STATUS_NOT_IMPLEMENTED;
57c2c66affSColin Finck break;
58c2c66affSColin Finck }
59c2c66affSColin Finck
60c2c66affSColin Finck if (Status != STATUS_PENDING)
61c2c66affSColin Finck {
62c2c66affSColin Finck Irp->IoStatus.Status = Status;
63c2c66affSColin Finck
64c2c66affSColin Finck DPRINT("Completing IRP at 0x%p\n", Irp);
65c2c66affSColin Finck
66c2c66affSColin Finck IoCompleteRequest(Irp, IO_NO_INCREMENT);
67c2c66affSColin Finck }
68c2c66affSColin Finck
69c2c66affSColin Finck DPRINT("Leaving. Status 0x%X\n", Status);
70c2c66affSColin Finck
71c2c66affSColin Finck return Status;
72c2c66affSColin Finck }
73c2c66affSColin Finck
74c2c66affSColin Finck
75c2c66affSColin Finck static NTSTATUS
76c2c66affSColin Finck NTAPI
PciPnpControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)77c2c66affSColin Finck PciPnpControl(
78c2c66affSColin Finck IN PDEVICE_OBJECT DeviceObject,
79c2c66affSColin Finck IN PIRP Irp)
80c2c66affSColin Finck /*
81c2c66affSColin Finck * FUNCTION: Handle Plug and Play IRPs
82c2c66affSColin Finck * ARGUMENTS:
83c2c66affSColin Finck * DeviceObject = Pointer to PDO or FDO
84c2c66affSColin Finck * Irp = Pointer to IRP that should be handled
85c2c66affSColin Finck * RETURNS:
86c2c66affSColin Finck * Status
87c2c66affSColin Finck */
88c2c66affSColin Finck {
89c2c66affSColin Finck PCOMMON_DEVICE_EXTENSION DeviceExtension;
90c2c66affSColin Finck NTSTATUS Status;
91c2c66affSColin Finck
92c2c66affSColin Finck DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
93c2c66affSColin Finck
94c2c66affSColin Finck DPRINT("IsFDO %u\n", DeviceExtension->IsFDO);
95c2c66affSColin Finck
96c2c66affSColin Finck if (DeviceExtension->IsFDO)
97c2c66affSColin Finck {
98c2c66affSColin Finck Status = FdoPnpControl(DeviceObject, Irp);
99c2c66affSColin Finck }
100c2c66affSColin Finck else
101c2c66affSColin Finck {
102c2c66affSColin Finck Status = PdoPnpControl(DeviceObject, Irp);
103c2c66affSColin Finck }
104c2c66affSColin Finck
105c2c66affSColin Finck return Status;
106c2c66affSColin Finck }
107c2c66affSColin Finck
108c2c66affSColin Finck
109c2c66affSColin Finck static NTSTATUS
110c2c66affSColin Finck NTAPI
PciPowerControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)111c2c66affSColin Finck PciPowerControl(
112c2c66affSColin Finck IN PDEVICE_OBJECT DeviceObject,
113c2c66affSColin Finck IN PIRP Irp)
114c2c66affSColin Finck /*
115c2c66affSColin Finck * FUNCTION: Handle power management IRPs
116c2c66affSColin Finck * ARGUMENTS:
117c2c66affSColin Finck * DeviceObject = Pointer to PDO or FDO
118c2c66affSColin Finck * Irp = Pointer to IRP that should be handled
119c2c66affSColin Finck * RETURNS:
120c2c66affSColin Finck * Status
121c2c66affSColin Finck */
122c2c66affSColin Finck {
123c2c66affSColin Finck PCOMMON_DEVICE_EXTENSION DeviceExtension;
124c2c66affSColin Finck NTSTATUS Status;
125c2c66affSColin Finck
126c2c66affSColin Finck DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
127c2c66affSColin Finck
128c2c66affSColin Finck if (DeviceExtension->IsFDO)
129c2c66affSColin Finck {
130c2c66affSColin Finck Status = FdoPowerControl(DeviceObject, Irp);
131c2c66affSColin Finck }
132c2c66affSColin Finck else
133c2c66affSColin Finck {
134c2c66affSColin Finck Status = PdoPowerControl(DeviceObject, Irp);
135c2c66affSColin Finck }
136c2c66affSColin Finck
137c2c66affSColin Finck return Status;
138c2c66affSColin Finck }
139c2c66affSColin Finck
140c2c66affSColin Finck
141c2c66affSColin Finck static NTSTATUS
142c2c66affSColin Finck NTAPI
PciAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject)143c2c66affSColin Finck PciAddDevice(
144c2c66affSColin Finck IN PDRIVER_OBJECT DriverObject,
145c2c66affSColin Finck IN PDEVICE_OBJECT PhysicalDeviceObject)
146c2c66affSColin Finck {
147c2c66affSColin Finck PFDO_DEVICE_EXTENSION DeviceExtension;
148c2c66affSColin Finck PDEVICE_OBJECT Fdo;
149c2c66affSColin Finck NTSTATUS Status;
150c2c66affSColin Finck
151c2c66affSColin Finck DPRINT("Called\n");
152c2c66affSColin Finck if (PhysicalDeviceObject == NULL)
153c2c66affSColin Finck return STATUS_SUCCESS;
154c2c66affSColin Finck
155c2c66affSColin Finck Status = IoCreateDevice(DriverObject,
156c2c66affSColin Finck sizeof(FDO_DEVICE_EXTENSION),
157c2c66affSColin Finck NULL,
158c2c66affSColin Finck FILE_DEVICE_BUS_EXTENDER,
159c2c66affSColin Finck FILE_DEVICE_SECURE_OPEN,
160c2c66affSColin Finck TRUE,
161c2c66affSColin Finck &Fdo);
162c2c66affSColin Finck if (!NT_SUCCESS(Status))
163c2c66affSColin Finck {
164c2c66affSColin Finck DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
165c2c66affSColin Finck return Status;
166c2c66affSColin Finck }
167c2c66affSColin Finck
168c2c66affSColin Finck DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
169c2c66affSColin Finck
170c2c66affSColin Finck RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
171c2c66affSColin Finck
172c2c66affSColin Finck DeviceExtension->Common.IsFDO = TRUE;
173c2c66affSColin Finck
174c2c66affSColin Finck DeviceExtension->Ldo = IoAttachDeviceToDeviceStack(Fdo,
175c2c66affSColin Finck PhysicalDeviceObject);
176c2c66affSColin Finck
177c2c66affSColin Finck DeviceExtension->State = dsStopped;
178c2c66affSColin Finck
179c2c66affSColin Finck Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
180c2c66affSColin Finck
181c2c66affSColin Finck //Fdo->Flags |= DO_POWER_PAGABLE;
182c2c66affSColin Finck
183c2c66affSColin Finck DPRINT("Done AddDevice\n");
184c2c66affSColin Finck
185c2c66affSColin Finck return STATUS_SUCCESS;
186c2c66affSColin Finck }
187c2c66affSColin Finck
188c2c66affSColin Finck DRIVER_UNLOAD PciUnload;
189c2c66affSColin Finck
190c2c66affSColin Finck VOID
191c2c66affSColin Finck NTAPI
PciUnload(IN PDRIVER_OBJECT DriverObject)192c2c66affSColin Finck PciUnload(
193c2c66affSColin Finck IN PDRIVER_OBJECT DriverObject)
194c2c66affSColin Finck {
195c2c66affSColin Finck /* The driver object extension is destroyed by the I/O manager */
196c2c66affSColin Finck UNREFERENCED_PARAMETER(DriverObject);
197c2c66affSColin Finck }
198c2c66affSColin Finck
199*734cd5e8SDmitry Borisov static
200*734cd5e8SDmitry Borisov CODE_SEG("INIT")
201*734cd5e8SDmitry Borisov VOID
PciLocateKdDevices(VOID)202*734cd5e8SDmitry Borisov PciLocateKdDevices(VOID)
203*734cd5e8SDmitry Borisov {
204*734cd5e8SDmitry Borisov ULONG i;
205*734cd5e8SDmitry Borisov NTSTATUS Status;
206*734cd5e8SDmitry Borisov WCHAR KeyNameBuffer[16];
207*734cd5e8SDmitry Borisov ULONG BusNumber, SlotNumber;
208*734cd5e8SDmitry Borisov RTL_QUERY_REGISTRY_TABLE QueryTable[3];
209*734cd5e8SDmitry Borisov
210*734cd5e8SDmitry Borisov RtlZeroMemory(QueryTable, sizeof(QueryTable));
211*734cd5e8SDmitry Borisov QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
212*734cd5e8SDmitry Borisov QueryTable[0].Name = L"Bus";
213*734cd5e8SDmitry Borisov QueryTable[0].EntryContext = &BusNumber;
214*734cd5e8SDmitry Borisov QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
215*734cd5e8SDmitry Borisov QueryTable[1].Name = L"Slot";
216*734cd5e8SDmitry Borisov QueryTable[1].EntryContext = &SlotNumber;
217*734cd5e8SDmitry Borisov
218*734cd5e8SDmitry Borisov for (i = 0; i < RTL_NUMBER_OF(PciDebuggingDevice); ++i)
219*734cd5e8SDmitry Borisov {
220*734cd5e8SDmitry Borisov PCI_SLOT_NUMBER PciSlot;
221*734cd5e8SDmitry Borisov
222*734cd5e8SDmitry Borisov RtlStringCbPrintfW(KeyNameBuffer, sizeof(KeyNameBuffer), L"PCI\\Debug\\%d", i);
223*734cd5e8SDmitry Borisov
224*734cd5e8SDmitry Borisov Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
225*734cd5e8SDmitry Borisov KeyNameBuffer,
226*734cd5e8SDmitry Borisov QueryTable,
227*734cd5e8SDmitry Borisov NULL,
228*734cd5e8SDmitry Borisov NULL);
229*734cd5e8SDmitry Borisov if (!NT_SUCCESS(Status))
230*734cd5e8SDmitry Borisov return;
231*734cd5e8SDmitry Borisov
232*734cd5e8SDmitry Borisov HasDebuggingDevice = TRUE;
233*734cd5e8SDmitry Borisov
234*734cd5e8SDmitry Borisov PciSlot.u.AsULONG = SlotNumber;
235*734cd5e8SDmitry Borisov PciDebuggingDevice[i].DeviceNumber = PciSlot.u.bits.DeviceNumber;
236*734cd5e8SDmitry Borisov PciDebuggingDevice[i].FunctionNumber = PciSlot.u.bits.FunctionNumber;
237*734cd5e8SDmitry Borisov PciDebuggingDevice[i].BusNumber = BusNumber;
238*734cd5e8SDmitry Borisov PciDebuggingDevice[i].InUse = TRUE;
239*734cd5e8SDmitry Borisov
240*734cd5e8SDmitry Borisov DPRINT1("PCI debugging device %02x:%02x.%x\n",
241*734cd5e8SDmitry Borisov BusNumber,
242*734cd5e8SDmitry Borisov PciSlot.u.bits.DeviceNumber,
243*734cd5e8SDmitry Borisov PciSlot.u.bits.FunctionNumber);
244*734cd5e8SDmitry Borisov }
245*734cd5e8SDmitry Borisov }
246*734cd5e8SDmitry Borisov
2473adf4508SJérôme Gardou CODE_SEG("INIT")
248c2c66affSColin Finck NTSTATUS
249c2c66affSColin Finck NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)250c2c66affSColin Finck DriverEntry(
251c2c66affSColin Finck IN PDRIVER_OBJECT DriverObject,
252c2c66affSColin Finck IN PUNICODE_STRING RegistryPath)
253c2c66affSColin Finck {
254c2c66affSColin Finck NTSTATUS Status;
255c2c66affSColin Finck
256c2c66affSColin Finck UNREFERENCED_PARAMETER(RegistryPath);
257c2c66affSColin Finck DPRINT("Peripheral Component Interconnect Bus Driver\n");
258c2c66affSColin Finck
259c2c66affSColin Finck DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PciDispatchDeviceControl;
260c2c66affSColin Finck DriverObject->MajorFunction[IRP_MJ_PNP] = PciPnpControl;
261c2c66affSColin Finck DriverObject->MajorFunction[IRP_MJ_POWER] = PciPowerControl;
262c2c66affSColin Finck DriverObject->DriverExtension->AddDevice = PciAddDevice;
263c2c66affSColin Finck DriverObject->DriverUnload = PciUnload;
264c2c66affSColin Finck
265c2c66affSColin Finck Status = IoAllocateDriverObjectExtension(DriverObject,
266c2c66affSColin Finck DriverObject,
267c2c66affSColin Finck sizeof(PCI_DRIVER_EXTENSION),
268c2c66affSColin Finck (PVOID*)&DriverExtension);
269c2c66affSColin Finck if (!NT_SUCCESS(Status))
270c2c66affSColin Finck return Status;
271c2c66affSColin Finck
272c2c66affSColin Finck RtlZeroMemory(DriverExtension, sizeof(PCI_DRIVER_EXTENSION));
273c2c66affSColin Finck
274c2c66affSColin Finck InitializeListHead(&DriverExtension->BusListHead);
275c2c66affSColin Finck KeInitializeSpinLock(&DriverExtension->BusListLock);
276c2c66affSColin Finck
277*734cd5e8SDmitry Borisov PciLocateKdDevices();
278*734cd5e8SDmitry Borisov
279c2c66affSColin Finck return STATUS_SUCCESS;
280c2c66affSColin Finck }
281c2c66affSColin Finck
282c2c66affSColin Finck
283c2c66affSColin Finck NTSTATUS
PciCreateDeviceIDString(PUNICODE_STRING DeviceID,PPCI_DEVICE Device)284c2c66affSColin Finck PciCreateDeviceIDString(PUNICODE_STRING DeviceID,
285c2c66affSColin Finck PPCI_DEVICE Device)
286c2c66affSColin Finck {
287c2c66affSColin Finck WCHAR Buffer[256];
288c2c66affSColin Finck
289c2c66affSColin Finck swprintf(Buffer,
290c2c66affSColin Finck L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
291c2c66affSColin Finck Device->PciConfig.VendorID,
292c2c66affSColin Finck Device->PciConfig.DeviceID,
293c2c66affSColin Finck (Device->PciConfig.u.type0.SubSystemID << 16) +
294c2c66affSColin Finck Device->PciConfig.u.type0.SubVendorID,
295c2c66affSColin Finck Device->PciConfig.RevisionID);
296c2c66affSColin Finck
297c2c66affSColin Finck return RtlCreateUnicodeString(DeviceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
298c2c66affSColin Finck }
299c2c66affSColin Finck
300c2c66affSColin Finck
301c2c66affSColin Finck NTSTATUS
PciCreateInstanceIDString(PUNICODE_STRING InstanceID,PPCI_DEVICE Device)302c2c66affSColin Finck PciCreateInstanceIDString(PUNICODE_STRING InstanceID,
303c2c66affSColin Finck PPCI_DEVICE Device)
304c2c66affSColin Finck {
305c2c66affSColin Finck WCHAR Buffer[3];
306c2c66affSColin Finck
307c2c66affSColin Finck swprintf(Buffer, L"%02X", Device->SlotNumber.u.AsULONG & 0xff);
308c2c66affSColin Finck
309c2c66affSColin Finck return RtlCreateUnicodeString(InstanceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
310c2c66affSColin Finck }
311c2c66affSColin Finck
312c2c66affSColin Finck
313c2c66affSColin Finck NTSTATUS
PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs,PPCI_DEVICE Device)314c2c66affSColin Finck PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs,
315c2c66affSColin Finck PPCI_DEVICE Device)
316c2c66affSColin Finck {
317c2c66affSColin Finck WCHAR Buffer[256];
318c2c66affSColin Finck UNICODE_STRING BufferU;
319c2c66affSColin Finck ULONG Index;
320c2c66affSColin Finck
321c2c66affSColin Finck Index = 0;
322c2c66affSColin Finck Index += swprintf(&Buffer[Index],
323c2c66affSColin Finck L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
324c2c66affSColin Finck Device->PciConfig.VendorID,
325c2c66affSColin Finck Device->PciConfig.DeviceID,
326c2c66affSColin Finck (Device->PciConfig.u.type0.SubSystemID << 16) +
327c2c66affSColin Finck Device->PciConfig.u.type0.SubVendorID,
328c2c66affSColin Finck Device->PciConfig.RevisionID);
329c2c66affSColin Finck Index++;
330c2c66affSColin Finck
331c2c66affSColin Finck Index += swprintf(&Buffer[Index],
332c2c66affSColin Finck L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
333c2c66affSColin Finck Device->PciConfig.VendorID,
334c2c66affSColin Finck Device->PciConfig.DeviceID,
335c2c66affSColin Finck (Device->PciConfig.u.type0.SubSystemID << 16) +
336c2c66affSColin Finck Device->PciConfig.u.type0.SubVendorID);
337c2c66affSColin Finck Index++;
338c2c66affSColin Finck
339c2c66affSColin Finck Index += swprintf(&Buffer[Index],
340c2c66affSColin Finck L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
341c2c66affSColin Finck Device->PciConfig.VendorID,
342c2c66affSColin Finck Device->PciConfig.DeviceID,
343c2c66affSColin Finck Device->PciConfig.BaseClass,
344c2c66affSColin Finck Device->PciConfig.SubClass,
345c2c66affSColin Finck Device->PciConfig.ProgIf);
346c2c66affSColin Finck Index++;
347c2c66affSColin Finck
348c2c66affSColin Finck Index += swprintf(&Buffer[Index],
349c2c66affSColin Finck L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
350c2c66affSColin Finck Device->PciConfig.VendorID,
351c2c66affSColin Finck Device->PciConfig.DeviceID,
352c2c66affSColin Finck Device->PciConfig.BaseClass,
353c2c66affSColin Finck Device->PciConfig.SubClass);
354c2c66affSColin Finck Index++;
355c2c66affSColin Finck
356c2c66affSColin Finck Buffer[Index] = UNICODE_NULL;
357c2c66affSColin Finck
358c2c66affSColin Finck BufferU.Length = BufferU.MaximumLength = (USHORT) Index * sizeof(WCHAR);
359c2c66affSColin Finck BufferU.Buffer = Buffer;
360c2c66affSColin Finck
361c2c66affSColin Finck return PciDuplicateUnicodeString(0, &BufferU, HardwareIDs);
362c2c66affSColin Finck }
363c2c66affSColin Finck
364c2c66affSColin Finck
365c2c66affSColin Finck NTSTATUS
PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs,PPCI_DEVICE Device)366c2c66affSColin Finck PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs,
367c2c66affSColin Finck PPCI_DEVICE Device)
368c2c66affSColin Finck {
369c2c66affSColin Finck WCHAR Buffer[256];
370c2c66affSColin Finck UNICODE_STRING BufferU;
371c2c66affSColin Finck ULONG Index;
372c2c66affSColin Finck
373c2c66affSColin Finck Index = 0;
374c2c66affSColin Finck Index += swprintf(&Buffer[Index],
375c2c66affSColin Finck L"PCI\\VEN_%04X&DEV_%04X&REV_%02X",
376c2c66affSColin Finck Device->PciConfig.VendorID,
377c2c66affSColin Finck Device->PciConfig.DeviceID,
378c2c66affSColin Finck Device->PciConfig.RevisionID);
379c2c66affSColin Finck Index++;
380c2c66affSColin Finck
381c2c66affSColin Finck Index += swprintf(&Buffer[Index],
382c2c66affSColin Finck L"PCI\\VEN_%04X&DEV_%04X",
383c2c66affSColin Finck Device->PciConfig.VendorID,
384c2c66affSColin Finck Device->PciConfig.DeviceID);
385c2c66affSColin Finck Index++;
386c2c66affSColin Finck
387c2c66affSColin Finck Index += swprintf(&Buffer[Index],
388c2c66affSColin Finck L"PCI\\VEN_%04X&CC_%02X%02X%02X",
389c2c66affSColin Finck Device->PciConfig.VendorID,
390c2c66affSColin Finck Device->PciConfig.BaseClass,
391c2c66affSColin Finck Device->PciConfig.SubClass,
392c2c66affSColin Finck Device->PciConfig.ProgIf);
393c2c66affSColin Finck Index++;
394c2c66affSColin Finck
395c2c66affSColin Finck Index += swprintf(&Buffer[Index],
396c2c66affSColin Finck L"PCI\\VEN_%04X&CC_%02X%02X",
397c2c66affSColin Finck Device->PciConfig.VendorID,
398c2c66affSColin Finck Device->PciConfig.BaseClass,
399c2c66affSColin Finck Device->PciConfig.SubClass);
400c2c66affSColin Finck Index++;
401c2c66affSColin Finck
402c2c66affSColin Finck Index += swprintf(&Buffer[Index],
403c2c66affSColin Finck L"PCI\\VEN_%04X",
404c2c66affSColin Finck Device->PciConfig.VendorID);
405c2c66affSColin Finck Index++;
406c2c66affSColin Finck
407c2c66affSColin Finck Index += swprintf(&Buffer[Index],
408c2c66affSColin Finck L"PCI\\CC_%02X%02X%02X",
409c2c66affSColin Finck Device->PciConfig.BaseClass,
410c2c66affSColin Finck Device->PciConfig.SubClass,
411c2c66affSColin Finck Device->PciConfig.ProgIf);
412c2c66affSColin Finck Index++;
413c2c66affSColin Finck
414c2c66affSColin Finck Index += swprintf(&Buffer[Index],
415c2c66affSColin Finck L"PCI\\CC_%02X%02X",
416c2c66affSColin Finck Device->PciConfig.BaseClass,
417c2c66affSColin Finck Device->PciConfig.SubClass);
418c2c66affSColin Finck Index++;
419c2c66affSColin Finck
420c2c66affSColin Finck Buffer[Index] = UNICODE_NULL;
421c2c66affSColin Finck
422c2c66affSColin Finck BufferU.Length = BufferU.MaximumLength = (USHORT)Index * sizeof(WCHAR);
423c2c66affSColin Finck BufferU.Buffer = Buffer;
424c2c66affSColin Finck
425c2c66affSColin Finck return PciDuplicateUnicodeString(0, &BufferU, CompatibleIDs);
426c2c66affSColin Finck }
427c2c66affSColin Finck
428c2c66affSColin Finck
429c2c66affSColin Finck NTSTATUS
PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription,PPCI_DEVICE Device)430c2c66affSColin Finck PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription,
431c2c66affSColin Finck PPCI_DEVICE Device)
432c2c66affSColin Finck {
433c2c66affSColin Finck PCWSTR Description;
434c2c66affSColin Finck
435c2c66affSColin Finck switch (Device->PciConfig.BaseClass)
436c2c66affSColin Finck {
437c2c66affSColin Finck case PCI_CLASS_PRE_20:
438c2c66affSColin Finck switch (Device->PciConfig.SubClass)
439c2c66affSColin Finck {
440c2c66affSColin Finck case PCI_SUBCLASS_PRE_20_VGA:
441c2c66affSColin Finck Description = L"VGA device";
442c2c66affSColin Finck break;
443c2c66affSColin Finck
444c2c66affSColin Finck default:
445c2c66affSColin Finck case PCI_SUBCLASS_PRE_20_NON_VGA:
446c2c66affSColin Finck Description = L"PCI device";
447c2c66affSColin Finck break;
448c2c66affSColin Finck }
449c2c66affSColin Finck break;
450c2c66affSColin Finck
451c2c66affSColin Finck case PCI_CLASS_MASS_STORAGE_CTLR:
452c2c66affSColin Finck switch (Device->PciConfig.SubClass)
453c2c66affSColin Finck {
454c2c66affSColin Finck case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR:
455c2c66affSColin Finck Description = L"SCSI controller";
456c2c66affSColin Finck break;
457c2c66affSColin Finck
458c2c66affSColin Finck case PCI_SUBCLASS_MSC_IDE_CTLR:
459c2c66affSColin Finck Description = L"IDE controller";
460c2c66affSColin Finck break;
461c2c66affSColin Finck
462c2c66affSColin Finck case PCI_SUBCLASS_MSC_FLOPPY_CTLR:
463c2c66affSColin Finck Description = L"Floppy disk controller";
464c2c66affSColin Finck break;
465c2c66affSColin Finck
466c2c66affSColin Finck case PCI_SUBCLASS_MSC_IPI_CTLR:
467c2c66affSColin Finck Description = L"IPI controller";
468c2c66affSColin Finck break;
469c2c66affSColin Finck
470c2c66affSColin Finck case PCI_SUBCLASS_MSC_RAID_CTLR:
471c2c66affSColin Finck Description = L"RAID controller";
472c2c66affSColin Finck break;
473c2c66affSColin Finck
474c2c66affSColin Finck default:
475c2c66affSColin Finck Description = L"Mass storage controller";
476c2c66affSColin Finck break;
477c2c66affSColin Finck }
478c2c66affSColin Finck break;
479c2c66affSColin Finck
480c2c66affSColin Finck case PCI_CLASS_NETWORK_CTLR:
481c2c66affSColin Finck switch (Device->PciConfig.SubClass)
482c2c66affSColin Finck {
483c2c66affSColin Finck case PCI_SUBCLASS_NET_ETHERNET_CTLR:
484c2c66affSColin Finck Description = L"Ethernet controller";
485c2c66affSColin Finck break;
486c2c66affSColin Finck
487c2c66affSColin Finck case PCI_SUBCLASS_NET_TOKEN_RING_CTLR:
488c2c66affSColin Finck Description = L"Token-Ring controller";
489c2c66affSColin Finck break;
490c2c66affSColin Finck
491c2c66affSColin Finck case PCI_SUBCLASS_NET_FDDI_CTLR:
492c2c66affSColin Finck Description = L"FDDI controller";
493c2c66affSColin Finck break;
494c2c66affSColin Finck
495c2c66affSColin Finck case PCI_SUBCLASS_NET_ATM_CTLR:
496c2c66affSColin Finck Description = L"ATM controller";
497c2c66affSColin Finck break;
498c2c66affSColin Finck
499c2c66affSColin Finck default:
500c2c66affSColin Finck Description = L"Network controller";
501c2c66affSColin Finck break;
502c2c66affSColin Finck }
503c2c66affSColin Finck break;
504c2c66affSColin Finck
505c2c66affSColin Finck case PCI_CLASS_DISPLAY_CTLR:
506c2c66affSColin Finck switch (Device->PciConfig.SubClass)
507c2c66affSColin Finck {
508c2c66affSColin Finck case PCI_SUBCLASS_VID_VGA_CTLR:
509c2c66affSColin Finck Description = L"VGA display controller";
510c2c66affSColin Finck break;
511c2c66affSColin Finck
512c2c66affSColin Finck case PCI_SUBCLASS_VID_XGA_CTLR:
513c2c66affSColin Finck Description = L"XGA display controller";
514c2c66affSColin Finck break;
515c2c66affSColin Finck
516c2c66affSColin Finck case PCI_SUBCLASS_VID_3D_CTLR:
517c2c66affSColin Finck Description = L"Multimedia display controller";
518c2c66affSColin Finck break;
519c2c66affSColin Finck
520c2c66affSColin Finck default:
521c2c66affSColin Finck Description = L"Other display controller";
522c2c66affSColin Finck break;
523c2c66affSColin Finck }
524c2c66affSColin Finck break;
525c2c66affSColin Finck
526c2c66affSColin Finck case PCI_CLASS_MULTIMEDIA_DEV:
527c2c66affSColin Finck switch (Device->PciConfig.SubClass)
528c2c66affSColin Finck {
529c2c66affSColin Finck case PCI_SUBCLASS_MM_VIDEO_DEV:
530c2c66affSColin Finck Description = L"Multimedia video device";
531c2c66affSColin Finck break;
532c2c66affSColin Finck
533c2c66affSColin Finck case PCI_SUBCLASS_MM_AUDIO_DEV:
534c2c66affSColin Finck Description = L"Multimedia audio device";
535c2c66affSColin Finck break;
536c2c66affSColin Finck
537c2c66affSColin Finck case PCI_SUBCLASS_MM_TELEPHONY_DEV:
538c2c66affSColin Finck Description = L"Multimedia telephony device";
539c2c66affSColin Finck break;
540c2c66affSColin Finck
541c2c66affSColin Finck default:
542c2c66affSColin Finck Description = L"Other multimedia device";
543c2c66affSColin Finck break;
544c2c66affSColin Finck }
545c2c66affSColin Finck break;
546c2c66affSColin Finck
547c2c66affSColin Finck case PCI_CLASS_MEMORY_CTLR:
548c2c66affSColin Finck switch (Device->PciConfig.SubClass)
549c2c66affSColin Finck {
550c2c66affSColin Finck case PCI_SUBCLASS_MEM_RAM:
551c2c66affSColin Finck Description = L"PCI Memory";
552c2c66affSColin Finck break;
553c2c66affSColin Finck
554c2c66affSColin Finck case PCI_SUBCLASS_MEM_FLASH:
555c2c66affSColin Finck Description = L"PCI Flash Memory";
556c2c66affSColin Finck break;
557c2c66affSColin Finck
558c2c66affSColin Finck default:
559c2c66affSColin Finck Description = L"Other memory controller";
560c2c66affSColin Finck break;
561c2c66affSColin Finck }
562c2c66affSColin Finck break;
563c2c66affSColin Finck
564c2c66affSColin Finck case PCI_CLASS_BRIDGE_DEV:
565c2c66affSColin Finck switch (Device->PciConfig.SubClass)
566c2c66affSColin Finck {
567c2c66affSColin Finck case PCI_SUBCLASS_BR_HOST:
568c2c66affSColin Finck Description = L"PCI-Host bridge";
569c2c66affSColin Finck break;
570c2c66affSColin Finck
571c2c66affSColin Finck case PCI_SUBCLASS_BR_ISA:
572c2c66affSColin Finck Description = L"PCI-ISA bridge";
573c2c66affSColin Finck break;
574c2c66affSColin Finck
575c2c66affSColin Finck case PCI_SUBCLASS_BR_EISA:
576c2c66affSColin Finck Description = L"PCI-EISA bridge";
577c2c66affSColin Finck break;
578c2c66affSColin Finck
579c2c66affSColin Finck case PCI_SUBCLASS_BR_MCA:
580c2c66affSColin Finck Description = L"PCI-Micro Channel bridge";
581c2c66affSColin Finck break;
582c2c66affSColin Finck
583c2c66affSColin Finck case PCI_SUBCLASS_BR_PCI_TO_PCI:
584c2c66affSColin Finck Description = L"PCI-PCI bridge";
585c2c66affSColin Finck break;
586c2c66affSColin Finck
587c2c66affSColin Finck case PCI_SUBCLASS_BR_PCMCIA:
588c2c66affSColin Finck Description = L"PCI-PCMCIA bridge";
589c2c66affSColin Finck break;
590c2c66affSColin Finck
591c2c66affSColin Finck case PCI_SUBCLASS_BR_NUBUS:
592c2c66affSColin Finck Description = L"PCI-NUBUS bridge";
593c2c66affSColin Finck break;
594c2c66affSColin Finck
595c2c66affSColin Finck case PCI_SUBCLASS_BR_CARDBUS:
596c2c66affSColin Finck Description = L"PCI-CARDBUS bridge";
597c2c66affSColin Finck break;
598c2c66affSColin Finck
599c2c66affSColin Finck default:
600c2c66affSColin Finck Description = L"Other bridge device";
601c2c66affSColin Finck break;
602c2c66affSColin Finck }
603c2c66affSColin Finck break;
604c2c66affSColin Finck
605c2c66affSColin Finck case PCI_CLASS_SIMPLE_COMMS_CTLR:
606c2c66affSColin Finck switch (Device->PciConfig.SubClass)
607c2c66affSColin Finck {
608c2c66affSColin Finck
609c2c66affSColin Finck default:
610c2c66affSColin Finck Description = L"Communication device";
611c2c66affSColin Finck break;
612c2c66affSColin Finck }
613c2c66affSColin Finck break;
614c2c66affSColin Finck
615c2c66affSColin Finck case PCI_CLASS_BASE_SYSTEM_DEV:
616c2c66affSColin Finck switch (Device->PciConfig.SubClass)
617c2c66affSColin Finck {
618c2c66affSColin Finck
619c2c66affSColin Finck default:
620c2c66affSColin Finck Description = L"System device";
621c2c66affSColin Finck break;
622c2c66affSColin Finck }
623c2c66affSColin Finck break;
624c2c66affSColin Finck
625c2c66affSColin Finck case PCI_CLASS_INPUT_DEV:
626c2c66affSColin Finck switch (Device->PciConfig.SubClass)
627c2c66affSColin Finck {
628c2c66affSColin Finck
629c2c66affSColin Finck default:
630c2c66affSColin Finck Description = L"Input device";
631c2c66affSColin Finck break;
632c2c66affSColin Finck }
633c2c66affSColin Finck break;
634c2c66affSColin Finck
635c2c66affSColin Finck case PCI_CLASS_DOCKING_STATION:
636c2c66affSColin Finck switch (Device->PciConfig.SubClass)
637c2c66affSColin Finck {
638c2c66affSColin Finck
639c2c66affSColin Finck default:
640c2c66affSColin Finck Description = L"Docking station";
641c2c66affSColin Finck break;
642c2c66affSColin Finck }
643c2c66affSColin Finck break;
644c2c66affSColin Finck
645c2c66affSColin Finck case PCI_CLASS_PROCESSOR:
646c2c66affSColin Finck switch (Device->PciConfig.SubClass)
647c2c66affSColin Finck {
648c2c66affSColin Finck
649c2c66affSColin Finck default:
650c2c66affSColin Finck Description = L"Processor";
651c2c66affSColin Finck break;
652c2c66affSColin Finck }
653c2c66affSColin Finck break;
654c2c66affSColin Finck
655c2c66affSColin Finck case PCI_CLASS_SERIAL_BUS_CTLR:
656c2c66affSColin Finck switch (Device->PciConfig.SubClass)
657c2c66affSColin Finck {
658c2c66affSColin Finck case PCI_SUBCLASS_SB_IEEE1394:
659c2c66affSColin Finck Description = L"FireWire controller";
660c2c66affSColin Finck break;
661c2c66affSColin Finck
662c2c66affSColin Finck case PCI_SUBCLASS_SB_ACCESS:
663c2c66affSColin Finck Description = L"ACCESS bus controller";
664c2c66affSColin Finck break;
665c2c66affSColin Finck
666c2c66affSColin Finck case PCI_SUBCLASS_SB_SSA:
667c2c66affSColin Finck Description = L"SSA controller";
668c2c66affSColin Finck break;
669c2c66affSColin Finck
670c2c66affSColin Finck case PCI_SUBCLASS_SB_USB:
671c2c66affSColin Finck Description = L"USB controller";
672c2c66affSColin Finck break;
673c2c66affSColin Finck
674c2c66affSColin Finck case PCI_SUBCLASS_SB_FIBRE_CHANNEL:
675c2c66affSColin Finck Description = L"Fibre Channel controller";
676c2c66affSColin Finck break;
677c2c66affSColin Finck
678c2c66affSColin Finck case PCI_SUBCLASS_SB_SMBUS:
679c2c66affSColin Finck Description = L"SMBus controller";
680c2c66affSColin Finck break;
681c2c66affSColin Finck
682c2c66affSColin Finck default:
683c2c66affSColin Finck Description = L"Other serial bus controller";
684c2c66affSColin Finck break;
685c2c66affSColin Finck }
686c2c66affSColin Finck break;
687c2c66affSColin Finck
688c2c66affSColin Finck default:
689c2c66affSColin Finck Description = L"Other PCI Device";
690c2c66affSColin Finck break;
691c2c66affSColin Finck }
692c2c66affSColin Finck
693c2c66affSColin Finck return RtlCreateUnicodeString(DeviceDescription, Description) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
694c2c66affSColin Finck }
695c2c66affSColin Finck
696c2c66affSColin Finck
697c2c66affSColin Finck NTSTATUS
PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation,PPCI_DEVICE Device)698c2c66affSColin Finck PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation,
699c2c66affSColin Finck PPCI_DEVICE Device)
700c2c66affSColin Finck {
701c2c66affSColin Finck WCHAR Buffer[256];
702c2c66affSColin Finck
703c2c66affSColin Finck swprintf(Buffer,
704c2c66affSColin Finck L"PCI-Bus %lu, Device %u, Function %u",
705c2c66affSColin Finck Device->BusNumber,
706c2c66affSColin Finck Device->SlotNumber.u.bits.DeviceNumber,
707c2c66affSColin Finck Device->SlotNumber.u.bits.FunctionNumber);
708c2c66affSColin Finck
709c2c66affSColin Finck return RtlCreateUnicodeString(DeviceLocation, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
710c2c66affSColin Finck }
711c2c66affSColin Finck
712c2c66affSColin Finck NTSTATUS
PciDuplicateUnicodeString(IN ULONG Flags,IN PCUNICODE_STRING SourceString,OUT PUNICODE_STRING DestinationString)713c2c66affSColin Finck PciDuplicateUnicodeString(
714c2c66affSColin Finck IN ULONG Flags,
715c2c66affSColin Finck IN PCUNICODE_STRING SourceString,
716c2c66affSColin Finck OUT PUNICODE_STRING DestinationString)
717c2c66affSColin Finck {
718c2c66affSColin Finck if (SourceString == NULL ||
719c2c66affSColin Finck DestinationString == NULL ||
720c2c66affSColin Finck SourceString->Length > SourceString->MaximumLength ||
721c2c66affSColin Finck (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL) ||
722c2c66affSColin Finck Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING ||
723c2c66affSColin Finck Flags >= 4)
724c2c66affSColin Finck {
725c2c66affSColin Finck return STATUS_INVALID_PARAMETER;
726c2c66affSColin Finck }
727c2c66affSColin Finck
728c2c66affSColin Finck if ((SourceString->Length == 0) &&
729c2c66affSColin Finck (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
730c2c66affSColin Finck RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
731c2c66affSColin Finck {
732c2c66affSColin Finck DestinationString->Length = 0;
733c2c66affSColin Finck DestinationString->MaximumLength = 0;
734c2c66affSColin Finck DestinationString->Buffer = NULL;
735c2c66affSColin Finck }
736c2c66affSColin Finck else
737c2c66affSColin Finck {
738c2c66affSColin Finck USHORT DestMaxLength = SourceString->Length;
739c2c66affSColin Finck
740c2c66affSColin Finck if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
741c2c66affSColin Finck DestMaxLength += sizeof(UNICODE_NULL);
742c2c66affSColin Finck
743c2c66affSColin Finck DestinationString->Buffer = ExAllocatePoolWithTag(PagedPool, DestMaxLength, TAG_PCI);
744c2c66affSColin Finck if (DestinationString->Buffer == NULL)
745c2c66affSColin Finck return STATUS_NO_MEMORY;
746c2c66affSColin Finck
747c2c66affSColin Finck RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
748c2c66affSColin Finck DestinationString->Length = SourceString->Length;
749c2c66affSColin Finck DestinationString->MaximumLength = DestMaxLength;
750c2c66affSColin Finck
751c2c66affSColin Finck if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
752c2c66affSColin Finck DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
753c2c66affSColin Finck }
754c2c66affSColin Finck
755c2c66affSColin Finck return STATUS_SUCCESS;
756c2c66affSColin Finck }
757c2c66affSColin Finck
758c2c66affSColin Finck /* EOF */
759