[syslinux:lwip] core: pxe: Improve the situation with installing and uninstalling irq handlers

syslinux-bot for Eric W. Biederman ebiederm at xmission.com
Fri Apr 22 20:06:06 PDT 2011


Commit-ID:  abf7a9d75878f7eac2fc363d934fce52fa33f532
Gitweb:     http://syslinux.zytor.com/commit/abf7a9d75878f7eac2fc363d934fce52fa33f532
Author:     Eric W. Biederman <ebiederm at xmission.com>
AuthorDate: Mon, 11 Apr 2011 22:47:31 -0700
Committer:  Eric W. Biederman <ebiederm at xmission.com>
CommitDate: Tue, 12 Apr 2011 14:41:18 -0700

core: pxe:  Improve the situation with installing and uninstalling irq handlers

Signed-off-by: Eric W. Biederman <ebiederm at xmission.com>


---
 core/fs/pxe/isr.c            |   56 +++++++++++++++++++++++++++++++++++++++++-
 core/fs/pxe/pxe.h            |    8 ++++++
 core/include/core.h          |    1 +
 core/lwip/src/netif/undiif.c |   22 +---------------
 core/pm.inc                  |    1 +
 5 files changed, 67 insertions(+), 21 deletions(-)

diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index 4eac5aa..4dcadc1 100644
--- a/core/fs/pxe/isr.c
+++ b/core/fs/pxe/isr.c
@@ -12,6 +12,46 @@
 
 extern uint8_t pxe_irq_pending;
 static DECLARE_INIT_SEMAPHORE(pxe_receive_thread_sem, 0);
+static struct thread *pxe_thread;
+
+bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old)
+{
+    far_ptr_t *entry;
+    unsigned int vec;
+  
+    if (irq < 8)
+	vec = irq + 0x08;
+    else if (irq < 16)
+	vec = (irq - 8) + 0x70;
+    else
+	return false;
+ 
+    entry = (far_ptr_t *)(vec << 2);
+    *old = *entry;
+    entry->ptr = (uint32_t)isr;
+    return true;
+}
+
+bool uninstall_irq_vector(uint8_t irq, void (*isr), far_ptr_t *old)
+{
+    far_ptr_t *entry;
+    unsigned int vec;
+   
+    if (irq < 8)
+	vec = irq + 0x08;
+    else if (irq < 16)
+	vec = (irq - 8) + 0x70;
+    else
+	return false;
+  
+    entry = (far_ptr_t *)(vec << 2);
+
+    if (entry->ptr != (uint32_t)isr)
+	return false;
+
+    *entry = *old;
+    return true;
+}
 
 static void pm_return(void)
 {
@@ -99,6 +139,20 @@ void pxe_init_isr(void)
      * avoid packet loss we need to move it into memory that we ourselves
      * manage, as soon as possible.
      */
-    start_thread("pxe receive", 16384, -20, pxe_receive_thread, NULL);
+    pxe_thread = start_thread("pxe receive", 16384, -20, pxe_receive_thread, NULL);
     core_pm_hook = pm_return;
 }
+
+
+void pxe_cleanup_isr(void)
+{
+    static __lowmem struct s_PXENV_UNDI_CLOSE undi_close;
+    int err;
+
+    core_pm_hook = core_pm_null_hook;
+    kill_thread(pxe_thread);
+ 
+    memset(&undi_close, 0, sizeof(undi_close));
+    err = pxe_call(PXENV_UNDI_CLOSE, &undi_close);
+    uninstall_irq_vector(pxe_irq_vector, pxe_isr, &pxe_irq_chain);
+}
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index f41bf82..810646e 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -236,9 +236,17 @@ static inline uint32_t gateway(uint32_t ip)
  * functions 
  */
 
+/* pxeisr.inc */
+extern uint8_t pxe_irq_vector;
+extern void pxe_isr(void);
+extern far_ptr_t pxe_irq_chain;
+
 /* isr.c */
 void pxe_init_isr(void);
+void pxe_cleanup_isr(void);
 void pxe_poll(void);
+bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old);
+bool uninstall_irq_vector(uint8_t irq, void (*isr), far_ptr_t *old);
 
 /* pxe.c */
 bool ip_ok(uint32_t);
diff --git a/core/include/core.h b/core/include/core.h
index 034e996..46c41bc 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -21,6 +21,7 @@ extern char ConfigFile[];
 extern void getlinsec(void);
 
 /* pm.inc */
+void core_pm_null_hook(void);
 extern void (*core_pm_hook)(void);
 
 /* getc.inc */
diff --git a/core/lwip/src/netif/undiif.c b/core/lwip/src/netif/undiif.c
index 1baeb97..a925e28 100644
--- a/core/lwip/src/netif/undiif.c
+++ b/core/lwip/src/netif/undiif.c
@@ -57,13 +57,13 @@
 #include "netif/ppp_oe.h"
 #include "lwip/netifapi.h"
 #include "lwip/tcpip.h"
+#include "../../../fs/pxe/pxe.h"
 
 #include <inttypes.h>
 #include <string.h>
 #include <syslinux/pxe_api.h>
 #include <dprintf.h>
 
-int pxe_call(int, void *);
 #define PKTBUF_SIZE	2048
 
 /* Define those to better describe your network interface. */
@@ -79,24 +79,6 @@ static struct netif undi_netif;
  * @param netif the already initialized lwip network interface structure
  *        for this undiif
  */
-extern uint8_t pxe_irq_vector;
-extern void pxe_isr(void);
-
-/* XXX: move this somewhere sensible */
-static void install_irq_vector(uint8_t irq, void (*isr)(void))
-{
-  unsigned int vec;
-
-  if (irq < 8)
-    vec = irq + 0x08;
-  else if (irq < 16)
-    vec = (irq - 8) + 0x70;
-  else
-    return;			/* ERROR */
-  
-  *(uint32_t *)(vec << 2) = (uint32_t)isr;
-}
-
 static void
 low_level_init(struct netif *netif)
 {
@@ -131,7 +113,7 @@ low_level_init(struct netif *netif)
 
   /* Install the interrupt vector */
   pxe_irq_vector = undi_info.IntNumber;
-  install_irq_vector(pxe_irq_vector, pxe_isr);
+  install_irq_vector(pxe_irq_vector, pxe_isr, &pxe_irq_chain);
 
   /* Open the UNDI stack - you'd think the BC would have done this... */
   undi_open.PktFilter = 0x0003;	/* FLTR_DIRECTED | FLTR_BRDCST */
diff --git a/core/pm.inc b/core/pm.inc
index 80685e5..8690cab 100644
--- a/core/pm.inc
+++ b/core/pm.inc
@@ -222,6 +222,7 @@ pm_irq:
 ; threaded derivatives to run the scheduler, or examine the result from
 ; interrupt routines.
 ;
+		global core_pm_null_hook
 core_pm_null_hook:
 		ret
 



More information about the Syslinux-commits mailing list