X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fum%2Fkernel%2Firq_user.c;h=b3074cbaa479ac3de6c42242006d8e5c1f33cb42;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=38e66ac84637ddef1e8176aedd1566ddfc182893;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c index 38e66ac84..b3074cbaa 100644 --- a/arch/um/kernel/irq_user.c +++ b/arch/um/kernel/irq_user.c @@ -83,8 +83,11 @@ void sigio_handler(int sig, union uml_pt_regs *regs) * can be freed here. */ next = irq_fd->next; - if(irq_fd->freed) + if(irq_fd->freed){ free_irq(irq_fd->irq, irq_fd->id); + free_irq_by_irq_and_dev(irq_fd->irq, + irq_fd->id); + } } } } @@ -233,9 +236,15 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg) (*prev)->fd, pollfds[i].fd); goto out; } - memcpy(&pollfds[i], &pollfds[i + 1], - (pollfds_num - i - 1) * sizeof(pollfds[0])); + pollfds_num--; + + /* This moves the *whole* array after pollfds[i] (though + * it doesn't spot as such)! */ + + memmove(&pollfds[i], &pollfds[i + 1], + (pollfds_num - i) * sizeof(pollfds[0])); + if(last_irq_ptr == &old_fd->next) last_irq_ptr = prev; *prev = (*prev)->next; @@ -263,7 +272,7 @@ static int same_irq_and_dev(struct irq_fd *irq, void *d) return((irq->irq == data->irq) && (irq->id == data->dev)); } -void free_irq_by_irq_and_dev(int irq, void *dev) +void free_irq_by_irq_and_dev(unsigned int irq, void *dev) { struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq, .dev = dev }); @@ -374,6 +383,8 @@ int deactivate_all_fds(void) if(err) return(err); } + /* If there is a signal already queued, after unblocking ignore it */ + set_handler(SIGIO, SIG_IGN, 0, -1); return(0); }