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