Junling Ma
unread,Aug 4, 2020, 5:06:37 PM8/4/20You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to bug-...@gnu.org
irqdev: make deliver_user_intr a linux irq handler
---
device/intr.c | 30 ++++++++++++++-----
device/intr.h | 1 -
linux/dev/arch/i386/kernel/irq.c | 51 +-------------------------------
3 files changed, 24 insertions(+), 58 deletions(-)
diff --git a/device/intr.c b/device/intr.c
index c98e5c39..b60a6a28 100644
--- a/device/intr.c
+++ b/device/intr.c
@@ -27,6 +27,10 @@ extern struct irqdev irqtab;
#define main_intr_queue irqtab.intr_queue
static boolean_t deliver_intr (int id, ipc_port_t dst_port);
+#define SA_SHIRQ 0x04000000
+struct pt_regs;
+extern int request_irq (unsigned int irq, void (*handler) (int, void *, struct pt_regs *),
+ unsigned long flags, const char *device, void *dev_id);
extern void free_irq (unsigned int irq, void *dev_id);
#define PROTECT(lock, critical_section) \
@@ -84,18 +88,18 @@ irq_acknowledge (ipc_port_t receive_port)
return D_SUCCESS;
}
-void
-deliver_user_intr (struct irqdev *dev, int id, user_intr_t *e)
+static void
+deliver_user_intr (int id, void *dev_id, struct pt_regs *regs)
{
+ spl_t s = splhigh();
+ user_intr_t *e = dev_id;
/* Until userland has handled the IRQ in the driver, we have to keep it
* disabled. Level-triggered interrupts would keep raising otherwise. */
- __disable_irq (dev->irq[id]);
-
- spl_t s = splhigh ();
+ __disable_irq (irqtab.irq[id]);
e->n_unacked++;
e->interrupts++;
- dev->tot_num_intr++;
- splx (s);
+ irqtab.tot_num_intr++;
+ splx(s);
thread_wakeup ((event_t) &intr_thread);
}
@@ -283,4 +287,16 @@ deliver_intr (int id, ipc_port_t dst_port)
return TRUE;
}
+int
+install_user_intr_handler (struct irqdev *dev, int id, unsigned long flags,
+ user_intr_t *user_intr)
+{
+ if (id >= NINTR)
+ return D_INVALID_OPERATION;
+ unsigned int irq = dev->irq[id];
+ if (irq >= NINTR)
+ return D_INVALID_OPERATION;
+ return request_irq (id, deliver_user_intr, SA_SHIRQ, NULL, user_intr);
+}
+
#endif /* MACH_XEN */
diff --git a/device/intr.h b/device/intr.h
index 55fc60dc..b1c09e6c 100644
--- a/device/intr.h
+++ b/device/intr.h
@@ -51,7 +51,6 @@ struct irqdev {
};
extern int install_user_intr_handler (struct irqdev *dev, int id, unsigned long flags, user_intr_t *e);
-extern void deliver_user_intr (struct irqdev *dev, int id, user_intr_t *e);
extern user_intr_t *insert_intr_entry (struct irqdev *dev, int id, ipc_port_t receive_port);
void intr_thread (void);
diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c
index a01f7ab6..aee10462 100644
--- a/linux/dev/arch/i386/kernel/irq.c
+++ b/linux/dev/arch/i386/kernel/irq.c
@@ -111,9 +111,7 @@ linux_intr (int irq)
{
// TODO I might need to check whether the interrupt belongs to
// the current device. But I don't do it for now.
- if (action->user_intr)
- deliver_user_intr(&irqtab, irq, action->user_intr);
- else if (action->handler)
+ if (action->handler)
action->handler (irq, action->dev_id, ®s);
action = action->next;
}
@@ -209,53 +207,6 @@ setup_x86_irq (int irq, struct linux_action *new)
return 0;
}
-int
-install_user_intr_handler (struct irqdev *dev, int id, unsigned long flags,
- user_intr_t *user_intr)
-{
- struct linux_action *action;
- struct linux_action *old;
- int retval;
-
- unsigned int irq = dev->irq[id];
-
- assert (irq < 16);
-
- /* Test whether the irq handler has been set */
- // TODO I need to protect the array when iterating it.
- old = irq_action[irq];
- while (old)
- {
- if (old->user_intr && old->user_intr->dst_port == user_intr->dst_port)
- {
- printk ("The interrupt handler has already been installed on line %d", irq);
- return linux_to_mach_error (-EAGAIN);
- }
- old = old->next;
- }
-
- /*
- * Hmm... Should I use `kalloc()' ?
- * By OKUJI Yoshinori.
- */
- action = (struct linux_action *)
- linux_kmalloc (sizeof (struct linux_action), GFP_KERNEL);
- if (action == NULL)
- return linux_to_mach_error (-ENOMEM);
-
- action->handler = NULL;
- action->next = NULL;
- action->dev_id = user_intr;
- action->flags = SA_SHIRQ;
- action->user_intr = user_intr;
-
- retval = setup_x86_irq (irq, action);
- if (retval)
- linux_kfree (action);
-
- return linux_to_mach_error (retval);
-}
-
/*
* Attach a handler to an IRQ.
*/
--
2.28.0.rc1