#include "kern_util.h"
#include "user.h"
#include "process.h"
-#include "signal_user.h"
#include "sigio.h"
#include "irq_user.h"
#include "os.h"
int pid;
int events;
int current_events;
- int freed;
};
static struct irq_fd *active_fds = NULL;
extern int io_count, intr_count;
+extern void free_irqs(void);
+
void sigio_handler(int sig, union uml_pt_regs *regs)
{
- struct irq_fd *irq_fd, *next;
+ struct irq_fd *irq_fd;
int i, n;
if(smp_sigio_handler()) return;
irq_fd = irq_fd->next;
}
- for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){
- next = irq_fd->next;
+ for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
if(irq_fd->current_events != 0){
irq_fd->current_events = 0;
do_IRQ(irq_fd->irq, regs);
-
- /* This is here because the next irq may be
- * freed in the handler. If a console goes
- * away, both the read and write irqs will be
- * freed. After do_IRQ, ->next will point to
- * a good IRQ.
- * Irqs can't be freed inside their handlers,
- * so the next best thing is to have them
- * marked as needing freeing, so that they
- * can be freed here.
- */
- next = irq_fd->next;
- if(irq_fd->freed)
- free_irq(irq_fd->irq, irq_fd->id);
}
}
}
+
+ free_irqs();
}
int activate_ipi(int fd, int pid)
.irq = irq,
.pid = pid,
.events = events,
- .current_events = 0,
- .freed = 0 } );
+ .current_events = 0 } );
/* Critical section - locked by a spinlock because this stuff can
* be changed from interrupt handlers. The stuff above is done
(*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;
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 });
return(irq);
}
-void free_irq_later(int irq, void *dev_id)
-{
- struct irq_fd *irq_fd;
- unsigned long flags;
-
- flags = irq_lock();
- for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
- if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
- break;
- }
- if(irq_fd == NULL){
- printk("free_irq_later found no irq, irq = %d, "
- "dev_id = 0x%p\n", irq, dev_id);
- goto out;
- }
- irq_fd->freed = 1;
- out:
- irq_unlock(flags);
-}
-
void reactivate_fd(int fd, int irqnum)
{
struct irq_fd *irq;
irq_unlock(flags);
}
+int deactivate_all_fds(void)
+{
+ struct irq_fd *irq;
+ int err;
+
+ for(irq=active_fds;irq != NULL;irq = irq->next){
+ err = os_clear_fd_async(irq->fd);
+ if(err)
+ return(err);
+ }
+ /* If there is a signal already queued, after unblocking ignore it */
+ set_handler(SIGIO, SIG_IGN, 0, -1);
+
+ return(0);
+}
+
void forward_ipi(int fd, int pid)
{
int err;