]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c
Fix a bug about the iSCSI DHCP dependency issue.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiDriver.c
CommitLineData
12618416 1/** @file\r
fd82de4e 2 The entry point of IScsi driver.\r
6a690e23 3\r
05a30011 4Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
7a444476 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
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
6a690e23 12\r
12618416 13**/\r
6a690e23 14\r
15#include "IScsiImpl.h"\r
16\r
17EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding = {\r
18 IScsiDriverBindingSupported,\r
19 IScsiDriverBindingStart,\r
20 IScsiDriverBindingStop,\r
21 0xa,\r
22 NULL,\r
23 NULL\r
24};\r
25\r
05a30011
WJ
26/**\r
27 Tests to see if this driver supports the RemainingDevicePath. \r
28\r
29 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This \r
30 parameter is ignored by device drivers, and is optional for bus \r
31 drivers. For bus drivers, if this parameter is not NULL, then \r
32 the bus driver must determine if the bus controller specified \r
33 by ControllerHandle and the child controller specified \r
34 by RemainingDevicePath are both supported by this \r
35 bus driver.\r
36\r
37 @retval EFI_SUCCESS The RemainingDevicePath is supported or NULL.\r
38 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
39 RemainingDevicePath is not supported by the driver specified by This.\r
40**/\r
41EFI_STATUS\r
42IScsiIsDevicePathSupported (\r
43 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
44 )\r
45{\r
46 EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;\r
47\r
48 CurrentDevicePath = RemainingDevicePath;\r
49 if (CurrentDevicePath != NULL) {\r
50 while (!IsDevicePathEnd (CurrentDevicePath)) {\r
51 if ((CurrentDevicePath->Type == MESSAGING_DEVICE_PATH) && (CurrentDevicePath->SubType == MSG_ISCSI_DP)) {\r
52 return EFI_SUCCESS;\r
53 }\r
54\r
55 CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);\r
56 }\r
57\r
58 return EFI_UNSUPPORTED;\r
59 }\r
60\r
61 return EFI_SUCCESS;\r
62}\r
63\r
fd82de4e 64/**\r
65 Tests to see if this driver supports a given controller. If a child device is provided, \r
66 it further tests to see if this driver supports creating a handle for the specified child device.\r
67\r
68 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
69 @param[in] ControllerHandle The handle of the controller to test. This handle \r
70 must support a protocol interface that supplies \r
71 an I/O abstraction to the driver.\r
72 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. \r
73 This parameter is ignored by device drivers, and is optional for bus drivers.\r
74\r
75\r
76 @retval EFI_SUCCESS The device specified by ControllerHandle and\r
77 RemainingDevicePath is supported by the driver specified by This.\r
78 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
79 RemainingDevicePath is already being managed by the driver\r
80 specified by This.\r
81 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
82 RemainingDevicePath is already being managed by a different\r
83 driver or an application that requires exclusive acces.\r
84 Currently not implemented.\r
85 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
86 RemainingDevicePath is not supported by the driver specified by This.\r
12618416 87**/\r
88EFI_STATUS\r
89EFIAPI\r
90IScsiDriverBindingSupported (\r
fd82de4e 91 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
12618416 92 IN EFI_HANDLE ControllerHandle,\r
fd82de4e 93 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
12618416 94 )\r
6a690e23 95{\r
96 EFI_STATUS Status;\r
6a690e23 97\r
98 Status = gBS->OpenProtocol (\r
99 ControllerHandle,\r
c8ad2d7a 100 &gEfiCallerIdGuid,\r
6a690e23 101 NULL,\r
102 This->DriverBindingHandle,\r
103 ControllerHandle,\r
104 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
105 );\r
106 if (!EFI_ERROR (Status)) {\r
107 return EFI_ALREADY_STARTED;\r
108 }\r
109\r
110 Status = gBS->OpenProtocol (\r
111 ControllerHandle,\r
112 &gEfiTcp4ServiceBindingProtocolGuid,\r
113 NULL,\r
114 This->DriverBindingHandle,\r
115 ControllerHandle,\r
116 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
117 );\r
118 if (EFI_ERROR (Status)) {\r
119 return EFI_UNSUPPORTED;\r
120 }\r
121\r
05a30011
WJ
122 Status = IScsiIsDevicePathSupported (RemainingDevicePath);\r
123 if (EFI_ERROR (Status)) {\r
124 return EFI_UNSUPPORTED;\r
125 }\r
6a690e23 126\r
05a30011
WJ
127 if (IScsiDhcpIsConfigured (ControllerHandle)) {\r
128 Status = gBS->OpenProtocol (\r
129 ControllerHandle,\r
130 &gEfiDhcp4ServiceBindingProtocolGuid,\r
131 NULL,\r
132 This->DriverBindingHandle,\r
133 ControllerHandle,\r
134 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
135 );\r
136 if (EFI_ERROR (Status)) {\r
137 return EFI_UNSUPPORTED;\r
6a690e23 138 }\r
6a690e23 139 }\r
140\r
141 return EFI_SUCCESS;\r
142}\r
143\r
12618416 144/**\r
55a64ae0 145 Start this driver on ControllerHandle. \r
146 \r
147 The Start() function is designed to be invoked from the EFI boot service ConnectController(). \r
148 As a result, much of the error checking on the parameters to Start() has been moved into this \r
149 common boot service. It is legal to call Start() from other locations, but the following calling \r
150 restrictions must be followed or the system behavior will not be deterministic.\r
fd82de4e 151 1. ControllerHandle must be a valid EFI_HANDLE.\r
152 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
153 EFI_DEVICE_PATH_PROTOCOL.\r
154 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
155 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. \r
156\r
157 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
158 @param[in] ControllerHandle The handle of the controller to start. This handle \r
159 must support a protocol interface that supplies \r
160 an I/O abstraction to the driver.\r
161 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. \r
162 This parameter is ignored by device drivers, and is optional for bus drivers.\r
163\r
164 @retval EFI_SUCCESS The device was started.\r
165 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.\r
166 Currently not implemented.\r
167 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
168 @retval Others The driver failded to start the device.\r
12618416 169**/\r
6a690e23 170EFI_STATUS\r
171EFIAPI\r
172IScsiDriverBindingStart (\r
fd82de4e 173 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
6a690e23 174 IN EFI_HANDLE ControllerHandle,\r
fd82de4e 175 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
6a690e23 176 )\r
6a690e23 177{\r
178 EFI_STATUS Status;\r
179 ISCSI_DRIVER_DATA *Private;\r
fd627b16 180 VOID *Interface;\r
181\r
182 Private = IScsiCreateDriverData (This->DriverBindingHandle, ControllerHandle);\r
183 if (Private == NULL) {\r
184 return EFI_OUT_OF_RESOURCES;\r
185 }\r
186\r
187 //\r
188 // Create a underlayer child instance, but not need to configure it. Just open ChildHandle\r
189 // via BY_DRIVER. That is, establishing the relationship between ControllerHandle and ChildHandle.\r
190 // Therefore, when DisconnectController(), especially VLAN virtual controller handle,\r
191 // IScsiDriverBindingStop() will be called.\r
192 //\r
193 Status = NetLibCreateServiceChild (\r
194 ControllerHandle,\r
195 This->DriverBindingHandle,\r
196 &gEfiTcp4ServiceBindingProtocolGuid,\r
197 &Private->ChildHandle\r
198 );\r
199\r
200 if (EFI_ERROR (Status)) {\r
201 goto ON_ERROR;\r
202 }\r
203\r
204 Status = gBS->OpenProtocol (\r
205 Private->ChildHandle,\r
206 &gEfiTcp4ProtocolGuid,\r
207 &Interface,\r
208 This->DriverBindingHandle,\r
209 ControllerHandle,\r
210 EFI_OPEN_PROTOCOL_BY_DRIVER\r
211 );\r
212 if (EFI_ERROR (Status)) {\r
213 goto ON_ERROR;\r
214 }\r
215\r
05a30011 216 //\r
fd627b16 217 // Always install private protocol no matter what happens later. We need to \r
218 // keep the relationship between ControllerHandle and ChildHandle.\r
219 //\r
220 Status = gBS->InstallProtocolInterface (\r
221 &ControllerHandle,\r
c8ad2d7a 222 &gEfiCallerIdGuid,\r
fd627b16 223 EFI_NATIVE_INTERFACE,\r
224 &Private->IScsiIdentifier\r
225 );\r
226 if (EFI_ERROR (Status)) {\r
227 goto ON_ERROR;\r
228 }\r
6a690e23 229\r
230 //\r
231 // Try to add a port configuration page for this controller.\r
232 //\r
233 IScsiConfigUpdateForm (This->DriverBindingHandle, ControllerHandle, TRUE);\r
234\r
6a690e23 235 //\r
236 // Get the iSCSI configuration data of this controller.\r
237 //\r
238 Status = IScsiGetConfigData (Private);\r
239 if (EFI_ERROR (Status)) {\r
240 goto ON_ERROR;\r
241 }\r
242 //\r
243 // Try to login and create an iSCSI session according to the configuration.\r
244 //\r
245 Status = IScsiSessionLogin (Private);\r
246 if (Status == EFI_MEDIA_CHANGED) {\r
247 //\r
248 // The specified target is not available and the redirection information is\r
249 // got, login the session again with the updated target address.\r
250 //\r
251 Status = IScsiSessionLogin (Private);\r
252 }\r
253\r
254 if (EFI_ERROR (Status)) {\r
255 goto ON_ERROR;\r
256 }\r
257 //\r
258 // Duplicate the Session's tcp connection device path. The source port field\r
259 // will be set to zero as one iSCSI session is comprised of several iSCSI\r
260 // connections.\r
261 //\r
262 Private->DevicePath = IScsiGetTcpConnDevicePath (Private);\r
263 if (Private->DevicePath == NULL) {\r
264 goto ON_ERROR;\r
265 }\r
266 //\r
267 // Install the updated device path onto the ExtScsiPassThruHandle.\r
268 //\r
269 Status = gBS->InstallProtocolInterface (\r
270 &Private->ExtScsiPassThruHandle,\r
271 &gEfiDevicePathProtocolGuid,\r
272 EFI_NATIVE_INTERFACE,\r
273 Private->DevicePath\r
274 );\r
275 if (EFI_ERROR (Status)) {\r
276 goto ON_ERROR;\r
277 }\r
fd627b16 278\r
6a690e23 279 //\r
280 // Update/Publish the iSCSI Boot Firmware Table.\r
281 //\r
282 IScsiPublishIbft ();\r
283\r
284 return EFI_SUCCESS;\r
285\r
286ON_ERROR:\r
287\r
288 IScsiSessionAbort (&Private->Session);\r
6a690e23 289\r
290 return Status;\r
291}\r
292\r
12618416 293/**\r
fd82de4e 294 Stop this driver on ControllerHandle. \r
295 \r
296 Release the control of this controller and remove the IScsi functions. The Stop()\r
297 function is designed to be invoked from the EFI boot service DisconnectController(). \r
298 As a result, much of the error checking on the parameters to Stop() has been moved \r
299 into this common boot service. It is legal to call Stop() from other locations, \r
300 but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
301 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
302 same driver's Start() function.\r
303 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
304 EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
305 Start() function, and the Start() function must have called OpenProtocol() on\r
306 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
307 \r
308 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
309 @param[in] ControllerHandle A handle to the device being stopped. The handle must \r
310 support a bus specific I/O protocol for the driver \r
311 to use to stop the device.\r
312 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.Not used.\r
313 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL \r
314 if NumberOfChildren is 0.Not used.\r
315\r
316 @retval EFI_SUCCESS The device was stopped.\r
317 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
12618416 318**/\r
6a690e23 319EFI_STATUS\r
320EFIAPI\r
321IScsiDriverBindingStop (\r
322 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
323 IN EFI_HANDLE ControllerHandle,\r
324 IN UINTN NumberOfChildren,\r
c5de0d55 325 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
6a690e23 326 )\r
6a690e23 327{\r
328 EFI_HANDLE IScsiController;\r
329 EFI_STATUS Status;\r
330 ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
331 ISCSI_DRIVER_DATA *Private;\r
332 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru;\r
333 ISCSI_CONNECTION *Conn;\r
334\r
335 if (NumberOfChildren != 0) {\r
336 //\r
337 // We should have only one child.\r
338 //\r
339 Status = gBS->OpenProtocol (\r
340 ChildHandleBuffer[0],\r
341 &gEfiExtScsiPassThruProtocolGuid,\r
342 (VOID **) &PassThru,\r
343 This->DriverBindingHandle,\r
344 ControllerHandle,\r
345 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
346 );\r
347 if (EFI_ERROR (Status)) {\r
348 return EFI_DEVICE_ERROR;\r
349 }\r
350\r
351 Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (PassThru);\r
352 Conn = NET_LIST_HEAD (&Private->Session.Conns, ISCSI_CONNECTION, Link);\r
353\r
354 //\r
355 // Previously the TCP4 protocol is opened BY_CHILD_CONTROLLER. Just close\r
356 // the protocol here but not uninstall the device path protocol and\r
357 // EXT SCSI PASS THRU protocol installed on ExtScsiPassThruHandle.\r
358 //\r
359 gBS->CloseProtocol (\r
360 Conn->Tcp4Io.Handle,\r
361 &gEfiTcp4ProtocolGuid,\r
362 Private->Image,\r
363 Private->ExtScsiPassThruHandle\r
364 );\r
365\r
366 return EFI_SUCCESS;\r
367 }\r
368 //\r
369 // Get the handle of the controller we are controling.\r
370 //\r
371 IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);\r
372\r
373 Status = gBS->OpenProtocol (\r
374 IScsiController,\r
c8ad2d7a 375 &gEfiCallerIdGuid,\r
6a690e23 376 (VOID **)&IScsiIdentifier,\r
377 This->DriverBindingHandle,\r
378 ControllerHandle,\r
379 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
380 );\r
381 if (EFI_ERROR (Status)) {\r
382 return EFI_DEVICE_ERROR;\r
383 }\r
384\r
385 Private = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
386\r
fd627b16 387 if (Private->ChildHandle != NULL) {\r
388 Status = gBS->CloseProtocol (\r
389 Private->ChildHandle,\r
390 &gEfiTcp4ProtocolGuid,\r
391 This->DriverBindingHandle,\r
392 IScsiController\r
393 );\r
394\r
395 ASSERT (!EFI_ERROR (Status));\r
396\r
397 Status = NetLibDestroyServiceChild (\r
398 IScsiController,\r
399 This->DriverBindingHandle,\r
400 &gEfiTcp4ServiceBindingProtocolGuid,\r
401 Private->ChildHandle\r
402 );\r
403 ASSERT (!EFI_ERROR (Status));\r
404 }\r
405\r
406 IScsiConfigUpdateForm (This->DriverBindingHandle, IScsiController, FALSE);\r
407\r
6a690e23 408 //\r
409 // Uninstall the private protocol.\r
410 //\r
411 gBS->UninstallProtocolInterface (\r
412 IScsiController,\r
c8ad2d7a 413 &gEfiCallerIdGuid,\r
6a690e23 414 &Private->IScsiIdentifier\r
415 );\r
416\r
417 //\r
418 // Update the iSCSI Boot Firware Table.\r
419 //\r
420 IScsiPublishIbft ();\r
421\r
422 IScsiSessionAbort (&Private->Session);\r
423 IScsiCleanDriverData (Private);\r
424\r
425 return EFI_SUCCESS;\r
426}\r
427\r
12618416 428/**\r
fd82de4e 429 Unloads an image(the iSCSI driver).\r
6a690e23 430\r
fd82de4e 431 @param[in] ImageHandle Handle that identifies the image to be unloaded.\r
6a690e23 432\r
fd82de4e 433 @retval EFI_SUCCESS The image has been unloaded.\r
963dbb30 434 @retval Others Other errors as indicated.\r
12618416 435**/\r
436EFI_STATUS\r
437EFIAPI\r
438EfiIScsiUnload (\r
439 IN EFI_HANDLE ImageHandle\r
440 )\r
6a690e23 441{\r
442 EFI_STATUS Status;\r
443 UINTN DeviceHandleCount;\r
444 EFI_HANDLE *DeviceHandleBuffer;\r
445 UINTN Index;\r
446\r
447 //\r
448 // Try to disonnect the driver from the devices it's controlling.\r
449 //\r
450 Status = gBS->LocateHandleBuffer (\r
451 AllHandles,\r
452 NULL,\r
453 NULL,\r
454 &DeviceHandleCount,\r
455 &DeviceHandleBuffer\r
456 );\r
457 if (!EFI_ERROR (Status)) {\r
458 for (Index = 0; Index < DeviceHandleCount; Index++) {\r
459 Status = gBS->DisconnectController (\r
460 DeviceHandleBuffer[Index],\r
461 ImageHandle,\r
462 NULL\r
463 );\r
464 }\r
465\r
466 if (DeviceHandleBuffer != NULL) {\r
766c7483 467 FreePool (DeviceHandleBuffer);\r
6a690e23 468 }\r
469 }\r
470 //\r
471 // Unload the iSCSI configuration form.\r
472 //\r
473 IScsiConfigFormUnload (gIScsiDriverBinding.DriverBindingHandle);\r
474\r
475 //\r
476 // Uninstall the protocols installed by iSCSI driver.\r
477 //\r
478 Status = gBS->UninstallMultipleProtocolInterfaces (\r
479 ImageHandle,\r
480 &gEfiDriverBindingProtocolGuid,\r
481 &gIScsiDriverBinding,\r
482 &gEfiComponentName2ProtocolGuid,\r
483 &gIScsiComponentName2,\r
484 &gEfiComponentNameProtocolGuid,\r
485 &gIScsiComponentName,\r
486 &gEfiIScsiInitiatorNameProtocolGuid,\r
487 &gIScsiInitiatorName,\r
488 NULL\r
489 );\r
490\r
491 return Status;\r
492}\r
493\r
12618416 494/**\r
fd82de4e 495 This is the declaration of an EFI image entry point. This entry point is\r
496 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
497 both device drivers and bus drivers. It initialize the global variables and \r
498 publish the driver binding protocol.\r
6a690e23 499\r
fd82de4e 500 @param[in] ImageHandle The firmware allocated handle for the UEFI image.\r
501 @param[in] SystemTable A pointer to the EFI System Table.\r
6a690e23 502\r
fd82de4e 503 @retval EFI_SUCCESS The operation completed successfully.\r
504 @retval EFI_ACCESS_DENIED EFI_ISCSI_INITIATOR_NAME_PROTOCOL was installed unexpectedly.\r
963dbb30 505 @retval Others Other errors as indicated.\r
12618416 506**/\r
507EFI_STATUS\r
508EFIAPI\r
509IScsiDriverEntryPoint (\r
510 IN EFI_HANDLE ImageHandle,\r
511 IN EFI_SYSTEM_TABLE *SystemTable\r
512 )\r
6a690e23 513{\r
f2a94e25 514 EFI_STATUS Status;\r
515 EFI_ISCSI_INITIATOR_NAME_PROTOCOL *IScsiInitiatorName;\r
516\r
517 //\r
518 // There should be only one EFI_ISCSI_INITIATOR_NAME_PROTOCOL.\r
519 //\r
520 Status = gBS->LocateProtocol (\r
521 &gEfiIScsiInitiatorNameProtocolGuid,\r
522 NULL,\r
b4df5011 523 (VOID**) &IScsiInitiatorName\r
f2a94e25 524 );\r
525\r
526 if (!EFI_ERROR (Status)) {\r
527 return EFI_ACCESS_DENIED;\r
528 }\r
6a690e23 529\r
530 //\r
531 // Initialize the EFI Driver Library\r
532 //\r
533 Status = EfiLibInstallDriverBindingComponentName2 (\r
534 ImageHandle,\r
535 SystemTable,\r
536 &gIScsiDriverBinding,\r
537 ImageHandle,\r
538 &gIScsiComponentName,\r
539 &gIScsiComponentName2\r
540 );\r
6a690e23 541\r
542 if (!EFI_ERROR (Status)) {\r
f2a94e25 543 //\r
544 // Install the iSCSI Initiator Name Protocol.\r
545 //\r
6a690e23 546 Status = gBS->InstallProtocolInterface (\r
547 &ImageHandle,\r
548 &gEfiIScsiInitiatorNameProtocolGuid,\r
549 EFI_NATIVE_INTERFACE,\r
550 &gIScsiInitiatorName\r
551 );\r
552 if (EFI_ERROR (Status)) {\r
553 gBS->UninstallMultipleProtocolInterfaces (\r
554 ImageHandle,\r
555 &gEfiDriverBindingProtocolGuid,\r
556 &gIScsiDriverBinding,\r
557 &gEfiComponentName2ProtocolGuid,\r
558 &gIScsiComponentName2,\r
559 &gEfiComponentNameProtocolGuid,\r
560 &gIScsiComponentName,\r
561 NULL\r
562 );\r
f2a94e25 563 return Status;\r
564 }\r
565 \r
566 //\r
567 // Initialize the configuration form of iSCSI.\r
568 //\r
963dbb30 569 Status = IScsiConfigFormInit ();\r
f2a94e25 570 if (EFI_ERROR (Status)) {\r
571 gBS->UninstallMultipleProtocolInterfaces (\r
572 ImageHandle,\r
573 &gEfiDriverBindingProtocolGuid,\r
574 &gIScsiDriverBinding,\r
575 &gEfiComponentName2ProtocolGuid,\r
576 &gIScsiComponentName2,\r
577 &gEfiComponentNameProtocolGuid,\r
578 &gIScsiComponentName,\r
579 &gEfiIScsiInitiatorNameProtocolGuid,\r
580 &gIScsiInitiatorName,\r
581 NULL\r
582 );\r
6a690e23 583 }\r
584 }\r
6a690e23 585 return Status;\r
586}\r
587\r