diff options
Diffstat (limited to 'arch/um/kernel/irq_user.c')
| -rw-r--r-- | arch/um/kernel/irq_user.c | 49 |
1 files changed, 7 insertions, 42 deletions
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c index c3ccaf24f3e0..0e32f5f4a887 100644 --- a/arch/um/kernel/irq_user.c +++ b/arch/um/kernel/irq_user.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include "kern_util.h" | 15 | #include "kern_util.h" |
| 16 | #include "user.h" | 16 | #include "user.h" |
| 17 | #include "process.h" | 17 | #include "process.h" |
| 18 | #include "signal_user.h" | ||
| 19 | #include "sigio.h" | 18 | #include "sigio.h" |
| 20 | #include "irq_user.h" | 19 | #include "irq_user.h" |
| 21 | #include "os.h" | 20 | #include "os.h" |
| @@ -29,7 +28,6 @@ struct irq_fd { | |||
| 29 | int pid; | 28 | int pid; |
| 30 | int events; | 29 | int events; |
| 31 | int current_events; | 30 | int current_events; |
| 32 | int freed; | ||
| 33 | }; | 31 | }; |
| 34 | 32 | ||
| 35 | static struct irq_fd *active_fds = NULL; | 33 | static struct irq_fd *active_fds = NULL; |
| @@ -41,9 +39,11 @@ static int pollfds_size = 0; | |||
| 41 | 39 | ||
| 42 | extern int io_count, intr_count; | 40 | extern int io_count, intr_count; |
| 43 | 41 | ||
| 42 | extern void free_irqs(void); | ||
| 43 | |||
| 44 | void sigio_handler(int sig, union uml_pt_regs *regs) | 44 | void sigio_handler(int sig, union uml_pt_regs *regs) |
| 45 | { | 45 | { |
| 46 | struct irq_fd *irq_fd, *next; | 46 | struct irq_fd *irq_fd; |
| 47 | int i, n; | 47 | int i, n; |
| 48 | 48 | ||
| 49 | if(smp_sigio_handler()) return; | 49 | if(smp_sigio_handler()) return; |
| @@ -66,29 +66,15 @@ void sigio_handler(int sig, union uml_pt_regs *regs) | |||
| 66 | irq_fd = irq_fd->next; | 66 | irq_fd = irq_fd->next; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){ | 69 | for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){ |
| 70 | next = irq_fd->next; | ||
| 71 | if(irq_fd->current_events != 0){ | 70 | if(irq_fd->current_events != 0){ |
| 72 | irq_fd->current_events = 0; | 71 | irq_fd->current_events = 0; |
| 73 | do_IRQ(irq_fd->irq, regs); | 72 | do_IRQ(irq_fd->irq, regs); |
| 74 | |||
| 75 | /* This is here because the next irq may be | ||
| 76 | * freed in the handler. If a console goes | ||
| 77 | * away, both the read and write irqs will be | ||
| 78 | * freed. After do_IRQ, ->next will point to | ||
| 79 | * a good IRQ. | ||
| 80 | * Irqs can't be freed inside their handlers, | ||
| 81 | * so the next best thing is to have them | ||
| 82 | * marked as needing freeing, so that they | ||
| 83 | * can be freed here. | ||
| 84 | */ | ||
| 85 | next = irq_fd->next; | ||
| 86 | if(irq_fd->freed){ | ||
| 87 | free_irq(irq_fd->irq, irq_fd->id); | ||
| 88 | } | ||
| 89 | } | 73 | } |
| 90 | } | 74 | } |
| 91 | } | 75 | } |
| 76 | |||
| 77 | free_irqs(); | ||
| 92 | } | 78 | } |
| 93 | 79 | ||
| 94 | int activate_ipi(int fd, int pid) | 80 | int activate_ipi(int fd, int pid) |
| @@ -136,8 +122,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
| 136 | .irq = irq, | 122 | .irq = irq, |
| 137 | .pid = pid, | 123 | .pid = pid, |
| 138 | .events = events, | 124 | .events = events, |
| 139 | .current_events = 0, | 125 | .current_events = 0 } ); |
| 140 | .freed = 0 } ); | ||
| 141 | 126 | ||
| 142 | /* Critical section - locked by a spinlock because this stuff can | 127 | /* Critical section - locked by a spinlock because this stuff can |
| 143 | * be changed from interrupt handlers. The stuff above is done | 128 | * be changed from interrupt handlers. The stuff above is done |
| @@ -313,26 +298,6 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) | |||
| 313 | return(irq); | 298 | return(irq); |
| 314 | } | 299 | } |
| 315 | 300 | ||
| 316 | void free_irq_later(int irq, void *dev_id) | ||
| 317 | { | ||
| 318 | struct irq_fd *irq_fd; | ||
| 319 | unsigned long flags; | ||
| 320 | |||
| 321 | flags = irq_lock(); | ||
| 322 | for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){ | ||
| 323 | if((irq_fd->irq == irq) && (irq_fd->id == dev_id)) | ||
| 324 | break; | ||
| 325 | } | ||
| 326 | if(irq_fd == NULL){ | ||
| 327 | printk("free_irq_later found no irq, irq = %d, " | ||
| 328 | "dev_id = 0x%p\n", irq, dev_id); | ||
| 329 | goto out; | ||
| 330 | } | ||
| 331 | irq_fd->freed = 1; | ||
| 332 | out: | ||
| 333 | irq_unlock(flags); | ||
| 334 | } | ||
| 335 | |||
| 336 | void reactivate_fd(int fd, int irqnum) | 301 | void reactivate_fd(int fd, int irqnum) |
| 337 | { | 302 | { |
| 338 | struct irq_fd *irq; | 303 | struct irq_fd *irq; |
