fixed bug in stop() function, that made stop() failure.
[people/mcb30/edk2.git] / edk2 / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcDriver.c
1 /** @file\r
2 \r
3 Copyright (c) 2007 - 2008, 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
11 \r
12 Module Name:\r
13 \r
14   PxeBcDriver.c\r
15 \r
16 Abstract:\r
17 \r
18   The driver binding for IP4 CONFIG protocol.\r
19 \r
20 \r
21 **/\r
22 \r
23 \r
24 #include "PxeBcImpl.h"\r
25 \r
26 \r
27 /**\r
28   The entry point for PxeBc driver which install the driver\r
29   binding and component name protocol on its image.\r
30 \r
31   @param  ImageHandle          The Image handle of the driver\r
32   @param  SystemTable          The system table\r
33 \r
34   @return EFI_SUCCESS\r
35   @return Others\r
36 \r
37 **/\r
38 EFI_STATUS\r
39 PxeBcDriverEntryPoint (\r
40   IN EFI_HANDLE             ImageHandle,\r
41   IN EFI_SYSTEM_TABLE       *SystemTable\r
42   )\r
43 {\r
44   return EfiLibInstallDriverBindingComponentName2 (\r
45           ImageHandle,\r
46           SystemTable,\r
47           &gPxeBcDriverBinding,\r
48           ImageHandle,\r
49           &gPxeBcComponentName,\r
50           &gPxeBcComponentName2\r
51           );\r
52 }\r
53 \r
54 \r
55 /**\r
56   Test to see if this driver supports ControllerHandle.\r
57 \r
58   @param  This                 Protocol instance pointer.\r
59   @param  ControllerHandle     Handle of device to test\r
60   @param  RemainingDevicePath  Optional parameter use to pick a specific child\r
61                                device to start.\r
62 \r
63   @return EFI_SUCCES\r
64   @return EFI_ALREADY_STARTED\r
65   @return Others\r
66 \r
67 **/\r
68 EFI_STATUS\r
69 EFIAPI\r
70 PxeBcDriverBindingSupported (\r
71   IN EFI_DRIVER_BINDING_PROTOCOL  * This,\r
72   IN EFI_HANDLE                   ControllerHandle,\r
73   IN EFI_DEVICE_PATH_PROTOCOL     * RemainingDevicePath OPTIONAL\r
74   )\r
75 {\r
76   EFI_PXE_BASE_CODE_PROTOCOL  *PxeBc;\r
77   EFI_STATUS                  Status;\r
78 \r
79   Status = gBS->OpenProtocol (\r
80                   ControllerHandle,\r
81                   &gEfiPxeBaseCodeProtocolGuid,\r
82                   (VOID **) &PxeBc,\r
83                   This->DriverBindingHandle,\r
84                   ControllerHandle,\r
85                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
86                   );\r
87 \r
88   if (!EFI_ERROR (Status)) {\r
89     return EFI_ALREADY_STARTED;\r
90   }\r
91 \r
92   Status = gBS->OpenProtocol (\r
93                   ControllerHandle,\r
94                   &gEfiDhcp4ServiceBindingProtocolGuid,\r
95                   NULL,\r
96                   This->DriverBindingHandle,\r
97                   ControllerHandle,\r
98                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
99                   );\r
100 \r
101   if (!EFI_ERROR (Status)) {\r
102 \r
103     Status = gBS->OpenProtocol (\r
104                     ControllerHandle,\r
105                     &gEfiMtftp4ServiceBindingProtocolGuid,\r
106                     NULL,\r
107                     This->DriverBindingHandle,\r
108                     ControllerHandle,\r
109                     EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
110                     );\r
111 \r
112   }\r
113 \r
114   return Status;\r
115 }\r
116 \r
117 \r
118 /**\r
119   Start this driver on ControllerHandle.\r
120 \r
121   @param  This                 Protocol instance pointer.\r
122   @param  ControllerHandle     Handle of device to bind driver to\r
123   @param  RemainingDevicePath  Optional parameter use to pick a specific child\r
124                                device to start.\r
125 \r
126   @return EFI_SUCCES\r
127   @return EFI_ALREADY_STARTED\r
128   @return EFI_OUT_OF_RESOURCES\r
129   @return Others\r
130 \r
131 **/\r
132 EFI_STATUS\r
133 EFIAPI\r
134 PxeBcDriverBindingStart (\r
135   IN EFI_DRIVER_BINDING_PROTOCOL  * This,\r
136   IN EFI_HANDLE                   ControllerHandle,\r
137   IN EFI_DEVICE_PATH_PROTOCOL     * RemainingDevicePath OPTIONAL\r
138   )\r
139 {\r
140   PXEBC_PRIVATE_DATA  *Private;\r
141   UINTN               Index;\r
142   EFI_STATUS          Status;\r
143 \r
144   Private = AllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA));\r
145   if (Private == NULL) {\r
146     return EFI_OUT_OF_RESOURCES;\r
147   }\r
148 \r
149   Private->Signature                    = PXEBC_PRIVATE_DATA_SIGNATURE;\r
150   Private->Controller                   = ControllerHandle;\r
151   Private->Image                        = This->DriverBindingHandle;\r
152   CopyMem (&Private->PxeBc, &mPxeBcProtocolTemplate, sizeof (Private->PxeBc));\r
153   Private->PxeBc.Mode                   = &Private->Mode;\r
154   CopyMem (&Private->LoadFile, &mLoadFileProtocolTemplate, sizeof (Private->LoadFile));\r
155 \r
156   Private->ProxyOffer.Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;\r
157   Private->Dhcp4Ack.Packet.Ack.Size     = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;\r
158   Private->PxeReply.Packet.Ack.Size     = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;\r
159 \r
160   for (Index = 0; Index < PXEBC_MAX_OFFER_NUM; Index++) {\r
161     Private->Dhcp4Offers[Index].Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;\r
162   }\r
163 \r
164   //\r
165   // Get the NII interface\r
166   //\r
167   Status = gBS->OpenProtocol (\r
168                   ControllerHandle,\r
169                   &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
170                   (VOID **) &Private->Nii,\r
171                   This->DriverBindingHandle,\r
172                   ControllerHandle,\r
173                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
174                   );\r
175   if (EFI_ERROR (Status)) {\r
176     goto ON_ERROR;\r
177   }\r
178 \r
179   Status = NetLibCreateServiceChild (\r
180             ControllerHandle,\r
181             This->DriverBindingHandle,\r
182             &gEfiArpServiceBindingProtocolGuid,\r
183             &Private->ArpChild\r
184             );\r
185   if (EFI_ERROR (Status)) {\r
186     goto ON_ERROR;\r
187   }\r
188 \r
189   Status = gBS->OpenProtocol (\r
190                   Private->ArpChild,\r
191                   &gEfiArpProtocolGuid,\r
192                   (VOID **) &Private->Arp,\r
193                   This->DriverBindingHandle,\r
194                   ControllerHandle,\r
195                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
196                   );\r
197   if (EFI_ERROR (Status)) {\r
198     goto ON_ERROR;\r
199   }\r
200 \r
201   Status = NetLibCreateServiceChild (\r
202             ControllerHandle,\r
203             This->DriverBindingHandle,\r
204             &gEfiDhcp4ServiceBindingProtocolGuid,\r
205             &Private->Dhcp4Child\r
206             );\r
207   if (EFI_ERROR (Status)) {\r
208     goto ON_ERROR;\r
209   }\r
210 \r
211   Status = gBS->OpenProtocol (\r
212                   Private->Dhcp4Child,\r
213                   &gEfiDhcp4ProtocolGuid,\r
214                   (VOID **) &Private->Dhcp4,\r
215                   This->DriverBindingHandle,\r
216                   ControllerHandle,\r
217                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
218                   );\r
219   if (EFI_ERROR (Status)) {\r
220     goto ON_ERROR;\r
221   }\r
222 \r
223   Status = NetLibCreateServiceChild (\r
224              ControllerHandle,\r
225              This->DriverBindingHandle,\r
226              &gEfiIp4ServiceBindingProtocolGuid,\r
227              &Private->Ip4Child\r
228              );\r
229   if (EFI_ERROR (Status)) {\r
230     goto ON_ERROR;\r
231   }\r
232 \r
233   Status = gBS->OpenProtocol (\r
234                   Private->Ip4Child,\r
235                   &gEfiIp4ProtocolGuid,\r
236                   (VOID **) &Private->Ip4,\r
237                   This->DriverBindingHandle,\r
238                   ControllerHandle,\r
239                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
240                   );\r
241   if (EFI_ERROR (Status)) {\r
242     goto ON_ERROR;\r
243   }\r
244 \r
245   Status = NetLibCreateServiceChild (\r
246              ControllerHandle,\r
247              This->DriverBindingHandle,\r
248              &gEfiMtftp4ServiceBindingProtocolGuid,\r
249              &Private->Mtftp4Child\r
250              );\r
251 \r
252   if (EFI_ERROR (Status)) {\r
253     goto ON_ERROR;\r
254   }\r
255 \r
256   Status = gBS->OpenProtocol (\r
257                   Private->Mtftp4Child,\r
258                   &gEfiMtftp4ProtocolGuid,\r
259                   (VOID **) &Private->Mtftp4,\r
260                   This->DriverBindingHandle,\r
261                   ControllerHandle,\r
262                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
263                   );\r
264 \r
265   if (EFI_ERROR (Status)) {\r
266     goto ON_ERROR;\r
267   }\r
268 \r
269   Status = NetLibCreateServiceChild (\r
270              ControllerHandle,\r
271              This->DriverBindingHandle,\r
272              &gEfiUdp4ServiceBindingProtocolGuid,\r
273              &Private->Udp4Child\r
274              );\r
275 \r
276   if (EFI_ERROR (Status)) {\r
277     goto ON_ERROR;\r
278   }\r
279 \r
280   Status = gBS->OpenProtocol (\r
281                   Private->Udp4Child,\r
282                   &gEfiUdp4ProtocolGuid,\r
283                   (VOID **) &Private->Udp4,\r
284                   This->DriverBindingHandle,\r
285                   ControllerHandle,\r
286                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
287                   );\r
288 \r
289   if (EFI_ERROR (Status)) {\r
290     goto ON_ERROR;\r
291   }\r
292 \r
293   ZeroMem (&Private->Udp4CfgData, sizeof (EFI_UDP4_CONFIG_DATA));\r
294   Private->Udp4CfgData.AcceptBroadcast    = FALSE;\r
295   Private->Udp4CfgData.AcceptPromiscuous  = FALSE;\r
296   Private->Udp4CfgData.AcceptAnyPort      = FALSE;\r
297   Private->Udp4CfgData.AllowDuplicatePort = TRUE;\r
298   Private->Udp4CfgData.TypeOfService      = DEFAULT_ToS;\r
299   Private->Udp4CfgData.TimeToLive         = DEFAULT_TTL;\r
300   Private->Udp4CfgData.DoNotFragment      = FALSE;\r
301   Private->Udp4CfgData.ReceiveTimeout     = 10000;  // 10 milliseconds\r
302   Private->Udp4CfgData.UseDefaultAddress  = FALSE;\r
303 \r
304   PxeBcInitSeedPacket (&Private->SeedPacket, Private->Udp4);\r
305   Private->MacLen = Private->SeedPacket.Dhcp4.Header.HwAddrLen;\r
306   CopyMem (&Private->Mac, &Private->SeedPacket.Dhcp4.Header.ClientHwAddr[0], Private->MacLen);\r
307 \r
308 \r
309   ZeroMem (&Private->Ip4ConfigData, sizeof (EFI_IP4_CONFIG_DATA));\r
310   Private->Ip4ConfigData.DefaultProtocol   = EFI_IP_PROTO_ICMP;\r
311   Private->Ip4ConfigData.AcceptIcmpErrors  = TRUE;\r
312   Private->Ip4ConfigData.TypeOfService     = DEFAULT_ToS;\r
313   Private->Ip4ConfigData.TimeToLive        = DEFAULT_TTL;\r
314   Private->Ip4ConfigData.DoNotFragment     = FALSE;\r
315   Private->Ip4ConfigData.RawData           = FALSE;\r
316 \r
317   Status = gBS->InstallMultipleProtocolInterfaces (\r
318                   &ControllerHandle,\r
319                   &gEfiPxeBaseCodeProtocolGuid,\r
320                   &Private->PxeBc,\r
321                   &gEfiLoadFileProtocolGuid,\r
322                   &Private->LoadFile,\r
323                   NULL\r
324                   );\r
325   if (EFI_ERROR (Status)) {\r
326     goto ON_ERROR;\r
327   }\r
328 \r
329   return EFI_SUCCESS;\r
330 \r
331 ON_ERROR:\r
332 \r
333   if (Private->Udp4Child != NULL) {\r
334     gBS->CloseProtocol (\r
335           Private->Udp4Child,\r
336           &gEfiUdp4ProtocolGuid,\r
337           This->DriverBindingHandle,\r
338           ControllerHandle\r
339           );\r
340     NetLibDestroyServiceChild (\r
341       ControllerHandle,\r
342       This->DriverBindingHandle,\r
343       &gEfiUdp4ServiceBindingProtocolGuid,\r
344       Private->Udp4Child\r
345       );\r
346   }\r
347 \r
348   if (Private->Mtftp4Child != NULL) {\r
349     gBS->CloseProtocol (\r
350           Private->Mtftp4Child,\r
351           &gEfiMtftp4ProtocolGuid,\r
352           This->DriverBindingHandle,\r
353           ControllerHandle\r
354           );\r
355 \r
356     NetLibDestroyServiceChild (\r
357       ControllerHandle,\r
358       This->DriverBindingHandle,\r
359       &gEfiMtftp4ServiceBindingProtocolGuid,\r
360       Private->Mtftp4Child\r
361       );\r
362   }\r
363 \r
364   if (Private->Ip4Child != NULL) {\r
365     gBS->CloseProtocol (\r
366           Private->Ip4Child,\r
367           &gEfiIp4ProtocolGuid,\r
368           This->DriverBindingHandle,\r
369           ControllerHandle\r
370           );\r
371 \r
372     NetLibDestroyServiceChild (\r
373       ControllerHandle,\r
374       This->DriverBindingHandle,\r
375       &gEfiIp4ServiceBindingProtocolGuid,\r
376       Private->Ip4Child\r
377       );\r
378   }\r
379 \r
380   if (Private->Dhcp4Child != NULL) {\r
381     gBS->CloseProtocol (\r
382           Private->Dhcp4Child,\r
383           &gEfiDhcp4ProtocolGuid,\r
384           This->DriverBindingHandle,\r
385           ControllerHandle\r
386           );\r
387 \r
388     NetLibDestroyServiceChild (\r
389       ControllerHandle,\r
390       This->DriverBindingHandle,\r
391       &gEfiDhcp4ServiceBindingProtocolGuid,\r
392       Private->Dhcp4Child\r
393       );\r
394   }\r
395 \r
396   if (Private->ArpChild != NULL) {\r
397     gBS->CloseProtocol (\r
398           Private->ArpChild,\r
399           &gEfiArpProtocolGuid,\r
400           This->DriverBindingHandle,\r
401           ControllerHandle\r
402           );\r
403 \r
404     NetLibDestroyServiceChild (\r
405       ControllerHandle,\r
406       This->DriverBindingHandle,\r
407       &gEfiArpServiceBindingProtocolGuid,\r
408       Private->ArpChild\r
409       );\r
410   }\r
411 \r
412   gBS->FreePool (Private);\r
413 \r
414   return Status;\r
415 }\r
416 \r
417 \r
418 /**\r
419   Stop this driver on ControllerHandle.\r
420 \r
421   @param  This                 Protocol instance pointer.\r
422   @param  ControllerHandle     Handle of device to stop driver on\r
423   @param  NumberOfChildren     Number of Handles in ChildHandleBuffer. If number of\r
424                                 children is zero stop the entire bus driver.\r
425   @param  ChildHandleBuffer    List of Child Handles to Stop.\r
426 \r
427   @return EFI_SUCCESS\r
428   @return EFI_DEVICE_ERROR\r
429   @return Others\r
430 \r
431 **/\r
432 EFI_STATUS\r
433 EFIAPI\r
434 PxeBcDriverBindingStop (\r
435   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
436   IN EFI_HANDLE                   ControllerHandle,\r
437   IN UINTN                        NumberOfChildren,\r
438   IN EFI_HANDLE                   *ChildHandleBuffer\r
439   )\r
440 {\r
441   PXEBC_PRIVATE_DATA          *Private;\r
442   EFI_PXE_BASE_CODE_PROTOCOL  *PxeBc;\r
443   EFI_HANDLE                  NicHandle;\r
444   EFI_STATUS                  Status;\r
445 \r
446   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);\r
447   if (NicHandle == NULL) {\r
448     NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);\r
449 \r
450     if (NicHandle == NULL) {\r
451       NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
452 \r
453       if (NicHandle == NULL) {\r
454         NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);\r
455 \r
456         if (NicHandle == NULL) {\r
457           NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);\r
458 \r
459           if (NicHandle == NULL) {\r
460             return EFI_DEVICE_ERROR;\r
461           }\r
462         }\r
463       }\r
464     }\r
465   }\r
466 \r
467   Status = gBS->OpenProtocol (\r
468                   NicHandle,\r
469                   &gEfiPxeBaseCodeProtocolGuid,\r
470                   (VOID **) &PxeBc,\r
471                   This->DriverBindingHandle,\r
472                   ControllerHandle,\r
473                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
474                   );\r
475 \r
476   if (EFI_ERROR (Status)) {\r
477     return Status;\r
478   }\r
479 \r
480   Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc);\r
481 \r
482   Status = gBS->UninstallMultipleProtocolInterfaces (\r
483                   NicHandle,\r
484                   &gEfiPxeBaseCodeProtocolGuid,\r
485                   &Private->PxeBc,\r
486                   &gEfiLoadFileProtocolGuid,\r
487                   &Private->LoadFile,\r
488                   NULL\r
489                   );\r
490 \r
491   if (!EFI_ERROR (Status)) {\r
492 \r
493     gBS->CloseProtocol (\r
494           Private->Udp4Child,\r
495           &gEfiUdp4ProtocolGuid,\r
496           This->DriverBindingHandle,\r
497           NicHandle\r
498           );\r
499     NetLibDestroyServiceChild (\r
500       NicHandle,\r
501       This->DriverBindingHandle,\r
502       &gEfiUdp4ServiceBindingProtocolGuid,\r
503       Private->Udp4Child\r
504       );\r
505 \r
506     gBS->CloseProtocol (\r
507           Private->Dhcp4Child,\r
508           &gEfiDhcp4ProtocolGuid,\r
509           This->DriverBindingHandle,\r
510           NicHandle\r
511           );\r
512     NetLibDestroyServiceChild (\r
513       NicHandle,\r
514       This->DriverBindingHandle,\r
515       &gEfiDhcp4ServiceBindingProtocolGuid,\r
516       Private->Dhcp4Child\r
517       );\r
518 \r
519     gBS->CloseProtocol (\r
520           Private->Mtftp4Child,\r
521           &gEfiMtftp4ProtocolGuid,\r
522           This->DriverBindingHandle,\r
523           NicHandle\r
524           );\r
525     NetLibDestroyServiceChild (\r
526       NicHandle,\r
527       This->DriverBindingHandle,\r
528       &gEfiMtftp4ServiceBindingProtocolGuid,\r
529       Private->Mtftp4Child\r
530       );\r
531 \r
532     gBS->CloseProtocol (\r
533           Private->Ip4Child,\r
534           &gEfiIp4ProtocolGuid,\r
535           This->DriverBindingHandle,\r
536           NicHandle\r
537           );\r
538     NetLibDestroyServiceChild (\r
539       NicHandle,\r
540       This->DriverBindingHandle,\r
541       &gEfiIp4ServiceBindingProtocolGuid,\r
542       Private->Ip4Child\r
543       );\r
544 \r
545     gBS->CloseProtocol (\r
546           Private->ArpChild,\r
547           &gEfiArpProtocolGuid,\r
548           This->DriverBindingHandle,\r
549           NicHandle\r
550           );\r
551     NetLibDestroyServiceChild (\r
552       NicHandle,\r
553       This->DriverBindingHandle,\r
554       &gEfiArpServiceBindingProtocolGuid,\r
555       Private->ArpChild\r
556       );\r
557 \r
558     gBS->FreePool (Private);\r
559   }\r
560 \r
561   return Status;\r
562 }\r
563 \r
564 EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {\r
565   PxeBcDriverBindingSupported,\r
566   PxeBcDriverBindingStart,\r
567   PxeBcDriverBindingStop,\r
568   0xa,\r
569   NULL,\r
570   NULL\r
571 };\r
572 \r
573 \r