summaryrefslogtreecommitdiffstats
path: root/arch/um/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers')
-rw-r--r--arch/um/drivers/Makefile6
-rw-r--r--arch/um/drivers/chan_kern.c22
-rw-r--r--arch/um/drivers/chan_user.c26
-rw-r--r--arch/um/drivers/daemon_user.c6
-rw-r--r--arch/um/drivers/line.c22
-rw-r--r--arch/um/drivers/mcast_kern.c4
-rw-r--r--arch/um/drivers/mcast_user.c47
-rw-r--r--arch/um/drivers/mconsole_kern.c36
-rw-r--r--arch/um/drivers/mmapper_kern.c24
-rw-r--r--arch/um/drivers/net_kern.c32
-rw-r--r--arch/um/drivers/net_user.c2
-rw-r--r--arch/um/drivers/port_kern.c1
-rw-r--r--arch/um/drivers/random.c16
-rw-r--r--arch/um/drivers/slip.h23
-rw-r--r--arch/um/drivers/slip_common.c54
-rw-r--r--arch/um/drivers/slip_common.h (renamed from arch/um/drivers/slip_proto.h)47
-rw-r--r--arch/um/drivers/slip_kern.c12
-rw-r--r--arch/um/drivers/slip_user.c152
-rw-r--r--arch/um/drivers/slirp.h26
-rw-r--r--arch/um/drivers/slirp_kern.c5
-rw-r--r--arch/um/drivers/slirp_user.c104
-rw-r--r--arch/um/drivers/ssl.c10
-rw-r--r--arch/um/drivers/stderr_console.c6
-rw-r--r--arch/um/drivers/stdio_console.c8
-rw-r--r--arch/um/drivers/ubd_kern.c340
-rw-r--r--arch/um/drivers/xterm_kern.c1
26 files changed, 378 insertions, 654 deletions
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 323f72c64cd2..b2de9916c32c 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -22,8 +22,8 @@ obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
obj-$(CONFIG_SSL) += ssl.o
obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
-obj-$(CONFIG_UML_NET_SLIP) += slip.o
-obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
+obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
+obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
obj-$(CONFIG_UML_NET_MCAST) += mcast.o
#obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP)
@@ -41,6 +41,6 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
obj-$(CONFIG_UML_RANDOM) += random.o
-USER_OBJS := fd.o null.o pty.o tty.o xterm.o
+USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o
include arch/um/scripts/Makefile.rules
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 0150038af795..14a12d6b3df6 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -20,9 +20,17 @@
#include "os.h"
#ifdef CONFIG_NOCONFIG_CHAN
+
+/* The printk's here are wrong because we are complaining that there is no
+ * output device, but printk is printing to that output device. The user will
+ * never see the error. printf would be better, except it can't run on a
+ * kernel stack because it will overflow it.
+ * Use printk for now since that will avoid crashing.
+ */
+
static void *not_configged_init(char *str, int device, struct chan_opts *opts)
{
- printf(KERN_ERR "Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(NULL);
}
@@ -30,27 +38,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
static int not_configged_open(int input, int output, int primary, void *data,
char **dev_out)
{
- printf(KERN_ERR "Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
static void not_configged_close(int fd, void *data)
{
- printf(KERN_ERR "Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
}
static int not_configged_read(int fd, char *c_out, void *data)
{
- printf(KERN_ERR "Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
static int not_configged_write(int fd, const char *buf, int len, void *data)
{
- printf(KERN_ERR "Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@@ -58,7 +66,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
static int not_configged_console_write(int fd, const char *buf, int len,
void *data)
{
- printf(KERN_ERR "Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@@ -66,7 +74,7 @@ static int not_configged_console_write(int fd, const char *buf, int len,
static int not_configged_window_size(int fd, void *data, unsigned short *rows,
unsigned short *cols)
{
- printf(KERN_ERR "Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 583b8e137c33..5d3768156c92 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -143,22 +143,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
{
struct winch_data data;
unsigned long stack;
- int fds[2], pid, n, err;
+ int fds[2], n, err;
char c;
err = os_pipe(fds, 1, 1);
if(err < 0){
printk("winch_tramp : os_pipe failed, err = %d\n", -err);
- return(err);
+ goto out;
}
data = ((struct winch_data) { .pty_fd = fd,
.pipe_fd = fds[1],
.close_me = fds[0] } );
- pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
- if(pid < 0){
+ err = run_helper_thread(winch_thread, &data, 0, &stack, 0);
+ if(err < 0){
printk("fork of winch_thread failed - errno = %d\n", errno);
- return(pid);
+ goto out_close;
}
os_close_file(fds[1]);
@@ -168,14 +168,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
printk("winch_tramp : failed to read synchronization byte\n");
printk("read failed, err = %d\n", -n);
printk("fd %d will not support SIGWINCH\n", fd);
- *fd_out = -1;
+ err = -EINVAL;
+ goto out_close1;
}
- return(pid);
+ return err ;
+
+ out_close:
+ os_close_file(fds[1]);
+ out_close1:
+ os_close_file(fds[0]);
+ out:
+ return err;
}
void register_winch(int fd, struct tty_struct *tty)
{
- int pid, thread, thread_fd;
+ int pid, thread, thread_fd = -1;
int count;
char c = 1;
@@ -186,7 +194,7 @@ void register_winch(int fd, struct tty_struct *tty)
if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
tty) && (pid == -1)){
thread = winch_tramp(fd, tty, &thread_fd);
- if(fd != -1){
+ if(thread > 0){
register_winch_irq(thread_fd, fd, thread, tty);
count = os_write_file(thread_fd, &c, sizeof(c));
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index cf15b4a8b517..c1b03f7c1daa 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -157,9 +157,9 @@ static void daemon_remove(void *data)
os_close_file(pri->fd);
os_close_file(pri->control);
- if(pri->data_addr != NULL) kfree(pri->data_addr);
- if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
- if(pri->local_addr != NULL) kfree(pri->local_addr);
+ kfree(pri->data_addr);
+ kfree(pri->ctl_addr);
+ kfree(pri->local_addr);
}
int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 025d3be8aca4..2bb4c4f5dec4 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -406,14 +406,12 @@ void line_disable(struct tty_struct *tty, int current_irq)
if(line->driver->read_irq == current_irq)
free_irq_later(line->driver->read_irq, tty);
else {
- free_irq_by_irq_and_dev(line->driver->read_irq, tty);
free_irq(line->driver->read_irq, tty);
}
if(line->driver->write_irq == current_irq)
free_irq_later(line->driver->write_irq, tty);
else {
- free_irq_by_irq_and_dev(line->driver->write_irq, tty);
free_irq(line->driver->write_irq, tty);
}
@@ -604,11 +602,26 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
return n;
}
-int line_remove(struct line *lines, unsigned int num, char *str)
+int line_id(char **str, int *start_out, int *end_out)
+{
+ char *end;
+ int n;
+
+ n = simple_strtoul(*str, &end, 0);
+ if((*end != '\0') || (end == *str))
+ return -1;
+
+ *str = end;
+ *start_out = n;
+ *end_out = n;
+ return n;
+}
+
+int line_remove(struct line *lines, unsigned int num, int n)
{
char config[sizeof("conxxxx=none\0")];
- sprintf(config, "%s=none", str);
+ sprintf(config, "%d=none", n);
return !line_setup(lines, num, config, 0);
}
@@ -758,7 +771,6 @@ static void unregister_winch(struct tty_struct *tty)
if(winch->pid != -1)
os_kill_process(winch->pid, 1);
- free_irq_by_irq_and_dev(WINCH_IRQ, winch);
free_irq(WINCH_IRQ, winch);
list_del(&winch->list);
kfree(winch);
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index faf714e87b5b..217438cdef33 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -73,7 +73,6 @@ int mcast_setup(char *str, char **mac_out, void *data)
struct mcast_init *init = data;
char *port_str = NULL, *ttl_str = NULL, *remain;
char *last;
- int n;
*init = ((struct mcast_init)
{ .addr = "239.192.168.1",
@@ -89,13 +88,12 @@ int mcast_setup(char *str, char **mac_out, void *data)
}
if(port_str != NULL){
- n = simple_strtoul(port_str, &last, 10);
+ init->port = simple_strtoul(port_str, &last, 10);
if((*last != '\0') || (last == port_str)){
printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
port_str);
return(0);
}
- init->port = htons(n);
}
if(ttl_str != NULL){
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 0fe1d9fa9139..7a0d115b29d0 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -38,7 +38,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
}
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = in_aton(addr);
- sin->sin_port = port;
+ sin->sin_port = htons(port);
return(sin);
}
@@ -55,28 +55,25 @@ static int mcast_open(void *data)
struct mcast_data *pri = data;
struct sockaddr_in *sin = pri->mcast_addr;
struct ip_mreq mreq;
- int fd, yes = 1;
+ int fd = -EINVAL, yes = 1, err = -EINVAL;;
- if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
- fd = -EINVAL;
+ if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
goto out;
- }
fd = socket(AF_INET, SOCK_DGRAM, 0);
+
if (fd < 0){
printk("mcast_open : data socket failed, errno = %d\n",
errno);
- fd = -ENOMEM;
+ fd = -errno;
goto out;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
errno);
- os_close_file(fd);
- fd = -EINVAL;
- goto out;
+ goto out_close;
}
/* set ttl according to config */
@@ -84,26 +81,20 @@ static int mcast_open(void *data)
sizeof(pri->ttl)) < 0) {
printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
errno);
- os_close_file(fd);
- fd = -EINVAL;
- goto out;
+ goto out_close;
}
/* set LOOP, so data does get fed back to local sockets */
if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
errno);
- os_close_file(fd);
- fd = -EINVAL;
- goto out;
+ goto out_close;
}
/* bind socket to mcast address */
if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
printk("mcast_open : data bind failed, errno = %d\n", errno);
- os_close_file(fd);
- fd = -EINVAL;
- goto out;
+ goto out_close;
}
/* subscribe to the multicast group */
@@ -117,12 +108,15 @@ static int mcast_open(void *data)
"interface on the host.\n");
printk("eth0 should be configured in order to use the "
"multicast transport.\n");
- os_close_file(fd);
- fd = -EINVAL;
+ goto out_close;
}
out:
- return(fd);
+ return fd;
+
+ out_close:
+ os_close_file(fd);
+ return err;
}
static void mcast_close(int fd, void *data)
@@ -164,14 +158,3 @@ struct net_user_info mcast_user_info = {
.delete_address = NULL,
.max_packet = MAX_PACKET - ETH_HEADER_OTHER
};
-
-/*
- * 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:
- */
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index d7c7adcc0a67..404de41a4f67 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -419,8 +419,9 @@ void mconsole_config(struct mc_request *req)
void mconsole_remove(struct mc_request *req)
{
struct mc_device *dev;
- char *ptr = req->request.data;
- int err;
+ char *ptr = req->request.data, *err_msg = "";
+ char error[256];
+ int err, start, end, n;
ptr += strlen("remove");
while(isspace(*ptr)) ptr++;
@@ -429,8 +430,35 @@ void mconsole_remove(struct mc_request *req)
mconsole_reply(req, "Bad remove option", 1, 0);
return;
}
- err = (*dev->remove)(&ptr[strlen(dev->name)]);
- mconsole_reply(req, "", err, 0);
+
+ ptr = &ptr[strlen(dev->name)];
+
+ err = 1;
+ n = (*dev->id)(&ptr, &start, &end);
+ if(n < 0){
+ err_msg = "Couldn't parse device number";
+ goto out;
+ }
+ else if((n < start) || (n > end)){
+ sprintf(error, "Invalid device number - must be between "
+ "%d and %d", start, end);
+ err_msg = error;
+ goto out;
+ }
+
+ err = (*dev->remove)(n);
+ switch(err){
+ case -ENODEV:
+ err_msg = "Device doesn't exist";
+ break;
+ case -EBUSY:
+ err_msg = "Device is currently open";
+ break;
+ default:
+ break;
+ }
+ out:
+ mconsole_reply(req, err_msg, err, 0);
}
#ifdef CONFIG_MAGIC_SYSRQ
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index a63231dffe05..a37a5ac13c22 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -18,6 +18,7 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
+#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
@@ -117,24 +118,39 @@ static struct file_operations mmapper_fops = {
.release = mmapper_release,
};
+static struct miscdevice mmapper_dev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "mmapper",
+ .fops = &mmapper_fops
+};
+
static int __init mmapper_init(void)
{
+ int err;
+
printk(KERN_INFO "Mapper v0.1\n");
v_buf = (char *) find_iomem("mmapper", &mmapper_size);
if(mmapper_size == 0){
printk(KERN_ERR "mmapper_init - find_iomem failed\n");
- return(0);
+ goto out;
}
- p_buf = __pa(v_buf);
+ err = misc_register(&mmapper_dev);
+ if(err){
+ printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
+ err);
+ goto out;
+ }
- devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper");
- return(0);
+ p_buf = __pa(v_buf);
+out:
+ return 0;
}
static void mmapper_exit(void)
{
+ misc_deregister(&mmapper_dev);
}
module_init(mmapper_init);
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 4eeaf88c1e97..1495007bf6c0 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -146,7 +146,6 @@ static int uml_net_close(struct net_device *dev)
netif_stop_queue(dev);
spin_lock(&lp->lock);
- free_irq_by_irq_and_dev(dev->irq, dev);
free_irq(dev->irq, dev);
if(lp->close != NULL)
(*lp->close)(lp->fd, &lp->user);
@@ -613,25 +612,35 @@ static int net_config(char *str)
return(err);
}
-static int net_remove(char *str)
+static int net_id(char **str, int *start_out, int *end_out)
+{
+ char *end;
+ int n;
+
+ n = simple_strtoul(*str, &end, 0);
+ if((*end != '\0') || (end == *str))
+ return -1;
+
+ *start_out = n;
+ *end_out = n;
+ *str = end;
+ return n;
+}
+
+static int net_remove(int n)
{
struct uml_net *device;
struct net_device *dev;
struct uml_net_private *lp;
- char *end;
- int n;
-
- n = simple_strtoul(str, &end, 0);
- if((*end != '\0') || (end == str))
- return(-1);
device = find_device(n);
if(device == NULL)
- return(0);
+ return -ENODEV;
dev = device->dev;
lp = dev->priv;
- if(lp->fd > 0) return(-1);
+ if(lp->fd > 0)
+ return -EBUSY;
if(lp->remove != NULL) (*lp->remove)(&lp->user);
unregister_netdev(dev);
platform_device_unregister(&device->pdev);
@@ -639,13 +648,14 @@ static int net_remove(char *str)
list_del(&device->list);
kfree(device);
free_netdev(dev);
- return(0);
+ return 0;
}
static struct mc_device net_mc = {
.name = "eth",
.config = net_config,
.get_config = NULL,
+ .id = net_id,
.remove = net_remove,
};
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 47229fe4a813..3730d4f12713 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -32,7 +32,7 @@ int tap_open_common(void *dev, char *gate_addr)
return(0);
}
-void tap_check_ips(char *gate_addr, char *eth_addr)
+void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
{
int tap_addr[4];
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index b5ee07472f79..c41efd207fcc 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -257,7 +257,6 @@ int port_wait(void *data)
* connection. Then we loop here throwing out failed
* connections until a good one is found.
*/
- free_irq_by_irq_and_dev(TELNETD_IRQ, conn);
free_irq(TELNETD_IRQ, conn);
if(conn->fd >= 0) break;
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index d43e9fab05a7..f9e22198e011 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -1,5 +1,10 @@
-/* Much of this ripped from hw_random.c */
-
+/* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */
+/* Much of this ripped from drivers/char/hw_random.c, see there for other
+ * copyright.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
@@ -12,8 +17,6 @@
*/
#define RNG_VERSION "1.0.0"
#define RNG_MODULE_NAME "random"
-#define RNG_DRIVER_NAME RNG_MODULE_NAME " virtual driver " RNG_VERSION
-#define PFX RNG_MODULE_NAME ": "
#define RNG_MISCDEV_MINOR 183 /* official */
@@ -98,7 +101,7 @@ static int __init rng_init (void)
err = misc_register (&rng_miscdev);
if (err) {
- printk (KERN_ERR PFX "misc device register failed\n");
+ printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n");
goto err_out_cleanup_hw;
}
@@ -120,3 +123,6 @@ static void __exit rng_cleanup (void)
module_init (rng_init);
module_exit (rng_cleanup);
+
+MODULE_DESCRIPTION("UML Host Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h
index 495f2f1b1420..bb0dab41c2e4 100644
--- a/arch/um/drivers/slip.h
+++ b/arch/um/drivers/slip.h
@@ -1,10 +1,7 @@
#ifndef __UM_SLIP_H
#define __UM_SLIP_H
-#define BUF_SIZE 1500
- /* two bytes each for a (pathological) max packet of escaped chars + *
- * terminating END char + initial END char */
-#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
+#include "slip_common.h"
struct slip_data {
void *dev;
@@ -12,28 +9,12 @@ struct slip_data {
char *addr;
char *gate_addr;
int slave;
- char ibuf[ENC_BUF_SIZE];
- char obuf[ENC_BUF_SIZE];
- int more; /* more data: do not read fd until ibuf has been drained */
- int pos;
- int esc;
+ struct slip_proto slip;
};
extern struct net_user_info slip_user_info;
-extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
#endif
-
-/*
- * 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:
- */
diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c
new file mode 100644
index 000000000000..e89cfc68fc3e
--- /dev/null
+++ b/arch/um/drivers/slip_common.c
@@ -0,0 +1,54 @@
+#include <string.h>
+#include "slip_common.h"
+#include "net_user.h"
+
+int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip)
+{
+ int i, n, size, start;
+
+ if(slip->more > 0){
+ i = 0;
+ while(i < slip->more){
+ size = slip_unesc(slip->ibuf[i++], slip->ibuf,
+ &slip->pos, &slip->esc);
+ if(size){
+ memcpy(buf, slip->ibuf, size);
+ memmove(slip->ibuf, &slip->ibuf[i],
+ slip->more - i);
+ slip->more = slip->more - i;
+ return size;
+ }
+ }
+ slip->more = 0;
+ }
+
+ n = net_read(fd, &slip->ibuf[slip->pos],
+ sizeof(slip->ibuf) - slip->pos);
+ if(n <= 0)
+ return n;
+
+ start = slip->pos;
+ for(i = 0; i < n; i++){
+ size = slip_unesc(slip->ibuf[start + i], slip->ibuf,&slip->pos,
+ &slip->esc);
+ if(size){
+ memcpy(buf, slip->ibuf, size);
+ memmove(slip->ibuf, &slip->ibuf[start+i+1],
+ n - (i + 1));
+ slip->more = n - (i + 1);
+ return size;
+ }
+ }
+ return 0;
+}
+
+int slip_proto_write(int fd, void *buf, int len, struct slip_proto *slip)
+{
+ int actual, n;
+
+ actual = slip_esc(buf, slip->obuf, len);
+ n = net_write(fd, slip->obuf, actual);
+ if(n < 0)
+ return n;
+ else return len;
+}
diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_common.h
index 7206361ace45..2ae76d8f1be1 100644
--- a/arch/um/drivers/slip_proto.h
+++ b/arch/um/drivers/slip_common.h
@@ -1,10 +1,10 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
+#ifndef __UM_SLIP_COMMON_H
+#define __UM_SLIP_COMMON_H
-#ifndef __UM_SLIP_PROTO_H__
-#define __UM_SLIP_PROTO_H__
+#define BUF_SIZE 1500
+ /* two bytes each for a (pathological) max packet of escaped chars + *
+ * terminating END char + initial END char */
+#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
/* SLIP protocol characters. */
#define SLIP_END 0300 /* indicates end of frame */
@@ -12,7 +12,8 @@
#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */
#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
-static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
+static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos,
+ int *esc)
{
int ret;
@@ -79,15 +80,25 @@ static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
return (ptr - d);
}
-#endif
+struct slip_proto {
+ unsigned char ibuf[ENC_BUF_SIZE];
+ unsigned char obuf[ENC_BUF_SIZE];
+ int more; /* more data: do not read fd until ibuf has been drained */
+ int pos;
+ int esc;
+};
+
+#define SLIP_PROTO_INIT { \
+ .ibuf = { '\0' }, \
+ .obuf = { '\0' }, \
+ .more = 0, \
+ .pos = 0, \
+ .esc = 0 \
+}
-/*
- * 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:
- */
+extern int slip_proto_read(int fd, void *buf, int len,
+ struct slip_proto *slip);
+extern int slip_proto_write(int fd, void *buf, int len,
+ struct slip_proto *slip);
+
+#endif
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 0886eedba213..9a6f5c85f902 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -26,16 +26,16 @@ void slip_init(struct net_device *dev, void *data)
.addr = NULL,
.gate_addr = init->gate_addr,
.slave = -1,
- .ibuf = { '\0' },
- .obuf = { '\0' },
- .pos = 0,
- .esc = 0,
+ .slip = SLIP_PROTO_INIT,
.dev = dev });
dev->init = NULL;
+ dev->header_cache_update = NULL;
+ dev->hard_header_cache = NULL;
+ dev->hard_header = NULL;
dev->hard_header_len = 0;
- dev->addr_len = 4;
- dev->type = ARPHRD_ETHER;
+ dev->addr_len = 0;
+ dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 256;
dev->flags = IFF_NOARP;
printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index d94846b1b4cf..71af444e591f 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -13,7 +13,7 @@
#include "user.h"
#include "net_user.h"
#include "slip.h"
-#include "slip_proto.h"
+#include "slip_common.h"
#include "helper.h"
#include "os.h"
@@ -77,41 +77,51 @@ static int slip_tramp(char **argv, int fd)
err = os_pipe(fds, 1, 0);
if(err < 0){
printk("slip_tramp : pipe failed, err = %d\n", -err);
- return(err);
+ goto out;
}
err = 0;
pe_data.stdin = fd;
pe_data.stdout = fds[1];
pe_data.close_me = fds[0];
- pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);
+ err = run_helper(slip_pre_exec, &pe_data, argv, NULL);
+ if(err < 0)
+ goto out_close;
+ pid = err;
+
+ output_len = page_size();
+ output = um_kmalloc(output_len);
+ if(output == NULL){
+ printk("slip_tramp : failed to allocate output buffer\n");
+ os_kill_process(pid, 1);
+ err = -ENOMEM;
+ goto out_free;
+ }
- if(pid < 0) err = pid;
- else {
- output_len = page_size();
- output = um_kmalloc(output_len);
- if(output == NULL)
- printk("slip_tramp : failed to allocate output "
- "buffer\n");
-
- os_close_file(fds[1]);
- read_output(fds[0], output, output_len);
- if(output != NULL){
- printk("%s", output);
- kfree(output);
- }
- CATCH_EINTR(err = waitpid(pid, &status, 0));
- if(err < 0)
- err = errno;
- else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
- printk("'%s' didn't exit with status 0\n", argv[0]);
- err = -EINVAL;
- }
+ os_close_file(fds[1]);
+ read_output(fds[0], output, output_len);
+ printk("%s", output);
+
+ CATCH_EINTR(err = waitpid(pid, &status, 0));
+ if(err < 0)
+ err = errno;
+ else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
+ printk("'%s' didn't exit with status 0\n", argv[0]);
+ err = -EINVAL;
}
+ else err = 0;
os_close_file(fds[0]);
- return(err);
+out_free:
+ kfree(output);
+ return err;
+
+out_close:
+ os_close_file(fds[0]);
+ os_close_file(fds[1]);
+out:
+ return err;
}
static int slip_open(void *data)
@@ -123,21 +133,26 @@ static int slip_open(void *data)
NULL };
int sfd, mfd, err;
- mfd = get_pty();
- if(mfd < 0){
- printk("umn : Failed to open pty, err = %d\n", -mfd);
- return(mfd);
+ err = get_pty();
+ if(err < 0){
+ printk("slip-open : Failed to open pty, err = %d\n", -err);
+ goto out;
}
- sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
- if(sfd < 0){
- printk("Couldn't open tty for slip line, err = %d\n", -sfd);
- os_close_file(mfd);
- return(sfd);
+ mfd = err;
+
+ err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
+ if(err < 0){
+ printk("Couldn't open tty for slip line, err = %d\n", -err);
+ goto out_close;
}
- if(set_up_tty(sfd)) return(-1);
+ sfd = err;
+
+ if(set_up_tty(sfd))
+ goto out_close2;
+
pri->slave = sfd;
- pri->pos = 0;
- pri->esc = 0;
+ pri->slip.pos = 0;
+ pri->slip.esc = 0;
if(pri->gate_addr != NULL){
sprintf(version_buf, "%d", UML_NET_VERSION);
strcpy(gate_buf, pri->gate_addr);
@@ -146,12 +161,12 @@ static int slip_open(void *data)
if(err < 0){
printk("slip_tramp failed - err = %d\n", -err);
- return(err);
+ goto out_close2;
}
err = os_get_ifname(pri->slave, pri->name);
if(err < 0){
printk("get_ifname failed, err = %d\n", -err);
- return(err);
+ goto out_close2;
}
iter_addresses(pri->dev, open_addr, pri->name);
}
@@ -160,10 +175,16 @@ static int slip_open(void *data)
if(err < 0){
printk("Failed to set slip discipline encapsulation - "
"err = %d\n", -err);
- return(err);
+ goto out_close2;
}
}
return(mfd);
+out_close2:
+ os_close_file(sfd);
+out_close:
+ os_close_file(mfd);
+out:
+ return err;
}
static void slip_close(int fd, void *data)
@@ -190,48 +211,12 @@ static void slip_close(int fd, void *data)
int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
{
- int i, n, size, start;
-
- if(pri->more>0) {
- i = 0;
- while(i < pri->more) {
- size = slip_unesc(pri->ibuf[i++],
- pri->ibuf, &pri->pos, &pri->esc);
- if(size){
- memcpy(buf, pri->ibuf, size);
- memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
- pri->more=pri->more-i;
- return(size);
- }
- }
- pri->more=0;
- }
-
- n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
- if(n <= 0) return(n);
-
- start = pri->pos;
- for(i = 0; i < n; i++){
- size = slip_unesc(pri->ibuf[start + i],
- pri->ibuf, &pri->pos, &pri->esc);
- if(size){
- memcpy(buf, pri->ibuf, size);
- memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
- pri->more=n-(i+1);
- return(size);
- }
- }
- return(0);
+ return slip_proto_read(fd, buf, len, &pri->slip);
}
int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
{
- int actual, n;
-
- actual = slip_esc(buf, pri->obuf, len);
- n = net_write(fd, pri->obuf, actual);
- if(n < 0) return(n);
- else return(len);
+ return slip_proto_write(fd, buf, len, &pri->slip);
}
static int slip_set_mtu(int mtu, void *data)
@@ -267,14 +252,3 @@ struct net_user_info slip_user_info = {
.delete_address = slip_del_addr,
.max_packet = BUF_SIZE
};
-
-/*
- * 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:
- */
diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h
index 04e407d1e44a..6cf88ab580c9 100644
--- a/arch/um/drivers/slirp.h
+++ b/arch/um/drivers/slirp.h
@@ -1,10 +1,7 @@
#ifndef __UM_SLIRP_H
#define __UM_SLIRP_H
-#define BUF_SIZE 1500
- /* two bytes each for a (pathological) max packet of escaped chars + *
- * terminating END char + initial END char */
-#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
+#include "slip_common.h"
#define SLIRP_MAX_ARGS 100
/*
@@ -24,28 +21,13 @@ struct slirp_data {
struct arg_list_dummy_wrapper argw;
int pid;
int slave;
- char ibuf[ENC_BUF_SIZE];
- char obuf[ENC_BUF_SIZE];
- int more; /* more data: do not read fd until ibuf has been drained */
- int pos;
- int esc;
+ struct slip_proto slip;
};
extern struct net_user_info slirp_user_info;
-extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
-extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri);
+extern int slirp_user_write(int fd, void *buf, int len,
+ struct slirp_data *pri);
#endif
-
-/*
- * 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:
- */
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index c9d6b52a831d..9864d27afdbe 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -25,10 +25,7 @@ void slirp_init(struct net_device *dev, void *data)
{ .argw = init->argw,
.pid = -1,
.slave = -1,
- .ibuf = { '\0' },
- .obuf = { '\0' },
- .pos = 0,
- .esc = 0,
+ .slip = SLIP_PROTO_INIT,
.dev = dev });
dev->init = NULL;
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index c322515c71cc..8d91f663d82c 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -12,7 +12,7 @@
#include "user.h"
#include "net_user.h"
#include "slirp.h"
-#include "slip_proto.h"
+#include "slip_common.h"
#include "helper.h"
#include "os.h"
@@ -48,47 +48,32 @@ static int slirp_tramp(char **argv, int fd)
return(pid);
}
-/* XXX This is just a trivial wrapper around os_pipe */
-static int slirp_datachan(int *mfd, int *sfd)
-{
- int fds[2], err;
-
- err = os_pipe(fds, 1, 1);
- if(err < 0){
- printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
- return(err);
- }
-
- *mfd = fds[0];
- *sfd = fds[1];
- return(0);
-}
-
static int slirp_open(void *data)
{
struct slirp_data *pri = data;
- int sfd, mfd, pid, err;
+ int fds[2], pid, err;
- err = slirp_datachan(&mfd, &sfd);
+ err = os_pipe(fds, 1, 1);
if(err)
return(err);
- pid = slirp_tramp(pri->argw.argv, sfd);
-
- if(pid < 0){
- printk("slirp_tramp failed - errno = %d\n", -pid);
- os_close_file(sfd);
- os_close_file(mfd);
- return(pid);
+ err = slirp_tramp(pri->argw.argv, fds[1]);
+ if(err < 0){
+ printk("slirp_tramp failed - errno = %d\n", -err);
+ goto out;
}
-
- pri->slave = sfd;
- pri->pos = 0;
- pri->esc = 0;
-
- pri->pid = pid;
-
- return(mfd);
+ pid = err;
+
+ pri->slave = fds[1];
+ pri->slip.pos = 0;
+ pri->slip.esc = 0;
+ pri->pid = err;
+
+ return(fds[0]);
+out:
+ os_close_file(fds[0]);
+ os_close_file(fds[1]);
+ return err;
}
static void slirp_close(int fd, void *data)
@@ -129,48 +114,12 @@ static void slirp_close(int fd, void *data)
int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
{
- int i, n, size, start;
-
- if(pri->more>0) {
- i = 0;
- while(i < pri->more) {
- size = slip_unesc(pri->ibuf[i++],
- pri->ibuf,&pri->pos,&pri->esc);
- if(size){
- memcpy(buf, pri->ibuf, size);
- memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
- pri->more=pri->more-i;
- return(size);
- }
- }
- pri->more=0;
- }
-
- n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
- if(n <= 0) return(n);
-
- start = pri->pos;
- for(i = 0; i < n; i++){
- size = slip_unesc(pri->ibuf[start + i],
- pri->ibuf,&pri->pos,&pri->esc);
- if(size){
- memcpy(buf, pri->ibuf, size);
- memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
- pri->more=n-(i+1);
- return(size);
- }
- }
- return(0);
+ return slip_proto_read(fd, buf, len, &pri->slip);
}
int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
{
- int actual, n;
-
- actual = slip_esc(buf, pri->obuf, len);
- n = net_write(fd, pri->obuf, actual);
- if(n < 0) return(n);
- else return(len);
+ return slip_proto_write(fd, buf, len, &pri->slip);
}
static int slirp_set_mtu(int mtu, void *data)
@@ -188,14 +137,3 @@ struct net_user_info slirp_user_info = {
.delete_address = NULL,
.max_packet = BUF_SIZE
};
-
-/*
- * 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:
- */
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index a2bac429f3d4..62e04ecfada8 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -22,7 +22,6 @@
#include "init.h"
#include "irq_user.h"
#include "mconsole_kern.h"
-#include "2_5compat.h"
static int ssl_version = 1;
@@ -50,7 +49,7 @@ static struct chan_opts opts = {
static int ssl_config(char *str);
static int ssl_get_config(char *dev, char *str, int size, char **error_out);
-static int ssl_remove(char *str);
+static int ssl_remove(int n);
static struct line_driver driver = {
.name = "UML serial line",
@@ -70,6 +69,7 @@ static struct line_driver driver = {
.name = "ssl",
.config = ssl_config,
.get_config = ssl_get_config,
+ .id = line_id,
.remove = ssl_remove,
},
};
@@ -95,10 +95,10 @@ static int ssl_get_config(char *dev, char *str, int size, char **error_out)
str, size, error_out));
}
-static int ssl_remove(char *str)
+static int ssl_remove(int n)
{
- return(line_remove(serial_lines,
- sizeof(serial_lines)/sizeof(serial_lines[0]), str));
+ return line_remove(serial_lines,
+ sizeof(serial_lines)/sizeof(serial_lines[0]), n);
}
int ssl_open(struct tty_struct *tty, struct file *filp)
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
index 98565b53d170..429ae8e6c7e5 100644
--- a/arch/um/drivers/stderr_console.c
+++ b/arch/um/drivers/stderr_console.c
@@ -22,9 +22,9 @@ static void stderr_console_write(struct console *console, const char *string,
}
static struct console stderr_console = {
- .name "stderr",
- .write stderr_console_write,
- .flags CON_PRINTBUFFER,
+ .name = "stderr",
+ .write = stderr_console_write,
+ .flags = CON_PRINTBUFFER,
};
static int __init stderr_console_init(void)
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 361d0be342b3..005aa6333b6e 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -28,7 +28,6 @@
#include "irq_user.h"
#include "mconsole_kern.h"
#include "init.h"
-#include "2_5compat.h"
#define MAX_TTYS (16)
@@ -56,7 +55,7 @@ static struct chan_opts opts = {
static int con_config(char *str);
static int con_get_config(char *dev, char *str, int size, char **error_out);
-static int con_remove(char *str);
+static int con_remove(int n);
static struct line_driver driver = {
.name = "UML console",
@@ -76,6 +75,7 @@ static struct line_driver driver = {
.name = "con",
.config = con_config,
.get_config = con_get_config,
+ .id = line_id,
.remove = con_remove,
},
};
@@ -100,9 +100,9 @@ static int con_get_config(char *dev, char *str, int size, char **error_out)
size, error_out));
}
-static int con_remove(char *str)
+static int con_remove(int n)
{
- return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
+ return line_remove(vts, sizeof(vts)/sizeof(vts[0]), n);
}
static int con_open(struct tty_struct *tty, struct file *filp)
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 9a56ff94308d..344b24d09a7c 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -49,13 +49,12 @@
#include "irq_user.h"
#include "irq_kern.h"
#include "ubd_user.h"
-#include "2_5compat.h"
#include "os.h"
#include "mem.h"
#include "mem_kern.h"
#include "cow.h"
-enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
+enum ubd_req { UBD_READ, UBD_WRITE };
struct io_thread_req {
enum ubd_req op;
@@ -68,8 +67,6 @@ struct io_thread_req {
unsigned long sector_mask;
unsigned long long cow_offset;
unsigned long bitmap_words[2];
- int map_fd;
- unsigned long long map_offset;
int error;
};
@@ -122,10 +119,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
#define MAX_DEV (8)
-/* Changed in early boot */
-static int ubd_do_mmap = 0;
-#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
-
static struct block_device_operations ubd_blops = {
.owner = THIS_MODULE,
.open = ubd_open,
@@ -175,12 +168,6 @@ struct ubd {
int no_cow;
struct cow cow;
struct platform_device pdev;
-
- int map_writes;
- int map_reads;
- int nomap_writes;
- int nomap_reads;
- int write_maps;
};
#define DEFAULT_COW { \
@@ -200,11 +187,6 @@ struct ubd {
.openflags = OPEN_FLAGS, \
.no_cow = 0, \
.cow = DEFAULT_COW, \
- .map_writes = 0, \
- .map_reads = 0, \
- .nomap_writes = 0, \
- .nomap_reads = 0, \
- .write_maps = 0, \
}
struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
@@ -314,13 +296,6 @@ static int ubd_setup_common(char *str, int *index_out)
int major;
str++;
- if(!strcmp(str, "mmap")){
- CHOOSE_MODE(printk("mmap not supported by the ubd "
- "driver in tt mode\n"),
- ubd_do_mmap = 1);
- return(0);
- }
-
if(!strcmp(str, "sync")){
global_openflags = of_sync(global_openflags);
return(0);
@@ -464,9 +439,9 @@ static int udb_setup(char *str)
__setup("udb", udb_setup);
__uml_help(udb_setup,
"udb\n"
-" This option is here solely to catch ubd -> udb typos, which can be\n\n"
-" to impossible to catch visually unless you specifically look for\n\n"
-" them. The only result of any option starting with 'udb' is an error\n\n"
+" This option is here solely to catch ubd -> udb typos, which can be\n"
+" to impossible to catch visually unless you specifically look for\n"
+" them. The only result of any option starting with 'udb' is an error\n"
" in the boot output.\n\n"
);
@@ -524,7 +499,7 @@ static void ubd_handler(void)
{
struct io_thread_req req;
struct request *rq = elv_next_request(ubd_queue);
- int n, err;
+ int n;
do_ubd = NULL;
intr_count++;
@@ -538,19 +513,6 @@ static void ubd_handler(void)
return;
}
- if((req.op != UBD_MMAP) &&
- ((req.offset != ((__u64) (rq->sector)) << 9) ||
- (req.length != (rq->current_nr_sectors) << 9)))
- panic("I/O op mismatch");
-
- if(req.map_fd != -1){
- err = physmem_subst_mapping(req.buffer, req.map_fd,
- req.map_offset, 1);
- if(err)
- printk("ubd_handler - physmem_subst_mapping failed, "
- "err = %d\n", -err);
- }
-
ubd_finish(rq, req.error);
reactivate_fd(thread_fd, UBD_IRQ);
do_ubd_request(ubd_queue);
@@ -583,14 +545,10 @@ static int ubd_file_size(struct ubd *dev, __u64 *size_out)
static void ubd_close(struct ubd *dev)
{
- if(ubd_do_mmap)
- physmem_forget_descriptor(dev->fd);
os_close_file(dev->fd);
if(dev->cow.file == NULL)
return;
- if(ubd_do_mmap)
- physmem_forget_descriptor(dev->cow.fd);
os_close_file(dev->cow.fd);
vfree(dev->cow.bitmap);
dev->cow.bitmap = NULL;
@@ -796,24 +754,34 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
return(len);
}
-static int ubd_remove(char *str)
+static int ubd_id(char **str, int *start_out, int *end_out)
+{
+ int n;
+
+ n = parse_unit(str);
+ *start_out = 0;
+ *end_out = MAX_DEV - 1;
+ return n;
+}
+
+static int ubd_remove(int n)
{
struct ubd *dev;
- int n, err = -ENODEV;
+ int err = -ENODEV;
- n = parse_unit(&str);
+ spin_lock(&ubd_lock);
- if((n < 0) || (n >= MAX_DEV))
- return(err);
+ if(ubd_gendisk[n] == NULL)
+ goto out;
dev = &ubd_dev[n];
- if(dev->count > 0)
- return(-EBUSY); /* you cannot remove a open disk */
- err = 0;
- spin_lock(&ubd_lock);
+ if(dev->file == NULL)
+ goto out;
- if(ubd_gendisk[n] == NULL)
+ /* you cannot remove a open disk */
+ err = -EBUSY;
+ if(dev->count > 0)
goto out;
del_gendisk(ubd_gendisk[n]);
@@ -829,15 +797,16 @@ static int ubd_remove(char *str)
platform_device_unregister(&dev->pdev);
*dev = ((struct ubd) DEFAULT_UBD);
err = 0;
- out:
- spin_unlock(&ubd_lock);
- return(err);
+out:
+ spin_unlock(&ubd_lock);
+ return err;
}
static struct mc_device ubd_mc = {
.name = "ubd",
.config = ubd_config,
.get_config = ubd_get_config,
+ .id = ubd_id,
.remove = ubd_remove,
};
@@ -1010,94 +979,13 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
req->bitmap_words, bitmap_len);
}
-static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
-{
- __u64 sector;
- unsigned char *bitmap;
- int bit, i;
-
- /* mmap must have been requested on the command line */
- if(!ubd_do_mmap)
- return(-1);
-
- /* The buffer must be page aligned */
- if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
- return(-1);
-
- /* The request must be a page long */
- if((req->current_nr_sectors << 9) != PAGE_SIZE)
- return(-1);
-
- if(dev->cow.file == NULL)
- return(dev->fd);
-
- sector = offset >> 9;
- bitmap = (unsigned char *) dev->cow.bitmap;
- bit = ubd_test_bit(sector, bitmap);
-
- for(i = 1; i < req->current_nr_sectors; i++){
- if(ubd_test_bit(sector + i, bitmap) != bit)
- return(-1);
- }
-
- if(bit || (rq_data_dir(req) == WRITE))
- offset += dev->cow.data_offset;
-
- /* The data on disk must be page aligned */
- if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
- return(-1);
-
- return(bit ? dev->fd : dev->cow.fd);
-}
-
-static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
- struct request *req,
- struct io_thread_req *io_req)
-{
- int err;
-
- if(rq_data_dir(req) == WRITE){
- /* Writes are almost no-ops since the new data is already in the
- * host page cache
- */
- dev->map_writes++;
- if(dev->cow.file != NULL)
- cowify_bitmap(io_req->offset, io_req->length,
- &io_req->sector_mask, &io_req->cow_offset,
- dev->cow.bitmap, dev->cow.bitmap_offset,
- io_req->bitmap_words,
- dev->cow.bitmap_len);
- }
- else {
- int w;
-
- if((dev->cow.file != NULL) && (fd == dev->cow.fd))
- w = 0;
- else w = dev->openflags.w;
-
- if((dev->cow.file != NULL) && (fd == dev->fd))
- offset += dev->cow.data_offset;
-
- err = physmem_subst_mapping(req->buffer, fd, offset, w);
- if(err){
- printk("physmem_subst_mapping failed, err = %d\n",
- -err);
- return(1);
- }
- dev->map_reads++;
- }
- io_req->op = UBD_MMAP;
- io_req->buffer = req->buffer;
- return(0);
-}
-
/* Called with ubd_io_lock held */
static int prepare_request(struct request *req, struct io_thread_req *io_req)
{
struct gendisk *disk = req->rq_disk;
struct ubd *dev = disk->private_data;
__u64 offset;
- int len, fd;
+ int len;
if(req->rq_status == RQ_INACTIVE) return(1);
@@ -1114,34 +1002,12 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
io_req->fds[1] = dev->fd;
- io_req->map_fd = -1;
io_req->cow_offset = -1;
io_req->offset = offset;
io_req->length = len;
io_req->error = 0;
io_req->sector_mask = 0;
- fd = mmap_fd(req, dev, io_req->offset);
- if(fd > 0){
- /* If mmapping is otherwise OK, but the first access to the
- * page is a write, then it's not mapped in yet. So we have
- * to write the data to disk first, then we can map the disk
- * page in and continue normally from there.
- */
- if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
- io_req->map_fd = dev->fd;
- io_req->map_offset = io_req->offset +
- dev->cow.data_offset;
- dev->write_maps++;
- }
- else return(prepare_mmap_request(dev, fd, io_req->offset, req,
- io_req));
- }
-
- if(rq_data_dir(req) == READ)
- dev->nomap_reads++;
- else dev->nomap_writes++;
-
io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
io_req->offsets[0] = 0;
io_req->offsets[1] = dev->cow.data_offset;
@@ -1229,143 +1095,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
return(-EINVAL);
}
-static int ubd_check_remapped(int fd, unsigned long address, int is_write,
- __u64 offset)
-{
- __u64 bitmap_offset;
- unsigned long new_bitmap[2];
- int i, err, n;
-
- /* If it's not a write access, we can't do anything about it */
- if(!is_write)
- return(0);
-
- /* We have a write */
- for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
- struct ubd *dev = &ubd_dev[i];
-
- if((dev->fd != fd) && (dev->cow.fd != fd))
- continue;
-
- /* It's a write to a ubd device */
-
- /* This should be impossible now */
- if(!dev->openflags.w){
- /* It's a write access on a read-only device - probably
- * shouldn't happen. If the kernel is trying to change
- * something with no intention of writing it back out,
- * then this message will clue us in that this needs
- * fixing
- */
- printk("Write access to mapped page from readonly ubd "
- "device %d\n", i);
- return(0);
- }
-
- /* It's a write to a writeable ubd device - it must be COWed
- * because, otherwise, the page would have been mapped in
- * writeable
- */
-
- if(!dev->cow.file)
- panic("Write fault on writeable non-COW ubd device %d",
- i);
-
- /* It should also be an access to the backing file since the
- * COW pages should be mapped in read-write
- */
-
- if(fd == dev->fd)
- panic("Write fault on a backing page of ubd "
- "device %d\n", i);
-
- /* So, we do the write, copying the backing data to the COW
- * file...
- */
-
- err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
- if(err < 0)
- panic("Couldn't seek to %lld in COW file of ubd "
- "device %d, err = %d",
- offset + dev->cow.data_offset, i, -err);
-
- n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
- if(n != PAGE_SIZE)
- panic("Couldn't copy data to COW file of ubd "
- "device %d, err = %d", i, -n);
-
- /* ... updating the COW bitmap... */
-
- cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
- dev->cow.bitmap, dev->cow.bitmap_offset,
- new_bitmap, dev->cow.bitmap_len);
-
- err = os_seek_file(dev->fd, bitmap_offset);
- if(err < 0)
- panic("Couldn't seek to %lld in COW file of ubd "
- "device %d, err = %d", bitmap_offset, i, -err);
-
- n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
- if(n != sizeof(new_bitmap))
- panic("Couldn't update bitmap of ubd device %d, "
- "err = %d", i, -n);
-
- /* Maybe we can map the COW page in, and maybe we can't. If
- * it is a pre-V3 COW file, we can't, since the alignment will
- * be wrong. If it is a V3 or later COW file which has been
- * moved to a system with a larger page size, then maybe we
- * can't, depending on the exact location of the page.
- */
-
- offset += dev->cow.data_offset;
-
- /* Remove the remapping, putting the original anonymous page
- * back. If the COW file can be mapped in, that is done.
- * Otherwise, the COW page is read in.
- */
-
- if(!physmem_remove_mapping((void *) address))
- panic("Address 0x%lx not remapped by ubd device %d",
- address, i);
- if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
- physmem_subst_mapping((void *) address, dev->fd,
- offset, 1);
- else {
- err = os_seek_file(dev->fd, offset);
- if(err < 0)
- panic("Couldn't seek to %lld in COW file of "
- "ubd device %d, err = %d", offset, i,
- -err);
-
- n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
- if(n != PAGE_SIZE)
- panic("Failed to read page from offset %llx of "
- "COW file of ubd device %d, err = %d",
- offset, i, -n);
- }
-
- return(1);
- }
-
- /* It's not a write on a ubd device */
- return(0);
-}
-
-static struct remapper ubd_remapper = {
- .list = LIST_HEAD_INIT(ubd_remapper.list),
- .proc = ubd_check_remapped,
-};
-
-static int ubd_remapper_setup(void)
-{
- if(ubd_do_mmap)
- register_remapper(&ubd_remapper);
-
- return(0);
-}
-
-__initcall(ubd_remapper_setup);
-
static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
{
struct uml_stat buf1, buf2;
@@ -1568,15 +1297,6 @@ void do_io(struct io_thread_req *req)
int err;
__u64 off;
- if(req->op == UBD_MMAP){
- /* Touch the page to force the host to do any necessary IO to
- * get it into memory
- */
- n = *((volatile int *) req->buffer);
- req->error = update_bitmap(req);
- return;
- }
-
nsectors = req->length / req->sectorsize;
start = 0;
do {
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index a4fdf3584ad2..d269a80f4b0c 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -69,7 +69,6 @@ int xterm_fd(int socket, int *pid_out)
* isn't set) this will hang... */
wait_for_completion(&data->ready);
- free_irq_by_irq_and_dev(XTERM_IRQ, data);
free_irq(XTERM_IRQ, data);
ret = data->new_fd;
OpenPOWER on IntegriCloud