+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of the controller to start. This handle \r
+ must support a protocol interface that supplies \r
+ an I/O abstraction to the driver.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This \r
+ parameter is ignored by device drivers, and is optional for bus \r
+ drivers. For a bus driver, if this parameter is NULL, then handles \r
+ for all the children of Controller are created by this driver. \r
+ If this parameter is not NULL and the first Device Path Node is \r
+ not the End of Device Path Node, then only the handle for the \r
+ child device specified by the first Device Path Node of \r
+ RemainingDevicePath is created by this driver.\r
+ If the first Device Path Node of RemainingDevicePath is \r
+ the End of Device Path Node, no child handle is created by this\r
+ driver.\r
+\r
+ @retval EFI_SUCCESS The device was started.\r
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error. Currently not implemented.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+ @retval Others The driver failed to start the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IScsiIp4DriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = IScsiStart (This->DriverBindingHandle, ControllerHandle, IP_VERSION_4);\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Stops a device controller or a bus controller.\r
+ \r
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). \r
+ As a result, much of the error checking on the parameters to Stop() has been moved \r
+ into this common boot service. It is legal to call Stop() from other locations, \r
+ but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
+ same driver's Start() function.\r
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
+ Start() function, and the Start() function must have called OpenProtocol() on\r
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
+ \r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must \r
+ support a bus specific I/O protocol for the driver \r
+ to use to stop the device.\r
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL \r
+ if NumberOfChildren is 0.\r
+\r
+ @retval EFI_SUCCESS The device was stopped.\r
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IScsiIp4DriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
+ )\r
+{\r
+ return IScsiStop (\r
+ This,\r
+ ControllerHandle,\r
+ NumberOfChildren,\r
+ ChildHandleBuffer,\r
+ IP_VERSION_4\r
+ );\r
+}\r
+\r
+/**\r
+ Tests to see if this driver supports a given controller. If a child device is provided, \r
+ it tests to see if this driver supports creating a handle for the specified child device.\r
+\r
+ This function checks to see if the driver specified by This supports the device specified by \r
+ ControllerHandle. Drivers typically use the device path attached to \r
+ ControllerHandle and/or the services from the bus I/O abstraction attached to \r
+ ControllerHandle to determine if the driver supports ControllerHandle. This function \r
+ may be called many times during platform initialization. In order to reduce boot times, the tests \r
+ performed by this function must be very small and take as little time as possible to execute. This \r
+ function must not change the state of any hardware devices, and this function must be aware that the \r
+ device specified by ControllerHandle may already be managed by the same driver or a \r
+ different driver. This function must match its calls to AllocatePages() with FreePages(), \r
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). \r
+ Since ControllerHandle may have been previously started by the same driver, if a protocol is \r
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required \r
+ to guarantee the state of ControllerHandle is not modified by this function.\r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of the controller to test. This handle \r
+ must support a protocol interface that supplies \r
+ an I/O abstraction to the driver.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This \r
+ parameter is ignored by device drivers, and is optional for bus \r
+ drivers. For bus drivers, if this parameter is not NULL, then \r
+ the bus driver must determine if the bus controller specified \r
+ by ControllerHandle and the child controller specified \r
+ by RemainingDevicePath are both supported by this \r
+ bus driver.\r
+\r
+ @retval EFI_SUCCESS The device specified by ControllerHandle and\r
+ RemainingDevicePath is supported by the driver specified by This.\r
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
+ RemainingDevicePath is already managed by the driver\r
+ specified by This.\r
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
+ RemainingDevicePath is already managed by a different\r
+ driver or an application that requires exclusive access.\r
+ Currently not implemented.\r
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
+ RemainingDevicePath is not supported by the driver specified by This.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IScsiIp6DriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ return IScsiSupported (\r
+ This,\r
+ ControllerHandle,\r
+ RemainingDevicePath,\r
+ IP_VERSION_6\r
+ );\r
+}\r
+\r
+/**\r
+ Starts a device controller or a bus controller.\r
+\r
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().\r
+ As a result, much of the error checking on the parameters to Start() has been moved into this \r
+ common boot service. It is legal to call Start() from other locations, \r
+ but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE.\r
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
+ EFI_DEVICE_PATH_PROTOCOL.\r
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. \r
+\r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle The handle of the controller to start. This handle \r
+ must support a protocol interface that supplies \r
+ an I/O abstraction to the driver.\r
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This \r
+ parameter is ignored by device drivers, and is optional for bus \r
+ drivers. For a bus driver, if this parameter is NULL, then handles \r
+ for all the children of Controller are created by this driver. \r
+ If this parameter is not NULL and the first Device Path Node is \r
+ not the End of Device Path Node, then only the handle for the \r
+ child device specified by the first Device Path Node of \r
+ RemainingDevicePath is created by this driver.\r
+ If the first Device Path Node of RemainingDevicePath is \r
+ the End of Device Path Node, no child handle is created by this\r
+ driver.\r
+\r
+ @retval EFI_SUCCESS The device was started.\r
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error. Currently not implemented.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+ @retval Others The driver failed to start the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IScsiIp6DriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = IScsiStart (This->DriverBindingHandle, ControllerHandle, IP_VERSION_6);\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Stops a device controller or a bus controller.\r
+ \r
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). \r
+ As a result, much of the error checking on the parameters to Stop() has been moved \r
+ into this common boot service. It is legal to call Stop() from other locations, \r
+ but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
+ same driver's Start() function.\r
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
+ Start() function, and the Start() function must have called OpenProtocol() on\r
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
+ \r
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must \r
+ support a bus specific I/O protocol for the driver \r
+ to use to stop the device.\r
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL \r
+ if NumberOfChildren is 0.\r
+\r
+ @retval EFI_SUCCESS The device was stopped.\r
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IScsiIp6DriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
+ )\r
+{\r
+ return IScsiStop (\r
+ This,\r
+ ControllerHandle,\r
+ NumberOfChildren,\r
+ ChildHandleBuffer,\r
+ IP_VERSION_6\r
+ );\r
+}\r
+\r
+/**\r
+ Unload the iSCSI driver.\r
+\r
+ @param[in] ImageHandle The handle of the driver image.\r
+\r
+ @retval EFI_SUCCESS The driver is unloaded.\r
+ @retval EFI_DEVICE_ERROR An unexpected error occurred.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IScsiUnload (\r
+ IN EFI_HANDLE ImageHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN DeviceHandleCount;\r
+ EFI_HANDLE *DeviceHandleBuffer;\r
+ UINTN Index;\r
+ EFI_COMPONENT_NAME_PROTOCOL *ComponentName;\r
+ EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;\r
+\r
+ //\r
+ // Try to disonnect the driver from the devices it's controlling.\r
+ //\r
+ Status = gBS->LocateHandleBuffer (\r
+ AllHandles,\r
+ NULL,\r
+ NULL,\r
+ &DeviceHandleCount,\r
+ &DeviceHandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Disconnect the iSCSI4 driver from the controlled device.\r
+ //\r
+ for (Index = 0; Index < DeviceHandleCount; Index++) {\r
+ Status = IScsiTestManagedDevice (\r
+ DeviceHandleBuffer[Index],\r
+ gIScsiIp4DriverBinding.DriverBindingHandle,\r
+ &gEfiTcp4ProtocolGuid)\r
+ ;\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+ Status = gBS->DisconnectController (\r
+ DeviceHandleBuffer[Index],\r
+ gIScsiIp4DriverBinding.DriverBindingHandle,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Disconnect the iSCSI6 driver from the controlled device.\r
+ //\r
+ for (Index = 0; Index < DeviceHandleCount; Index++) {\r
+ Status = IScsiTestManagedDevice (\r
+ DeviceHandleBuffer[Index],\r
+ gIScsiIp6DriverBinding.DriverBindingHandle,\r
+ &gEfiTcp6ProtocolGuid\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+ Status = gBS->DisconnectController (\r
+ DeviceHandleBuffer[Index],\r
+ gIScsiIp6DriverBinding.DriverBindingHandle,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Unload the iSCSI configuration form.\r
+ //\r
+ Status = IScsiConfigFormUnload (gIScsiIp4DriverBinding.DriverBindingHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ \r
+ //\r
+ // Uninstall the protocols installed by iSCSI driver.\r
+ //\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ ImageHandle,\r
+ &gEfiAuthenticationInfoProtocolGuid,\r
+ &gIScsiAuthenticationInfo,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ \r
+ if (gIScsiControllerNameTable!= NULL) {\r
+ Status = FreeUnicodeStringTable (gIScsiControllerNameTable);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ gIScsiControllerNameTable = NULL;\r
+ }\r
+\r
+ //\r
+ // Uninstall the ComponentName and ComponentName2 protocol from iSCSI4 driver binding handle\r
+ // if it has been installed.\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ gIScsiIp4DriverBinding.DriverBindingHandle,\r
+ &gEfiComponentNameProtocolGuid,\r
+ (VOID **) &ComponentName\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ gIScsiIp4DriverBinding.DriverBindingHandle,\r
+ &gEfiComponentNameProtocolGuid,\r
+ ComponentName,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
+ \r
+ Status = gBS->HandleProtocol (\r
+ gIScsiIp4DriverBinding.DriverBindingHandle,\r
+ &gEfiComponentName2ProtocolGuid,\r
+ (VOID **) &ComponentName2\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ gIScsiIp4DriverBinding.DriverBindingHandle,\r
+ &gEfiComponentName2ProtocolGuid,\r
+ ComponentName2,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Uninstall the ComponentName and ComponentName2 protocol from iSCSI6 driver binding handle\r
+ // if it has been installed.\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ gIScsiIp6DriverBinding.DriverBindingHandle,\r
+ &gEfiComponentNameProtocolGuid,\r
+ (VOID **) &ComponentName\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ gIScsiIp6DriverBinding.DriverBindingHandle,\r
+ &gEfiComponentNameProtocolGuid,\r
+ ComponentName,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
+ \r
+ Status = gBS->HandleProtocol (\r
+ gIScsiIp6DriverBinding.DriverBindingHandle,\r
+ &gEfiComponentName2ProtocolGuid,\r
+ (VOID **) &ComponentName2\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ gIScsiIp6DriverBinding.DriverBindingHandle,\r
+ &gEfiComponentName2ProtocolGuid,\r
+ ComponentName2,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Uninstall the IScsiInitiatorNameProtocol and all the driver binding protocols.\r
+ //\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ gIScsiIp4DriverBinding.DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid,\r
+ &gIScsiIp4DriverBinding,\r
+ &gEfiIScsiInitiatorNameProtocolGuid,\r
+ &gIScsiInitiatorName,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ gIScsiIp6DriverBinding.DriverBindingHandle,\r
+ &gEfiDriverBindingProtocolGuid,\r
+ &gIScsiIp6DriverBinding,\r
+ NULL\r
+ );\r
+\r
+ON_EXIT:\r
+\r
+ if (DeviceHandleBuffer != NULL) {\r
+ FreePool (DeviceHandleBuffer);\r
+ }\r
+ \r
+ return Status;\r
+}\r
+\r
+/**\r
+ This is the declaration of an EFI image entry point. This entry point is\r
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
+ both device drivers and bus drivers.\r
+ \r
+ The entry point for iSCSI driver which initializes the global variables and\r
+ installs the driver binding, component name protocol, iSCSI initiator name\r
+ protocol and Authentication Info protocol on its image.\r
+ \r
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The operation completed successfully.\r
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IScsiDriverEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r