1 /** @file
2   The driver binding for VLAN configuration module.
3 
4 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution.  The full
8 text of the license may be found at<BR>
9 http://opensource.org/licenses/bsd-license.php
10 
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include "VlanConfigImpl.h"
17 
18 EFI_DRIVER_BINDING_PROTOCOL gVlanConfigDriverBinding = {
19   VlanConfigDriverBindingSupported,
20   VlanConfigDriverBindingStart,
21   VlanConfigDriverBindingStop,
22   0xa,
23   NULL,
24   NULL
25 };
26 
27 /**
28   The entry point for IP4 config driver which install the driver
29   binding and component name protocol on its image.
30 
31   @param[in]  ImageHandle        The image handle of the driver.
32   @param[in]  SystemTable        The system table.
33 
34   @retval EFI_SUCCES             All the related protocols are installed on the driver.
35   @retval Others                 Failed to install protocols.
36 
37 **/
38 EFI_STATUS
39 EFIAPI
VlanConfigDriverEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)40 VlanConfigDriverEntryPoint (
41   IN EFI_HANDLE          ImageHandle,
42   IN EFI_SYSTEM_TABLE    *SystemTable
43   )
44 {
45   return EfiLibInstallDriverBindingComponentName2 (
46            ImageHandle,
47            SystemTable,
48            &gVlanConfigDriverBinding,
49            ImageHandle,
50            &gVlanConfigComponentName,
51            &gVlanConfigComponentName2
52            );
53 }
54 
55 
56 /**
57   Test to see if this driver supports ControllerHandle.
58 
59   @param[in]  This                 Protocol instance pointer.
60   @param[in]  ControllerHandle     Handle of device to test
61   @param[in]  RemainingDevicePath  Optional parameter use to pick a specific child
62                                    device to start.
63 
64   @retval EFI_SUCCES           This driver supports this device
65   @retval EFI_ALREADY_STARTED  This driver is already running on this device
66   @retval other                This driver does not support this device
67 
68 **/
69 EFI_STATUS
70 EFIAPI
VlanConfigDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL)71 VlanConfigDriverBindingSupported (
72   IN EFI_DRIVER_BINDING_PROTOCOL     *This,
73   IN EFI_HANDLE                      ControllerHandle,
74   IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath OPTIONAL
75   )
76 {
77   EFI_STATUS                Status;
78   EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;
79 
80   Status = gBS->OpenProtocol (
81                   ControllerHandle,
82                   &gEfiVlanConfigProtocolGuid,
83                   (VOID **) &VlanConfig,
84                   This->DriverBindingHandle,
85                   ControllerHandle,
86                   EFI_OPEN_PROTOCOL_BY_DRIVER
87                   );
88   if (EFI_ERROR (Status)) {
89     return Status;
90   }
91 
92   //
93   // Close the VlanConfig protocol opened for supported test
94   //
95   gBS->CloseProtocol (
96          ControllerHandle,
97          &gEfiVlanConfigProtocolGuid,
98          This->DriverBindingHandle,
99          ControllerHandle
100          );
101 
102   return Status;
103 }
104 
105 
106 /**
107   Start this driver on ControllerHandle.
108 
109   @param[in]  This                 Protocol instance pointer.
110   @param[in]  ControllerHandle     Handle of device to bind driver to
111   @param[in]  RemainingDevicePath  Optional parameter use to pick a specific child
112                                    device to start.
113 
114   @retval EFI_SUCCES           This driver is added to ControllerHandle
115   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
116   @retval other                This driver does not support this device
117 
118 **/
119 EFI_STATUS
120 EFIAPI
VlanConfigDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL)121 VlanConfigDriverBindingStart (
122   IN EFI_DRIVER_BINDING_PROTOCOL     *This,
123   IN EFI_HANDLE                      ControllerHandle,
124   IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath OPTIONAL
125   )
126 {
127   EFI_STATUS                Status;
128   EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;
129   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
130   VLAN_CONFIG_PRIVATE_DATA  *PrivateData;
131 
132   //
133   // Check for multiple start
134   //
135   Status = gBS->OpenProtocol (
136                   ControllerHandle,
137                   &gEfiCallerIdGuid,
138                   (VOID **) &PrivateData,
139                   This->DriverBindingHandle,
140                   ControllerHandle,
141                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
142                   );
143   if (!EFI_ERROR (Status)) {
144     return EFI_ALREADY_STARTED;
145   }
146 
147   //
148   // Open VlanConfig protocol by driver
149   //
150   Status = gBS->OpenProtocol (
151                   ControllerHandle,
152                   &gEfiVlanConfigProtocolGuid,
153                   (VOID **) &VlanConfig,
154                   This->DriverBindingHandle,
155                   ControllerHandle,
156                   EFI_OPEN_PROTOCOL_BY_DRIVER
157                   );
158   if (EFI_ERROR (Status)) {
159     return Status;
160   }
161 
162   //
163   // Get parent device path
164   //
165   Status = gBS->OpenProtocol (
166                   ControllerHandle,
167                   &gEfiDevicePathProtocolGuid,
168                   (VOID **) &DevicePath,
169                   This->DriverBindingHandle,
170                   ControllerHandle,
171                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
172                   );
173   if (EFI_ERROR (Status)) {
174     goto ErrorExit;
175   }
176 
177   //
178   // Create a private data for this network device
179   //
180   PrivateData = AllocateCopyPool (sizeof (VLAN_CONFIG_PRIVATE_DATA), &mVlanConfigPrivateDateTemplate);
181   if (PrivateData == NULL) {
182     Status = EFI_OUT_OF_RESOURCES;
183     goto ErrorExit;
184   }
185 
186   PrivateData->ImageHandle = This->DriverBindingHandle;
187   PrivateData->ControllerHandle = ControllerHandle;
188   PrivateData->VlanConfig = VlanConfig;
189   PrivateData->ParentDevicePath = DevicePath;
190 
191   //
192   // Install VLAN configuration form
193   //
194   Status = InstallVlanConfigForm (PrivateData);
195   if (EFI_ERROR (Status)) {
196     goto ErrorExit;
197   }
198 
199   //
200   // Install private GUID
201   //
202   Status = gBS->InstallMultipleProtocolInterfaces (
203                   &ControllerHandle,
204                   &gEfiCallerIdGuid,
205                   PrivateData,
206                   NULL
207                   );
208   if (EFI_ERROR (Status)) {
209     goto ErrorExit;
210   }
211   return Status;
212 
213 ErrorExit:
214   gBS->CloseProtocol (
215          ControllerHandle,
216          &gEfiVlanConfigProtocolGuid,
217          This->DriverBindingHandle,
218          ControllerHandle
219          );
220 
221   gBS->CloseProtocol (
222          ControllerHandle,
223          &gEfiDevicePathProtocolGuid,
224          This->DriverBindingHandle,
225          ControllerHandle
226          );
227 
228   if (PrivateData != NULL) {
229     UninstallVlanConfigForm (PrivateData);
230     FreePool (PrivateData);
231   }
232 
233   return Status;
234 }
235 
236 
237 /**
238   Stop this driver on ControllerHandle.
239 
240   @param[in]  This                 Protocol instance pointer.
241   @param[in]  ControllerHandle     Handle of device to stop driver on
242   @param[in]  NumberOfChildren     Number of Handles in ChildHandleBuffer. If number
243                                    of children is zero stop the entire bus driver.
244   @param[in]  ChildHandleBuffer    List of Child Handles to Stop.
245 
246   @retval EFI_SUCCES           This driver is removed ControllerHandle
247   @retval other                This driver was not removed from this device
248 
249 **/
250 EFI_STATUS
251 EFIAPI
VlanConfigDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)252 VlanConfigDriverBindingStop (
253   IN EFI_DRIVER_BINDING_PROTOCOL     *This,
254   IN EFI_HANDLE                      ControllerHandle,
255   IN UINTN                           NumberOfChildren,
256   IN EFI_HANDLE                      *ChildHandleBuffer
257   )
258 {
259   EFI_STATUS                Status;
260   VLAN_CONFIG_PRIVATE_DATA  *PrivateData;
261 
262   //
263   // Retrieve the PrivateData from ControllerHandle
264   //
265   Status = gBS->OpenProtocol (
266                   ControllerHandle,
267                   &gEfiCallerIdGuid,
268                   (VOID **) &PrivateData,
269                   This->DriverBindingHandle,
270                   ControllerHandle,
271                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
272                   );
273   if (EFI_ERROR (Status)) {
274     return Status;
275   }
276   ASSERT (PrivateData->Signature == VLAN_CONFIG_PRIVATE_DATA_SIGNATURE);
277 
278   if (NumberOfChildren != 0) {
279     if (NumberOfChildren != 1 || ChildHandleBuffer[0] != PrivateData->DriverHandle) {
280       return EFI_DEVICE_ERROR;
281     }
282 
283     return UninstallVlanConfigForm (PrivateData);
284   }
285 
286   //
287   // Uninstall the private GUID
288   //
289   Status = gBS->UninstallMultipleProtocolInterfaces (
290                   ControllerHandle,
291                   &gEfiCallerIdGuid,
292                   PrivateData,
293                   NULL
294                   );
295   if (EFI_ERROR (Status)) {
296     return Status;
297   }
298 
299   Status = gBS->CloseProtocol (
300                   ControllerHandle,
301                   &gEfiVlanConfigProtocolGuid,
302                   This->DriverBindingHandle,
303                   ControllerHandle
304                   );
305   return Status;
306 }
307