]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[ifmgmt] Rewrite iflinkwait() to use monojob_wait()
authorMichael Brown <mcb30@ipxe.org>
Fri, 1 Nov 2013 17:38:45 +0000 (17:38 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 5 Nov 2013 17:15:24 +0000 (17:15 +0000)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/usr/ifmgmt.h
src/usr/dhcpmgmt.c
src/usr/ifmgmt.c
src/usr/lotest.c

index f762c7ba9e4e8fd56f9ec3d394af81ececcd6441..0b265fea957e0f5054ddc2c3a80a76aff7302d05 100644 (file)
@@ -14,6 +14,6 @@ struct net_device;
 extern int ifopen ( struct net_device *netdev );
 extern void ifclose ( struct net_device *netdev );
 extern void ifstat ( struct net_device *netdev );
-extern int iflinkwait ( struct net_device *netdev, unsigned int max_wait_ms );
+extern int iflinkwait ( struct net_device *netdev, unsigned long timeout );
 
 #endif /* _USR_IFMGMT_H */
index 7b8e53701b56ea98ec8e43127dd847dc827982eb..9309671e9cc20ca8963649b184100b6ee093eb8e 100644 (file)
@@ -25,11 +25,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/netdevice.h>
 #include <ipxe/dhcp.h>
 #include <ipxe/monojob.h>
-#include <ipxe/process.h>
+#include <ipxe/timer.h>
 #include <usr/ifmgmt.h>
 #include <usr/dhcpmgmt.h>
 
-#define LINK_WAIT_MS   15000
+/** Default time to wait for link-up */
+#define LINK_WAIT_TIMEOUT ( 15 * TICKS_PER_SEC )
 
 /** @file
  *
@@ -45,7 +46,7 @@ int dhcp ( struct net_device *netdev ) {
                return rc;
 
        /* Wait for link-up */
-       if ( ( rc = iflinkwait ( netdev, LINK_WAIT_MS ) ) != 0 )
+       if ( ( rc = iflinkwait ( netdev, LINK_WAIT_TIMEOUT ) ) != 0 )
                return rc;
 
        /* Perform DHCP */
index 94e6e87546442857a628ed0609199d41cb77a5c2..cf7e6b6a348c8c8edd2887f31e00406100922069 100644 (file)
@@ -26,8 +26,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/console.h>
 #include <ipxe/netdevice.h>
 #include <ipxe/device.h>
-#include <ipxe/process.h>
-#include <ipxe/keys.h>
+#include <ipxe/job.h>
+#include <ipxe/monojob.h>
+#include <ipxe/nap.h>
 #include <usr/ifmgmt.h>
 
 /** @file
@@ -104,49 +105,104 @@ void ifstat ( struct net_device *netdev ) {
        ifstat_errors ( &netdev->rx_stats, "RXE" );
 }
 
+/** Network device poller */
+struct ifpoller {
+       /** Job control interface */
+       struct interface job;
+       /** Network device */
+       struct net_device *netdev;
+       /**
+        * Check progress
+        *
+        * @v ifpoller          Network device poller
+        * @ret ongoing_rc      Ongoing job status code (if known)
+        */
+       int ( * progress ) ( struct ifpoller *ifpoller );
+};
+
+/**
+ * Report network device poller progress
+ *
+ * @v ifpoller         Network device poller
+ * @v progress         Progress report to fill in
+ * @ret ongoing_rc     Ongoing job status code (if known)
+ */
+static int ifpoller_progress ( struct ifpoller *ifpoller,
+                              struct job_progress *progress __unused ) {
+
+       /* Reduce CPU utilisation */
+       cpu_nap();
+
+       /* Hand off to current progress checker */
+       return ifpoller->progress ( ifpoller );
+}
+
+/** Network device poller operations */
+static struct interface_operation ifpoller_job_op[] = {
+       INTF_OP ( job_progress, struct ifpoller *, ifpoller_progress ),
+};
+
+/** Network device poller descriptor */
+static struct interface_descriptor ifpoller_job_desc =
+       INTF_DESC ( struct ifpoller, job, ifpoller_job_op );
+
+/**
+ * Poll network device until completion
+ *
+ * @v netdev           Network device
+ * @v timeout          Timeout period, in ticks
+ * @v progress         Method to check progress
+ * @ret rc             Return status code
+ */
+static int ifpoller_wait ( struct net_device *netdev, unsigned long timeout,
+                          int ( * progress ) ( struct ifpoller *ifpoller ) ) {
+       static struct ifpoller ifpoller = {
+               .job = INTF_INIT ( ifpoller_job_desc ),
+       };
+
+       ifpoller.netdev = netdev;
+       ifpoller.progress = progress;
+       intf_plug_plug ( &monojob, &ifpoller.job );
+       return monojob_wait ( "", timeout );
+}
+
+/**
+ * Check link-up progress
+ *
+ * @v ifpoller         Network device poller
+ * @ret ongoing_rc     Ongoing job status code (if known)
+ */
+static int iflinkwait_progress ( struct ifpoller *ifpoller ) {
+       struct net_device *netdev = ifpoller->netdev;
+       int ongoing_rc = netdev->link_rc;
+
+       /* Terminate successfully if link is up */
+       if ( ongoing_rc == 0 )
+               intf_close ( &ifpoller->job, 0 );
+
+       /* Otherwise, report link status as ongoing job status */
+       return ongoing_rc;
+}
+
 /**
  * Wait for link-up, with status indication
  *
  * @v netdev           Network device
- * @v max_wait_ms      Maximum time to wait, in ms
+ * @v timeout          Timeout period, in ticks
  */
-int iflinkwait ( struct net_device *netdev, unsigned int max_wait_ms ) {
-       int key;
+int iflinkwait ( struct net_device *netdev, unsigned long timeout ) {
        int rc;
 
-       /* Allow link state to be updated */
-       netdev_poll ( netdev );
+       /* Ensure device is open */
+       if ( ( rc = ifopen ( netdev ) ) != 0 )
+               return rc;
 
+       /* Return immediately if link is already up */
+       netdev_poll ( netdev );
        if ( netdev_link_ok ( netdev ) )
                return 0;
 
-       printf ( "Waiting for link-up on %s...", netdev->name );
-
-       while ( 1 ) {
-               if ( netdev_link_ok ( netdev ) ) {
-                       rc = 0;
-                       break;
-               }
-               if ( max_wait_ms-- == 0 ) {
-                       rc = netdev->link_rc;
-                       break;
-               }
-               step();
-               if ( iskey() ) {
-                       key = getchar();
-                       if ( key == CTRL_C ) {
-                               rc = -ECANCELED;
-                               break;
-                       }
-               }
-               mdelay ( 1 );
-       }
-
-       if ( rc == 0 ) {
-               printf ( " ok\n" );
-       } else {
-               printf ( " failed: %s\n", strerror ( rc ) );
-       }
-
-       return rc;
+       /* Wait for link-up */
+       printf ( "Waiting for link-up on %s", netdev->name );
+       return ifpoller_wait ( netdev, timeout, iflinkwait_progress );
 }
index 905290a5e4aed750e89fa1e3a3efb8a8f6cdc2c0..51d1a5d6e7c181b8af01625dfcc77d7d98ad5cdb 100644 (file)
@@ -39,8 +39,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
  *
  */
 
-#define LINK_WAIT_MS 15000
-
 /**
  * Process received packet
  *
@@ -189,9 +187,9 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
                return rc;
 
        /* Wait for link-up */
-       if ( ( rc = iflinkwait ( sender, LINK_WAIT_MS ) ) != 0 )
+       if ( ( rc = iflinkwait ( sender, 0 ) ) != 0 )
                return rc;
-       if ( ( rc = iflinkwait ( receiver, LINK_WAIT_MS ) ) != 0 )
+       if ( ( rc = iflinkwait ( receiver, 0 ) ) != 0 )
                return rc;
 
        /* Allocate data buffer */