]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDriver.c
Add a check for CreateQuestion may be return NULL.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / Ip4ConfigDriver.c
CommitLineData
b2570da8 1/** @file\r
402fa70f 2 The driver binding for IP4 CONFIG protocol.\r
b2570da8 3\r
6d3ea23f 4Copyright (c) 2006 - 2009, Intel Corporation.<BR>\r
b2570da8 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
402fa70f 7which accompanies this distribution. The full text of the license may be found at<BR>\r
b2570da8 8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
b2570da8 13**/\r
14\r
15\r
16#include "Ip4Config.h"\r
17\r
c8d8f1e3 18EFI_DRIVER_BINDING_PROTOCOL gIp4ConfigDriverBinding = {\r
19 Ip4ConfigDriverBindingSupported,\r
20 Ip4ConfigDriverBindingStart,\r
21 Ip4ConfigDriverBindingStop,\r
22 0xa,\r
23 NULL,\r
24 NULL\r
25};\r
b2570da8 26\r
27/**\r
28 Stop all the auto configuration when the IP4 configure driver is\r
29 being unloaded.\r
30\r
31 @param ImageHandle The driver that is being unloaded\r
32\r
33 @retval EFI_SUCCESS The driver has been ready for unload.\r
34\r
35**/\r
36EFI_STATUS\r
37EFIAPI\r
38EfiIp4ConfigUnload (\r
39 IN EFI_HANDLE ImageHandle\r
40 )\r
41{\r
42 UINT32 Index;\r
43\r
44 //\r
45 // Stop all the IP4_CONFIG instances\r
46 //\r
47 for (Index = 0; Index < MAX_IP4_CONFIG_IN_VARIABLE; Index++) {\r
48 if (mIp4ConfigNicList[Index] == NULL) {\r
49 continue;\r
50 }\r
51\r
52 gIp4ConfigDriverBinding.Stop (\r
53 &gIp4ConfigDriverBinding,\r
54 mIp4ConfigNicList[Index]->MnpHandle,\r
55 0,\r
56 NULL\r
57 );\r
58 }\r
59\r
60 return NetLibDefaultUnload (ImageHandle);\r
61}\r
62\r
7bce0c5a 63/**\r
64 The entry point for IP4 config driver which install the driver\r
65 binding and component name protocol on its image.\r
66\r
67 @param ImageHandle The image handle of the driver.\r
68 @param SystemTable The system table.\r
b2570da8 69\r
7bce0c5a 70 @retval EFI_SUCCES All the related protocols are installed on the driver.\r
71 @retval Others Failed to install protocols.\r
72\r
73**/\r
b2570da8 74EFI_STATUS\r
6d3ea23f 75EFIAPI\r
b2570da8 76Ip4ConfigDriverEntryPoint (\r
77 IN EFI_HANDLE ImageHandle,\r
78 IN EFI_SYSTEM_TABLE *SystemTable\r
79 )\r
b2570da8 80{\r
83cbd279 81 return EfiLibInstallDriverBindingComponentName2 (\r
b2570da8 82 ImageHandle,\r
83 SystemTable,\r
84 &gIp4ConfigDriverBinding,\r
85 ImageHandle,\r
86 &gIp4ConfigComponentName,\r
83cbd279 87 &gIp4ConfigComponentName2\r
b2570da8 88 );\r
89}\r
90\r
91\r
92/**\r
93 Test to see if this driver supports ControllerHandle.\r
94\r
95 @param This Protocol instance pointer.\r
96 @param ControllerHandle Handle of device to test\r
97 @param RemainingDevicePath Optional parameter use to pick a specific child\r
98 device to start.\r
99\r
100 @retval EFI_SUCCES This driver supports this device\r
101 @retval EFI_ALREADY_STARTED This driver is already running on this device\r
102 @retval other This driver does not support this device\r
103\r
104**/\r
105EFI_STATUS\r
106EFIAPI\r
107Ip4ConfigDriverBindingSupported (\r
108 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
109 IN EFI_HANDLE ControllerHandle,\r
110 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
111 )\r
112{\r
113 EFI_STATUS Status;\r
114\r
115 Status = gBS->OpenProtocol (\r
116 ControllerHandle,\r
117 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
118 NULL,\r
119 This->DriverBindingHandle,\r
120 ControllerHandle,\r
121 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
122 );\r
123\r
124 return Status;\r
125}\r
126\r
127\r
128/**\r
129 Start this driver on ControllerHandle.\r
130\r
131 @param This Protocol instance pointer.\r
132 @param ControllerHandle Handle of device to bind driver to\r
133 @param RemainingDevicePath Optional parameter use to pick a specific child\r
134 device to start.\r
135\r
136 @retval EFI_SUCCES This driver is added to ControllerHandle\r
137 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
138 @retval other This driver does not support this device\r
139\r
140**/\r
141EFI_STATUS\r
142EFIAPI\r
143Ip4ConfigDriverBindingStart (\r
144 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
145 IN EFI_HANDLE ControllerHandle,\r
146 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
147 )\r
148{\r
149 EFI_IP4_CONFIG_PROTOCOL *Ip4Config;\r
150 EFI_MANAGED_NETWORK_PROTOCOL *Mnp;\r
151 EFI_HANDLE MnpHandle;\r
152 IP4_CONFIG_INSTANCE *Instance;\r
153 EFI_SIMPLE_NETWORK_MODE SnpMode;\r
154 IP4_CONFIG_VARIABLE *Variable;\r
155 NIC_IP4_CONFIG_INFO *NicConfig;\r
156 IP4_CONFIG_VARIABLE *NewVariable;\r
157 EFI_STATUS Status;\r
158 UINT32 Index;\r
159\r
160 //\r
161 // Check for multiple start.\r
162 //\r
163 Status = gBS->OpenProtocol (\r
164 ControllerHandle,\r
165 &gEfiIp4ConfigProtocolGuid,\r
4eb65aff 166 (VOID **) &Ip4Config,\r
b2570da8 167 This->DriverBindingHandle,\r
168 ControllerHandle,\r
169 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
170 );\r
171\r
172 if (!EFI_ERROR (Status)) {\r
173 return EFI_ALREADY_STARTED;\r
174 }\r
175\r
176 //\r
177 // Create a MNP child\r
178 //\r
179 Mnp = NULL;\r
180 MnpHandle = NULL;\r
181 Instance = NULL;\r
182\r
183 Status = NetLibCreateServiceChild (\r
184 ControllerHandle,\r
185 This->DriverBindingHandle,\r
186 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
187 &MnpHandle\r
188 );\r
189\r
190 if (EFI_ERROR (Status)) {\r
191 return Status;\r
192 }\r
193\r
194 Status = gBS->OpenProtocol (\r
195 MnpHandle,\r
196 &gEfiManagedNetworkProtocolGuid,\r
197 (VOID **) &Mnp,\r
198 This->DriverBindingHandle,\r
199 ControllerHandle,\r
200 EFI_OPEN_PROTOCOL_BY_DRIVER\r
201 );\r
202\r
203 if (EFI_ERROR (Status)) {\r
204 goto ON_ERROR;\r
205 }\r
206\r
207 //\r
208 // Allocate an instance then initialize it\r
209 //\r
e48e37fc 210 Instance = AllocatePool (sizeof (IP4_CONFIG_INSTANCE));\r
b2570da8 211\r
212 if (Instance == NULL) {\r
213 Status = EFI_OUT_OF_RESOURCES;\r
214 goto ON_ERROR;\r
215 }\r
216\r
217 Instance->Signature = IP4_CONFIG_INSTANCE_SIGNATURE;\r
218 Instance->Controller = ControllerHandle;\r
219 Instance->Image = This->DriverBindingHandle;\r
220\r
67a58d0f 221 CopyMem (&Instance->Ip4ConfigProtocol, &mIp4ConfigProtocolTemplate, sizeof (mIp4ConfigProtocolTemplate));\r
222 CopyMem (&Instance->NicIp4Protocol, &mNicIp4ConfigProtocolTemplate, sizeof (mNicIp4ConfigProtocolTemplate));\r
b2570da8 223\r
224 Instance->State = IP4_CONFIG_STATE_IDLE;\r
225 Instance->Mnp = Mnp;\r
226 Instance->MnpHandle = MnpHandle;\r
227\r
228 Instance->DoneEvent = NULL;\r
229 Instance->ReconfigEvent = NULL;\r
230 Instance->Result = EFI_NOT_READY;\r
231 Instance->NicConfig = NULL;\r
232\r
233 Instance->Dhcp4 = NULL;\r
234 Instance->Dhcp4Handle = NULL;\r
235 Instance->Dhcp4Event = NULL;\r
236\r
237 Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);\r
238\r
239 if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {\r
240 goto ON_ERROR;\r
241 }\r
242\r
243 Instance->NicAddr.Type = (UINT16) SnpMode.IfType;\r
244 Instance->NicAddr.Len = (UINT8) SnpMode.HwAddressSize;\r
687a2e5f 245 CopyMem (&Instance->NicAddr.MacAddr, &SnpMode.CurrentAddress, sizeof (Instance->NicAddr.MacAddr));\r
b2570da8 246\r
247 //\r
248 // Add it to the global list, and compose the name\r
249 //\r
250 for (Index = 0; Index < MAX_IP4_CONFIG_IN_VARIABLE; Index++) {\r
251 if (mIp4ConfigNicList[Index] == NULL) {\r
252 mIp4ConfigNicList[Index] = Instance;\r
253 Instance->NicIndex = Index;\r
254\r
255 if (Instance->NicAddr.Type == NET_IFTYPE_ETHERNET) {\r
256 Instance->NicName[0] = 'e';\r
257 Instance->NicName[1] = 't';\r
258 Instance->NicName[2] = 'h';\r
259 Instance->NicName[3] = (UINT16) ('0' + Index);\r
260 Instance->NicName[4] = 0;\r
261 } else {\r
262 Instance->NicName[0] = 'u';\r
263 Instance->NicName[1] = 'n';\r
264 Instance->NicName[2] = 'k';\r
265 Instance->NicName[3] = (UINT16) ('0' + Index);\r
266 Instance->NicName[4] = 0;\r
267 }\r
268\r
269 break;\r
270 }\r
271 }\r
272\r
273 if (Index == MAX_IP4_CONFIG_IN_VARIABLE) {\r
274 Status = EFI_OUT_OF_RESOURCES;\r
275 goto ON_ERROR;\r
276 }\r
277\r
278 //\r
279 // Install the IP4_CONFIG and NIC_IP4CONFIG protocols\r
280 //\r
281 Status = gBS->InstallMultipleProtocolInterfaces (\r
282 &ControllerHandle,\r
283 &gEfiIp4ConfigProtocolGuid,\r
284 &Instance->Ip4ConfigProtocol,\r
285 &gEfiNicIp4ConfigProtocolGuid,\r
286 &Instance->NicIp4Protocol,\r
287 NULL\r
288 );\r
289\r
290 if (EFI_ERROR (Status)) {\r
291 mIp4ConfigNicList[Index] = NULL;\r
292 goto ON_ERROR;\r
293 }\r
294\r
295 //\r
296 // Get the previous configure parameters. If an error happend here,\r
297 // just ignore it because the driver should be able to operate.\r
298 //\r
299 Variable = Ip4ConfigReadVariable ();\r
300\r
301 if (Variable == NULL) {\r
302 return EFI_SUCCESS;\r
303 }\r
304\r
305 NicConfig = Ip4ConfigFindNicVariable (Variable, &Instance->NicAddr);\r
306\r
307 if (NicConfig == NULL) {\r
308 goto ON_EXIT;\r
309 }\r
310\r
311 //\r
312 // Don't modify the permant static configuration\r
313 //\r
314 if (NicConfig->Perment && (NicConfig->Source == IP4_CONFIG_SOURCE_STATIC)) {\r
315 goto ON_EXIT;\r
316 }\r
317\r
318 //\r
319 // Delete the non-permant configuration and remove the previous\r
320 // acquired DHCP parameters. Only doing DHCP itself is permant\r
321 //\r
322 NewVariable = NULL;\r
323\r
324 if (!NicConfig->Perment) {\r
325 NewVariable = Ip4ConfigModifyVariable (Variable, &Instance->NicAddr, NULL);\r
326\r
327 } else if (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP) {\r
e48e37fc 328 ZeroMem (&NicConfig->Ip4Info, sizeof (EFI_IP4_IPCONFIG_DATA));\r
b2570da8 329 NewVariable = Ip4ConfigModifyVariable (Variable, &Instance->NicAddr, NicConfig);\r
330\r
331 }\r
332\r
333 Ip4ConfigWriteVariable (NewVariable);\r
334\r
335 if (NewVariable != NULL) {\r
e48e37fc 336 gBS->FreePool (NewVariable);\r
b2570da8 337 }\r
338\r
339ON_EXIT:\r
e48e37fc 340 gBS->FreePool (Variable);\r
b2570da8 341\r
342 if (NicConfig != NULL) {\r
e48e37fc 343 gBS->FreePool (NicConfig);\r
b2570da8 344 }\r
345\r
346 return EFI_SUCCESS;\r
347\r
348ON_ERROR:\r
349 if (Instance != NULL) {\r
e48e37fc 350 gBS->FreePool (Instance);\r
b2570da8 351 }\r
352\r
353 if (Mnp != NULL) {\r
354 gBS->CloseProtocol (\r
355 MnpHandle,\r
356 &gEfiManagedNetworkProtocolGuid,\r
357 This->DriverBindingHandle,\r
358 ControllerHandle\r
359 );\r
360 }\r
361\r
362 NetLibDestroyServiceChild (\r
363 ControllerHandle,\r
364 This->DriverBindingHandle,\r
365 &gEfiManagedNetworkProtocolGuid,\r
366 MnpHandle\r
367 );\r
368\r
369 return Status;\r
370}\r
371\r
372\r
373/**\r
374 Stop this driver on ControllerHandle.\r
375\r
376 @param This Protocol instance pointer.\r
377 @param ControllerHandle Handle of device to stop driver on\r
378 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
379 children is zero stop the entire bus driver.\r
380 @param ChildHandleBuffer List of Child Handles to Stop.\r
381\r
382 @retval EFI_SUCCES This driver is removed ControllerHandle\r
383 @retval other This driver was not removed from this device\r
384\r
385**/\r
386EFI_STATUS\r
387EFIAPI\r
388Ip4ConfigDriverBindingStop (\r
389 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
390 IN EFI_HANDLE ControllerHandle,\r
391 IN UINTN NumberOfChildren,\r
392 IN EFI_HANDLE *ChildHandleBuffer\r
393 )\r
394{\r
395 IP4_CONFIG_INSTANCE *Instance;\r
396 EFI_IP4_CONFIG_PROTOCOL *Ip4Config;\r
397 EFI_HANDLE NicHandle;\r
398 EFI_STATUS Status;\r
399\r
400 //\r
401 // IP4_CONFIG instance opens an MNP child. It may also create and open\r
402 // a DHCP child. If this is the DHCP handle, stop the DHCP process. If\r
403 // it is the MNP child, stop the whole driver.\r
404 //\r
405 //\r
406 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);\r
407\r
408 if (NicHandle != NULL) {\r
409 //\r
410 // Get our context back then clean the DHCP up. Notify the user if necessary.\r
411 //\r
412 Status = gBS->OpenProtocol (\r
413 NicHandle,\r
414 &gEfiIp4ConfigProtocolGuid,\r
415 (VOID **) &Ip4Config,\r
416 This->DriverBindingHandle,\r
417 ControllerHandle,\r
418 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
419 );\r
420\r
421 if (EFI_ERROR (Status)) {\r
422 return Status;\r
423 }\r
424\r
425 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config);\r
426 ASSERT (ControllerHandle == Instance->Dhcp4Handle);\r
427\r
428 Ip4ConfigCleanDhcp4 (Instance);\r
429\r
430 Instance->State = IP4_CONFIG_STATE_CONFIGURED;\r
431 Instance->Result = EFI_DEVICE_ERROR;\r
432\r
433 if (Instance->DoneEvent != NULL) {\r
434 gBS->SignalEvent (Instance->DoneEvent);\r
435 }\r
436\r
437 return EFI_SUCCESS;\r
438 }\r
439\r
440 //\r
441 // This is a MNP handle, stop the whole driver\r
442 //\r
443 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);\r
444\r
445 if (NicHandle == NULL) {\r
446 return EFI_SUCCESS;\r
447 }\r
448\r
449 //\r
450 // Get our context back.\r
451 //\r
452 Status = gBS->OpenProtocol (\r
453 NicHandle,\r
454 &gEfiIp4ConfigProtocolGuid,\r
455 (VOID **) &Ip4Config,\r
456 This->DriverBindingHandle,\r
457 ControllerHandle,\r
458 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
459 );\r
460\r
461 if (EFI_ERROR (Status)) {\r
462 return Status;\r
463 }\r
464\r
465 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config);\r
466\r
467 //\r
468 // Unload the protocols first to inform the top drivers\r
469 //\r
470 Status = gBS->UninstallMultipleProtocolInterfaces (\r
471 NicHandle,\r
472 &gEfiIp4ConfigProtocolGuid,\r
473 &Instance->Ip4ConfigProtocol,\r
474 &gEfiNicIp4ConfigProtocolGuid,\r
475 &Instance->NicIp4Protocol,\r
476 NULL\r
477 );\r
478\r
479 if (EFI_ERROR (Status)) {\r
480 return Status;\r
481 }\r
482\r
483 //\r
484 // Release all the resources\r
485 //\r
486 if (Instance->MnpHandle != NULL) {\r
487 gBS->CloseProtocol (\r
488 Instance->MnpHandle,\r
489 &gEfiManagedNetworkProtocolGuid,\r
490 This->DriverBindingHandle,\r
491 NicHandle\r
492 );\r
493\r
494 NetLibDestroyServiceChild (\r
495 NicHandle,\r
496 Instance->Image,\r
497 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
498 Instance->MnpHandle\r
499 );\r
500\r
501 Instance->Mnp = NULL;\r
502 Instance->MnpHandle = NULL;\r
503 }\r
504\r
505 Ip4ConfigCleanConfig (Instance);\r
506 mIp4ConfigNicList[Instance->NicIndex] = NULL;\r
e48e37fc 507 gBS->FreePool (Instance);\r
b2570da8 508\r
509 return EFI_SUCCESS;\r
510}\r
511\r