]> git.proxmox.com Git - mirror_edk2.git/blob - Nt32Pkg/Library/EdkGenericBdsLib/BdsConnect.c
6362c20b70aa9d2b0033c4f0680b1bd12233a2a2
[mirror_edk2.git] / Nt32Pkg / Library / EdkGenericBdsLib / BdsConnect.c
1 /*++
2
3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 BdsConnect.c
15
16 Abstract:
17
18 BDS Lib functions which relate with connect the device
19
20 --*/
21
22 #include <EdkGenericBdsLibInternal.h>
23
24 VOID
25 BdsLibConnectAll (
26 VOID
27 )
28 /*++
29
30 Routine Description:
31
32 This function will connect all the system driver to controller
33 first, and then special connect the default console, this make
34 sure all the system controller avialbe and the platform default
35 console connected.
36
37 Arguments:
38
39 None
40
41 Returns:
42
43 None
44
45 --*/
46 {
47 //
48 // Connect the platform console first
49 //
50 BdsLibConnectAllDefaultConsoles ();
51
52 //
53 // Generic way to connect all the drivers
54 //
55 BdsLibConnectAllDriversToAllControllers ();
56
57 //
58 // Here we have the assumption that we have already had
59 // platform default console
60 //
61 BdsLibConnectAllDefaultConsoles ();
62 }
63
64 VOID
65 BdsLibGenericConnectAll (
66 VOID
67 )
68 /*++
69
70 Routine Description:
71
72 This function will connect all the system drivers to all controllers
73 first, and then connect all the console devices the system current
74 have. After this we should get all the device work and console avariable
75 if the system have console device.
76
77 Arguments:
78
79 None
80
81 Returns:
82
83 None
84
85 --*/
86 {
87 //
88 // Most generic way to connect all the drivers
89 //
90 BdsLibConnectAllDriversToAllControllers ();
91 BdsLibConnectAllConsoles ();
92 }
93
94 EFI_STATUS
95 BdsLibConnectDevicePath (
96 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect
97 )
98 /*++
99
100 Routine Description:
101 This function will create all handles associate with every device
102 path node. If the handle associate with one device path node can not
103 be created success, then still give one chance to do the dispatch,
104 which load the missing drivers if possible.
105
106 Arguments:
107
108 DevicePathToConnect - The device path which will be connected, it can
109 be a multi-instance device path
110
111 Returns:
112
113 EFI_SUCCESS - All handles associate with every device path
114 node have been created
115
116 EFI_OUT_OF_RESOURCES - There is no resource to create new handles
117
118 EFI_NOT_FOUND - Create the handle associate with one device
119 path node failed
120
121 --*/
122 {
123 EFI_STATUS Status;
124 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
125 EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
126 EFI_DEVICE_PATH_PROTOCOL *Instance;
127 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
128 EFI_DEVICE_PATH_PROTOCOL *Next;
129 EFI_HANDLE Handle;
130 EFI_HANDLE PreviousHandle;
131 UINTN Size;
132
133 if (DevicePathToConnect == NULL) {
134 return EFI_SUCCESS;
135 }
136
137 DevicePath = DuplicateDevicePath (DevicePathToConnect);
138 CopyOfDevicePath = DevicePath;
139 if (DevicePath == NULL) {
140 return EFI_OUT_OF_RESOURCES;
141 }
142
143 do {
144 //
145 // The outer loop handles multi instance device paths.
146 // Only console variables contain multiple instance device paths.
147 //
148 // After this call DevicePath points to the next Instance
149 //
150 Instance = GetNextDevicePathInstance (&DevicePath, &Size);
151 Next = Instance;
152 while (!IsDevicePathEndType (Next)) {
153 Next = NextDevicePathNode (Next);
154 }
155
156 SetDevicePathEndNode (Next);
157
158 //
159 // Start the real work of connect with RemainingDevicePath
160 //
161 PreviousHandle = NULL;
162 do {
163 //
164 // Find the handle that best matches the Device Path. If it is only a
165 // partial match the remaining part of the device path is returned in
166 // RemainingDevicePath.
167 //
168 RemainingDevicePath = Instance;
169 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);
170
171 if (!EFI_ERROR (Status)) {
172 if (Handle == PreviousHandle) {
173 //
174 // If no forward progress is made try invoking the Dispatcher.
175 // A new FV may have been added to the system an new drivers
176 // may now be found.
177 // Status == EFI_SUCCESS means a driver was dispatched
178 // Status == EFI_NOT_FOUND means no new drivers were dispatched
179 //
180 Status = gDS->Dispatch ();
181 }
182
183 if (!EFI_ERROR (Status)) {
184 PreviousHandle = Handle;
185 //
186 // Connect all drivers that apply to Handle and RemainingDevicePath,
187 // the Recursive flag is FALSE so only one level will be expanded.
188 //
189 // Do not check the connect status here, if the connect controller fail,
190 // then still give the chance to do dispatch, because partial
191 // RemainingDevicepath may be in the new FV
192 //
193 // 1. If the connect fail, RemainingDevicepath and handle will not
194 // change, so next time will do the dispatch, then dispatch's status
195 // will take effect
196 // 2. If the connect success, the RemainingDevicepath and handle will
197 // change, then avoid the dispatch, we have chance to continue the
198 // next connection
199 //
200 gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
201 }
202 }
203 //
204 // Loop until RemainingDevicePath is an empty device path
205 //
206 } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
207
208 } while (DevicePath != NULL);
209
210 if (CopyOfDevicePath != NULL) {
211 FreePool (CopyOfDevicePath);
212 }
213 //
214 // All handle with DevicePath exists in the handle database
215 //
216 return Status;
217 }
218
219 EFI_STATUS
220 BdsLibConnectAllEfi (
221 VOID
222 )
223 /*++
224
225 Routine Description:
226
227 This function will connect all current system handles recursively. The
228 connection will finish until every handle's child handle created if it have.
229
230 Arguments:
231
232 None
233
234 Returns:
235
236 EFI_SUCCESS - All handles and it's child handle have been connected
237
238 EFI_STATUS - Return the status of gBS->LocateHandleBuffer().
239
240 --*/
241 {
242 EFI_STATUS Status;
243 UINTN HandleCount;
244 EFI_HANDLE *HandleBuffer;
245 UINTN Index;
246
247 Status = gBS->LocateHandleBuffer (
248 AllHandles,
249 NULL,
250 NULL,
251 &HandleCount,
252 &HandleBuffer
253 );
254 if (EFI_ERROR (Status)) {
255 return Status;
256 }
257
258 for (Index = 0; Index < HandleCount; Index++) {
259 Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
260 }
261
262 FreePool (HandleBuffer);
263
264 return EFI_SUCCESS;
265 }
266
267 EFI_STATUS
268 BdsLibDisconnectAllEfi (
269 VOID
270 )
271 /*++
272
273 Routine Description:
274
275 This function will disconnect all current system handles. The disconnection
276 will finish until every handle have been disconnected.
277
278 Arguments:
279
280 None
281
282 Returns:
283
284 EFI_SUCCESS - All handles have been disconnected
285
286 EFI_STATUS - Return the status of gBS->LocateHandleBuffer().
287
288 --*/
289 {
290 EFI_STATUS Status;
291 UINTN HandleCount;
292 EFI_HANDLE *HandleBuffer;
293 UINTN Index;
294
295 //
296 // Disconnect all
297 //
298 Status = gBS->LocateHandleBuffer (
299 AllHandles,
300 NULL,
301 NULL,
302 &HandleCount,
303 &HandleBuffer
304 );
305 if (EFI_ERROR (Status)) {
306 return Status;
307 }
308
309 for (Index = 0; Index < HandleCount; Index++) {
310 Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
311 }
312
313 FreePool (HandleBuffer);
314
315 return EFI_SUCCESS;
316 }
317
318 VOID
319 BdsLibConnectAllDriversToAllControllers (
320 VOID
321 )
322 /*++
323
324 Routine Description:
325
326 Connects all drivers to all controllers.
327 This function make sure all the current system driver will manage
328 the correspoinding controllers if have. And at the same time, make
329 sure all the system controllers have driver to manage it if have.
330
331 Arguments:
332
333 None
334
335 Returns:
336
337 None
338
339 --*/
340 {
341 EFI_STATUS Status;
342
343 do {
344 //
345 // Connect All EFI 1.10 drivers following EFI 1.10 algorithm
346 //
347 BdsLibConnectAllEfi ();
348
349 //
350 // Check to see if it's possible to dispatch an more DXE drivers.
351 // The BdsLibConnectAllEfi () may have made new DXE drivers show up.
352 // If anything is Dispatched Status == EFI_SUCCESS and we will try
353 // the connect again.
354 //
355 Status = gDS->Dispatch ();
356
357 } while (!EFI_ERROR (Status));
358
359 }