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