core: pxe: Improve the situation with installing and uninstalling irq handlers
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 12 Apr 2011 05:47:31 +0000 (22:47 -0700)
committerEric W. Biederman <ebiederm@xmission.com>
Tue, 12 Apr 2011 21:41:18 +0000 (14:41 -0700)
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
core/fs/pxe/isr.c
core/fs/pxe/pxe.h
core/include/core.h
core/lwip/src/netif/undiif.c
core/pm.inc

index 4eac5aa..4dcadc1 100644 (file)
 
 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);
+}
index f41bf82..810646e 100644 (file)
@@ -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);
index 034e996..46c41bc 100644 (file)
@@ -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 */
index 1baeb97..a925e28 100644 (file)
 #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 */
index 80685e5..8690cab 100644 (file)
@@ -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