Build Hardware IDs and Compatible IDs for PCI devices.
[reactos.git] / reactos / drivers / bus / pci / pci.c
1 /* $Id: pci.c,v 1.7 2004/06/09 14:22:53 ekohl Exp $
2 *
3 * PROJECT: ReactOS PCI Bus driver
4 * FILE: pci.c
5 * PURPOSE: Driver entry
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * UPDATE HISTORY:
8 * 10-09-2001 CSH Created
9 */
10
11 #include <ddk/ntddk.h>
12
13 #include "pcidef.h"
14 #include "pci.h"
15
16 #define NDEBUG
17 #include <debug.h>
18
19
20 #ifdef ALLOC_PRAGMA
21
22 // Make the initialization routines discardable, so that they
23 // don't waste space
24
25 #pragma alloc_text(init, DriverEntry)
26
27 #endif /* ALLOC_PRAGMA */
28
29 /*** PUBLIC ******************************************************************/
30
31
32 /*** PRIVATE *****************************************************************/
33
34 NTSTATUS
35 STDCALL
36 PciDispatchDeviceControl(
37 IN PDEVICE_OBJECT DeviceObject,
38 IN PIRP Irp)
39 {
40 PIO_STACK_LOCATION IrpSp;
41 NTSTATUS Status;
42
43 DPRINT("Called. IRP is at (0x%X)\n", Irp);
44
45 Irp->IoStatus.Information = 0;
46
47 IrpSp = IoGetCurrentIrpStackLocation(Irp);
48 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
49 default:
50 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
51 Status = STATUS_NOT_IMPLEMENTED;
52 break;
53 }
54
55 if (Status != STATUS_PENDING) {
56 Irp->IoStatus.Status = Status;
57
58 DPRINT("Completing IRP at 0x%X\n", Irp);
59
60 IoCompleteRequest(Irp, IO_NO_INCREMENT);
61 }
62
63 DPRINT("Leaving. Status 0x%X\n", Status);
64
65 return Status;
66 }
67
68
69 NTSTATUS
70 STDCALL
71 PciPnpControl(
72 IN PDEVICE_OBJECT DeviceObject,
73 IN PIRP Irp)
74 /*
75 * FUNCTION: Handle Plug and Play IRPs
76 * ARGUMENTS:
77 * DeviceObject = Pointer to PDO or FDO
78 * Irp = Pointer to IRP that should be handled
79 * RETURNS:
80 * Status
81 */
82 {
83 PCOMMON_DEVICE_EXTENSION DeviceExtension;
84 NTSTATUS Status;
85
86 DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
87
88 DPRINT("IsFDO %d\n", DeviceExtension->IsFDO);
89
90 if (DeviceExtension->IsFDO) {
91 Status = FdoPnpControl(DeviceObject, Irp);
92 } else {
93 Status = PdoPnpControl(DeviceObject, Irp);
94 }
95
96 return Status;
97 }
98
99
100 NTSTATUS
101 STDCALL
102 PciPowerControl(
103 IN PDEVICE_OBJECT DeviceObject,
104 IN PIRP Irp)
105 /*
106 * FUNCTION: Handle power management IRPs
107 * ARGUMENTS:
108 * DeviceObject = Pointer to PDO or FDO
109 * Irp = Pointer to IRP that should be handled
110 * RETURNS:
111 * Status
112 */
113 {
114 PCOMMON_DEVICE_EXTENSION DeviceExtension;
115 NTSTATUS Status;
116
117 DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
118
119 if (DeviceExtension->IsFDO) {
120 Status = FdoPowerControl(DeviceObject, Irp);
121 } else {
122 Status = PdoPowerControl(DeviceObject, Irp);
123 }
124
125 return Status;
126 }
127
128
129 NTSTATUS
130 STDCALL
131 PciAddDevice(
132 IN PDRIVER_OBJECT DriverObject,
133 IN PDEVICE_OBJECT PhysicalDeviceObject)
134 {
135 PFDO_DEVICE_EXTENSION DeviceExtension;
136 PDEVICE_OBJECT Fdo;
137 NTSTATUS Status;
138
139 DPRINT("Called\n");
140
141 Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION),
142 NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo);
143 if (!NT_SUCCESS(Status)) {
144 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
145 return Status;
146 }
147
148 DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
149
150 RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
151
152 DeviceExtension->Common.IsFDO = TRUE;
153
154 DeviceExtension->Ldo =
155 IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject);
156
157 DeviceExtension->State = dsStopped;
158
159 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
160
161 //Fdo->Flags |= DO_POWER_PAGABLE;
162
163 DPRINT("Done AddDevice\n");
164
165 return STATUS_SUCCESS;
166 }
167
168
169 NTSTATUS
170 STDCALL
171 DriverEntry(
172 IN PDRIVER_OBJECT DriverObject,
173 IN PUNICODE_STRING RegistryPath)
174 {
175 DbgPrint("Peripheral Component Interconnect Bus Driver\n");
176
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;
181
182 return STATUS_SUCCESS;
183 }
184
185
186 BOOLEAN
187 PciCreateUnicodeString(
188 PUNICODE_STRING Destination,
189 PWSTR Source,
190 POOL_TYPE PoolType)
191 {
192 ULONG Length;
193
194 if (!Source)
195 {
196 RtlInitUnicodeString(Destination, NULL);
197 return TRUE;
198 }
199
200 Length = (wcslen(Source) + 1) * sizeof(WCHAR);
201
202 Destination->Buffer = ExAllocatePool(PoolType, Length);
203
204 if (Destination->Buffer == NULL)
205 {
206 return FALSE;
207 }
208
209 RtlCopyMemory(Destination->Buffer, Source, Length);
210
211 Destination->MaximumLength = Length;
212
213 Destination->Length = Length - sizeof(WCHAR);
214
215 return TRUE;
216 }
217
218
219 NTSTATUS
220 PciDuplicateUnicodeString(
221 PUNICODE_STRING Destination,
222 PUNICODE_STRING Source,
223 POOL_TYPE PoolType)
224 {
225 if (Source == NULL)
226 {
227 RtlInitUnicodeString(Destination, NULL);
228 return STATUS_SUCCESS;
229 }
230
231 Destination->Buffer = ExAllocatePool(PoolType, Source->MaximumLength);
232 if (Destination->Buffer == NULL)
233 {
234 return STATUS_INSUFFICIENT_RESOURCES;
235 }
236
237 Destination->MaximumLength = Source->MaximumLength;
238 Destination->Length = Source->Length;
239 RtlCopyMemory(Destination->Buffer, Source->Buffer, Source->MaximumLength);
240
241 return STATUS_SUCCESS;
242 }
243
244
245 BOOLEAN
246 PciCreateDeviceIDString(PUNICODE_STRING DeviceID,
247 PPCI_DEVICE Device)
248 {
249 WCHAR Buffer[256];
250
251 swprintf(Buffer,
252 L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
253 Device->PciConfig.VendorID,
254 Device->PciConfig.DeviceID,
255 (Device->PciConfig.u.type0.SubSystemID << 16) +
256 Device->PciConfig.u.type0.SubVendorID,
257 Device->PciConfig.RevisionID);
258
259 if (!PciCreateUnicodeString(DeviceID, Buffer, PagedPool))
260 {
261 return FALSE;
262 }
263
264 return TRUE;
265 }
266
267
268 BOOLEAN
269 PciCreateInstanceIDString(PUNICODE_STRING DeviceID,
270 PPCI_DEVICE Device)
271 {
272 /* FIXME */
273
274 #if 0
275 swprintf(Buffer,
276 L"%02lx&%04lx",
277 Device->BusNumber,
278 Device->SlotNumber.SlotNumber.u.AsULONG);
279 #endif
280
281 return PciCreateUnicodeString(DeviceID, L"0000", PagedPool);
282 }
283
284
285 BOOLEAN
286 PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs,
287 PPCI_DEVICE Device)
288 {
289 WCHAR Buffer[256];
290 ULONG Length;
291 ULONG Index;
292
293 Index = 0;
294 Index += swprintf(&Buffer[Index],
295 L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
296 Device->PciConfig.VendorID,
297 Device->PciConfig.DeviceID,
298 (Device->PciConfig.u.type0.SubSystemID << 16) +
299 Device->PciConfig.u.type0.SubVendorID,
300 Device->PciConfig.RevisionID);
301 Index++;
302
303 Index += swprintf(&Buffer[Index],
304 L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
305 Device->PciConfig.VendorID,
306 Device->PciConfig.DeviceID,
307 (Device->PciConfig.u.type0.SubSystemID << 16) +
308 Device->PciConfig.u.type0.SubVendorID);
309 Index++;
310
311 Buffer[Index] = UNICODE_NULL;
312
313 Length = (Index + 1) * sizeof(WCHAR);
314 HardwareIDs->Buffer = ExAllocatePool(PagedPool, Length);
315 if (Buffer == NULL)
316 {
317 return FALSE;
318 }
319
320 HardwareIDs->Length = Length - sizeof(WCHAR);
321 HardwareIDs->MaximumLength = Length;
322 RtlCopyMemory(HardwareIDs->Buffer, Buffer, Length);
323
324 return TRUE;
325 }
326
327
328 BOOLEAN
329 PciCreateCompatibleIDsString(PUNICODE_STRING HardwareIDs,
330 PPCI_DEVICE Device)
331 {
332 WCHAR Buffer[256];
333 ULONG Length;
334 ULONG Index;
335
336 Index = 0;
337 Index += swprintf(&Buffer[Index],
338 L"PCI\\VEN_%04X&DEV_%04X&REV_%02X&CC_%02X%02X",
339 Device->PciConfig.VendorID,
340 Device->PciConfig.DeviceID,
341 Device->PciConfig.RevisionID,
342 Device->PciConfig.BaseClass,
343 Device->PciConfig.SubClass);
344 Index++;
345
346 Index += swprintf(&Buffer[Index],
347 L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
348 Device->PciConfig.VendorID,
349 Device->PciConfig.DeviceID,
350 Device->PciConfig.BaseClass,
351 Device->PciConfig.SubClass,
352 Device->PciConfig.ProgIf);
353 Index++;
354
355 Index += swprintf(&Buffer[Index],
356 L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
357 Device->PciConfig.VendorID,
358 Device->PciConfig.DeviceID,
359 Device->PciConfig.BaseClass,
360 Device->PciConfig.SubClass);
361 Index++;
362
363 Index += swprintf(&Buffer[Index],
364 L"PCI\\VEN_%04X&CC_%02X%02X%02X",
365 Device->PciConfig.VendorID,
366 Device->PciConfig.BaseClass,
367 Device->PciConfig.SubClass,
368 Device->PciConfig.ProgIf);
369 Index++;
370
371 Index += swprintf(&Buffer[Index],
372 L"PCI\\VEN_%04X&CC_%02X%02X",
373 Device->PciConfig.VendorID,
374 Device->PciConfig.BaseClass,
375 Device->PciConfig.SubClass);
376 Index++;
377
378 Index += swprintf(&Buffer[Index],
379 L"PCI\\VEN_%04X",
380 Device->PciConfig.VendorID);
381 Index++;
382
383 Index += swprintf(&Buffer[Index],
384 L"PCI\\CC_%02X%02X%02X",
385 Device->PciConfig.BaseClass,
386 Device->PciConfig.SubClass,
387 Device->PciConfig.ProgIf);
388 Index++;
389
390 Index += swprintf(&Buffer[Index],
391 L"PCI\\CC_%02X%02X",
392 Device->PciConfig.BaseClass,
393 Device->PciConfig.SubClass);
394 Index++;
395
396 Buffer[Index] = UNICODE_NULL;
397
398 Length = (Index + 1) * sizeof(WCHAR);
399 HardwareIDs->Buffer = ExAllocatePool(PagedPool, Length);
400 if (Buffer == NULL)
401 {
402 return FALSE;
403 }
404
405 HardwareIDs->Length = Length - sizeof(WCHAR);
406 HardwareIDs->MaximumLength = Length;
407 RtlCopyMemory(HardwareIDs->Buffer, Buffer, Length);
408
409 return TRUE;
410 }
411
412 /* EOF */