Build Hardware IDs and Compatible IDs for PCI devices.
[reactos.git] / reactos / drivers / bus / pci / pdo.c
1 /* $Id: pdo.c,v 1.5 2004/06/09 14:22:53 ekohl Exp $
2 *
3 * PROJECT: ReactOS PCI bus driver
4 * FILE: pdo.c
5 * PURPOSE: Child device object dispatch routines
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 DEFINE_GUID(GUID_BUS_TYPE_PCI, 0xc8ebdfb0L, 0xb510, 0x11d0, 0x80, 0xe5, 0x00, 0xa0, 0xc9, 0x25, 0x42, 0xe3);
20
21 /*** PRIVATE *****************************************************************/
22
23 NTSTATUS
24 PdoQueryId(
25 IN PDEVICE_OBJECT DeviceObject,
26 IN PIRP Irp,
27 PIO_STACK_LOCATION IrpSp)
28 {
29 PPDO_DEVICE_EXTENSION DeviceExtension;
30 UNICODE_STRING String;
31 NTSTATUS Status;
32
33 DPRINT("Called\n");
34
35 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
36
37 // Irp->IoStatus.Information = 0;
38
39 Status = STATUS_SUCCESS;
40
41 RtlInitUnicodeString(&String, NULL);
42
43 switch (IrpSp->Parameters.QueryId.IdType) {
44 case BusQueryDeviceID:
45 Status = PciDuplicateUnicodeString(
46 &String,
47 &DeviceExtension->DeviceID,
48 PagedPool);
49
50 DPRINT("DeviceID: %S\n", String.Buffer);
51
52 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
53 break;
54
55 case BusQueryHardwareIDs:
56 Status = PciDuplicateUnicodeString(
57 &String,
58 &DeviceExtension->HardwareIDs,
59 PagedPool);
60
61 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
62 break;
63
64 case BusQueryCompatibleIDs:
65 Status = PciDuplicateUnicodeString(
66 &String,
67 &DeviceExtension->CompatibleIDs,
68 PagedPool);
69
70 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
71 break;
72
73 case BusQueryInstanceID:
74 Status = PciDuplicateUnicodeString(
75 &String,
76 &DeviceExtension->InstanceID,
77 PagedPool);
78
79 DPRINT("InstanceID: %S\n", String.Buffer);
80
81 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
82 break;
83
84 case BusQueryDeviceSerialNumber:
85 default:
86 Status = STATUS_NOT_IMPLEMENTED;
87 }
88
89 return Status;
90 }
91
92
93 NTSTATUS
94 PdoQueryBusInformation(
95 IN PDEVICE_OBJECT DeviceObject,
96 IN PIRP Irp,
97 PIO_STACK_LOCATION IrpSp)
98 {
99 PPDO_DEVICE_EXTENSION DeviceExtension;
100 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
101 PPNP_BUS_INFORMATION BusInformation;
102
103 DPRINT("Called\n");
104
105 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
106 FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->Fdo->DeviceExtension;
107 BusInformation = ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
108 Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
109 if (BusInformation != NULL)
110 {
111 BusInformation->BusTypeGuid = GUID_BUS_TYPE_PCI;
112 BusInformation->LegacyBusType = PCIBus;
113 BusInformation->BusNumber = DeviceExtension->BusNumber;
114
115 return STATUS_SUCCESS;
116 }
117
118 return STATUS_INSUFFICIENT_RESOURCES;
119 }
120
121
122 NTSTATUS
123 PdoQueryCapabilities(
124 IN PDEVICE_OBJECT DeviceObject,
125 IN PIRP Irp,
126 PIO_STACK_LOCATION IrpSp)
127 {
128 PPDO_DEVICE_EXTENSION DeviceExtension;
129 PDEVICE_CAPABILITIES DeviceCapabilities;
130
131 DPRINT("Called\n");
132
133 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
134 DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
135
136 DeviceCapabilities->Address =
137 DeviceCapabilities->UINumber = DeviceExtension->SlotNumber.u.AsULONG;
138
139 return STATUS_SUCCESS;
140 }
141
142
143 NTSTATUS
144 PdoSetPower(
145 IN PDEVICE_OBJECT DeviceObject,
146 IN PIRP Irp,
147 PIO_STACK_LOCATION IrpSp)
148 {
149 PPDO_DEVICE_EXTENSION DeviceExtension;
150 NTSTATUS Status;
151
152 DPRINT("Called\n");
153
154 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
155
156 if (IrpSp->Parameters.Power.Type == DevicePowerState) {
157 Status = STATUS_SUCCESS;
158 switch (IrpSp->Parameters.Power.State.SystemState) {
159 default:
160 Status = STATUS_UNSUCCESSFUL;
161 }
162 } else {
163 Status = STATUS_UNSUCCESSFUL;
164 }
165
166 return Status;
167 }
168
169
170 /*** PUBLIC ******************************************************************/
171
172 NTSTATUS
173 PdoPnpControl(
174 PDEVICE_OBJECT DeviceObject,
175 PIRP Irp)
176 /*
177 * FUNCTION: Handle Plug and Play IRPs for the child device
178 * ARGUMENTS:
179 * DeviceObject = Pointer to physical device object of the child device
180 * Irp = Pointer to IRP that should be handled
181 * RETURNS:
182 * Status
183 */
184 {
185 PIO_STACK_LOCATION IrpSp;
186 NTSTATUS Status;
187
188 DPRINT("Called\n");
189
190 Status = Irp->IoStatus.Status;
191
192 IrpSp = IoGetCurrentIrpStackLocation(Irp);
193
194 switch (IrpSp->MinorFunction) {
195 #if 0
196 case IRP_MN_CANCEL_REMOVE_DEVICE:
197 break;
198
199 case IRP_MN_CANCEL_STOP_DEVICE:
200 break;
201
202 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
203 break;
204
205 case IRP_MN_EJECT:
206 break;
207 #endif
208
209 case IRP_MN_QUERY_BUS_INFORMATION:
210 Status = PdoQueryBusInformation(DeviceObject, Irp, IrpSp);
211 break;
212
213 case IRP_MN_QUERY_CAPABILITIES:
214 Status = PdoQueryCapabilities(DeviceObject, Irp, IrpSp);
215 break;
216
217 #if 0
218 case IRP_MN_QUERY_DEVICE_RELATIONS:
219 /* FIXME: Possibly handle for RemovalRelations */
220 break;
221
222 case IRP_MN_QUERY_DEVICE_TEXT:
223 break;
224 #endif
225
226 case IRP_MN_QUERY_ID:
227 Status = PdoQueryId(DeviceObject, Irp, IrpSp);
228 break;
229
230 #if 0
231 case IRP_MN_QUERY_PNP_DEVICE_STATE:
232 break;
233
234 case IRP_MN_QUERY_REMOVE_DEVICE:
235 break;
236
237 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
238 break;
239
240 case IRP_MN_QUERY_RESOURCES:
241 break;
242
243 case IRP_MN_QUERY_STOP_DEVICE:
244 break;
245
246 case IRP_MN_REMOVE_DEVICE:
247 break;
248
249 case IRP_MN_SET_LOCK:
250 break;
251
252 case IRP_MN_START_DEVICE:
253 break;
254
255 case IRP_MN_STOP_DEVICE:
256 break;
257
258 case IRP_MN_SURPRISE_REMOVAL:
259 break;
260 #endif
261 default:
262 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
263 break;
264 }
265
266 if (Status != STATUS_PENDING) {
267 Irp->IoStatus.Status = Status;
268 IoCompleteRequest(Irp, IO_NO_INCREMENT);
269 }
270
271 DPRINT("Leaving. Status 0x%X\n", Status);
272
273 return Status;
274 }
275
276 NTSTATUS
277 PdoPowerControl(
278 PDEVICE_OBJECT DeviceObject,
279 PIRP Irp)
280 /*
281 * FUNCTION: Handle power management IRPs for the child device
282 * ARGUMENTS:
283 * DeviceObject = Pointer to physical device object of the child device
284 * Irp = Pointer to IRP that should be handled
285 * RETURNS:
286 * Status
287 */
288 {
289 PIO_STACK_LOCATION IrpSp;
290 NTSTATUS Status;
291
292 DPRINT("Called\n");
293
294 IrpSp = IoGetCurrentIrpStackLocation(Irp);
295
296 switch (IrpSp->MinorFunction) {
297 case IRP_MN_SET_POWER:
298 Status = PdoSetPower(DeviceObject, Irp, IrpSp);
299 break;
300
301 default:
302 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
303 Status = STATUS_NOT_IMPLEMENTED;
304 break;
305 }
306
307 if (Status != STATUS_PENDING) {
308 Irp->IoStatus.Status = Status;
309 IoCompleteRequest(Irp, IO_NO_INCREMENT);
310 }
311
312 DPRINT("Leaving. Status 0x%X\n", Status);
313
314 return Status;
315 }
316
317 /* EOF */