3 Copyright (c) 2004 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 #include "IScsiImpl.h"
22 EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding
= {
23 IScsiDriverBindingSupported
,
24 IScsiDriverBindingStart
,
25 IScsiDriverBindingStop
,
31 EFI_GUID mIScsiPrivateGuid
= ISCSI_PRIVATE_GUID
;
35 IScsiDriverBindingSupported (
36 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
37 IN EFI_HANDLE ControllerHandle
,
38 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
44 Test to see if iSCSI driver supports the given controller.
48 This - Protocol instance pointer.
49 ControllerHandle - Handle of controller to test.
50 RemainingDevicePath - Optional parameter use to pick a specific child device to start.
54 EFI_SUCCES - This driver supports the controller.
55 EFI_ALREADY_STARTED - This driver is already running on this device.
56 EFI_UNSUPPORTED - This driver doesn't support the controller.
61 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
63 Status
= gBS
->OpenProtocol (
67 This
->DriverBindingHandle
,
69 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
71 if (!EFI_ERROR (Status
)) {
72 return EFI_ALREADY_STARTED
;
75 Status
= gBS
->OpenProtocol (
77 &gEfiTcp4ServiceBindingProtocolGuid
,
79 This
->DriverBindingHandle
,
81 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
83 if (EFI_ERROR (Status
)) {
84 return EFI_UNSUPPORTED
;
87 CurrentDevicePath
= RemainingDevicePath
;
88 if (CurrentDevicePath
!= NULL
) {
89 while (!IsDevicePathEnd (CurrentDevicePath
)) {
90 if ((CurrentDevicePath
->Type
== MESSAGING_DEVICE_PATH
) && (CurrentDevicePath
->SubType
== MSG_ISCSI_DP
)) {
94 CurrentDevicePath
= NextDevicePathNode (CurrentDevicePath
);
97 return EFI_UNSUPPORTED
;
105 IScsiDriverBindingStart (
106 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
107 IN EFI_HANDLE ControllerHandle
,
108 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
114 Start to manage the controller.
118 This - Protocol instance pointer.
119 ControllerHandle - Handle of the controller.
120 RemainingDevicePath - Optional parameter use to pick a specific child device to start.
124 EFI_SUCCES - This driver supports this device.
125 EFI_ALREADY_STARTED - This driver is already running on this device.
130 ISCSI_DRIVER_DATA
*Private
;
133 // Try to add a port configuration page for this controller.
135 IScsiConfigUpdateForm (This
->DriverBindingHandle
, ControllerHandle
, TRUE
);
137 Private
= IScsiCreateDriverData (This
->DriverBindingHandle
, ControllerHandle
);
138 if (Private
== NULL
) {
139 return EFI_OUT_OF_RESOURCES
;
142 // Get the iSCSI configuration data of this controller.
144 Status
= IScsiGetConfigData (Private
);
145 if (EFI_ERROR (Status
)) {
149 // Try to login and create an iSCSI session according to the configuration.
151 Status
= IScsiSessionLogin (Private
);
152 if (Status
== EFI_MEDIA_CHANGED
) {
154 // The specified target is not available and the redirection information is
155 // got, login the session again with the updated target address.
157 Status
= IScsiSessionLogin (Private
);
160 if (EFI_ERROR (Status
)) {
164 // Duplicate the Session's tcp connection device path. The source port field
165 // will be set to zero as one iSCSI session is comprised of several iSCSI
168 Private
->DevicePath
= IScsiGetTcpConnDevicePath (Private
);
169 if (Private
->DevicePath
== NULL
) {
173 // Install the updated device path onto the ExtScsiPassThruHandle.
175 Status
= gBS
->InstallProtocolInterface (
176 &Private
->ExtScsiPassThruHandle
,
177 &gEfiDevicePathProtocolGuid
,
178 EFI_NATIVE_INTERFACE
,
181 if (EFI_ERROR (Status
)) {
185 // Install the iSCSI private stuff as a flag to indicate this controller
186 // is already controlled by iSCSI driver.
188 Status
= gBS
->InstallProtocolInterface (
191 EFI_NATIVE_INTERFACE
,
192 &Private
->IScsiIdentifier
194 if (EFI_ERROR (Status
)) {
198 // Update/Publish the iSCSI Boot Firmware Table.
206 IScsiSessionAbort (&Private
->Session
);
207 IScsiCleanDriverData (Private
);
214 IScsiDriverBindingStop (
215 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
216 IN EFI_HANDLE ControllerHandle
,
217 IN UINTN NumberOfChildren
,
218 IN EFI_HANDLE
*ChildHandleBuffer
224 Release the control of this controller and remove the iSCSI functions.
228 This - Protocol instance pointer.
229 ControllerHandle - Handle of controller to stop.
230 NumberOfChildren - Not used.
231 ChildHandleBuffer - Not used.
235 EFI_SUCCES - This driver supports this device.
239 EFI_HANDLE IScsiController
;
241 ISCSI_PRIVATE_PROTOCOL
*IScsiIdentifier
;
242 ISCSI_DRIVER_DATA
*Private
;
243 EFI_EXT_SCSI_PASS_THRU_PROTOCOL
*PassThru
;
244 ISCSI_CONNECTION
*Conn
;
246 if (NumberOfChildren
!= 0) {
248 // We should have only one child.
250 Status
= gBS
->OpenProtocol (
251 ChildHandleBuffer
[0],
252 &gEfiExtScsiPassThruProtocolGuid
,
254 This
->DriverBindingHandle
,
256 EFI_OPEN_PROTOCOL_GET_PROTOCOL
258 if (EFI_ERROR (Status
)) {
259 return EFI_DEVICE_ERROR
;
262 Private
= ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (PassThru
);
263 Conn
= NET_LIST_HEAD (&Private
->Session
.Conns
, ISCSI_CONNECTION
, Link
);
266 // Previously the TCP4 protocol is opened BY_CHILD_CONTROLLER. Just close
267 // the protocol here but not uninstall the device path protocol and
268 // EXT SCSI PASS THRU protocol installed on ExtScsiPassThruHandle.
272 &gEfiTcp4ProtocolGuid
,
274 Private
->ExtScsiPassThruHandle
280 // Get the handle of the controller we are controling.
282 IScsiController
= NetLibGetNicHandle (ControllerHandle
, &gEfiTcp4ProtocolGuid
);
284 Status
= gBS
->OpenProtocol (
287 (VOID
**)&IScsiIdentifier
,
288 This
->DriverBindingHandle
,
290 EFI_OPEN_PROTOCOL_GET_PROTOCOL
292 if (EFI_ERROR (Status
)) {
293 return EFI_DEVICE_ERROR
;
296 Private
= ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier
);
299 // Uninstall the private protocol.
301 gBS
->UninstallProtocolInterface (
304 &Private
->IScsiIdentifier
308 // Update the iSCSI Boot Firware Table.
312 IScsiSessionAbort (&Private
->Session
);
313 IScsiCleanDriverData (Private
);
321 IN EFI_HANDLE ImageHandle
327 Unload the iSCSI driver.
331 ImageHandle - The handle of the driver image.
335 EFI_SUCCESS - The driver is unloaded.
336 EFI_DEVICE_ERROR - Some unexpected error happened.
341 UINTN DeviceHandleCount
;
342 EFI_HANDLE
*DeviceHandleBuffer
;
346 // Try to disonnect the driver from the devices it's controlling.
348 Status
= gBS
->LocateHandleBuffer (
355 if (!EFI_ERROR (Status
)) {
356 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
357 Status
= gBS
->DisconnectController (
358 DeviceHandleBuffer
[Index
],
364 if (DeviceHandleBuffer
!= NULL
) {
365 gBS
->FreePool (DeviceHandleBuffer
);
369 // Unload the iSCSI configuration form.
371 IScsiConfigFormUnload (gIScsiDriverBinding
.DriverBindingHandle
);
374 // Uninstall the protocols installed by iSCSI driver.
376 Status
= gBS
->UninstallMultipleProtocolInterfaces (
378 &gEfiDriverBindingProtocolGuid
,
379 &gIScsiDriverBinding
,
380 &gEfiComponentName2ProtocolGuid
,
381 &gIScsiComponentName2
,
382 &gEfiComponentNameProtocolGuid
,
383 &gIScsiComponentName
,
384 &gEfiIScsiInitiatorNameProtocolGuid
,
385 &gIScsiInitiatorName
,
394 IScsiDriverEntryPoint (
395 IN EFI_HANDLE ImageHandle
,
396 IN EFI_SYSTEM_TABLE
*SystemTable
402 Initialize the global variables publish the driver binding protocol.
406 ImageHandle - The handle of the driver image.
407 SystemTable - The EFI system table.
411 EFI_SUCCESS - The protocols are installed.
412 EFI_DEVICE_ERROR - Some unexpected error happened.
417 EFI_ISCSI_INITIATOR_NAME_PROTOCOL
*IScsiInitiatorName
;
420 // There should be only one EFI_ISCSI_INITIATOR_NAME_PROTOCOL.
422 Status
= gBS
->LocateProtocol (
423 &gEfiIScsiInitiatorNameProtocolGuid
,
428 if (!EFI_ERROR (Status
)) {
429 return EFI_ACCESS_DENIED
;
433 // Initialize the EFI Driver Library
435 Status
= EfiLibInstallDriverBindingComponentName2 (
438 &gIScsiDriverBinding
,
440 &gIScsiComponentName
,
441 &gIScsiComponentName2
444 if (!EFI_ERROR (Status
)) {
446 // Install the iSCSI Initiator Name Protocol.
448 Status
= gBS
->InstallProtocolInterface (
450 &gEfiIScsiInitiatorNameProtocolGuid
,
451 EFI_NATIVE_INTERFACE
,
454 if (EFI_ERROR (Status
)) {
455 gBS
->UninstallMultipleProtocolInterfaces (
457 &gEfiDriverBindingProtocolGuid
,
458 &gIScsiDriverBinding
,
459 &gEfiComponentName2ProtocolGuid
,
460 &gIScsiComponentName2
,
461 &gEfiComponentNameProtocolGuid
,
462 &gIScsiComponentName
,
469 // Initialize the configuration form of iSCSI.
471 Status
= IScsiConfigFormInit (gIScsiDriverBinding
.DriverBindingHandle
);
472 if (EFI_ERROR (Status
)) {
473 gBS
->UninstallMultipleProtocolInterfaces (
475 &gEfiDriverBindingProtocolGuid
,
476 &gIScsiDriverBinding
,
477 &gEfiComponentName2ProtocolGuid
,
478 &gIScsiComponentName2
,
479 &gEfiComponentNameProtocolGuid
,
480 &gIScsiComponentName
,
481 &gEfiIScsiInitiatorNameProtocolGuid
,
482 &gIScsiInitiatorName
,