bug-hurd
[Top][All Lists]
Advanced

[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, &regs);
       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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]