xref: /reactos/drivers/bus/pcix/fdo.c (revision c2c66aff)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * PROJECT:         ReactOS PCI Bus Driver
3*c2c66affSColin Finck  * LICENSE:         BSD - See COPYING.ARM in the top level directory
4*c2c66affSColin Finck  * FILE:            drivers/bus/pci/fdo.c
5*c2c66affSColin Finck  * PURPOSE:         FDO Device Management
6*c2c66affSColin Finck  * PROGRAMMERS:     ReactOS Portable Systems Group
7*c2c66affSColin Finck  */
8*c2c66affSColin Finck 
9*c2c66affSColin Finck /* INCLUDES *******************************************************************/
10*c2c66affSColin Finck 
11*c2c66affSColin Finck #include <pci.h>
12*c2c66affSColin Finck 
13*c2c66affSColin Finck #define NDEBUG
14*c2c66affSColin Finck #include <debug.h>
15*c2c66affSColin Finck 
16*c2c66affSColin Finck /* GLOBALS ********************************************************************/
17*c2c66affSColin Finck 
18*c2c66affSColin Finck SINGLE_LIST_ENTRY PciFdoExtensionListHead;
19*c2c66affSColin Finck BOOLEAN PciBreakOnDefault;
20*c2c66affSColin Finck 
21*c2c66affSColin Finck PCI_MN_DISPATCH_TABLE PciFdoDispatchPowerTable[] =
22*c2c66affSColin Finck {
23*c2c66affSColin Finck     {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoWaitWake},
24*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
25*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoSetPowerState},
26*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryPower},
27*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}
28*c2c66affSColin Finck };
29*c2c66affSColin Finck 
30*c2c66affSColin Finck PCI_MN_DISPATCH_TABLE PciFdoDispatchPnpTable[] =
31*c2c66affSColin Finck {
32*c2c66affSColin Finck     {IRP_UPWARD,   (PCI_DISPATCH_FUNCTION)PciFdoIrpStartDevice},
33*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryRemoveDevice},
34*c2c66affSColin Finck     {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoIrpRemoveDevice},
35*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpCancelRemoveDevice},
36*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpStopDevice},
37*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryStopDevice},
38*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpCancelStopDevice},
39*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryDeviceRelations},
40*c2c66affSColin Finck     {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryInterface},
41*c2c66affSColin Finck     {IRP_UPWARD,   (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryCapabilities},
42*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
43*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
44*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
45*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
46*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
47*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
48*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
49*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
50*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
51*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
52*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
53*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
54*c2c66affSColin Finck     {IRP_UPWARD,   (PCI_DISPATCH_FUNCTION)PciFdoIrpDeviceUsageNotification},
55*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpSurpriseRemoval},
56*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryLegacyBusInformation},
57*c2c66affSColin Finck     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}
58*c2c66affSColin Finck };
59*c2c66affSColin Finck 
60*c2c66affSColin Finck PCI_MJ_DISPATCH_TABLE PciFdoDispatchTable =
61*c2c66affSColin Finck {
62*c2c66affSColin Finck     IRP_MN_QUERY_LEGACY_BUS_INFORMATION,
63*c2c66affSColin Finck     PciFdoDispatchPnpTable,
64*c2c66affSColin Finck     IRP_MN_QUERY_POWER,
65*c2c66affSColin Finck     PciFdoDispatchPowerTable,
66*c2c66affSColin Finck     IRP_DOWNWARD,
67*c2c66affSColin Finck     (PCI_DISPATCH_FUNCTION)PciIrpNotSupported,
68*c2c66affSColin Finck     IRP_DOWNWARD,
69*c2c66affSColin Finck     (PCI_DISPATCH_FUNCTION)PciIrpNotSupported
70*c2c66affSColin Finck };
71*c2c66affSColin Finck 
72*c2c66affSColin Finck /* FUNCTIONS ******************************************************************/
73*c2c66affSColin Finck 
74*c2c66affSColin Finck NTSTATUS
75*c2c66affSColin Finck NTAPI
PciFdoIrpStartDevice(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)76*c2c66affSColin Finck PciFdoIrpStartDevice(IN PIRP Irp,
77*c2c66affSColin Finck                      IN PIO_STACK_LOCATION IoStackLocation,
78*c2c66affSColin Finck                      IN PPCI_FDO_EXTENSION DeviceExtension)
79*c2c66affSColin Finck {
80*c2c66affSColin Finck     NTSTATUS Status;
81*c2c66affSColin Finck     PCM_RESOURCE_LIST Resources;
82*c2c66affSColin Finck     PAGED_CODE();
83*c2c66affSColin Finck 
84*c2c66affSColin Finck     /* The device stack must be starting the FDO in a success path */
85*c2c66affSColin Finck     if (!NT_SUCCESS(Irp->IoStatus.Status)) return STATUS_NOT_SUPPORTED;
86*c2c66affSColin Finck 
87*c2c66affSColin Finck     /* Attempt to switch the state machine to the started state */
88*c2c66affSColin Finck     Status = PciBeginStateTransition(DeviceExtension, PciStarted);
89*c2c66affSColin Finck     if (!NT_SUCCESS(Status)) return Status;
90*c2c66affSColin Finck 
91*c2c66affSColin Finck     /* Check for any boot-provided resources */
92*c2c66affSColin Finck     Resources = IoStackLocation->Parameters.StartDevice.AllocatedResources;
93*c2c66affSColin Finck     if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension)))
94*c2c66affSColin Finck     {
95*c2c66affSColin Finck         /* These resources would only be for non-root FDOs, unhandled for now */
96*c2c66affSColin Finck         ASSERT(Resources->Count == 1);
97*c2c66affSColin Finck         UNIMPLEMENTED_DBGBREAK();
98*c2c66affSColin Finck     }
99*c2c66affSColin Finck 
100*c2c66affSColin Finck     /* Initialize the arbiter for this FDO */
101*c2c66affSColin Finck     Status = PciInitializeArbiterRanges(DeviceExtension, Resources);
102*c2c66affSColin Finck     if (!NT_SUCCESS(Status))
103*c2c66affSColin Finck     {
104*c2c66affSColin Finck         /* Cancel the transition if this failed */
105*c2c66affSColin Finck         PciCancelStateTransition(DeviceExtension, PciStarted);
106*c2c66affSColin Finck         return Status;
107*c2c66affSColin Finck     }
108*c2c66affSColin Finck 
109*c2c66affSColin Finck     /* Again, check for boot-provided resources for non-root FDO */
110*c2c66affSColin Finck     if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension)))
111*c2c66affSColin Finck     {
112*c2c66affSColin Finck         /* Unhandled for now */
113*c2c66affSColin Finck         ASSERT(Resources->Count == 1);
114*c2c66affSColin Finck         UNIMPLEMENTED_DBGBREAK();
115*c2c66affSColin Finck     }
116*c2c66affSColin Finck 
117*c2c66affSColin Finck     /* Commit the transition to the started state */
118*c2c66affSColin Finck     PciCommitStateTransition(DeviceExtension, PciStarted);
119*c2c66affSColin Finck     return STATUS_SUCCESS;
120*c2c66affSColin Finck }
121*c2c66affSColin Finck 
122*c2c66affSColin Finck NTSTATUS
123*c2c66affSColin Finck NTAPI
PciFdoIrpQueryRemoveDevice(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)124*c2c66affSColin Finck PciFdoIrpQueryRemoveDevice(IN PIRP Irp,
125*c2c66affSColin Finck                            IN PIO_STACK_LOCATION IoStackLocation,
126*c2c66affSColin Finck                            IN PPCI_FDO_EXTENSION DeviceExtension)
127*c2c66affSColin Finck {
128*c2c66affSColin Finck     UNREFERENCED_PARAMETER(Irp);
129*c2c66affSColin Finck     UNREFERENCED_PARAMETER(IoStackLocation);
130*c2c66affSColin Finck     UNREFERENCED_PARAMETER(DeviceExtension);
131*c2c66affSColin Finck 
132*c2c66affSColin Finck     UNIMPLEMENTED;
133*c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
134*c2c66affSColin Finck }
135*c2c66affSColin Finck 
136*c2c66affSColin Finck NTSTATUS
137*c2c66affSColin Finck NTAPI
PciFdoIrpRemoveDevice(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)138*c2c66affSColin Finck PciFdoIrpRemoveDevice(IN PIRP Irp,
139*c2c66affSColin Finck                       IN PIO_STACK_LOCATION IoStackLocation,
140*c2c66affSColin Finck                       IN PPCI_FDO_EXTENSION DeviceExtension)
141*c2c66affSColin Finck {
142*c2c66affSColin Finck     UNREFERENCED_PARAMETER(Irp);
143*c2c66affSColin Finck     UNREFERENCED_PARAMETER(IoStackLocation);
144*c2c66affSColin Finck     UNREFERENCED_PARAMETER(DeviceExtension);
145*c2c66affSColin Finck 
146*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
147*c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
148*c2c66affSColin Finck }
149*c2c66affSColin Finck 
150*c2c66affSColin Finck NTSTATUS
151*c2c66affSColin Finck NTAPI
PciFdoIrpCancelRemoveDevice(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)152*c2c66affSColin Finck PciFdoIrpCancelRemoveDevice(IN PIRP Irp,
153*c2c66affSColin Finck                             IN PIO_STACK_LOCATION IoStackLocation,
154*c2c66affSColin Finck                             IN PPCI_FDO_EXTENSION DeviceExtension)
155*c2c66affSColin Finck {
156*c2c66affSColin Finck     UNREFERENCED_PARAMETER(Irp);
157*c2c66affSColin Finck     UNREFERENCED_PARAMETER(IoStackLocation);
158*c2c66affSColin Finck     UNREFERENCED_PARAMETER(DeviceExtension);
159*c2c66affSColin Finck 
160*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
161*c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
162*c2c66affSColin Finck }
163*c2c66affSColin Finck 
164*c2c66affSColin Finck NTSTATUS
165*c2c66affSColin Finck NTAPI
PciFdoIrpStopDevice(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)166*c2c66affSColin Finck PciFdoIrpStopDevice(IN PIRP Irp,
167*c2c66affSColin Finck                     IN PIO_STACK_LOCATION IoStackLocation,
168*c2c66affSColin Finck                     IN PPCI_FDO_EXTENSION DeviceExtension)
169*c2c66affSColin Finck {
170*c2c66affSColin Finck     UNREFERENCED_PARAMETER(Irp);
171*c2c66affSColin Finck     UNREFERENCED_PARAMETER(IoStackLocation);
172*c2c66affSColin Finck     UNREFERENCED_PARAMETER(DeviceExtension);
173*c2c66affSColin Finck 
174*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
175*c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
176*c2c66affSColin Finck }
177*c2c66affSColin Finck 
178*c2c66affSColin Finck NTSTATUS
179*c2c66affSColin Finck NTAPI
PciFdoIrpQueryStopDevice(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)180*c2c66affSColin Finck PciFdoIrpQueryStopDevice(IN PIRP Irp,
181*c2c66affSColin Finck                          IN PIO_STACK_LOCATION IoStackLocation,
182*c2c66affSColin Finck                          IN PPCI_FDO_EXTENSION DeviceExtension)
183*c2c66affSColin Finck {
184*c2c66affSColin Finck     UNREFERENCED_PARAMETER(Irp);
185*c2c66affSColin Finck     UNREFERENCED_PARAMETER(IoStackLocation);
186*c2c66affSColin Finck     UNREFERENCED_PARAMETER(DeviceExtension);
187*c2c66affSColin Finck 
188*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
189*c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
190*c2c66affSColin Finck }
191*c2c66affSColin Finck 
192*c2c66affSColin Finck NTSTATUS
193*c2c66affSColin Finck NTAPI
PciFdoIrpCancelStopDevice(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)194*c2c66affSColin Finck PciFdoIrpCancelStopDevice(IN PIRP Irp,
195*c2c66affSColin Finck                           IN PIO_STACK_LOCATION IoStackLocation,
196*c2c66affSColin Finck                           IN PPCI_FDO_EXTENSION DeviceExtension)
197*c2c66affSColin Finck {
198*c2c66affSColin Finck     UNREFERENCED_PARAMETER(Irp);
199*c2c66affSColin Finck     UNREFERENCED_PARAMETER(IoStackLocation);
200*c2c66affSColin Finck     UNREFERENCED_PARAMETER(DeviceExtension);
201*c2c66affSColin Finck 
202*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
203*c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
204*c2c66affSColin Finck }
205*c2c66affSColin Finck 
206*c2c66affSColin Finck NTSTATUS
207*c2c66affSColin Finck NTAPI
PciFdoIrpQueryDeviceRelations(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)208*c2c66affSColin Finck PciFdoIrpQueryDeviceRelations(IN PIRP Irp,
209*c2c66affSColin Finck                               IN PIO_STACK_LOCATION IoStackLocation,
210*c2c66affSColin Finck                               IN PPCI_FDO_EXTENSION DeviceExtension)
211*c2c66affSColin Finck {
212*c2c66affSColin Finck     NTSTATUS Status;
213*c2c66affSColin Finck     PAGED_CODE();
214*c2c66affSColin Finck 
215*c2c66affSColin Finck     /* Are bus relations being queried? */
216*c2c66affSColin Finck     if (IoStackLocation->Parameters.QueryDeviceRelations.Type != BusRelations)
217*c2c66affSColin Finck     {
218*c2c66affSColin Finck         /* The FDO is a bus, so only bus relations can be obtained */
219*c2c66affSColin Finck         Status = STATUS_NOT_SUPPORTED;
220*c2c66affSColin Finck     }
221*c2c66affSColin Finck     else
222*c2c66affSColin Finck     {
223*c2c66affSColin Finck         /* Scan the PCI bus and build the device relations for the caller */
224*c2c66affSColin Finck         Status = PciQueryDeviceRelations(DeviceExtension,
225*c2c66affSColin Finck                                          (PDEVICE_RELATIONS*)
226*c2c66affSColin Finck                                          &Irp->IoStatus.Information);
227*c2c66affSColin Finck     }
228*c2c66affSColin Finck 
229*c2c66affSColin Finck     /* Return the enumeration status back */
230*c2c66affSColin Finck     return Status;
231*c2c66affSColin Finck }
232*c2c66affSColin Finck 
233*c2c66affSColin Finck NTSTATUS
234*c2c66affSColin Finck NTAPI
PciFdoIrpQueryInterface(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)235*c2c66affSColin Finck PciFdoIrpQueryInterface(IN PIRP Irp,
236*c2c66affSColin Finck                         IN PIO_STACK_LOCATION IoStackLocation,
237*c2c66affSColin Finck                         IN PPCI_FDO_EXTENSION DeviceExtension)
238*c2c66affSColin Finck {
239*c2c66affSColin Finck     NTSTATUS Status;
240*c2c66affSColin Finck     PAGED_CODE();
241*c2c66affSColin Finck     ASSERT(DeviceExtension->ExtensionType == PciFdoExtensionType);
242*c2c66affSColin Finck 
243*c2c66affSColin Finck     /* Deleted extensions don't respond to IRPs */
244*c2c66affSColin Finck     if (DeviceExtension->DeviceState == PciDeleted)
245*c2c66affSColin Finck     {
246*c2c66affSColin Finck         /* Hand it back to try to deal with it */
247*c2c66affSColin Finck         return PciPassIrpFromFdoToPdo(DeviceExtension, Irp);
248*c2c66affSColin Finck     }
249*c2c66affSColin Finck 
250*c2c66affSColin Finck     /* Query our driver for this interface */
251*c2c66affSColin Finck     Status = PciQueryInterface(DeviceExtension,
252*c2c66affSColin Finck                                IoStackLocation->Parameters.QueryInterface.
253*c2c66affSColin Finck                                InterfaceType,
254*c2c66affSColin Finck                                IoStackLocation->Parameters.QueryInterface.
255*c2c66affSColin Finck                                Size,
256*c2c66affSColin Finck                                IoStackLocation->Parameters.QueryInterface.
257*c2c66affSColin Finck                                Version,
258*c2c66affSColin Finck                                IoStackLocation->Parameters.QueryInterface.
259*c2c66affSColin Finck                                InterfaceSpecificData,
260*c2c66affSColin Finck                                IoStackLocation->Parameters.QueryInterface.
261*c2c66affSColin Finck                                Interface,
262*c2c66affSColin Finck                                FALSE);
263*c2c66affSColin Finck     if (NT_SUCCESS(Status))
264*c2c66affSColin Finck     {
265*c2c66affSColin Finck         /* We found it, let the PDO handle it */
266*c2c66affSColin Finck         Irp->IoStatus.Status = Status;
267*c2c66affSColin Finck         return PciPassIrpFromFdoToPdo(DeviceExtension, Irp);
268*c2c66affSColin Finck     }
269*c2c66affSColin Finck     else if (Status == STATUS_NOT_SUPPORTED)
270*c2c66affSColin Finck     {
271*c2c66affSColin Finck         /* Otherwise, we can't handle it, let someone else down the stack try */
272*c2c66affSColin Finck         Status = PciCallDownIrpStack(DeviceExtension, Irp);
273*c2c66affSColin Finck         if (Status == STATUS_NOT_SUPPORTED)
274*c2c66affSColin Finck         {
275*c2c66affSColin Finck             /* They can't either, try a last-resort interface lookup */
276*c2c66affSColin Finck             Status = PciQueryInterface(DeviceExtension,
277*c2c66affSColin Finck                                        IoStackLocation->Parameters.QueryInterface.
278*c2c66affSColin Finck                                        InterfaceType,
279*c2c66affSColin Finck                                        IoStackLocation->Parameters.QueryInterface.
280*c2c66affSColin Finck                                        Size,
281*c2c66affSColin Finck                                        IoStackLocation->Parameters.QueryInterface.
282*c2c66affSColin Finck                                        Version,
283*c2c66affSColin Finck                                        IoStackLocation->Parameters.QueryInterface.
284*c2c66affSColin Finck                                        InterfaceSpecificData,
285*c2c66affSColin Finck                                        IoStackLocation->Parameters.QueryInterface.
286*c2c66affSColin Finck                                        Interface,
287*c2c66affSColin Finck                                        TRUE);
288*c2c66affSColin Finck         }
289*c2c66affSColin Finck     }
290*c2c66affSColin Finck 
291*c2c66affSColin Finck     /* Has anyone claimed this interface yet? */
292*c2c66affSColin Finck     if (Status == STATUS_NOT_SUPPORTED)
293*c2c66affSColin Finck     {
294*c2c66affSColin Finck         /* No, return the original IRP status */
295*c2c66affSColin Finck         Status = Irp->IoStatus.Status;
296*c2c66affSColin Finck     }
297*c2c66affSColin Finck     else
298*c2c66affSColin Finck     {
299*c2c66affSColin Finck         /* Yes, set the new IRP status */
300*c2c66affSColin Finck         Irp->IoStatus.Status = Status;
301*c2c66affSColin Finck     }
302*c2c66affSColin Finck 
303*c2c66affSColin Finck     /* Complete this IRP */
304*c2c66affSColin Finck     IoCompleteRequest(Irp, IO_NO_INCREMENT);
305*c2c66affSColin Finck     return Status;
306*c2c66affSColin Finck }
307*c2c66affSColin Finck 
308*c2c66affSColin Finck NTSTATUS
309*c2c66affSColin Finck NTAPI
PciFdoIrpQueryCapabilities(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)310*c2c66affSColin Finck PciFdoIrpQueryCapabilities(IN PIRP Irp,
311*c2c66affSColin Finck                            IN PIO_STACK_LOCATION IoStackLocation,
312*c2c66affSColin Finck                            IN PPCI_FDO_EXTENSION DeviceExtension)
313*c2c66affSColin Finck {
314*c2c66affSColin Finck     PDEVICE_CAPABILITIES Capabilities;
315*c2c66affSColin Finck     PAGED_CODE();
316*c2c66affSColin Finck     ASSERT_FDO(DeviceExtension);
317*c2c66affSColin Finck 
318*c2c66affSColin Finck     UNREFERENCED_PARAMETER(Irp);
319*c2c66affSColin Finck 
320*c2c66affSColin Finck     /* Get the capabilities */
321*c2c66affSColin Finck     Capabilities = IoStackLocation->Parameters.DeviceCapabilities.Capabilities;
322*c2c66affSColin Finck 
323*c2c66affSColin Finck     /* Inherit wake levels and power mappings from the higher-up capabilities */
324*c2c66affSColin Finck     DeviceExtension->PowerState.SystemWakeLevel = Capabilities->SystemWake;
325*c2c66affSColin Finck     DeviceExtension->PowerState.DeviceWakeLevel = Capabilities->DeviceWake;
326*c2c66affSColin Finck     RtlCopyMemory(DeviceExtension->PowerState.SystemStateMapping,
327*c2c66affSColin Finck                   Capabilities->DeviceState,
328*c2c66affSColin Finck                   sizeof(DeviceExtension->PowerState.SystemStateMapping));
329*c2c66affSColin Finck 
330*c2c66affSColin Finck     /* Dump the capabilities and return success */
331*c2c66affSColin Finck     PciDebugDumpQueryCapabilities(Capabilities);
332*c2c66affSColin Finck     return STATUS_SUCCESS;
333*c2c66affSColin Finck }
334*c2c66affSColin Finck 
335*c2c66affSColin Finck NTSTATUS
336*c2c66affSColin Finck NTAPI
PciFdoIrpDeviceUsageNotification(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)337*c2c66affSColin Finck PciFdoIrpDeviceUsageNotification(IN PIRP Irp,
338*c2c66affSColin Finck                                  IN PIO_STACK_LOCATION IoStackLocation,
339*c2c66affSColin Finck                                  IN PPCI_FDO_EXTENSION DeviceExtension)
340*c2c66affSColin Finck {
341*c2c66affSColin Finck     UNREFERENCED_PARAMETER(Irp);
342*c2c66affSColin Finck     UNREFERENCED_PARAMETER(IoStackLocation);
343*c2c66affSColin Finck     UNREFERENCED_PARAMETER(DeviceExtension);
344*c2c66affSColin Finck 
345*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
346*c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
347*c2c66affSColin Finck }
348*c2c66affSColin Finck 
349*c2c66affSColin Finck NTSTATUS
350*c2c66affSColin Finck NTAPI
PciFdoIrpSurpriseRemoval(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)351*c2c66affSColin Finck PciFdoIrpSurpriseRemoval(IN PIRP Irp,
352*c2c66affSColin Finck                          IN PIO_STACK_LOCATION IoStackLocation,
353*c2c66affSColin Finck                          IN PPCI_FDO_EXTENSION DeviceExtension)
354*c2c66affSColin Finck {
355*c2c66affSColin Finck     UNREFERENCED_PARAMETER(Irp);
356*c2c66affSColin Finck     UNREFERENCED_PARAMETER(IoStackLocation);
357*c2c66affSColin Finck     UNREFERENCED_PARAMETER(DeviceExtension);
358*c2c66affSColin Finck 
359*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
360*c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
361*c2c66affSColin Finck }
362*c2c66affSColin Finck 
363*c2c66affSColin Finck NTSTATUS
364*c2c66affSColin Finck NTAPI
PciFdoIrpQueryLegacyBusInformation(IN PIRP Irp,IN PIO_STACK_LOCATION IoStackLocation,IN PPCI_FDO_EXTENSION DeviceExtension)365*c2c66affSColin Finck PciFdoIrpQueryLegacyBusInformation(IN PIRP Irp,
366*c2c66affSColin Finck                                    IN PIO_STACK_LOCATION IoStackLocation,
367*c2c66affSColin Finck                                    IN PPCI_FDO_EXTENSION DeviceExtension)
368*c2c66affSColin Finck {
369*c2c66affSColin Finck     UNREFERENCED_PARAMETER(Irp);
370*c2c66affSColin Finck     UNREFERENCED_PARAMETER(IoStackLocation);
371*c2c66affSColin Finck     UNREFERENCED_PARAMETER(DeviceExtension);
372*c2c66affSColin Finck 
373*c2c66affSColin Finck     UNIMPLEMENTED_DBGBREAK();
374*c2c66affSColin Finck     return STATUS_NOT_SUPPORTED;
375*c2c66affSColin Finck }
376*c2c66affSColin Finck 
377*c2c66affSColin Finck VOID
378*c2c66affSColin Finck NTAPI
PciGetHotPlugParameters(IN PPCI_FDO_EXTENSION FdoExtension)379*c2c66affSColin Finck PciGetHotPlugParameters(IN PPCI_FDO_EXTENSION FdoExtension)
380*c2c66affSColin Finck {
381*c2c66affSColin Finck     ACPI_EVAL_INPUT_BUFFER InputBuffer;
382*c2c66affSColin Finck     PACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
383*c2c66affSColin Finck     ULONG Length;
384*c2c66affSColin Finck     NTSTATUS Status;
385*c2c66affSColin Finck     PAGED_CODE();
386*c2c66affSColin Finck 
387*c2c66affSColin Finck     /* We should receive 4 parameters, per the HPP specification */
388*c2c66affSColin Finck     Length = sizeof(ACPI_EVAL_OUTPUT_BUFFER) + 4 * sizeof(ACPI_METHOD_ARGUMENT);
389*c2c66affSColin Finck 
390*c2c66affSColin Finck     /* Allocate the buffer to hold the parameters */
391*c2c66affSColin Finck     OutputBuffer = ExAllocatePoolWithTag(PagedPool, Length, PCI_POOL_TAG);
392*c2c66affSColin Finck     if (!OutputBuffer) return;
393*c2c66affSColin Finck 
394*c2c66affSColin Finck     /* Initialize the output and input buffers. The method is _HPP */
395*c2c66affSColin Finck     RtlZeroMemory(OutputBuffer, Length);
396*c2c66affSColin Finck     *(PULONG)InputBuffer.MethodName = 'PPH_';
397*c2c66affSColin Finck     InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
398*c2c66affSColin Finck     do
399*c2c66affSColin Finck     {
400*c2c66affSColin Finck         /* Send the IOCTL to the ACPI driver */
401*c2c66affSColin Finck         Status = PciSendIoctl(FdoExtension->PhysicalDeviceObject,
402*c2c66affSColin Finck                               IOCTL_ACPI_EVAL_METHOD,
403*c2c66affSColin Finck                               &InputBuffer,
404*c2c66affSColin Finck                               sizeof(InputBuffer),
405*c2c66affSColin Finck                               OutputBuffer,
406*c2c66affSColin Finck                               Length);
407*c2c66affSColin Finck         if (!NT_SUCCESS(Status))
408*c2c66affSColin Finck         {
409*c2c66affSColin Finck             /* The method failed, check if we can salvage data from parent */
410*c2c66affSColin Finck             if (!PCI_IS_ROOT_FDO(FdoExtension))
411*c2c66affSColin Finck             {
412*c2c66affSColin Finck                 /* Copy the root bus' hot plug parameters */
413*c2c66affSColin Finck                 FdoExtension->HotPlugParameters = FdoExtension->ParentFdoExtension->HotPlugParameters;
414*c2c66affSColin Finck             }
415*c2c66affSColin Finck 
416*c2c66affSColin Finck             /* Nothing more to do on this path */
417*c2c66affSColin Finck             break;
418*c2c66affSColin Finck         }
419*c2c66affSColin Finck 
420*c2c66affSColin Finck         /* ACPI sent back some data. 4 parameters are expected in the output */
421*c2c66affSColin Finck         if (OutputBuffer->Count != 4) break;
422*c2c66affSColin Finck 
423*c2c66affSColin Finck         /* HotPlug PCI Support not yet implemented */
424*c2c66affSColin Finck         UNIMPLEMENTED_DBGBREAK();
425*c2c66affSColin Finck     } while (FALSE);
426*c2c66affSColin Finck 
427*c2c66affSColin Finck     /* Free the buffer and return */
428*c2c66affSColin Finck     ExFreePoolWithTag(OutputBuffer, 0);
429*c2c66affSColin Finck }
430*c2c66affSColin Finck 
431*c2c66affSColin Finck VOID
432*c2c66affSColin Finck NTAPI
PciInitializeFdoExtensionCommonFields(PPCI_FDO_EXTENSION FdoExtension,IN PDEVICE_OBJECT DeviceObject,IN PDEVICE_OBJECT PhysicalDeviceObject)433*c2c66affSColin Finck PciInitializeFdoExtensionCommonFields(PPCI_FDO_EXTENSION FdoExtension,
434*c2c66affSColin Finck                                       IN PDEVICE_OBJECT DeviceObject,
435*c2c66affSColin Finck                                       IN PDEVICE_OBJECT PhysicalDeviceObject)
436*c2c66affSColin Finck {
437*c2c66affSColin Finck     /* Initialize the extension */
438*c2c66affSColin Finck     RtlZeroMemory(FdoExtension, sizeof(PCI_FDO_EXTENSION));
439*c2c66affSColin Finck 
440*c2c66affSColin Finck     /* Setup the common fields */
441*c2c66affSColin Finck     FdoExtension->PhysicalDeviceObject = PhysicalDeviceObject;
442*c2c66affSColin Finck     FdoExtension->FunctionalDeviceObject = DeviceObject;
443*c2c66affSColin Finck     FdoExtension->ExtensionType = PciFdoExtensionType;
444*c2c66affSColin Finck     FdoExtension->PowerState.CurrentSystemState = PowerSystemWorking;
445*c2c66affSColin Finck     FdoExtension->PowerState.CurrentDeviceState = PowerDeviceD0;
446*c2c66affSColin Finck     FdoExtension->IrpDispatchTable = &PciFdoDispatchTable;
447*c2c66affSColin Finck 
448*c2c66affSColin Finck     /* Initialize the extension locks */
449*c2c66affSColin Finck     KeInitializeEvent(&FdoExtension->SecondaryExtLock, SynchronizationEvent, TRUE);
450*c2c66affSColin Finck     KeInitializeEvent(&FdoExtension->ChildListLock, SynchronizationEvent, TRUE);
451*c2c66affSColin Finck 
452*c2c66affSColin Finck     /* Initialize the default state */
453*c2c66affSColin Finck     PciInitializeState(FdoExtension);
454*c2c66affSColin Finck }
455*c2c66affSColin Finck 
456*c2c66affSColin Finck NTSTATUS
457*c2c66affSColin Finck NTAPI
PciAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject)458*c2c66affSColin Finck PciAddDevice(IN PDRIVER_OBJECT DriverObject,
459*c2c66affSColin Finck              IN PDEVICE_OBJECT PhysicalDeviceObject)
460*c2c66affSColin Finck {
461*c2c66affSColin Finck     PCM_RESOURCE_LIST Descriptor;
462*c2c66affSColin Finck     PDEVICE_OBJECT AttachedTo;
463*c2c66affSColin Finck     PPCI_FDO_EXTENSION FdoExtension;
464*c2c66affSColin Finck     PPCI_FDO_EXTENSION ParentExtension;
465*c2c66affSColin Finck     PPCI_PDO_EXTENSION PdoExtension;
466*c2c66affSColin Finck     PDEVICE_OBJECT DeviceObject;
467*c2c66affSColin Finck     UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
468*c2c66affSColin Finck     PKEY_VALUE_PARTIAL_INFORMATION ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
469*c2c66affSColin Finck     NTSTATUS Status;
470*c2c66affSColin Finck     HANDLE KeyHandle;
471*c2c66affSColin Finck     UNICODE_STRING ValueName;
472*c2c66affSColin Finck     ULONG ResultLength;
473*c2c66affSColin Finck     PAGED_CODE();
474*c2c66affSColin Finck     DPRINT1("PCI - AddDevice (a new bus). PDO: %p (Driver: %wZ)\n",
475*c2c66affSColin Finck             PhysicalDeviceObject, &PhysicalDeviceObject->DriverObject->DriverName);
476*c2c66affSColin Finck 
477*c2c66affSColin Finck     /* Zero out variables so failure path knows what to do */
478*c2c66affSColin Finck     AttachedTo = NULL;
479*c2c66affSColin Finck     FdoExtension = NULL;
480*c2c66affSColin Finck     PdoExtension = NULL;
481*c2c66affSColin Finck     DeviceObject = NULL;
482*c2c66affSColin Finck 
483*c2c66affSColin Finck     do
484*c2c66affSColin Finck     {
485*c2c66affSColin Finck         /* Check if there's already a device extension for this bus */
486*c2c66affSColin Finck         ParentExtension = PciFindParentPciFdoExtension(PhysicalDeviceObject,
487*c2c66affSColin Finck                                                        &PciGlobalLock);
488*c2c66affSColin Finck         if (ParentExtension)
489*c2c66affSColin Finck         {
490*c2c66affSColin Finck             /* Make sure we find a real PDO */
491*c2c66affSColin Finck             PdoExtension = PhysicalDeviceObject->DeviceExtension;
492*c2c66affSColin Finck             ASSERT_PDO(PdoExtension);
493*c2c66affSColin Finck 
494*c2c66affSColin Finck             /* Make sure it's a PCI-to-PCI bridge */
495*c2c66affSColin Finck             if ((PdoExtension->BaseClass != PCI_CLASS_BRIDGE_DEV) ||
496*c2c66affSColin Finck                 (PdoExtension->SubClass != PCI_SUBCLASS_BR_PCI_TO_PCI))
497*c2c66affSColin Finck             {
498*c2c66affSColin Finck                 /* This should never happen */
499*c2c66affSColin Finck                 DPRINT1("PCI - PciAddDevice for Non-Root/Non-PCI-PCI bridge,\n"
500*c2c66affSColin Finck                         "      Class %02x, SubClass %02x, will not add.\n",
501*c2c66affSColin Finck                         PdoExtension->BaseClass,
502*c2c66affSColin Finck                         PdoExtension->SubClass);
503*c2c66affSColin Finck                 ASSERT((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
504*c2c66affSColin Finck                        (PdoExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI));
505*c2c66affSColin Finck 
506*c2c66affSColin Finck                 /* Enter the failure path */
507*c2c66affSColin Finck                 Status = STATUS_INVALID_DEVICE_REQUEST;
508*c2c66affSColin Finck                 break;
509*c2c66affSColin Finck             }
510*c2c66affSColin Finck 
511*c2c66affSColin Finck             /* Subordinate bus on the bridge */
512*c2c66affSColin Finck             DPRINT1("PCI - AddDevice (new bus is child of bus 0x%x).\n",
513*c2c66affSColin Finck                     ParentExtension->BaseBus);
514*c2c66affSColin Finck 
515*c2c66affSColin Finck             /* Make sure PCI bus numbers are configured */
516*c2c66affSColin Finck             if (!PciAreBusNumbersConfigured(PdoExtension))
517*c2c66affSColin Finck             {
518*c2c66affSColin Finck                 /* This is a critical failure */
519*c2c66affSColin Finck                 DPRINT1("PCI - Bus numbers not configured for bridge (0x%x.0x%x.0x%x)\n",
520*c2c66affSColin Finck                         ParentExtension->BaseBus,
521*c2c66affSColin Finck                         PdoExtension->Slot.u.bits.DeviceNumber,
522*c2c66affSColin Finck                         PdoExtension->Slot.u.bits.FunctionNumber);
523*c2c66affSColin Finck 
524*c2c66affSColin Finck                 /* Enter the failure path */
525*c2c66affSColin Finck                 Status = STATUS_INVALID_DEVICE_REQUEST;
526*c2c66affSColin Finck                 break;
527*c2c66affSColin Finck             }
528*c2c66affSColin Finck         }
529*c2c66affSColin Finck 
530*c2c66affSColin Finck         /* Create the FDO for the bus */
531*c2c66affSColin Finck         Status = IoCreateDevice(DriverObject,
532*c2c66affSColin Finck                                 sizeof(PCI_FDO_EXTENSION),
533*c2c66affSColin Finck                                 NULL,
534*c2c66affSColin Finck                                 FILE_DEVICE_BUS_EXTENDER,
535*c2c66affSColin Finck                                 0,
536*c2c66affSColin Finck                                 0,
537*c2c66affSColin Finck                                 &DeviceObject);
538*c2c66affSColin Finck         if (!NT_SUCCESS(Status)) break;
539*c2c66affSColin Finck 
540*c2c66affSColin Finck         /* Initialize the extension for the FDO */
541*c2c66affSColin Finck         FdoExtension = DeviceObject->DeviceExtension;
542*c2c66affSColin Finck         PciInitializeFdoExtensionCommonFields(DeviceObject->DeviceExtension,
543*c2c66affSColin Finck                                               DeviceObject,
544*c2c66affSColin Finck                                               PhysicalDeviceObject);
545*c2c66affSColin Finck 
546*c2c66affSColin Finck         /* Attach to the root PDO */
547*c2c66affSColin Finck         Status = STATUS_NO_SUCH_DEVICE;
548*c2c66affSColin Finck         AttachedTo = IoAttachDeviceToDeviceStack(DeviceObject,
549*c2c66affSColin Finck                                                  PhysicalDeviceObject);
550*c2c66affSColin Finck         ASSERT(AttachedTo != NULL);
551*c2c66affSColin Finck         if (!AttachedTo) break;
552*c2c66affSColin Finck         FdoExtension->AttachedDeviceObject = AttachedTo;
553*c2c66affSColin Finck 
554*c2c66affSColin Finck         /* Check if this is a child bus, or the root */
555*c2c66affSColin Finck         if (ParentExtension)
556*c2c66affSColin Finck         {
557*c2c66affSColin Finck             /* The child inherits root data */
558*c2c66affSColin Finck             FdoExtension->BaseBus = PdoExtension->Dependent.type1.SecondaryBus;
559*c2c66affSColin Finck             FdoExtension->BusRootFdoExtension = ParentExtension->BusRootFdoExtension;
560*c2c66affSColin Finck             PdoExtension->BridgeFdoExtension = FdoExtension;
561*c2c66affSColin Finck             FdoExtension->ParentFdoExtension = ParentExtension;
562*c2c66affSColin Finck         }
563*c2c66affSColin Finck         else
564*c2c66affSColin Finck         {
565*c2c66affSColin Finck             /* Query the boot configuration */
566*c2c66affSColin Finck             Status = PciGetDeviceProperty(PhysicalDeviceObject,
567*c2c66affSColin Finck                                           DevicePropertyBootConfiguration,
568*c2c66affSColin Finck                                           (PVOID*)&Descriptor);
569*c2c66affSColin Finck             if (!NT_SUCCESS(Status))
570*c2c66affSColin Finck             {
571*c2c66affSColin Finck                 /* No configuration has been set */
572*c2c66affSColin Finck                 Descriptor = NULL;
573*c2c66affSColin Finck             }
574*c2c66affSColin Finck             else
575*c2c66affSColin Finck             {
576*c2c66affSColin Finck                 /* Root PDO in ReactOS does not assign boot resources */
577*c2c66affSColin Finck                 UNIMPLEMENTED_DBGBREAK("Encountered during setup\n");
578*c2c66affSColin Finck                 Descriptor = NULL;
579*c2c66affSColin Finck             }
580*c2c66affSColin Finck 
581*c2c66affSColin Finck             if (Descriptor)
582*c2c66affSColin Finck             {
583*c2c66affSColin Finck                 /* Root PDO in ReactOS does not assign boot resources */
584*c2c66affSColin Finck                 UNIMPLEMENTED_DBGBREAK();
585*c2c66affSColin Finck             }
586*c2c66affSColin Finck             else
587*c2c66affSColin Finck             {
588*c2c66affSColin Finck                 /* Default configuration isn't the normal path on Windows */
589*c2c66affSColin Finck                 if (PciBreakOnDefault)
590*c2c66affSColin Finck                 {
591*c2c66affSColin Finck                     /* If a second bus is found and there's still no data, crash */
592*c2c66affSColin Finck                     KeBugCheckEx(PCI_BUS_DRIVER_INTERNAL,
593*c2c66affSColin Finck                                  0xDEAD0010u,
594*c2c66affSColin Finck                                  (ULONG_PTR)DeviceObject,
595*c2c66affSColin Finck                                  0,
596*c2c66affSColin Finck                                  0);
597*c2c66affSColin Finck                 }
598*c2c66affSColin Finck 
599*c2c66affSColin Finck                 /* Warn that a default configuration will be used, and set bus 0 */
600*c2c66affSColin Finck                 DPRINT1("PCI   Will use default configuration.\n");
601*c2c66affSColin Finck                 PciBreakOnDefault = TRUE;
602*c2c66affSColin Finck                 FdoExtension->BaseBus = 0;
603*c2c66affSColin Finck             }
604*c2c66affSColin Finck 
605*c2c66affSColin Finck             /* This is the root bus */
606*c2c66affSColin Finck             FdoExtension->BusRootFdoExtension = FdoExtension;
607*c2c66affSColin Finck         }
608*c2c66affSColin Finck 
609*c2c66affSColin Finck         /* Get the HAL or ACPI Bus Handler Callbacks for Configuration Access */
610*c2c66affSColin Finck         Status = PciGetConfigHandlers(FdoExtension);
611*c2c66affSColin Finck         if (!NT_SUCCESS(Status)) break;
612*c2c66affSColin Finck 
613*c2c66affSColin Finck         /* Initialize all the supported PCI arbiters */
614*c2c66affSColin Finck         Status = PciInitializeArbiters(FdoExtension);
615*c2c66affSColin Finck         if (!NT_SUCCESS(Status)) break;
616*c2c66affSColin Finck 
617*c2c66affSColin Finck         /* This is a real FDO, insert it into the list */
618*c2c66affSColin Finck         FdoExtension->Fake = FALSE;
619*c2c66affSColin Finck         PciInsertEntryAtTail(&PciFdoExtensionListHead,
620*c2c66affSColin Finck                              FdoExtension,
621*c2c66affSColin Finck                              &PciGlobalLock);
622*c2c66affSColin Finck 
623*c2c66affSColin Finck         /* Open the device registry key so that we can query the errata flags */
624*c2c66affSColin Finck         IoOpenDeviceRegistryKey(DeviceObject,
625*c2c66affSColin Finck                                 PLUGPLAY_REGKEY_DEVICE,
626*c2c66affSColin Finck                                 KEY_ALL_ACCESS,
627*c2c66affSColin Finck                                 &KeyHandle),
628*c2c66affSColin Finck 
629*c2c66affSColin Finck         /* Open the value that contains errata flags for this bus instance */
630*c2c66affSColin Finck         RtlInitUnicodeString(&ValueName, L"HackFlags");
631*c2c66affSColin Finck         Status = ZwQueryValueKey(KeyHandle,
632*c2c66affSColin Finck                                  &ValueName,
633*c2c66affSColin Finck                                  KeyValuePartialInformation,
634*c2c66affSColin Finck                                  ValueInfo,
635*c2c66affSColin Finck                                  sizeof(Buffer),
636*c2c66affSColin Finck                                  &ResultLength);
637*c2c66affSColin Finck         ZwClose(KeyHandle);
638*c2c66affSColin Finck         if (NT_SUCCESS(Status))
639*c2c66affSColin Finck         {
640*c2c66affSColin Finck             /* Make sure the data is of expected type and size */
641*c2c66affSColin Finck             if ((ValueInfo->Type == REG_DWORD) &&
642*c2c66affSColin Finck                 (ValueInfo->DataLength == sizeof(ULONG)))
643*c2c66affSColin Finck             {
644*c2c66affSColin Finck                 /* Read the flags for this bus */
645*c2c66affSColin Finck                 FdoExtension->BusHackFlags = *(PULONG)&ValueInfo->Data;
646*c2c66affSColin Finck             }
647*c2c66affSColin Finck         }
648*c2c66affSColin Finck 
649*c2c66affSColin Finck         /* Query ACPI for PCI HotPlug Support */
650*c2c66affSColin Finck         PciGetHotPlugParameters(FdoExtension);
651*c2c66affSColin Finck 
652*c2c66affSColin Finck         /* The Bus FDO is now initialized */
653*c2c66affSColin Finck         DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
654*c2c66affSColin Finck         return STATUS_SUCCESS;
655*c2c66affSColin Finck     } while (FALSE);
656*c2c66affSColin Finck 
657*c2c66affSColin Finck     /* This is the failure path */
658*c2c66affSColin Finck     ASSERT(!NT_SUCCESS(Status));
659*c2c66affSColin Finck 
660*c2c66affSColin Finck     /* Check if the FDO extension exists */
661*c2c66affSColin Finck     if (FdoExtension) DPRINT1("Should destroy secondaries\n");
662*c2c66affSColin Finck 
663*c2c66affSColin Finck     /* Delete device objects */
664*c2c66affSColin Finck     if (AttachedTo) IoDetachDevice(AttachedTo);
665*c2c66affSColin Finck     if (DeviceObject) IoDeleteDevice(DeviceObject);
666*c2c66affSColin Finck     return Status;
667*c2c66affSColin Finck }
668*c2c66affSColin Finck 
669*c2c66affSColin Finck /* EOF */
670