- Support for IRP_MN_QUERY_BUS_INFORMATION and devices on multiple PCI buses.
[reactos.git] / reactos / drivers / bus / pci / pdo.c
1 /* $Id: pdo.c,v 1.3 2004/03/12 19:40:05 navaraf 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 = PciCreateUnicodeString(
46 &String,
47 DeviceExtension->DeviceID.Buffer,
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 case BusQueryCompatibleIDs:
57 Status = STATUS_NOT_IMPLEMENTED;
58 break;
59
60 case BusQueryInstanceID:
61 Status = PciCreateUnicodeString(
62 &String,
63 L"0000",
64 PagedPool);
65
66 DPRINT("InstanceID: %S\n", String.Buffer);
67
68 Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
69 break;
70
71 case BusQueryDeviceSerialNumber:
72 default:
73 Status = STATUS_NOT_IMPLEMENTED;
74 }
75
76 return Status;
77 }
78
79
80 NTSTATUS
81 PdoQueryBusInformation(
82 IN PDEVICE_OBJECT DeviceObject,
83 IN PIRP Irp,
84 PIO_STACK_LOCATION IrpSp)
85 {
86 PPDO_DEVICE_EXTENSION DeviceExtension;
87 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
88 PPNP_BUS_INFORMATION BusInformation;
89
90 DPRINT("Called\n");
91
92 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
93 FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->Fdo->DeviceExtension;
94 BusInformation = ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
95 Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
96 if (BusInformation != NULL)
97 {
98 BusInformation->BusTypeGuid = GUID_BUS_TYPE_PCI;
99 BusInformation->LegacyBusType = PCIBus;
100 BusInformation->BusNumber = DeviceExtension->BusNumber;
101
102 return STATUS_INSUFFICIENT_RESOURCES;
103 }
104
105 return STATUS_SUCCESS;
106 }
107
108
109 NTSTATUS
110 PdoSetPower(
111 IN PDEVICE_OBJECT DeviceObject,
112 IN PIRP Irp,
113 PIO_STACK_LOCATION IrpSp)
114 {
115 PPDO_DEVICE_EXTENSION DeviceExtension;
116 NTSTATUS Status;
117
118 DPRINT("Called\n");
119
120 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
121
122 if (IrpSp->Parameters.Power.Type == DevicePowerState) {
123 Status = STATUS_SUCCESS;
124 switch (IrpSp->Parameters.Power.State.SystemState) {
125 default:
126 Status = STATUS_UNSUCCESSFUL;
127 }
128 } else {
129 Status = STATUS_UNSUCCESSFUL;
130 }
131
132 return Status;
133 }
134
135
136 /*** PUBLIC ******************************************************************/
137
138 NTSTATUS
139 PdoPnpControl(
140 PDEVICE_OBJECT DeviceObject,
141 PIRP Irp)
142 /*
143 * FUNCTION: Handle Plug and Play IRPs for the child device
144 * ARGUMENTS:
145 * DeviceObject = Pointer to physical device object of the child device
146 * Irp = Pointer to IRP that should be handled
147 * RETURNS:
148 * Status
149 */
150 {
151 PIO_STACK_LOCATION IrpSp;
152 NTSTATUS Status;
153
154 DPRINT("Called\n");
155
156 Status = Irp->IoStatus.Status;
157
158 IrpSp = IoGetCurrentIrpStackLocation(Irp);
159
160 switch (IrpSp->MinorFunction) {
161 #if 0
162 case IRP_MN_CANCEL_REMOVE_DEVICE:
163 break;
164
165 case IRP_MN_CANCEL_STOP_DEVICE:
166 break;
167
168 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
169 break;
170
171 case IRP_MN_EJECT:
172 break;
173 #endif
174
175 case IRP_MN_QUERY_BUS_INFORMATION:
176 Status = PdoQueryBusInformation(DeviceObject, Irp, IrpSp);
177 break;
178
179 #if 0
180 case IRP_MN_QUERY_CAPABILITIES:
181 break;
182
183 case IRP_MN_QUERY_DEVICE_RELATIONS:
184 /* FIXME: Possibly handle for RemovalRelations */
185 break;
186
187 case IRP_MN_QUERY_DEVICE_TEXT:
188 break;
189 #endif
190 case IRP_MN_QUERY_ID:
191 Status = PdoQueryId(DeviceObject, Irp, IrpSp);
192 break;
193 #if 0
194 case IRP_MN_QUERY_PNP_DEVICE_STATE:
195 break;
196
197 case IRP_MN_QUERY_REMOVE_DEVICE:
198 break;
199
200 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
201 break;
202
203 case IRP_MN_QUERY_RESOURCES:
204 break;
205
206 case IRP_MN_QUERY_STOP_DEVICE:
207 break;
208
209 case IRP_MN_REMOVE_DEVICE:
210 break;
211
212 case IRP_MN_SET_LOCK:
213 break;
214
215 case IRP_MN_START_DEVICE:
216 break;
217
218 case IRP_MN_STOP_DEVICE:
219 break;
220
221 case IRP_MN_SURPRISE_REMOVAL:
222 break;
223 #endif
224 default:
225 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
226 break;
227 }
228
229 if (Status != STATUS_PENDING) {
230 Irp->IoStatus.Status = Status;
231 IoCompleteRequest(Irp, IO_NO_INCREMENT);
232 }
233
234 DPRINT("Leaving. Status 0x%X\n", Status);
235
236 return Status;
237 }
238
239 NTSTATUS
240 PdoPowerControl(
241 PDEVICE_OBJECT DeviceObject,
242 PIRP Irp)
243 /*
244 * FUNCTION: Handle power management IRPs for the child device
245 * ARGUMENTS:
246 * DeviceObject = Pointer to physical device object of the child device
247 * Irp = Pointer to IRP that should be handled
248 * RETURNS:
249 * Status
250 */
251 {
252 PIO_STACK_LOCATION IrpSp;
253 NTSTATUS Status;
254
255 DPRINT("Called\n");
256
257 IrpSp = IoGetCurrentIrpStackLocation(Irp);
258
259 switch (IrpSp->MinorFunction) {
260 case IRP_MN_SET_POWER:
261 Status = PdoSetPower(DeviceObject, Irp, IrpSp);
262 break;
263
264 default:
265 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
266 Status = STATUS_NOT_IMPLEMENTED;
267 break;
268 }
269
270 if (Status != STATUS_PENDING) {
271 Irp->IoStatus.Status = Status;
272 IoCompleteRequest(Irp, IO_NO_INCREMENT);
273 }
274
275 DPRINT("Leaving. Status 0x%X\n", Status);
276
277 return Status;
278 }
279
280 /* EOF */