[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2] irqdev: make deliver_user_intr a linux irq handler
From: |
Junling Ma |
Subject: |
[PATCH v2] irqdev: make deliver_user_intr a linux irq handler |
Date: |
Tue, 4 Aug 2020 14:06:28 -0700 |
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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH v2] irqdev: make deliver_user_intr a linux irq handler,
Junling Ma <=