From: Eric W. Biederman Date: Tue, 12 Apr 2011 05:47:31 +0000 (-0700) Subject: core: pxe: Improve the situation with installing and uninstalling irq handlers X-Git-Tag: syslinux-4.10-pre1~15 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=abf7a9d75878f7eac2fc363d934fce52fa33f532;p=platform%2Fupstream%2Fsyslinux.git core: pxe: Improve the situation with installing and uninstalling irq handlers Signed-off-by: Eric W. Biederman --- 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 #include #include #include -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