aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers')
-rw-r--r--arch/um/drivers/Makefile4
-rw-r--r--arch/um/drivers/harddog_kern.c14
-rw-r--r--arch/um/drivers/hostaudio_kern.c12
-rw-r--r--arch/um/drivers/line.c13
-rw-r--r--arch/um/drivers/mcast.h24
-rw-r--r--arch/um/drivers/mcast_kern.c120
-rw-r--r--arch/um/drivers/mcast_user.c165
-rw-r--r--arch/um/drivers/mconsole_kern.c22
-rw-r--r--arch/um/drivers/mmapper_kern.c12
-rw-r--r--arch/um/drivers/random.c1
-rw-r--r--arch/um/drivers/ubd_kern.c13
-rw-r--r--arch/um/drivers/umcast.h27
-rw-r--r--arch/um/drivers/umcast_kern.c188
-rw-r--r--arch/um/drivers/umcast_user.c186
-rw-r--r--arch/um/drivers/xterm.c2
15 files changed, 441 insertions, 362 deletions
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 1d9b6ae967b0..e7582e1d248c 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -9,7 +9,7 @@
9slip-objs := slip_kern.o slip_user.o 9slip-objs := slip_kern.o slip_user.o
10slirp-objs := slirp_kern.o slirp_user.o 10slirp-objs := slirp_kern.o slirp_user.o
11daemon-objs := daemon_kern.o daemon_user.o 11daemon-objs := daemon_kern.o daemon_user.o
12mcast-objs := mcast_kern.o mcast_user.o 12umcast-objs := umcast_kern.o umcast_user.o
13net-objs := net_kern.o net_user.o 13net-objs := net_kern.o net_user.o
14mconsole-objs := mconsole_kern.o mconsole_user.o 14mconsole-objs := mconsole_kern.o mconsole_user.o
15hostaudio-objs := hostaudio_kern.o 15hostaudio-objs := hostaudio_kern.o
@@ -44,7 +44,7 @@ obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
44obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o 44obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
45obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 45obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
46obj-$(CONFIG_UML_NET_VDE) += vde.o 46obj-$(CONFIG_UML_NET_VDE) += vde.o
47obj-$(CONFIG_UML_NET_MCAST) += mcast.o 47obj-$(CONFIG_UML_NET_MCAST) += umcast.o
48obj-$(CONFIG_UML_NET_PCAP) += pcap.o 48obj-$(CONFIG_UML_NET_PCAP) += pcap.o
49obj-$(CONFIG_UML_NET) += net.o 49obj-$(CONFIG_UML_NET) += net.o
50obj-$(CONFIG_MCONSOLE) += mconsole.o 50obj-$(CONFIG_MCONSOLE) += mconsole.o
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index cfcac1ff4cf2..2d0266d0254d 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -42,7 +42,7 @@
42#include <linux/miscdevice.h> 42#include <linux/miscdevice.h>
43#include <linux/watchdog.h> 43#include <linux/watchdog.h>
44#include <linux/reboot.h> 44#include <linux/reboot.h>
45#include <linux/smp_lock.h> 45#include <linux/mutex.h>
46#include <linux/init.h> 46#include <linux/init.h>
47#include <linux/spinlock.h> 47#include <linux/spinlock.h>
48#include <asm/uaccess.h> 48#include <asm/uaccess.h>
@@ -50,6 +50,7 @@
50 50
51MODULE_LICENSE("GPL"); 51MODULE_LICENSE("GPL");
52 52
53static DEFINE_MUTEX(harddog_mutex);
53static DEFINE_SPINLOCK(lock); 54static DEFINE_SPINLOCK(lock);
54static int timer_alive; 55static int timer_alive;
55static int harddog_in_fd = -1; 56static int harddog_in_fd = -1;
@@ -66,7 +67,7 @@ static int harddog_open(struct inode *inode, struct file *file)
66 int err = -EBUSY; 67 int err = -EBUSY;
67 char *sock = NULL; 68 char *sock = NULL;
68 69
69 lock_kernel(); 70 mutex_lock(&harddog_mutex);
70 spin_lock(&lock); 71 spin_lock(&lock);
71 if(timer_alive) 72 if(timer_alive)
72 goto err; 73 goto err;
@@ -83,11 +84,11 @@ static int harddog_open(struct inode *inode, struct file *file)
83 84
84 timer_alive = 1; 85 timer_alive = 1;
85 spin_unlock(&lock); 86 spin_unlock(&lock);
86 unlock_kernel(); 87 mutex_unlock(&harddog_mutex);
87 return nonseekable_open(inode, file); 88 return nonseekable_open(inode, file);
88err: 89err:
89 spin_unlock(&lock); 90 spin_unlock(&lock);
90 unlock_kernel(); 91 mutex_unlock(&harddog_mutex);
91 return err; 92 return err;
92} 93}
93 94
@@ -153,9 +154,9 @@ static long harddog_ioctl(struct file *file,
153{ 154{
154 long ret; 155 long ret;
155 156
156 lock_kernel(); 157 mutex_lock(&harddog_mutex);
157 ret = harddog_ioctl_unlocked(file, cmd, arg); 158 ret = harddog_ioctl_unlocked(file, cmd, arg);
158 unlock_kernel(); 159 mutex_unlock(&harddog_mutex);
159 160
160 return ret; 161 return ret;
161} 162}
@@ -166,6 +167,7 @@ static const struct file_operations harddog_fops = {
166 .unlocked_ioctl = harddog_ioctl, 167 .unlocked_ioctl = harddog_ioctl,
167 .open = harddog_open, 168 .open = harddog_open,
168 .release = harddog_release, 169 .release = harddog_release,
170 .llseek = no_llseek,
169}; 171};
170 172
171static struct miscdevice harddog_miscdev = { 173static struct miscdevice harddog_miscdev = {
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index 63c740a85b4c..f9f6a4e20590 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -8,7 +8,7 @@
8#include "linux/slab.h" 8#include "linux/slab.h"
9#include "linux/sound.h" 9#include "linux/sound.h"
10#include "linux/soundcard.h" 10#include "linux/soundcard.h"
11#include "linux/smp_lock.h" 11#include "linux/mutex.h"
12#include "asm/uaccess.h" 12#include "asm/uaccess.h"
13#include "init.h" 13#include "init.h"
14#include "os.h" 14#include "os.h"
@@ -63,6 +63,8 @@ static int set_mixer(char *name, int *add)
63__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP); 63__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
64#endif 64#endif
65 65
66static DEFINE_MUTEX(hostaudio_mutex);
67
66/* /dev/dsp file operations */ 68/* /dev/dsp file operations */
67 69
68static ssize_t hostaudio_read(struct file *file, char __user *buffer, 70static ssize_t hostaudio_read(struct file *file, char __user *buffer,
@@ -198,9 +200,9 @@ static int hostaudio_open(struct inode *inode, struct file *file)
198 w = 1; 200 w = 1;
199 201
200 kparam_block_sysfs_write(dsp); 202 kparam_block_sysfs_write(dsp);
201 lock_kernel(); 203 mutex_lock(&hostaudio_mutex);
202 ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); 204 ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
203 unlock_kernel(); 205 mutex_unlock(&hostaudio_mutex);
204 kparam_unblock_sysfs_write(dsp); 206 kparam_unblock_sysfs_write(dsp);
205 207
206 if (ret < 0) { 208 if (ret < 0) {
@@ -259,9 +261,9 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
259 w = 1; 261 w = 1;
260 262
261 kparam_block_sysfs_write(mixer); 263 kparam_block_sysfs_write(mixer);
262 lock_kernel(); 264 mutex_lock(&hostaudio_mutex);
263 ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); 265 ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
264 unlock_kernel(); 266 mutex_unlock(&hostaudio_mutex);
265 kparam_unblock_sysfs_write(mixer); 267 kparam_unblock_sysfs_write(mixer);
266 268
267 if (ret < 0) { 269 if (ret < 0) {
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 7f7338c90784..35dd0b86401a 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -255,8 +255,8 @@ static const struct {
255 { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" }, 255 { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" },
256}; 256};
257 257
258int line_ioctl(struct tty_struct *tty, struct file * file, 258int line_ioctl(struct tty_struct *tty, unsigned int cmd,
259 unsigned int cmd, unsigned long arg) 259 unsigned long arg)
260{ 260{
261 int ret; 261 int ret;
262 int i; 262 int i;
@@ -727,6 +727,9 @@ struct winch {
727 727
728static void free_winch(struct winch *winch, int free_irq_ok) 728static void free_winch(struct winch *winch, int free_irq_ok)
729{ 729{
730 if (free_irq_ok)
731 free_irq(WINCH_IRQ, winch);
732
730 list_del(&winch->list); 733 list_del(&winch->list);
731 734
732 if (winch->pid != -1) 735 if (winch->pid != -1)
@@ -735,8 +738,6 @@ static void free_winch(struct winch *winch, int free_irq_ok)
735 os_close_file(winch->fd); 738 os_close_file(winch->fd);
736 if (winch->stack != 0) 739 if (winch->stack != 0)
737 free_stack(winch->stack, 0); 740 free_stack(winch->stack, 0);
738 if (free_irq_ok)
739 free_irq(WINCH_IRQ, winch);
740 kfree(winch); 741 kfree(winch);
741} 742}
742 743
@@ -820,12 +821,12 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
820 821
821static void unregister_winch(struct tty_struct *tty) 822static void unregister_winch(struct tty_struct *tty)
822{ 823{
823 struct list_head *ele; 824 struct list_head *ele, *next;
824 struct winch *winch; 825 struct winch *winch;
825 826
826 spin_lock(&winch_handler_lock); 827 spin_lock(&winch_handler_lock);
827 828
828 list_for_each(ele, &winch_handlers) { 829 list_for_each_safe(ele, next, &winch_handlers) {
829 winch = list_entry(ele, struct winch, list); 830 winch = list_entry(ele, struct winch, list);
830 if (winch->tty == tty) { 831 if (winch->tty == tty) {
831 free_winch(winch, 1); 832 free_winch(winch, 1);
diff --git a/arch/um/drivers/mcast.h b/arch/um/drivers/mcast.h
deleted file mode 100644
index 6fa282e896be..000000000000
--- a/arch/um/drivers/mcast.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __DRIVERS_MCAST_H
7#define __DRIVERS_MCAST_H
8
9#include "net_user.h"
10
11struct mcast_data {
12 char *addr;
13 unsigned short port;
14 void *mcast_addr;
15 int ttl;
16 void *dev;
17};
18
19extern const struct net_user_info mcast_user_info;
20
21extern int mcast_user_write(int fd, void *buf, int len,
22 struct mcast_data *pri);
23
24#endif
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
deleted file mode 100644
index ffc6416d5ed7..000000000000
--- a/arch/um/drivers/mcast_kern.c
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * user-mode-linux networking multicast transport
3 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
5 *
6 * based on the existing uml-networking code, which is
7 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
8 * James Leu (jleu@mindspring.net).
9 * Copyright (C) 2001 by various other people who didn't put their name here.
10 *
11 * Licensed under the GPL.
12 */
13
14#include "linux/init.h"
15#include <linux/netdevice.h>
16#include "mcast.h"
17#include "net_kern.h"
18
19struct mcast_init {
20 char *addr;
21 int port;
22 int ttl;
23};
24
25static void mcast_init(struct net_device *dev, void *data)
26{
27 struct uml_net_private *pri;
28 struct mcast_data *dpri;
29 struct mcast_init *init = data;
30
31 pri = netdev_priv(dev);
32 dpri = (struct mcast_data *) pri->user;
33 dpri->addr = init->addr;
34 dpri->port = init->port;
35 dpri->ttl = init->ttl;
36 dpri->dev = dev;
37
38 printk("mcast backend multicast address: %s:%u, TTL:%u\n",
39 dpri->addr, dpri->port, dpri->ttl);
40}
41
42static int mcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
43{
44 return net_recvfrom(fd, skb_mac_header(skb),
45 skb->dev->mtu + ETH_HEADER_OTHER);
46}
47
48static int mcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
49{
50 return mcast_user_write(fd, skb->data, skb->len,
51 (struct mcast_data *) &lp->user);
52}
53
54static const struct net_kern_info mcast_kern_info = {
55 .init = mcast_init,
56 .protocol = eth_protocol,
57 .read = mcast_read,
58 .write = mcast_write,
59};
60
61static int mcast_setup(char *str, char **mac_out, void *data)
62{
63 struct mcast_init *init = data;
64 char *port_str = NULL, *ttl_str = NULL, *remain;
65 char *last;
66
67 *init = ((struct mcast_init)
68 { .addr = "239.192.168.1",
69 .port = 1102,
70 .ttl = 1 });
71
72 remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
73 NULL);
74 if (remain != NULL) {
75 printk(KERN_ERR "mcast_setup - Extra garbage on "
76 "specification : '%s'\n", remain);
77 return 0;
78 }
79
80 if (port_str != NULL) {
81 init->port = simple_strtoul(port_str, &last, 10);
82 if ((*last != '\0') || (last == port_str)) {
83 printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
84 port_str);
85 return 0;
86 }
87 }
88
89 if (ttl_str != NULL) {
90 init->ttl = simple_strtoul(ttl_str, &last, 10);
91 if ((*last != '\0') || (last == ttl_str)) {
92 printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
93 ttl_str);
94 return 0;
95 }
96 }
97
98 printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
99 init->port, init->ttl);
100
101 return 1;
102}
103
104static struct transport mcast_transport = {
105 .list = LIST_HEAD_INIT(mcast_transport.list),
106 .name = "mcast",
107 .setup = mcast_setup,
108 .user = &mcast_user_info,
109 .kern = &mcast_kern_info,
110 .private_size = sizeof(struct mcast_data),
111 .setup_size = sizeof(struct mcast_init),
112};
113
114static int register_mcast(void)
115{
116 register_transport(&mcast_transport);
117 return 0;
118}
119
120late_initcall(register_mcast);
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
deleted file mode 100644
index ee19e91568a2..000000000000
--- a/arch/um/drivers/mcast_user.c
+++ /dev/null
@@ -1,165 +0,0 @@
1/*
2 * user-mode-linux networking multicast transport
3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
5 *
6 * based on the existing uml-networking code, which is
7 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
8 * James Leu (jleu@mindspring.net).
9 * Copyright (C) 2001 by various other people who didn't put their name here.
10 *
11 * Licensed under the GPL.
12 *
13 */
14
15#include <unistd.h>
16#include <errno.h>
17#include <netinet/in.h>
18#include "kern_constants.h"
19#include "mcast.h"
20#include "net_user.h"
21#include "um_malloc.h"
22#include "user.h"
23
24static struct sockaddr_in *new_addr(char *addr, unsigned short port)
25{
26 struct sockaddr_in *sin;
27
28 sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
29 if (sin == NULL) {
30 printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
31 "failed\n");
32 return NULL;
33 }
34 sin->sin_family = AF_INET;
35 sin->sin_addr.s_addr = in_aton(addr);
36 sin->sin_port = htons(port);
37 return sin;
38}
39
40static int mcast_user_init(void *data, void *dev)
41{
42 struct mcast_data *pri = data;
43
44 pri->mcast_addr = new_addr(pri->addr, pri->port);
45 pri->dev = dev;
46 return 0;
47}
48
49static void mcast_remove(void *data)
50{
51 struct mcast_data *pri = data;
52
53 kfree(pri->mcast_addr);
54 pri->mcast_addr = NULL;
55}
56
57static int mcast_open(void *data)
58{
59 struct mcast_data *pri = data;
60 struct sockaddr_in *sin = pri->mcast_addr;
61 struct ip_mreq mreq;
62 int fd, yes = 1, err = -EINVAL;
63
64
65 if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
66 goto out;
67
68 fd = socket(AF_INET, SOCK_DGRAM, 0);
69
70 if (fd < 0) {
71 err = -errno;
72 printk(UM_KERN_ERR "mcast_open : data socket failed, "
73 "errno = %d\n", errno);
74 goto out;
75 }
76
77 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
78 err = -errno;
79 printk(UM_KERN_ERR "mcast_open: SO_REUSEADDR failed, "
80 "errno = %d\n", errno);
81 goto out_close;
82 }
83
84 /* set ttl according to config */
85 if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
86 sizeof(pri->ttl)) < 0) {
87 err = -errno;
88 printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_TTL failed, "
89 "error = %d\n", errno);
90 goto out_close;
91 }
92
93 /* set LOOP, so data does get fed back to local sockets */
94 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
95 err = -errno;
96 printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_LOOP failed, "
97 "error = %d\n", errno);
98 goto out_close;
99 }
100
101 /* bind socket to mcast address */
102 if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
103 err = -errno;
104 printk(UM_KERN_ERR "mcast_open : data bind failed, "
105 "errno = %d\n", errno);
106 goto out_close;
107 }
108
109 /* subscribe to the multicast group */
110 mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
111 mreq.imr_interface.s_addr = 0;
112 if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
113 &mreq, sizeof(mreq)) < 0) {
114 err = -errno;
115 printk(UM_KERN_ERR "mcast_open: IP_ADD_MEMBERSHIP failed, "
116 "error = %d\n", errno);
117 printk(UM_KERN_ERR "There appears not to be a multicast-"
118 "capable network interface on the host.\n");
119 printk(UM_KERN_ERR "eth0 should be configured in order to use "
120 "the multicast transport.\n");
121 goto out_close;
122 }
123
124 return fd;
125
126 out_close:
127 close(fd);
128 out:
129 return err;
130}
131
132static void mcast_close(int fd, void *data)
133{
134 struct ip_mreq mreq;
135 struct mcast_data *pri = data;
136 struct sockaddr_in *sin = pri->mcast_addr;
137
138 mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
139 mreq.imr_interface.s_addr = 0;
140 if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
141 &mreq, sizeof(mreq)) < 0) {
142 printk(UM_KERN_ERR "mcast_open: IP_DROP_MEMBERSHIP failed, "
143 "error = %d\n", errno);
144 }
145
146 close(fd);
147}
148
149int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
150{
151 struct sockaddr_in *data_addr = pri->mcast_addr;
152
153 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
154}
155
156const struct net_user_info mcast_user_info = {
157 .init = mcast_user_init,
158 .open = mcast_open,
159 .close = mcast_close,
160 .remove = mcast_remove,
161 .add_address = NULL,
162 .delete_address = NULL,
163 .mtu = ETH_MAX_PACKET,
164 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
165};
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index ebc680717e59..c70e047eed72 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -124,35 +124,18 @@ void mconsole_log(struct mc_request *req)
124#if 0 124#if 0
125void mconsole_proc(struct mc_request *req) 125void mconsole_proc(struct mc_request *req)
126{ 126{
127 struct nameidata nd;
128 struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt; 127 struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
129 struct file *file; 128 struct file *file;
130 int n, err; 129 int n;
131 char *ptr = req->request.data, *buf; 130 char *ptr = req->request.data, *buf;
132 mm_segment_t old_fs = get_fs(); 131 mm_segment_t old_fs = get_fs();
133 132
134 ptr += strlen("proc"); 133 ptr += strlen("proc");
135 ptr = skip_spaces(ptr); 134 ptr = skip_spaces(ptr);
136 135
137 err = vfs_path_lookup(mnt->mnt_root, mnt, ptr, LOOKUP_FOLLOW, &nd); 136 file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
138 if (err) {
139 mconsole_reply(req, "Failed to look up file", 1, 0);
140 goto out;
141 }
142
143 err = may_open(&nd.path, MAY_READ, O_RDONLY);
144 if (result) {
145 mconsole_reply(req, "Failed to open file", 1, 0);
146 path_put(&nd.path);
147 goto out;
148 }
149
150 file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
151 current_cred());
152 err = PTR_ERR(file);
153 if (IS_ERR(file)) { 137 if (IS_ERR(file)) {
154 mconsole_reply(req, "Failed to open file", 1, 0); 138 mconsole_reply(req, "Failed to open file", 1, 0);
155 path_put(&nd.path);
156 goto out; 139 goto out;
157 } 140 }
158 141
@@ -843,6 +826,7 @@ static ssize_t mconsole_proc_write(struct file *file,
843static const struct file_operations mconsole_proc_fops = { 826static const struct file_operations mconsole_proc_fops = {
844 .owner = THIS_MODULE, 827 .owner = THIS_MODULE,
845 .write = mconsole_proc_write, 828 .write = mconsole_proc_write,
829 .llseek = noop_llseek,
846}; 830};
847 831
848static int create_proc_mconsole(void) 832static int create_proc_mconsole(void)
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index 7158393b6793..c0ef803c7c70 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -37,13 +37,7 @@ static ssize_t mmapper_write(struct file *file, const char __user *buf,
37 if (*ppos > mmapper_size) 37 if (*ppos > mmapper_size)
38 return -EINVAL; 38 return -EINVAL;
39 39
40 if (count > mmapper_size - *ppos) 40 return simple_write_to_buffer(v_buf, mmapper_size, ppos, buf, count);
41 count = mmapper_size - *ppos;
42
43 if (copy_from_user(&v_buf[*ppos], buf, count))
44 return -EFAULT;
45
46 return count;
47} 41}
48 42
49static long mmapper_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 43static long mmapper_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -93,6 +87,7 @@ static const struct file_operations mmapper_fops = {
93 .mmap = mmapper_mmap, 87 .mmap = mmapper_mmap,
94 .open = mmapper_open, 88 .open = mmapper_open,
95 .release = mmapper_release, 89 .release = mmapper_release,
90 .llseek = default_llseek,
96}; 91};
97 92
98/* 93/*
@@ -121,7 +116,7 @@ static int __init mmapper_init(void)
121 if (err) { 116 if (err) {
122 printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", 117 printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
123 err); 118 err);
124 return err;; 119 return err;
125 } 120 }
126 return 0; 121 return 0;
127} 122}
@@ -136,3 +131,4 @@ module_exit(mmapper_exit);
136 131
137MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>"); 132MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
138MODULE_DESCRIPTION("DSPLinux simulator mmapper driver"); 133MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
134MODULE_LICENSE("GPL");
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index 4949044773ba..981085a93f30 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -100,6 +100,7 @@ static const struct file_operations rng_chrdev_ops = {
100 .owner = THIS_MODULE, 100 .owner = THIS_MODULE,
101 .open = rng_dev_open, 101 .open = rng_dev_open,
102 .read = rng_dev_read, 102 .read = rng_dev_read,
103 .llseek = noop_llseek,
103}; 104};
104 105
105/* rng_init shouldn't be called more than once at boot time */ 106/* rng_init shouldn't be called more than once at boot time */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 9734994cba1e..620f5b70957d 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -33,7 +33,7 @@
33#include "linux/mm.h" 33#include "linux/mm.h"
34#include "linux/slab.h" 34#include "linux/slab.h"
35#include "linux/vmalloc.h" 35#include "linux/vmalloc.h"
36#include "linux/smp_lock.h" 36#include "linux/mutex.h"
37#include "linux/blkpg.h" 37#include "linux/blkpg.h"
38#include "linux/genhd.h" 38#include "linux/genhd.h"
39#include "linux/spinlock.h" 39#include "linux/spinlock.h"
@@ -100,6 +100,7 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
100#define DRIVER_NAME "uml-blkdev" 100#define DRIVER_NAME "uml-blkdev"
101 101
102static DEFINE_MUTEX(ubd_lock); 102static DEFINE_MUTEX(ubd_lock);
103static DEFINE_MUTEX(ubd_mutex); /* replaces BKL, might not be needed */
103 104
104static int ubd_open(struct block_device *bdev, fmode_t mode); 105static int ubd_open(struct block_device *bdev, fmode_t mode);
105static int ubd_release(struct gendisk *disk, fmode_t mode); 106static int ubd_release(struct gendisk *disk, fmode_t mode);
@@ -184,7 +185,7 @@ struct ubd {
184 .no_cow = 0, \ 185 .no_cow = 0, \
185 .shared = 0, \ 186 .shared = 0, \
186 .cow = DEFAULT_COW, \ 187 .cow = DEFAULT_COW, \
187 .lock = SPIN_LOCK_UNLOCKED, \ 188 .lock = __SPIN_LOCK_UNLOCKED(ubd_devs.lock), \
188 .request = NULL, \ 189 .request = NULL, \
189 .start_sg = 0, \ 190 .start_sg = 0, \
190 .end_sg = 0, \ 191 .end_sg = 0, \
@@ -1101,7 +1102,7 @@ static int ubd_open(struct block_device *bdev, fmode_t mode)
1101 struct ubd *ubd_dev = disk->private_data; 1102 struct ubd *ubd_dev = disk->private_data;
1102 int err = 0; 1103 int err = 0;
1103 1104
1104 lock_kernel(); 1105 mutex_lock(&ubd_mutex);
1105 if(ubd_dev->count == 0){ 1106 if(ubd_dev->count == 0){
1106 err = ubd_open_dev(ubd_dev); 1107 err = ubd_open_dev(ubd_dev);
1107 if(err){ 1108 if(err){
@@ -1120,7 +1121,7 @@ static int ubd_open(struct block_device *bdev, fmode_t mode)
1120 err = -EROFS; 1121 err = -EROFS;
1121 }*/ 1122 }*/
1122out: 1123out:
1123 unlock_kernel(); 1124 mutex_unlock(&ubd_mutex);
1124 return err; 1125 return err;
1125} 1126}
1126 1127
@@ -1128,10 +1129,10 @@ static int ubd_release(struct gendisk *disk, fmode_t mode)
1128{ 1129{
1129 struct ubd *ubd_dev = disk->private_data; 1130 struct ubd *ubd_dev = disk->private_data;
1130 1131
1131 lock_kernel(); 1132 mutex_lock(&ubd_mutex);
1132 if(--ubd_dev->count == 0) 1133 if(--ubd_dev->count == 0)
1133 ubd_close_dev(ubd_dev); 1134 ubd_close_dev(ubd_dev);
1134 unlock_kernel(); 1135 mutex_unlock(&ubd_mutex);
1135 return 0; 1136 return 0;
1136} 1137}
1137 1138
diff --git a/arch/um/drivers/umcast.h b/arch/um/drivers/umcast.h
new file mode 100644
index 000000000000..6f8c0fe890fb
--- /dev/null
+++ b/arch/um/drivers/umcast.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __DRIVERS_UMCAST_H
7#define __DRIVERS_UMCAST_H
8
9#include "net_user.h"
10
11struct umcast_data {
12 char *addr;
13 unsigned short lport;
14 unsigned short rport;
15 void *listen_addr;
16 void *remote_addr;
17 int ttl;
18 int unicast;
19 void *dev;
20};
21
22extern const struct net_user_info umcast_user_info;
23
24extern int umcast_user_write(int fd, void *buf, int len,
25 struct umcast_data *pri);
26
27#endif
diff --git a/arch/um/drivers/umcast_kern.c b/arch/um/drivers/umcast_kern.c
new file mode 100644
index 000000000000..42dab11d2ecf
--- /dev/null
+++ b/arch/um/drivers/umcast_kern.c
@@ -0,0 +1,188 @@
1/*
2 * user-mode-linux networking multicast transport
3 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
5 *
6 * based on the existing uml-networking code, which is
7 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
8 * James Leu (jleu@mindspring.net).
9 * Copyright (C) 2001 by various other people who didn't put their name here.
10 *
11 * Licensed under the GPL.
12 */
13
14#include "linux/init.h"
15#include <linux/netdevice.h>
16#include "umcast.h"
17#include "net_kern.h"
18
19struct umcast_init {
20 char *addr;
21 int lport;
22 int rport;
23 int ttl;
24 bool unicast;
25};
26
27static void umcast_init(struct net_device *dev, void *data)
28{
29 struct uml_net_private *pri;
30 struct umcast_data *dpri;
31 struct umcast_init *init = data;
32
33 pri = netdev_priv(dev);
34 dpri = (struct umcast_data *) pri->user;
35 dpri->addr = init->addr;
36 dpri->lport = init->lport;
37 dpri->rport = init->rport;
38 dpri->unicast = init->unicast;
39 dpri->ttl = init->ttl;
40 dpri->dev = dev;
41
42 if (dpri->unicast) {
43 printk(KERN_INFO "ucast backend address: %s:%u listen port: "
44 "%u\n", dpri->addr, dpri->rport, dpri->lport);
45 } else {
46 printk(KERN_INFO "mcast backend multicast address: %s:%u, "
47 "TTL:%u\n", dpri->addr, dpri->lport, dpri->ttl);
48 }
49}
50
51static int umcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
52{
53 return net_recvfrom(fd, skb_mac_header(skb),
54 skb->dev->mtu + ETH_HEADER_OTHER);
55}
56
57static int umcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
58{
59 return umcast_user_write(fd, skb->data, skb->len,
60 (struct umcast_data *) &lp->user);
61}
62
63static const struct net_kern_info umcast_kern_info = {
64 .init = umcast_init,
65 .protocol = eth_protocol,
66 .read = umcast_read,
67 .write = umcast_write,
68};
69
70static int mcast_setup(char *str, char **mac_out, void *data)
71{
72 struct umcast_init *init = data;
73 char *port_str = NULL, *ttl_str = NULL, *remain;
74 char *last;
75
76 *init = ((struct umcast_init)
77 { .addr = "239.192.168.1",
78 .lport = 1102,
79 .ttl = 1 });
80
81 remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
82 NULL);
83 if (remain != NULL) {
84 printk(KERN_ERR "mcast_setup - Extra garbage on "
85 "specification : '%s'\n", remain);
86 return 0;
87 }
88
89 if (port_str != NULL) {
90 init->lport = simple_strtoul(port_str, &last, 10);
91 if ((*last != '\0') || (last == port_str)) {
92 printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
93 port_str);
94 return 0;
95 }
96 }
97
98 if (ttl_str != NULL) {
99 init->ttl = simple_strtoul(ttl_str, &last, 10);
100 if ((*last != '\0') || (last == ttl_str)) {
101 printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
102 ttl_str);
103 return 0;
104 }
105 }
106
107 init->unicast = false;
108 init->rport = init->lport;
109
110 printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
111 init->lport, init->ttl);
112
113 return 1;
114}
115
116static int ucast_setup(char *str, char **mac_out, void *data)
117{
118 struct umcast_init *init = data;
119 char *lport_str = NULL, *rport_str = NULL, *remain;
120 char *last;
121
122 *init = ((struct umcast_init)
123 { .addr = "",
124 .lport = 1102,
125 .rport = 1102 });
126
127 remain = split_if_spec(str, mac_out, &init->addr,
128 &lport_str, &rport_str, NULL);
129 if (remain != NULL) {
130 printk(KERN_ERR "ucast_setup - Extra garbage on "
131 "specification : '%s'\n", remain);
132 return 0;
133 }
134
135 if (lport_str != NULL) {
136 init->lport = simple_strtoul(lport_str, &last, 10);
137 if ((*last != '\0') || (last == lport_str)) {
138 printk(KERN_ERR "ucast_setup - Bad listen port : "
139 "'%s'\n", lport_str);
140 return 0;
141 }
142 }
143
144 if (rport_str != NULL) {
145 init->rport = simple_strtoul(rport_str, &last, 10);
146 if ((*last != '\0') || (last == rport_str)) {
147 printk(KERN_ERR "ucast_setup - Bad remote port : "
148 "'%s'\n", rport_str);
149 return 0;
150 }
151 }
152
153 init->unicast = true;
154
155 printk(KERN_INFO "Configured ucast device: :%u -> %s:%u\n",
156 init->lport, init->addr, init->rport);
157
158 return 1;
159}
160
161static struct transport mcast_transport = {
162 .list = LIST_HEAD_INIT(mcast_transport.list),
163 .name = "mcast",
164 .setup = mcast_setup,
165 .user = &umcast_user_info,
166 .kern = &umcast_kern_info,
167 .private_size = sizeof(struct umcast_data),
168 .setup_size = sizeof(struct umcast_init),
169};
170
171static struct transport ucast_transport = {
172 .list = LIST_HEAD_INIT(ucast_transport.list),
173 .name = "ucast",
174 .setup = ucast_setup,
175 .user = &umcast_user_info,
176 .kern = &umcast_kern_info,
177 .private_size = sizeof(struct umcast_data),
178 .setup_size = sizeof(struct umcast_init),
179};
180
181static int register_umcast(void)
182{
183 register_transport(&mcast_transport);
184 register_transport(&ucast_transport);
185 return 0;
186}
187
188late_initcall(register_umcast);
diff --git a/arch/um/drivers/umcast_user.c b/arch/um/drivers/umcast_user.c
new file mode 100644
index 000000000000..59c56fd6f52a
--- /dev/null
+++ b/arch/um/drivers/umcast_user.c
@@ -0,0 +1,186 @@
1/*
2 * user-mode-linux networking multicast transport
3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
5 *
6 * based on the existing uml-networking code, which is
7 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
8 * James Leu (jleu@mindspring.net).
9 * Copyright (C) 2001 by various other people who didn't put their name here.
10 *
11 * Licensed under the GPL.
12 *
13 */
14
15#include <unistd.h>
16#include <errno.h>
17#include <netinet/in.h>
18#include "kern_constants.h"
19#include "umcast.h"
20#include "net_user.h"
21#include "um_malloc.h"
22#include "user.h"
23
24static struct sockaddr_in *new_addr(char *addr, unsigned short port)
25{
26 struct sockaddr_in *sin;
27
28 sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
29 if (sin == NULL) {
30 printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
31 "failed\n");
32 return NULL;
33 }
34 sin->sin_family = AF_INET;
35 if (addr)
36 sin->sin_addr.s_addr = in_aton(addr);
37 else
38 sin->sin_addr.s_addr = INADDR_ANY;
39 sin->sin_port = htons(port);
40 return sin;
41}
42
43static int umcast_user_init(void *data, void *dev)
44{
45 struct umcast_data *pri = data;
46
47 pri->remote_addr = new_addr(pri->addr, pri->rport);
48 if (pri->unicast)
49 pri->listen_addr = new_addr(NULL, pri->lport);
50 else
51 pri->listen_addr = pri->remote_addr;
52 pri->dev = dev;
53 return 0;
54}
55
56static void umcast_remove(void *data)
57{
58 struct umcast_data *pri = data;
59
60 kfree(pri->listen_addr);
61 if (pri->unicast)
62 kfree(pri->remote_addr);
63 pri->listen_addr = pri->remote_addr = NULL;
64}
65
66static int umcast_open(void *data)
67{
68 struct umcast_data *pri = data;
69 struct sockaddr_in *lsin = pri->listen_addr;
70 struct sockaddr_in *rsin = pri->remote_addr;
71 struct ip_mreq mreq;
72 int fd, yes = 1, err = -EINVAL;
73
74
75 if ((!pri->unicast && lsin->sin_addr.s_addr == 0) ||
76 (rsin->sin_addr.s_addr == 0) ||
77 (lsin->sin_port == 0) || (rsin->sin_port == 0))
78 goto out;
79
80 fd = socket(AF_INET, SOCK_DGRAM, 0);
81
82 if (fd < 0) {
83 err = -errno;
84 printk(UM_KERN_ERR "umcast_open : data socket failed, "
85 "errno = %d\n", errno);
86 goto out;
87 }
88
89 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
90 err = -errno;
91 printk(UM_KERN_ERR "umcast_open: SO_REUSEADDR failed, "
92 "errno = %d\n", errno);
93 goto out_close;
94 }
95
96 if (!pri->unicast) {
97 /* set ttl according to config */
98 if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
99 sizeof(pri->ttl)) < 0) {
100 err = -errno;
101 printk(UM_KERN_ERR "umcast_open: IP_MULTICAST_TTL "
102 "failed, error = %d\n", errno);
103 goto out_close;
104 }
105
106 /* set LOOP, so data does get fed back to local sockets */
107 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP,
108 &yes, sizeof(yes)) < 0) {
109 err = -errno;
110 printk(UM_KERN_ERR "umcast_open: IP_MULTICAST_LOOP "
111 "failed, error = %d\n", errno);
112 goto out_close;
113 }
114 }
115
116 /* bind socket to the address */
117 if (bind(fd, (struct sockaddr *) lsin, sizeof(*lsin)) < 0) {
118 err = -errno;
119 printk(UM_KERN_ERR "umcast_open : data bind failed, "
120 "errno = %d\n", errno);
121 goto out_close;
122 }
123
124 if (!pri->unicast) {
125 /* subscribe to the multicast group */
126 mreq.imr_multiaddr.s_addr = lsin->sin_addr.s_addr;
127 mreq.imr_interface.s_addr = 0;
128 if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
129 &mreq, sizeof(mreq)) < 0) {
130 err = -errno;
131 printk(UM_KERN_ERR "umcast_open: IP_ADD_MEMBERSHIP "
132 "failed, error = %d\n", errno);
133 printk(UM_KERN_ERR "There appears not to be a "
134 "multicast-capable network interface on the "
135 "host.\n");
136 printk(UM_KERN_ERR "eth0 should be configured in order "
137 "to use the multicast transport.\n");
138 goto out_close;
139 }
140 }
141
142 return fd;
143
144 out_close:
145 close(fd);
146 out:
147 return err;
148}
149
150static void umcast_close(int fd, void *data)
151{
152 struct umcast_data *pri = data;
153
154 if (!pri->unicast) {
155 struct ip_mreq mreq;
156 struct sockaddr_in *lsin = pri->listen_addr;
157
158 mreq.imr_multiaddr.s_addr = lsin->sin_addr.s_addr;
159 mreq.imr_interface.s_addr = 0;
160 if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
161 &mreq, sizeof(mreq)) < 0) {
162 printk(UM_KERN_ERR "umcast_close: IP_DROP_MEMBERSHIP "
163 "failed, error = %d\n", errno);
164 }
165 }
166
167 close(fd);
168}
169
170int umcast_user_write(int fd, void *buf, int len, struct umcast_data *pri)
171{
172 struct sockaddr_in *data_addr = pri->remote_addr;
173
174 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
175}
176
177const struct net_user_info umcast_user_info = {
178 .init = umcast_user_init,
179 .open = umcast_open,
180 .close = umcast_close,
181 .remove = umcast_remove,
182 .add_address = NULL,
183 .delete_address = NULL,
184 .mtu = ETH_MAX_PACKET,
185 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
186};
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index da2caa5a21ef..8ac7146c237f 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -90,7 +90,7 @@ static int xterm_open(int input, int output, int primary, void *d,
90 int pid, fd, new, err; 90 int pid, fd, new, err;
91 char title[256], file[] = "/tmp/xterm-pipeXXXXXX"; 91 char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
92 char *argv[] = { terminal_emulator, title_switch, title, exec_switch, 92 char *argv[] = { terminal_emulator, title_switch, title, exec_switch,
93 "/usr/lib/uml/port-helper", "-uml-socket", 93 OS_LIB_PATH "/uml/port-helper", "-uml-socket",
94 file, NULL }; 94 file, NULL };
95 95
96 if (access(argv[4], X_OK) < 0) 96 if (access(argv[4], X_OK) < 0)