]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/EfiSocketLib/Service.c
Fix port retry behavior during connect - All port error paths exit through ConnectCom...
[mirror_edk2.git] / StdLib / EfiSocketLib / Service.c
index 49c8884612091ea087145ec25ebd363e87f2b6ba..414cace00b5dfaefc6df3c42285924a05f56748c 100644 (file)
 \r
 #include "Socket.h"\r
 \r
-EFI_TCP4_PROTOCOL * mpEfiTcpClose4 [ 1024 ];\r
-\r
 \r
 /**\r
   Connect to the network service bindings\r
 \r
   Walk the network service protocols on the controller handle and\r
-  locate any that are not in use.  Create service structures to\r
-  manage the service binding for the socket driver.\r
+  locate any that are not in use.  Create ::ESL_SERVICE structures to\r
+  manage the network layer interfaces for the socket driver.  Tag\r
+  each of the network interfaces that are being used.  Finally, this\r
+  routine calls ESL_SOCKET_BINDING::pfnInitialize to prepare the network\r
+  interface for use by the socket layer.\r
 \r
   @param [in] BindingHandle    Handle for protocol binding.\r
   @param [in] Controller       Handle of device to work with.\r
 \r
   @retval EFI_SUCCESS          This driver is added to Controller.\r
-  @retval other                This driver does not support this device.\r
+  @retval EFI_OUT_OF_RESOURCES No more memory available.\r
+  @retval EFI_UNSUPPORTED      This driver does not support this device.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -39,12 +41,15 @@ EslServiceConnect (
   )\r
 {\r
   BOOLEAN bInUse;\r
+  EFI_STATUS ExitStatus;\r
   UINTN LengthInBytes;\r
-  CONST DT_SOCKET_BINDING * pEnd;\r
+  UINT8 * pBuffer;\r
+  CONST ESL_SOCKET_BINDING * pEnd;\r
   VOID * pJunk;\r
-  VOID * pInterface;\r
-  DT_SERVICE * pService;\r
-  CONST DT_SOCKET_BINDING * pSocketBinding;\r
+  ESL_SERVICE ** ppServiceListHead;\r
+  ESL_SERVICE * pService;\r
+  CONST ESL_SOCKET_BINDING * pSocketBinding;\r
+  EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding;\r
   EFI_STATUS Status;\r
   EFI_TPL TplPrevious;\r
 \r
@@ -53,7 +58,7 @@ EslServiceConnect (
   //\r
   //  Assume the list is empty\r
   //\r
-  Status = EFI_UNSUPPORTED;\r
+  ExitStatus = EFI_UNSUPPORTED;\r
   bInUse = FALSE;\r
 \r
   //\r
@@ -68,7 +73,7 @@ EslServiceConnect (
     Status = gBS->OpenProtocol (\r
                     Controller,\r
                     pSocketBinding->pNetworkBinding,\r
-                    &pInterface,\r
+                    (VOID**)&pServiceBinding,\r
                     BindingHandle,\r
                     Controller,\r
                     EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -108,7 +113,7 @@ EslServiceConnect (
           pService->Signature = SERVICE_SIGNATURE;\r
           pService->pSocketBinding = pSocketBinding;\r
           pService->Controller = Controller;\r
-          pService->pInterface = pInterface;\r
+          pService->pServiceBinding = pServiceBinding;\r
 \r
           //\r
           //  Mark the controller in use\r
@@ -154,9 +159,13 @@ EslServiceConnect (
               RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
 \r
               //\r
-              //  Initialize the service\r
+              //  Connect the service to the list\r
               //\r
-              Status = pSocketBinding->pfnInitialize ( pService );\r
+              pBuffer = (UINT8 *)&mEslLayer;\r
+              pBuffer = &pBuffer[ pSocketBinding->ServiceListOffset ];\r
+              ppServiceListHead = (ESL_SERVICE **)pBuffer;\r
+              pService->pNext = *ppServiceListHead;\r
+              *ppServiceListHead = pService;\r
 \r
               //\r
               //  Release the socket layer synchronization\r
@@ -164,28 +173,9 @@ EslServiceConnect (
               RESTORE_TPL ( TplPrevious );\r
 \r
               //\r
-              //  Determine if the initialization was successful\r
+              //  At least one service was made available\r
               //\r
-              if ( EFI_ERROR ( Status )) {\r
-                DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
-                          "ERROR - Failed to initialize service %s on 0x%08x, Status: %r\r\n",\r
-                          pSocketBinding->pName,\r
-                          Controller,\r
-                          Status ));\r
-\r
-                //\r
-                //  Free the network service binding if necessary\r
-                //\r
-                gBS->UninstallMultipleProtocolInterfaces (\r
-                          Controller,\r
-                          pSocketBinding->pTagGuid,\r
-                          pService,\r
-                          NULL );\r
-                DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
-                            "Removed:   %s TagGuid from 0x%08x\r\n",\r
-                            pSocketBinding->pName,\r
-                            Controller ));\r
-              }\r
+              ExitStatus = EFI_SUCCESS;\r
             }\r
             else {\r
               DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
@@ -234,6 +224,8 @@ EslServiceConnect (
           DEBUG (( DEBUG_ERROR | DEBUG_INIT,\r
                     "ERROR - Failed service allocation, Status: %r\r\n",\r
                     Status ));\r
+          ExitStatus = EFI_OUT_OF_RESOURCES;\r
+          break;\r
         }\r
       }\r
     }\r
@@ -247,18 +239,19 @@ EslServiceConnect (
   //\r
   //  Display the driver start status\r
   //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
+  DBG_EXIT_STATUS ( ExitStatus );\r
+  return ExitStatus;\r
 }\r
 \r
 \r
 /**\r
-  Shutdown the network connections to this controller by removing\r
-  NetworkInterfaceIdentifier protocol and closing the DevicePath\r
-  and PciIo protocols on Controller.\r
+  Shutdown the connections to the network layer by locating the\r
+  tags on the network interfaces established by ::EslServiceConnect.\r
+  This routine shutdowns any activity on the network interface and\r
+  then frees the ::ESL_SERVICE structures.\r
 \r
   @param [in] BindingHandle    Handle for protocol binding.\r
-  @param [in] Controller           Handle of device to stop driver on.\r
+  @param [in] Controller       Handle of device to stop driver on.\r
 \r
   @retval EFI_SUCCESS          This driver is removed Controller.\r
   @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.\r
@@ -272,9 +265,13 @@ EslServiceDisconnect (
   IN  EFI_HANDLE Controller\r
   )\r
 {\r
-  CONST DT_SOCKET_BINDING * pEnd;\r
-  DT_SERVICE * pService;\r
-  CONST DT_SOCKET_BINDING * pSocketBinding;\r
+  UINT8 * pBuffer;\r
+  CONST ESL_SOCKET_BINDING * pEnd;\r
+  ESL_PORT * pPort;\r
+  ESL_SERVICE * pPreviousService;\r
+  ESL_SERVICE * pService;\r
+  ESL_SERVICE ** ppServiceListHead;\r
+  CONST ESL_SOCKET_BINDING * pSocketBinding;\r
   EFI_STATUS Status;\r
   EFI_TPL TplPrevious;\r
   \r
@@ -310,9 +307,54 @@ EslServiceDisconnect (
       RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
 \r
       //\r
-      //  Shutdown the service\r
+      //  Walk the list of ports\r
       //\r
-      pSocketBinding->pfnShutdown ( pService );\r
+      pPort = pService->pPortList;\r
+      while ( NULL != pPort ) {\r
+        //\r
+        //  Remove the port from the port list\r
+        //\r
+        pPort->pService = NULL;\r
+        pService->pPortList = pPort->pLinkService;\r
+  \r
+        //\r
+        //  Close the port\r
+        //\r
+        EslSocketPortCloseStart ( pPort,\r
+                                  TRUE,\r
+                                  DEBUG_POOL | DEBUG_INIT );\r
+\r
+        //\r
+        //  Set the next port\r
+        //\r
+        pPort = pService->pPortList;\r
+      }\r
+    \r
+      //\r
+      //  Remove the service from the service list\r
+      //\r
+      pBuffer = (UINT8 *)&mEslLayer;\r
+      pBuffer = &pBuffer[ pService->pSocketBinding->ServiceListOffset ];\r
+      ppServiceListHead = (ESL_SERVICE **)pBuffer;\r
+      pPreviousService = *ppServiceListHead;\r
+      if ( pService == pPreviousService ) {\r
+        //\r
+        //  Remove the service from the beginning of the list\r
+        //\r
+        *ppServiceListHead = pService->pNext;\r
+      }\r
+      else {\r
+        //\r
+        //  Remove the service from the middle of the list\r
+        //\r
+        while ( NULL != pPreviousService ) {\r
+          if ( pService == pPreviousService->pNext ) {\r
+            pPreviousService->pNext = pService->pNext;\r
+            break;\r
+          }\r
+          pPreviousService = pPreviousService->pNext;\r
+        }\r
+      }\r
 \r
       //\r
       //  Release the socket layer synchronization\r
@@ -387,48 +429,6 @@ EslServiceDisconnect (
 \r
 \r
 \r
-/**\r
-Install the socket service\r
-\r
-@param [in] pImageHandle      Address of the image handle\r
-\r
-@retval EFI_SUCCESS     Service installed successfully\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EslServiceInstall (\r
-  IN EFI_HANDLE * pImageHandle\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-\r
-  //\r
-  //  Install the socket service binding protocol\r
-  //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  pImageHandle,\r
-                  &gEfiSocketServiceBindingProtocolGuid,\r
-                  &mEslLayer.ServiceBinding,\r
-                  NULL\r
-                  );\r
-  if ( !EFI_ERROR ( Status )) {\r
-    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
-              "Installed: gEfiSocketServiceBindingProtocolGuid on   0x%08x\r\n",\r
-              *pImageHandle ));\r
-  }\r
-  else {\r
-    DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
-              "ERROR - InstallMultipleProtocolInterfaces failed, Status: %r\r\n",\r
-              Status ));\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  return Status;\r
-}\r
-\r
-\r
 /**\r
 Initialize the service layer\r
 \r
@@ -441,69 +441,20 @@ EslServiceLoad (
   IN EFI_HANDLE ImageHandle\r
   )\r
 {\r
-  DT_LAYER * pLayer;\r
+  ESL_LAYER * pLayer;\r
 \r
   //\r
   //  Save the image handle\r
   //\r
   pLayer = &mEslLayer;\r
+  ZeroMem ( pLayer, sizeof ( *pLayer ));\r
   pLayer->Signature = LAYER_SIGNATURE;\r
   pLayer->ImageHandle = ImageHandle;\r
 \r
-  //\r
-  //  Initialize the TCP4 close\r
-  //\r
-  pLayer->TcpCloseMax4 = DIM ( mpEfiTcpClose4 );\r
-  pLayer->ppTcpClose4 = mpEfiTcpClose4;\r
-\r
   //\r
   //  Connect the service binding protocol to the image handle\r
   //\r
-  pLayer->ServiceBinding.CreateChild = EslSocketCreateChild;\r
-  pLayer->ServiceBinding.DestroyChild = EslSocketDestroyChild;\r
-}\r
-\r
-\r
-/**\r
-Uninstall the socket service\r
-\r
-@param [in] ImageHandle       Handle for the image.\r
-\r
-@retval EFI_SUCCESS     Service installed successfully\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EslServiceUninstall (\r
-  IN EFI_HANDLE ImageHandle\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-\r
-  //\r
-  //  Install the socket service binding protocol\r
-  //\r
-  Status = gBS->UninstallMultipleProtocolInterfaces (\r
-              ImageHandle,\r
-              &gEfiSocketServiceBindingProtocolGuid,\r
-              &mEslLayer.ServiceBinding,\r
-              NULL\r
-              );\r
-  if ( !EFI_ERROR ( Status )) {\r
-    DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
-                "Removed:   gEfiSocketServiceBindingProtocolGuid from 0x%08x\r\n",\r
-                ImageHandle ));\r
-  }\r
-  else {\r
-    DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT,\r
-                "ERROR - Failed to remove gEfiSocketServiceBindingProtocolGuid from 0x%08x, Status: %r\r\n",\r
-                ImageHandle,\r
-                Status ));\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  return Status;\r
+  pLayer->pServiceBinding = &mEfiServiceBinding;\r
 }\r
 \r
 \r
@@ -517,13 +468,12 @@ EslServiceUnload (
   VOID\r
   )\r
 {\r
-  DT_LAYER * pLayer;\r
+  ESL_LAYER * pLayer;\r
 \r
   //\r
   //  Undo the work by ServiceLoad\r
   //\r
   pLayer = &mEslLayer;\r
   pLayer->ImageHandle = NULL;\r
-  pLayer->ServiceBinding.CreateChild = NULL;\r
-  pLayer->ServiceBinding.DestroyChild = NULL;\r
+  pLayer->pServiceBinding = NULL;\r
 }\r