432711f0533af11c510089735c49886640e23b72
[reactos.git] / reactos / drivers / bus / pci / pci.c
1 /*
2 * PROJECT: ReactOS PCI Bus driver
3 * FILE: pci.c
4 * PURPOSE: Driver entry
5 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
6 * UPDATE HISTORY:
7 * 10-09-2001 CSH Created
8 */
9
10 #include <ddk/ntddk.h>
11 #include <ddk/ntifs.h>
12 #include <stdio.h>
13
14 #include "pcidef.h"
15 #include "pci.h"
16
17 #define NDEBUG
18 #include <debug.h>
19
20
21 #ifdef ALLOC_PRAGMA
22
23 // Make the initialization routines discardable, so that they
24 // don't waste space
25
26 #pragma alloc_text(init, DriverEntry)
27
28 #endif /* ALLOC_PRAGMA */
29
30 /*** PUBLIC ******************************************************************/
31
32
33 /*** PRIVATE *****************************************************************/
34
35 static NTSTATUS
36 STDCALL
37 PciDispatchDeviceControl(
38 IN PDEVICE_OBJECT DeviceObject,
39 IN PIRP Irp)
40 {
41 PIO_STACK_LOCATION IrpSp;
42 NTSTATUS Status;
43
44 DPRINT("Called. IRP is at (0x%X)\n", Irp);
45
46 Irp->IoStatus.Information = 0;
47
48 IrpSp = IoGetCurrentIrpStackLocation(Irp);
49 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
50 default:
51 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
52 Status = STATUS_NOT_IMPLEMENTED;
53 break;
54 }
55
56 if (Status != STATUS_PENDING) {
57 Irp->IoStatus.Status = Status;
58
59 DPRINT("Completing IRP at 0x%X\n", Irp);
60
61 IoCompleteRequest(Irp, IO_NO_INCREMENT);
62 }
63
64 DPRINT("Leaving. Status 0x%X\n", Status);
65
66 return Status;
67 }
68
69
70 static NTSTATUS
71 STDCALL
72 PciPnpControl(
73 IN PDEVICE_OBJECT DeviceObject,
74 IN PIRP Irp)
75 /*
76 * FUNCTION: Handle Plug and Play IRPs
77 * ARGUMENTS:
78 * DeviceObject = Pointer to PDO or FDO
79 * Irp = Pointer to IRP that should be handled
80 * RETURNS:
81 * Status
82 */
83 {
84 PCOMMON_DEVICE_EXTENSION DeviceExtension;
85 NTSTATUS Status;
86
87 DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
88
89 DPRINT("IsFDO %d\n", DeviceExtension->IsFDO);
90
91 if (DeviceExtension->IsFDO) {
92 Status = FdoPnpControl(DeviceObject, Irp);
93 } else {
94 Status = PdoPnpControl(DeviceObject, Irp);
95 }
96
97 return Status;
98 }
99
100
101 static NTSTATUS
102 STDCALL
103 PciPowerControl(
104 IN PDEVICE_OBJECT DeviceObject,
105 IN PIRP Irp)
106 /*
107 * FUNCTION: Handle power management IRPs
108 * ARGUMENTS:
109 * DeviceObject = Pointer to PDO or FDO
110 * Irp = Pointer to IRP that should be handled
111 * RETURNS:
112 * Status
113 */
114 {
115 PCOMMON_DEVICE_EXTENSION DeviceExtension;
116 NTSTATUS Status;
117
118 DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
119
120 if (DeviceExtension->IsFDO) {
121 Status = FdoPowerControl(DeviceObject, Irp);
122 } else {
123 Status = PdoPowerControl(DeviceObject, Irp);
124 }
125
126 return Status;
127 }
128
129
130 static NTSTATUS
131 STDCALL
132 PciAddDevice(
133 IN PDRIVER_OBJECT DriverObject,
134 IN PDEVICE_OBJECT PhysicalDeviceObject)
135 {
136 PFDO_DEVICE_EXTENSION DeviceExtension;
137 PDEVICE_OBJECT Fdo;
138 NTSTATUS Status;
139
140 DPRINT("Called\n");
141
142 Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION),
143 NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo);
144 if (!NT_SUCCESS(Status)) {
145 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
146 return Status;
147 }
148
149 DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
150
151 RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
152
153 DeviceExtension->Common.IsFDO = TRUE;
154
155 DeviceExtension->Ldo =
156 IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject);
157
158 DeviceExtension->State = dsStopped;
159
160 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
161
162 //Fdo->Flags |= DO_POWER_PAGABLE;
163
164 DPRINT("Done AddDevice\n");
165
166 return STATUS_SUCCESS;
167 }
168
169
170 NTSTATUS
171 STDCALL
172 DriverEntry(
173 IN PDRIVER_OBJECT DriverObject,
174 IN PUNICODE_STRING RegistryPath)
175 {
176 DPRINT("Peripheral Component Interconnect Bus Driver\n");
177
178 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PciDispatchDeviceControl;
179 DriverObject->MajorFunction[IRP_MJ_PNP] = PciPnpControl;
180 DriverObject->MajorFunction[IRP_MJ_POWER] = PciPowerControl;
181 DriverObject->DriverExtension->AddDevice = PciAddDevice;
182
183 return STATUS_SUCCESS;
184 }
185
186
187 NTSTATUS
188 PciCreateDeviceIDString(PUNICODE_STRING DeviceID,
189 PPCI_DEVICE Device)
190 {
191 WCHAR Buffer[256];
192
193 swprintf(Buffer,
194 L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
195 Device->PciConfig.VendorID,
196 Device->PciConfig.DeviceID,
197 (Device->PciConfig.u.type0.SubSystemID << 16) +
198 Device->PciConfig.u.type0.SubVendorID,
199 Device->PciConfig.RevisionID);
200
201 return RtlCreateUnicodeString(DeviceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
202 }
203
204
205 NTSTATUS
206 PciCreateInstanceIDString(PUNICODE_STRING InstanceID,
207 PPCI_DEVICE Device)
208 {
209 WCHAR Buffer[32];
210 ULONG Index;
211
212 Index = 0;
213 if (((PPDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension)->PciDevice->BusNumber != 0)
214 {
215 /* FIXME: Copy InstanceID of parent PCI bus to Buffer */
216 // Index += swprintf(Buffer, ....);
217 }
218
219 swprintf(&Buffer[Index], L"%02X", Device->SlotNumber.u.AsULONG & 0xff);
220
221 return RtlCreateUnicodeString(InstanceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
222 }
223
224
225 NTSTATUS
226 PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs,
227 PPCI_DEVICE Device)
228 {
229 WCHAR Buffer[256];
230 UNICODE_STRING BufferU;
231 ULONG Index;
232
233 Index = 0;
234 Index += swprintf(&Buffer[Index],
235 L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
236 Device->PciConfig.VendorID,
237 Device->PciConfig.DeviceID,
238 (Device->PciConfig.u.type0.SubSystemID << 16) +
239 Device->PciConfig.u.type0.SubVendorID,
240 Device->PciConfig.RevisionID);
241 Index++;
242
243 Index += swprintf(&Buffer[Index],
244 L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
245 Device->PciConfig.VendorID,
246 Device->PciConfig.DeviceID,
247 (Device->PciConfig.u.type0.SubSystemID << 16) +
248 Device->PciConfig.u.type0.SubVendorID);
249 Index++;
250
251 Index += swprintf(&Buffer[Index],
252 L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
253 Device->PciConfig.VendorID,
254 Device->PciConfig.DeviceID,
255 Device->PciConfig.BaseClass,
256 Device->PciConfig.SubClass,
257 Device->PciConfig.ProgIf);
258 Index++;
259
260 Index += swprintf(&Buffer[Index],
261 L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
262 Device->PciConfig.VendorID,
263 Device->PciConfig.DeviceID,
264 Device->PciConfig.BaseClass,
265 Device->PciConfig.SubClass);
266 Index++;
267
268 Buffer[Index] = UNICODE_NULL;
269
270 BufferU.Length = BufferU.MaximumLength = Index * sizeof(WCHAR);
271 BufferU.Buffer = Buffer;
272
273 return RtlDuplicateUnicodeString(0, &BufferU, HardwareIDs);
274 }
275
276
277 NTSTATUS
278 PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs,
279 PPCI_DEVICE Device)
280 {
281 WCHAR Buffer[256];
282 UNICODE_STRING BufferU;
283 ULONG Index;
284
285 Index = 0;
286 Index += swprintf(&Buffer[Index],
287 L"PCI\\VEN_%04X&DEV_%04X&REV_%02X",
288 Device->PciConfig.VendorID,
289 Device->PciConfig.DeviceID,
290 Device->PciConfig.RevisionID);
291 Index++;
292
293 Index += swprintf(&Buffer[Index],
294 L"PCI\\VEN_%04X&DEV_%04X",
295 Device->PciConfig.VendorID,
296 Device->PciConfig.DeviceID);
297 Index++;
298
299 Index += swprintf(&Buffer[Index],
300 L"PCI\\VEN_%04X&CC_%02X%02X%02X",
301 Device->PciConfig.VendorID,
302 Device->PciConfig.BaseClass,
303 Device->PciConfig.SubClass,
304 Device->PciConfig.ProgIf);
305 Index++;
306
307 Index += swprintf(&Buffer[Index],
308 L"PCI\\VEN_%04X&CC_%02X%02X",
309 Device->PciConfig.VendorID,
310 Device->PciConfig.BaseClass,
311 Device->PciConfig.SubClass);
312 Index++;
313
314 Index += swprintf(&Buffer[Index],
315 L"PCI\\VEN_%04X",
316 Device->PciConfig.VendorID);
317 Index++;
318
319 Index += swprintf(&Buffer[Index],
320 L"PCI\\CC_%02X%02X%02X",
321 Device->PciConfig.BaseClass,
322 Device->PciConfig.SubClass,
323 Device->PciConfig.ProgIf);
324 Index++;
325
326 Index += swprintf(&Buffer[Index],
327 L"PCI\\CC_%02X%02X",
328 Device->PciConfig.BaseClass,
329 Device->PciConfig.SubClass);
330 Index++;
331
332 Buffer[Index] = UNICODE_NULL;
333
334 BufferU.Length = BufferU.MaximumLength = Index * sizeof(WCHAR);
335 BufferU.Buffer = Buffer;
336
337 return RtlDuplicateUnicodeString(0, &BufferU, CompatibleIDs);
338 }
339
340
341 NTSTATUS
342 PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription,
343 PPCI_DEVICE Device)
344 {
345 PCWSTR Description;
346
347 switch (Device->PciConfig.BaseClass)
348 {
349 case PCI_CLASS_PRE_20:
350 switch (Device->PciConfig.SubClass)
351 {
352 case PCI_SUBCLASS_PRE_20_VGA:
353 Description = L"VGA device";
354 break;
355
356 default:
357 case PCI_SUBCLASS_PRE_20_NON_VGA:
358 Description = L"PCI device";
359 break;
360 }
361 break;
362
363 case PCI_CLASS_MASS_STORAGE_CTLR:
364 switch (Device->PciConfig.SubClass)
365 {
366 case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR:
367 Description = L"SCSI controller";
368 break;
369
370 case PCI_SUBCLASS_MSC_IDE_CTLR:
371 Description = L"IDE controller";
372 break;
373
374 case PCI_SUBCLASS_MSC_FLOPPY_CTLR:
375 Description = L"Floppy disk controller";
376 break;
377
378 case PCI_SUBCLASS_MSC_IPI_CTLR:
379 Description = L"IPI controller";
380 break;
381
382 case PCI_SUBCLASS_MSC_RAID_CTLR:
383 Description = L"RAID controller";
384 break;
385
386 default:
387 Description = L"Mass storage controller";
388 break;
389 }
390 break;
391
392 case PCI_CLASS_NETWORK_CTLR:
393 switch (Device->PciConfig.SubClass)
394 {
395 case PCI_SUBCLASS_NET_ETHERNET_CTLR:
396 Description = L"Ethernet controller";
397 break;
398
399 case PCI_SUBCLASS_NET_TOKEN_RING_CTLR:
400 Description = L"Token-Ring controller";
401 break;
402
403 case PCI_SUBCLASS_NET_FDDI_CTLR:
404 Description = L"FDDI controller";
405 break;
406
407 case PCI_SUBCLASS_NET_ATM_CTLR:
408 Description = L"ATM controller";
409 break;
410
411 default:
412 Description = L"Network controller";
413 break;
414 }
415 break;
416
417 case PCI_CLASS_DISPLAY_CTLR:
418 switch (Device->PciConfig.SubClass)
419 {
420 case PCI_SUBCLASS_VID_VGA_CTLR:
421 Description = L"VGA display controller";
422 break;
423
424 case PCI_SUBCLASS_VID_XGA_CTLR:
425 Description = L"XGA display controller";
426 break;
427
428 case PCI_SUBLCASS_VID_3D_CTLR:
429 Description = L"Multimedia display controller";
430 break;
431
432 default:
433 Description = L"Other display controller";
434 break;
435 }
436 break;
437
438 case PCI_CLASS_MULTIMEDIA_DEV:
439 switch (Device->PciConfig.SubClass)
440 {
441 case PCI_SUBCLASS_MM_VIDEO_DEV:
442 Description = L"Multimedia video device";
443 break;
444
445 case PCI_SUBCLASS_MM_AUDIO_DEV:
446 Description = L"Multimedia audio device";
447 break;
448
449 case PCI_SUBCLASS_MM_TELEPHONY_DEV:
450 Description = L"Multimedia telephony device";
451 break;
452
453 default:
454 Description = L"Other multimedia device";
455 break;
456 }
457 break;
458
459 case PCI_CLASS_MEMORY_CTLR:
460 switch (Device->PciConfig.SubClass)
461 {
462 case PCI_SUBCLASS_MEM_RAM:
463 Description = L"PCI Memory";
464 break;
465
466 case PCI_SUBCLASS_MEM_FLASH:
467 Description = L"PCI Flash Memory";
468 break;
469
470 default:
471 Description = L"Other memory controller";
472 break;
473 }
474 break;
475
476 case PCI_CLASS_BRIDGE_DEV:
477 switch (Device->PciConfig.SubClass)
478 {
479 case PCI_SUBCLASS_BR_HOST:
480 Description = L"PCI-Host bridge";
481 break;
482
483 case PCI_SUBCLASS_BR_ISA:
484 Description = L"PCI-ISA bridge";
485 break;
486
487 case PCI_SUBCLASS_BR_EISA:
488 Description = L"PCI-EISA bridge";
489 break;
490
491 case PCI_SUBCLASS_BR_MCA:
492 Description = L"PCI-Micro Channel bridge";
493 break;
494
495 case PCI_SUBCLASS_BR_PCI_TO_PCI:
496 Description = L"PCI-PCI bridge";
497 break;
498
499 case PCI_SUBCLASS_BR_PCMCIA:
500 Description = L"PCI-PCMCIA bridge";
501 break;
502
503 case PCI_SUBCLASS_BR_NUBUS:
504 Description = L"PCI-NUBUS bridge";
505 break;
506
507 case PCI_SUBCLASS_BR_CARDBUS:
508 Description = L"PCI-CARDBUS bridge";
509 break;
510
511 default:
512 Description = L"Other bridge device";
513 break;
514 }
515 break;
516
517 case PCI_CLASS_SIMPLE_COMMS_CTLR:
518 switch (Device->PciConfig.SubClass)
519 {
520
521 default:
522 Description = L"Communication device";
523 break;
524 }
525 break;
526
527 case PCI_CLASS_BASE_SYSTEM_DEV:
528 switch (Device->PciConfig.SubClass)
529 {
530
531 default:
532 Description = L"System device";
533 break;
534 }
535 break;
536
537 case PCI_CLASS_INPUT_DEV:
538 switch (Device->PciConfig.SubClass)
539 {
540
541 default:
542 Description = L"Input device";
543 break;
544 }
545 break;
546
547 case PCI_CLASS_DOCKING_STATION:
548 switch (Device->PciConfig.SubClass)
549 {
550
551 default:
552 Description = L"Docking station";
553 break;
554 }
555 break;
556
557 case PCI_CLASS_PROCESSOR:
558 switch (Device->PciConfig.SubClass)
559 {
560
561 default:
562 Description = L"Processor";
563 break;
564 }
565 break;
566
567 case PCI_CLASS_SERIAL_BUS_CTLR:
568 switch (Device->PciConfig.SubClass)
569 {
570 case PCI_SUBCLASS_SB_IEEE1394:
571 Description = L"FireWire controller";
572 break;
573
574 case PCI_SUBCLASS_SB_ACCESS:
575 Description = L"ACCESS bus controller";
576 break;
577
578 case PCI_SUBCLASS_SB_SSA:
579 Description = L"SSA controller";
580 break;
581
582 case PCI_SUBCLASS_SB_USB:
583 Description = L"USB controller";
584 break;
585
586 case PCI_SUBCLASS_SB_FIBRE_CHANNEL:
587 Description = L"Fibre Channel controller";
588 break;
589
590 default:
591 Description = L"Other serial bus controller";
592 break;
593 }
594 break;
595
596 default:
597 Description = L"Other PCI Device";
598 break;
599 }
600
601 return RtlCreateUnicodeString(DeviceDescription, Description) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
602 }
603
604
605 NTSTATUS
606 PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation,
607 PPCI_DEVICE Device)
608 {
609 WCHAR Buffer[256];
610
611 swprintf(Buffer,
612 L"PCI-Bus %lu, Device %u, Function %u",
613 Device->BusNumber,
614 Device->SlotNumber.u.bits.DeviceNumber,
615 Device->SlotNumber.u.bits.FunctionNumber);
616
617 return RtlCreateUnicodeString(DeviceLocation, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
618 }
619
620 /* EOF */