aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2011-04-12 04:38:21 -0700
committerEric W. Biederman <ebiederm@xmission.com>2011-04-12 14:41:24 -0700
commit6a54b8029280339e6b54c8c0f2780c74713cdffb (patch)
treeda6cb52104b04159233e2f01faa7479c24066d74
parent2674de6ed89756ad1b6954354e461bfd36f9d402 (diff)
downloadsyslinux-devel-6a54b8029280339e6b54c8c0f2780c74713cdffb.tar.gz
syslinux-devel-6a54b8029280339e6b54c8c0f2780c74713cdffb.tar.xz
syslinux-devel-6a54b8029280339e6b54c8c0f2780c74713cdffb.zip
pxe: Cleanup interrupt handling making it reliabe and in spec
- Rework pm_return into pxe_poll_wakeups and use the new sched_hook_funk to call it from schedule. That is a little extra work but it is always correct to do. - Unconditionally call schedule from the pm_core_hook. schedule now does everything pm_return used to do if perhaps in a more braindead way so this is correct and safe. - Declare undiif_input in pxe.h - Stop exporting pxe_poll. Having it exported helped me track down what was going on but it was the wrong way to do things and exporting it is no longer needed. - Rename pxe_poll pxe_process_irq for clarity. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
-rw-r--r--core/fs/pxe/isr.c27
-rw-r--r--core/fs/pxe/pxe.h2
2 files changed, 10 insertions, 19 deletions
diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index 4dcadc18..cb2300e0 100644
--- a/core/fs/pxe/isr.c
+++ b/core/fs/pxe/isr.c
@@ -53,34 +53,23 @@ bool uninstall_irq_vector(uint8_t irq, void (*isr), far_ptr_t *old)
return true;
}
-static void pm_return(void)
+static void pxe_poll_wakeups(void)
{
static jiffies_t last_jiffies = 0;
jiffies_t now = jiffies();
-
- __schedule_lock++;
if (now != last_jiffies) {
last_jiffies = now;
__thread_process_timeouts();
- __need_schedule = true; /* Switch threads if more than one runnable */
}
-
+
if (pxe_irq_pending) {
pxe_irq_pending = 0;
- if (pxe_receive_thread_sem.count <= 0)
- sem_up(&pxe_receive_thread_sem);
+ sem_up(&pxe_receive_thread_sem);
}
-
- __schedule_lock--;
-
- if (__need_schedule)
- __schedule();
}
-void undiif_input(t_PXENV_UNDI_ISR *);
-
-void pxe_poll(void)
+static void pxe_process_irq(void)
{
static __lowmem t_PXENV_UNDI_ISR isr;
@@ -104,7 +93,7 @@ void pxe_poll(void)
break;
case PXENV_UNDI_ISR_OUT_RECEIVE:
- undiif_input(&isr);
+ undiif_input(&isr);
break;
case PXENV_UNDI_ISR_OUT_BUSY:
@@ -126,13 +115,14 @@ static void pxe_receive_thread(void *dummy)
for (;;) {
sem_down(&pxe_receive_thread_sem, 0);
- pxe_poll();
+ pxe_process_irq();
}
}
void pxe_init_isr(void)
{
start_idle_thread();
+ sched_hook_func = pxe_poll_wakeups;
/*
* Run the pxe receive thread at elevated priority, since the UNDI
* stack is likely to have very limited memory available; therefore to
@@ -140,7 +130,7 @@ void pxe_init_isr(void)
* manage, as soon as possible.
*/
pxe_thread = start_thread("pxe receive", 16384, -20, pxe_receive_thread, NULL);
- core_pm_hook = pm_return;
+ core_pm_hook = __schedule;
}
@@ -149,6 +139,7 @@ void pxe_cleanup_isr(void)
static __lowmem struct s_PXENV_UNDI_CLOSE undi_close;
int err;
+ sched_hook_func = NULL;
core_pm_hook = core_pm_null_hook;
kill_thread(pxe_thread);
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index 9236b109..d30e7839 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -244,7 +244,6 @@ 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);
@@ -257,6 +256,7 @@ int pxe_getc(struct inode *inode);
/* undiif.c */
int undiif_start(uint32_t ip, uint32_t netmask, uint32_t gw);
+void undiif_input(t_PXENV_UNDI_ISR *isr);
/* dhcp_options.c */
void parse_dhcp(int);