#include "linux/sched.h"
#include "linux/slab.h"
#include "linux/interrupt.h"
-#include "linux/irq.h"
#include "linux/spinlock.h"
#include "linux/errno.h"
+#include "asm/atomic.h"
#include "asm/semaphore.h"
#include "asm/errno.h"
#include "kern_util.h"
struct port_list {
struct list_head list;
+ atomic_t wait_count;
int has_connection;
- struct semaphore sem;
+ struct completion done;
int port;
int fd;
spinlock_t lock;
conn->fd = fd;
list_add(&conn->list, &conn->port->connections);
- up(&conn->port->sem);
+ complete(&conn->port->done);
return(IRQ_HANDLED);
}
+#define NO_WAITER_MSG \
+ "****\n" \
+ "There are currently no UML consoles waiting for port connections.\n" \
+ "Either disconnect from one to make it available or activate some more\n" \
+ "by enabling more consoles in the UML /etc/inittab.\n" \
+ "****\n"
+
static int port_accept(struct port_list *port)
{
struct connection *conn;
goto out_free;
}
+ if(atomic_read(&port->wait_count) == 0){
+ os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG));
+ printk("No one waiting for port\n");
+ }
list_add(&conn->list, &port->pending);
return(1);
*port = ((struct port_list)
{ .list = LIST_HEAD_INIT(port->list),
+ .wait_count = ATOMIC_INIT(0),
.has_connection = 0,
- .sem = __SEMAPHORE_INITIALIZER(port->sem,
- 0),
- .lock = SPIN_LOCK_UNLOCKED,
.port = port_num,
.fd = fd,
.pending = LIST_HEAD_INIT(port->pending),
.connections = LIST_HEAD_INIT(port->connections) });
+ spin_lock_init(&port->lock);
+ init_completion(&port->done);
list_add(&port->list, &ports);
found:
struct port_list *port = dev->port;
int fd;
+ atomic_inc(&port->wait_count);
while(1){
- if(down_interruptible(&port->sem))
- return(-ERESTARTSYS);
+ fd = -ERESTARTSYS;
+ if(wait_for_completion_interruptible(&port->done))
+ goto out;
spin_lock(&port->lock);
dev->helper_pid = conn->helper_pid;
dev->telnetd_pid = conn->telnetd_pid;
kfree(conn);
-
- return(fd);
+ out:
+ atomic_dec(&port->wait_count);
+ return fd;
}
void port_remove_dev(void *d)
}
__uml_exitcall(free_port);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */