aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers')
-rw-r--r--arch/um/drivers/chan_kern.c1
-rw-r--r--arch/um/drivers/chan_user.c14
-rw-r--r--arch/um/drivers/cow_sys.h18
-rw-r--r--arch/um/drivers/daemon_user.c31
-rw-r--r--arch/um/drivers/fd.c1
-rw-r--r--arch/um/drivers/harddog_user.c1
-rw-r--r--arch/um/drivers/line.c1
-rw-r--r--arch/um/drivers/mcast_user.c16
-rw-r--r--arch/um/drivers/mconsole_kern.c1
-rw-r--r--arch/um/drivers/mconsole_user.c1
-rw-r--r--arch/um/drivers/mmapper_kern.c1
-rw-r--r--arch/um/drivers/net_kern.c162
-rw-r--r--arch/um/drivers/net_user.c4
-rw-r--r--arch/um/drivers/pcap_user.c38
-rw-r--r--arch/um/drivers/port_user.c1
-rw-r--r--arch/um/drivers/pty.c2
-rw-r--r--arch/um/drivers/slip_user.c7
-rw-r--r--arch/um/drivers/slirp_user.c4
-rw-r--r--arch/um/drivers/ssl.c5
-rw-r--r--arch/um/drivers/stdio_console.c5
-rw-r--r--arch/um/drivers/tty.c1
-rw-r--r--arch/um/drivers/ubd_kern.c351
-rw-r--r--arch/um/drivers/ubd_user.c16
-rw-r--r--arch/um/drivers/xterm.c1
24 files changed, 347 insertions, 336 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 9fdfad649536..3aa351611763 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -12,7 +12,6 @@
12#include <linux/tty_flip.h> 12#include <linux/tty_flip.h>
13#include <asm/irq.h> 13#include <asm/irq.h>
14#include "chan_kern.h" 14#include "chan_kern.h"
15#include "user_util.h"
16#include "kern.h" 15#include "kern.h"
17#include "irq_user.h" 16#include "irq_user.h"
18#include "sigio.h" 17#include "sigio.h"
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 0cad3546cb89..13f0bf852b2a 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -14,7 +14,6 @@
14#include <sys/ioctl.h> 14#include <sys/ioctl.h>
15#include <sys/socket.h> 15#include <sys/socket.h>
16#include "kern_util.h" 16#include "kern_util.h"
17#include "user_util.h"
18#include "chan_user.h" 17#include "chan_user.h"
19#include "user.h" 18#include "user.h"
20#include "os.h" 19#include "os.h"
@@ -158,7 +157,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
158 */ 157 */
159 err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0); 158 err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0);
160 if(err < 0){ 159 if(err < 0){
161 printk("fork of winch_thread failed - errno = %d\n", errno); 160 printk("fork of winch_thread failed - errno = %d\n", -err);
162 goto out_close; 161 goto out_close;
163 } 162 }
164 163
@@ -204,14 +203,3 @@ void register_winch(int fd, struct tty_struct *tty)
204 } 203 }
205 } 204 }
206} 205}
207
208/*
209 * Overrides for Emacs so that we follow Linus's tabbing style.
210 * Emacs will notice this stuff at the end of the file and automatically
211 * adjust the settings for this buffer only. This must remain at the end
212 * of the file.
213 * ---------------------------------------------------------------------------
214 * Local variables:
215 * c-file-style: "linux"
216 * End:
217 */
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index c6a308464acb..15453845d2ba 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -2,14 +2,13 @@
2#define __COW_SYS_H__ 2#define __COW_SYS_H__
3 3
4#include "kern_util.h" 4#include "kern_util.h"
5#include "user_util.h"
6#include "os.h" 5#include "os.h"
7#include "user.h" 6#include "user.h"
8#include "um_malloc.h" 7#include "um_malloc.h"
9 8
10static inline void *cow_malloc(int size) 9static inline void *cow_malloc(int size)
11{ 10{
12 return(um_kmalloc(size)); 11 return um_kmalloc(size);
13} 12}
14 13
15static inline void cow_free(void *ptr) 14static inline void cow_free(void *ptr)
@@ -21,29 +20,22 @@ static inline void cow_free(void *ptr)
21 20
22static inline char *cow_strdup(char *str) 21static inline char *cow_strdup(char *str)
23{ 22{
24 return(uml_strdup(str)); 23 return uml_strdup(str);
25} 24}
26 25
27static inline int cow_seek_file(int fd, __u64 offset) 26static inline int cow_seek_file(int fd, __u64 offset)
28{ 27{
29 return(os_seek_file(fd, offset)); 28 return os_seek_file(fd, offset);
30} 29}
31 30
32static inline int cow_file_size(char *file, unsigned long long *size_out) 31static inline int cow_file_size(char *file, unsigned long long *size_out)
33{ 32{
34 return(os_file_size(file, size_out)); 33 return os_file_size(file, size_out);
35} 34}
36 35
37static inline int cow_write_file(int fd, void *buf, int size) 36static inline int cow_write_file(int fd, void *buf, int size)
38{ 37{
39 return(os_write_file(fd, buf, size)); 38 return os_write_file(fd, buf, size);
40} 39}
41 40
42#endif 41#endif
43
44/*
45 * ---------------------------------------------------------------------------
46 * Local variables:
47 * c-file-style: "linux"
48 * End:
49 */
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 021b82c7a759..b869e3899683 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -14,7 +14,6 @@
14#include "net_user.h" 14#include "net_user.h"
15#include "daemon.h" 15#include "daemon.h"
16#include "kern_util.h" 16#include "kern_util.h"
17#include "user_util.h"
18#include "user.h" 17#include "user.h"
19#include "os.h" 18#include "os.h"
20#include "um_malloc.h" 19#include "um_malloc.h"
@@ -39,11 +38,11 @@ static struct sockaddr_un *new_addr(void *name, int len)
39 sun = um_kmalloc(sizeof(struct sockaddr_un)); 38 sun = um_kmalloc(sizeof(struct sockaddr_un));
40 if(sun == NULL){ 39 if(sun == NULL){
41 printk("new_addr: allocation of sockaddr_un failed\n"); 40 printk("new_addr: allocation of sockaddr_un failed\n");
42 return(NULL); 41 return NULL;
43 } 42 }
44 sun->sun_family = AF_UNIX; 43 sun->sun_family = AF_UNIX;
45 memcpy(sun->sun_path, name, len); 44 memcpy(sun->sun_path, name, len);
46 return(sun); 45 return sun;
47} 46}
48 47
49static int connect_to_switch(struct daemon_data *pri) 48static int connect_to_switch(struct daemon_data *pri)
@@ -112,7 +111,7 @@ static int connect_to_switch(struct daemon_data *pri)
112 } 111 }
113 112
114 pri->data_addr = sun; 113 pri->data_addr = sun;
115 return(fd); 114 return fd;
116 115
117 out_free: 116 out_free:
118 kfree(sun); 117 kfree(sun);
@@ -120,10 +119,10 @@ static int connect_to_switch(struct daemon_data *pri)
120 os_close_file(fd); 119 os_close_file(fd);
121 out: 120 out:
122 os_close_file(pri->control); 121 os_close_file(pri->control);
123 return(err); 122 return err;
124} 123}
125 124
126static void daemon_user_init(void *data, void *dev) 125static int daemon_user_init(void *data, void *dev)
127{ 126{
128 struct daemon_data *pri = data; 127 struct daemon_data *pri = data;
129 struct timeval tv; 128 struct timeval tv;
@@ -146,13 +145,16 @@ static void daemon_user_init(void *data, void *dev)
146 if(pri->fd < 0){ 145 if(pri->fd < 0){
147 kfree(pri->local_addr); 146 kfree(pri->local_addr);
148 pri->local_addr = NULL; 147 pri->local_addr = NULL;
148 return pri->fd;
149 } 149 }
150
151 return 0;
150} 152}
151 153
152static int daemon_open(void *data) 154static int daemon_open(void *data)
153{ 155{
154 struct daemon_data *pri = data; 156 struct daemon_data *pri = data;
155 return(pri->fd); 157 return pri->fd;
156} 158}
157 159
158static void daemon_remove(void *data) 160static void daemon_remove(void *data)
@@ -176,12 +178,12 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
176{ 178{
177 struct sockaddr_un *data_addr = pri->data_addr; 179 struct sockaddr_un *data_addr = pri->data_addr;
178 180
179 return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr))); 181 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
180} 182}
181 183
182static int daemon_set_mtu(int mtu, void *data) 184static int daemon_set_mtu(int mtu, void *data)
183{ 185{
184 return(mtu); 186 return mtu;
185} 187}
186 188
187const struct net_user_info daemon_user_info = { 189const struct net_user_info daemon_user_info = {
@@ -194,14 +196,3 @@ const struct net_user_info daemon_user_info = {
194 .delete_address = NULL, 196 .delete_address = NULL,
195 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 197 .max_packet = MAX_PACKET - ETH_HEADER_OTHER
196}; 198};
197
198/*
199 * Overrides for Emacs so that we follow Linus's tabbing style.
200 * Emacs will notice this stuff at the end of the file and automatically
201 * adjust the settings for this buffer only. This must remain at the end
202 * of the file.
203 * ---------------------------------------------------------------------------
204 * Local variables:
205 * c-file-style: "linux"
206 * End:
207 */
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 218aa0e9b792..7f083ec47a4f 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -9,7 +9,6 @@
9#include <termios.h> 9#include <termios.h>
10#include <errno.h> 10#include <errno.h>
11#include "user.h" 11#include "user.h"
12#include "user_util.h"
13#include "chan_user.h" 12#include "chan_user.h"
14#include "os.h" 13#include "os.h"
15#include "um_malloc.h" 14#include "um_malloc.h"
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index c495ecf263b1..5eeecf8917c3 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -6,7 +6,6 @@
6#include <stdio.h> 6#include <stdio.h>
7#include <unistd.h> 7#include <unistd.h>
8#include <errno.h> 8#include <errno.h>
9#include "user_util.h"
10#include "user.h" 9#include "user.h"
11#include "mconsole.h" 10#include "mconsole.h"
12#include "os.h" 11#include "os.h"
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index f75d7b05c481..ced99106f798 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -13,7 +13,6 @@
13#include "irq_user.h" 13#include "irq_user.h"
14#include "line.h" 14#include "line.h"
15#include "kern.h" 15#include "kern.h"
16#include "user_util.h"
17#include "kern_util.h" 16#include "kern_util.h"
18#include "os.h" 17#include "os.h"
19#include "irq_kern.h" 18#include "irq_kern.h"
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index b827e82884c9..d319db16d4ec 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -20,7 +20,6 @@
20#include "net_user.h" 20#include "net_user.h"
21#include "mcast.h" 21#include "mcast.h"
22#include "kern_util.h" 22#include "kern_util.h"
23#include "user_util.h"
24#include "user.h" 23#include "user.h"
25#include "os.h" 24#include "os.h"
26#include "um_malloc.h" 25#include "um_malloc.h"
@@ -34,20 +33,21 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
34 sin = um_kmalloc(sizeof(struct sockaddr_in)); 33 sin = um_kmalloc(sizeof(struct sockaddr_in));
35 if(sin == NULL){ 34 if(sin == NULL){
36 printk("new_addr: allocation of sockaddr_in failed\n"); 35 printk("new_addr: allocation of sockaddr_in failed\n");
37 return(NULL); 36 return NULL;
38 } 37 }
39 sin->sin_family = AF_INET; 38 sin->sin_family = AF_INET;
40 sin->sin_addr.s_addr = in_aton(addr); 39 sin->sin_addr.s_addr = in_aton(addr);
41 sin->sin_port = htons(port); 40 sin->sin_port = htons(port);
42 return(sin); 41 return sin;
43} 42}
44 43
45static void mcast_user_init(void *data, void *dev) 44static int mcast_user_init(void *data, void *dev)
46{ 45{
47 struct mcast_data *pri = data; 46 struct mcast_data *pri = data;
48 47
49 pri->mcast_addr = new_addr(pri->addr, pri->port); 48 pri->mcast_addr = new_addr(pri->addr, pri->port);
50 pri->dev = dev; 49 pri->dev = dev;
50 return 0;
51} 51}
52 52
53static void mcast_remove(void *data) 53static void mcast_remove(void *data)
@@ -107,8 +107,8 @@ static int mcast_open(void *data)
107 err = -errno; 107 err = -errno;
108 printk("mcast_open : data bind failed, errno = %d\n", errno); 108 printk("mcast_open : data bind failed, errno = %d\n", errno);
109 goto out_close; 109 goto out_close;
110 } 110 }
111 111
112 /* subscribe to the multicast group */ 112 /* subscribe to the multicast group */
113 mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr; 113 mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
114 mreq.imr_interface.s_addr = 0; 114 mreq.imr_interface.s_addr = 0;
@@ -153,12 +153,12 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
153{ 153{
154 struct sockaddr_in *data_addr = pri->mcast_addr; 154 struct sockaddr_in *data_addr = pri->mcast_addr;
155 155
156 return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr))); 156 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
157} 157}
158 158
159static int mcast_set_mtu(int mtu, void *data) 159static int mcast_set_mtu(int mtu, void *data)
160{ 160{
161 return(mtu); 161 return mtu;
162} 162}
163 163
164const struct net_user_info mcast_user_info = { 164const struct net_user_info mcast_user_info = {
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 65ad2932672c..542c9ef858f8 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -25,7 +25,6 @@
25#include "linux/console.h" 25#include "linux/console.h"
26#include "asm/irq.h" 26#include "asm/irq.h"
27#include "asm/uaccess.h" 27#include "asm/uaccess.h"
28#include "user_util.h"
29#include "kern_util.h" 28#include "kern_util.h"
30#include "kern.h" 29#include "kern.h"
31#include "mconsole.h" 30#include "mconsole.h"
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index f02634fbf32a..62e5ad63181a 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -17,7 +17,6 @@
17#include "sysdep/ptrace.h" 17#include "sysdep/ptrace.h"
18#include "mconsole.h" 18#include "mconsole.h"
19#include "os.h" 19#include "os.h"
20#include "user_util.h"
21 20
22static struct mconsole_command commands[] = { 21static struct mconsole_command commands[] = {
23 /* With uts namespaces, uts information becomes process-specific, so 22 /* With uts namespaces, uts information becomes process-specific, so
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index df3516e47d4d..e41a08f04694 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -15,7 +15,6 @@
15#include <linux/miscdevice.h> 15#include <linux/miscdevice.h>
16#include <asm/uaccess.h> 16#include <asm/uaccess.h>
17#include "mem_user.h" 17#include "mem_user.h"
18#include "user_util.h"
19 18
20/* These are set in mmapper_init, which is called at boot time */ 19/* These are set in mmapper_init, which is called at boot time */
21static unsigned long mmapper_size; 20static unsigned long mmapper_size;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 859303730b2f..baac4ad5e68e 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -21,7 +21,6 @@
21#include "linux/ethtool.h" 21#include "linux/ethtool.h"
22#include "linux/platform_device.h" 22#include "linux/platform_device.h"
23#include "asm/uaccess.h" 23#include "asm/uaccess.h"
24#include "user_util.h"
25#include "kern_util.h" 24#include "kern_util.h"
26#include "net_kern.h" 25#include "net_kern.h"
27#include "net_user.h" 26#include "net_user.h"
@@ -284,7 +283,7 @@ void uml_net_user_timer_expire(unsigned long _conn)
284#endif 283#endif
285} 284}
286 285
287static void setup_etheraddr(char *str, unsigned char *addr) 286static void setup_etheraddr(char *str, unsigned char *addr, char *name)
288{ 287{
289 char *end; 288 char *end;
290 int i; 289 int i;
@@ -303,15 +302,32 @@ static void setup_etheraddr(char *str, unsigned char *addr)
303 } 302 }
304 str = end + 1; 303 str = end + 1;
305 } 304 }
306 if(addr[0] & 1){ 305 if (is_multicast_ether_addr(addr)) {
307 printk(KERN_ERR 306 printk(KERN_ERR
308 "Attempt to assign a broadcast ethernet address to a " 307 "Attempt to assign a multicast ethernet address to a "
309 "device disallowed\n"); 308 "device disallowed\n");
310 goto random; 309 goto random;
311 } 310 }
311 if (!is_valid_ether_addr(addr)) {
312 printk(KERN_ERR
313 "Attempt to assign an invalid ethernet address to a "
314 "device disallowed\n");
315 goto random;
316 }
317 if (!is_local_ether_addr(addr)) {
318 printk(KERN_WARNING
319 "Warning: attempt to assign a globally valid ethernet address to a "
320 "device\n");
321 printk(KERN_WARNING "You should better enable the 2nd rightmost bit "
322 "in the first byte of the MAC, i.e. "
323 "%02x:%02x:%02x:%02x:%02x:%02x\n",
324 addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], addr[5]);
325 }
312 return; 326 return;
313 327
314random: 328random:
329 printk(KERN_INFO
330 "Choosing a random ethernet address for device %s\n", name);
315 random_ether_addr(addr); 331 random_ether_addr(addr);
316} 332}
317 333
@@ -325,31 +341,53 @@ static struct platform_driver uml_net_driver = {
325}; 341};
326static int driver_registered; 342static int driver_registered;
327 343
328static int eth_configure(int n, void *init, char *mac, 344static void net_device_release(struct device *dev)
329 struct transport *transport) 345{
346 struct uml_net *device = dev->driver_data;
347 struct net_device *netdev = device->dev;
348 struct uml_net_private *lp = netdev->priv;
349
350 if(lp->remove != NULL)
351 (*lp->remove)(&lp->user);
352 list_del(&device->list);
353 kfree(device);
354 free_netdev(netdev);
355}
356
357static void eth_configure(int n, void *init, char *mac,
358 struct transport *transport)
330{ 359{
331 struct uml_net *device; 360 struct uml_net *device;
332 struct net_device *dev; 361 struct net_device *dev;
333 struct uml_net_private *lp; 362 struct uml_net_private *lp;
334 int save, err, size; 363 int err, size;
335 364
336 size = transport->private_size + sizeof(struct uml_net_private) + 365 size = transport->private_size + sizeof(struct uml_net_private);
337 sizeof(((struct uml_net_private *) 0)->user);
338 366
339 device = kzalloc(sizeof(*device), GFP_KERNEL); 367 device = kzalloc(sizeof(*device), GFP_KERNEL);
340 if (device == NULL) { 368 if (device == NULL) {
341 printk(KERN_ERR "eth_configure failed to allocate uml_net\n"); 369 printk(KERN_ERR "eth_configure failed to allocate struct "
342 return(1); 370 "uml_net\n");
371 return;
372 }
373
374 dev = alloc_etherdev(size);
375 if (dev == NULL) {
376 printk(KERN_ERR "eth_configure: failed to allocate struct "
377 "net_device for eth%d\n", n);
378 goto out_free_device;
343 } 379 }
344 380
345 INIT_LIST_HEAD(&device->list); 381 INIT_LIST_HEAD(&device->list);
346 device->index = n; 382 device->index = n;
347 383
348 spin_lock(&devices_lock); 384 /* If this name ends up conflicting with an existing registered
349 list_add(&device->list, &devices); 385 * netdevice, that is OK, register_netdev{,ice}() will notice this
350 spin_unlock(&devices_lock); 386 * and fail.
387 */
388 snprintf(dev->name, sizeof(dev->name), "eth%d", n);
351 389
352 setup_etheraddr(mac, device->mac); 390 setup_etheraddr(mac, device->mac, dev->name);
353 391
354 printk(KERN_INFO "Netdevice %d ", n); 392 printk(KERN_INFO "Netdevice %d ", n);
355 printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", 393 printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
@@ -357,11 +395,6 @@ static int eth_configure(int n, void *init, char *mac,
357 device->mac[2], device->mac[3], 395 device->mac[2], device->mac[3],
358 device->mac[4], device->mac[5]); 396 device->mac[4], device->mac[5]);
359 printk(": "); 397 printk(": ");
360 dev = alloc_etherdev(size);
361 if (dev == NULL) {
362 printk(KERN_ERR "eth_configure: failed to allocate device\n");
363 return 1;
364 }
365 398
366 lp = dev->priv; 399 lp = dev->priv;
367 /* This points to the transport private data. It's still clear, but we 400 /* This points to the transport private data. It's still clear, but we
@@ -376,47 +409,20 @@ static int eth_configure(int n, void *init, char *mac,
376 } 409 }
377 device->pdev.id = n; 410 device->pdev.id = n;
378 device->pdev.name = DRIVER_NAME; 411 device->pdev.name = DRIVER_NAME;
379 platform_device_register(&device->pdev); 412 device->pdev.dev.release = net_device_release;
413 device->pdev.dev.driver_data = device;
414 if(platform_device_register(&device->pdev))
415 goto out_free_netdev;
380 SET_NETDEV_DEV(dev,&device->pdev.dev); 416 SET_NETDEV_DEV(dev,&device->pdev.dev);
381 417
382 /* If this name ends up conflicting with an existing registered
383 * netdevice, that is OK, register_netdev{,ice}() will notice this
384 * and fail.
385 */
386 snprintf(dev->name, sizeof(dev->name), "eth%d", n);
387 device->dev = dev; 418 device->dev = dev;
388 419
420 /*
421 * These just fill in a data structure, so there's no failure
422 * to be worried about.
423 */
389 (*transport->kern->init)(dev, init); 424 (*transport->kern->init)(dev, init);
390 425
391 dev->mtu = transport->user->max_packet;
392 dev->open = uml_net_open;
393 dev->hard_start_xmit = uml_net_start_xmit;
394 dev->stop = uml_net_close;
395 dev->get_stats = uml_net_get_stats;
396 dev->set_multicast_list = uml_net_set_multicast_list;
397 dev->tx_timeout = uml_net_tx_timeout;
398 dev->set_mac_address = uml_net_set_mac;
399 dev->change_mtu = uml_net_change_mtu;
400 dev->ethtool_ops = &uml_net_ethtool_ops;
401 dev->watchdog_timeo = (HZ >> 1);
402 dev->irq = UM_ETH_IRQ;
403
404 rtnl_lock();
405 err = register_netdevice(dev);
406 rtnl_unlock();
407 if (err) {
408 device->dev = NULL;
409 /* XXX: should we call ->remove() here? */
410 free_netdev(dev);
411 return 1;
412 }
413
414 /* lp.user is the first four bytes of the transport data, which
415 * has already been initialized. This structure assignment will
416 * overwrite that, so we make sure that .user gets overwritten with
417 * what it already has.
418 */
419 save = lp->user[0];
420 *lp = ((struct uml_net_private) 426 *lp = ((struct uml_net_private)
421 { .list = LIST_HEAD_INIT(lp->list), 427 { .list = LIST_HEAD_INIT(lp->list),
422 .dev = dev, 428 .dev = dev,
@@ -430,20 +436,52 @@ static int eth_configure(int n, void *init, char *mac,
430 .write = transport->kern->write, 436 .write = transport->kern->write,
431 .add_address = transport->user->add_address, 437 .add_address = transport->user->add_address,
432 .delete_address = transport->user->delete_address, 438 .delete_address = transport->user->delete_address,
433 .set_mtu = transport->user->set_mtu, 439 .set_mtu = transport->user->set_mtu });
434 .user = { save } });
435 440
436 init_timer(&lp->tl); 441 init_timer(&lp->tl);
437 spin_lock_init(&lp->lock); 442 spin_lock_init(&lp->lock);
438 lp->tl.function = uml_net_user_timer_expire; 443 lp->tl.function = uml_net_user_timer_expire;
439 memcpy(lp->mac, device->mac, sizeof(lp->mac)); 444 memcpy(lp->mac, device->mac, sizeof(lp->mac));
440 445
441 if (transport->user->init) 446 if ((transport->user->init != NULL) &&
442 (*transport->user->init)(&lp->user, dev); 447 ((*transport->user->init)(&lp->user, dev) != 0))
448 goto out_unregister;
443 449
444 set_ether_mac(dev, device->mac); 450 set_ether_mac(dev, device->mac);
451 dev->mtu = transport->user->max_packet;
452 dev->open = uml_net_open;
453 dev->hard_start_xmit = uml_net_start_xmit;
454 dev->stop = uml_net_close;
455 dev->get_stats = uml_net_get_stats;
456 dev->set_multicast_list = uml_net_set_multicast_list;
457 dev->tx_timeout = uml_net_tx_timeout;
458 dev->set_mac_address = uml_net_set_mac;
459 dev->change_mtu = uml_net_change_mtu;
460 dev->ethtool_ops = &uml_net_ethtool_ops;
461 dev->watchdog_timeo = (HZ >> 1);
462 dev->irq = UM_ETH_IRQ;
445 463
446 return 0; 464 rtnl_lock();
465 err = register_netdevice(dev);
466 rtnl_unlock();
467 if (err)
468 goto out_undo_user_init;
469
470 spin_lock(&devices_lock);
471 list_add(&device->list, &devices);
472 spin_unlock(&devices_lock);
473
474 return;
475
476out_undo_user_init:
477 if (transport->user->remove != NULL)
478 (*transport->user->remove)(&lp->user);
479out_unregister:
480 platform_device_unregister(&device->pdev);
481out_free_netdev:
482 free_netdev(dev);
483out_free_device:
484 kfree(device);
447} 485}
448 486
449static struct uml_net *find_device(int n) 487static struct uml_net *find_device(int n)
@@ -666,13 +704,9 @@ static int net_remove(int n, char **error_out)
666 lp = dev->priv; 704 lp = dev->priv;
667 if(lp->fd > 0) 705 if(lp->fd > 0)
668 return -EBUSY; 706 return -EBUSY;
669 if(lp->remove != NULL) (*lp->remove)(&lp->user);
670 unregister_netdev(dev); 707 unregister_netdev(dev);
671 platform_device_unregister(&device->pdev); 708 platform_device_unregister(&device->pdev);
672 709
673 list_del(&device->list);
674 kfree(device);
675 free_netdev(dev);
676 return 0; 710 return 0;
677} 711}
678 712
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 0ffd7ac295d4..3503cff867c3 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -14,11 +14,11 @@
14#include <sys/wait.h> 14#include <sys/wait.h>
15#include <sys/time.h> 15#include <sys/time.h>
16#include "user.h" 16#include "user.h"
17#include "user_util.h"
18#include "kern_util.h" 17#include "kern_util.h"
19#include "net_user.h" 18#include "net_user.h"
20#include "os.h" 19#include "os.h"
21#include "um_malloc.h" 20#include "um_malloc.h"
21#include "kern_constants.h"
22 22
23int tap_open_common(void *dev, char *gate_addr) 23int tap_open_common(void *dev, char *gate_addr)
24{ 24{
@@ -216,7 +216,7 @@ static void change(char *dev, char *what, unsigned char *addr,
216 sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], 216 sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
217 netmask[2], netmask[3]); 217 netmask[2], netmask[3]);
218 218
219 output_len = page_size(); 219 output_len = UM_KERN_PAGE_SIZE;
220 output = um_kmalloc(output_len); 220 output = um_kmalloc(output_len);
221 if(output == NULL) 221 if(output == NULL)
222 printk("change : failed to allocate output buffer\n"); 222 printk("change : failed to allocate output buffer\n");
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index 11921a7baa7b..dc0a903ef9a6 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -18,7 +18,7 @@
18 18
19#define PCAP_FD(p) (*(int *)(p)) 19#define PCAP_FD(p) (*(int *)(p))
20 20
21static void pcap_user_init(void *data, void *dev) 21static int pcap_user_init(void *data, void *dev)
22{ 22{
23 struct pcap_data *pri = data; 23 struct pcap_data *pri = data;
24 pcap_t *p; 24 pcap_t *p;
@@ -28,11 +28,12 @@ static void pcap_user_init(void *data, void *dev)
28 if(p == NULL){ 28 if(p == NULL){
29 printk("pcap_user_init : pcap_open_live failed - '%s'\n", 29 printk("pcap_user_init : pcap_open_live failed - '%s'\n",
30 errors); 30 errors);
31 return; 31 return -EINVAL;
32 } 32 }
33 33
34 pri->dev = dev; 34 pri->dev = dev;
35 pri->pcap = p; 35 pri->pcap = p;
36 return 0;
36} 37}
37 38
38static int pcap_open(void *data) 39static int pcap_open(void *data)
@@ -42,39 +43,39 @@ static int pcap_open(void *data)
42 int err; 43 int err;
43 44
44 if(pri->pcap == NULL) 45 if(pri->pcap == NULL)
45 return(-ENODEV); 46 return -ENODEV;
46 47
47 if(pri->filter != NULL){ 48 if(pri->filter != NULL){
48 err = dev_netmask(pri->dev, &netmask); 49 err = dev_netmask(pri->dev, &netmask);
49 if(err < 0){ 50 if(err < 0){
50 printk("pcap_open : dev_netmask failed\n"); 51 printk("pcap_open : dev_netmask failed\n");
51 return(-EIO); 52 return -EIO;
52 } 53 }
53 54
54 pri->compiled = um_kmalloc(sizeof(struct bpf_program)); 55 pri->compiled = um_kmalloc(sizeof(struct bpf_program));
55 if(pri->compiled == NULL){ 56 if(pri->compiled == NULL){
56 printk("pcap_open : kmalloc failed\n"); 57 printk("pcap_open : kmalloc failed\n");
57 return(-ENOMEM); 58 return -ENOMEM;
58 } 59 }
59 60
60 err = pcap_compile(pri->pcap, 61 err = pcap_compile(pri->pcap,
61 (struct bpf_program *) pri->compiled, 62 (struct bpf_program *) pri->compiled,
62 pri->filter, pri->optimize, netmask); 63 pri->filter, pri->optimize, netmask);
63 if(err < 0){ 64 if(err < 0){
64 printk("pcap_open : pcap_compile failed - '%s'\n", 65 printk("pcap_open : pcap_compile failed - '%s'\n",
65 pcap_geterr(pri->pcap)); 66 pcap_geterr(pri->pcap));
66 return(-EIO); 67 return -EIO;
67 } 68 }
68 69
69 err = pcap_setfilter(pri->pcap, pri->compiled); 70 err = pcap_setfilter(pri->pcap, pri->compiled);
70 if(err < 0){ 71 if(err < 0){
71 printk("pcap_open : pcap_setfilter failed - '%s'\n", 72 printk("pcap_open : pcap_setfilter failed - '%s'\n",
72 pcap_geterr(pri->pcap)); 73 pcap_geterr(pri->pcap));
73 return(-EIO); 74 return -EIO;
74 } 75 }
75 } 76 }
76 77
77 return(PCAP_FD(pri->pcap)); 78 return PCAP_FD(pri->pcap);
78} 79}
79 80
80static void pcap_remove(void *data) 81static void pcap_remove(void *data)
@@ -114,11 +115,11 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
114 n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata); 115 n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
115 if(n < 0){ 116 if(n < 0){
116 printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap)); 117 printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
117 return(-EIO); 118 return -EIO;
118 } 119 }
119 else if(n == 0) 120 else if(n == 0)
120 return(0); 121 return 0;
121 return(hdata.len); 122 return hdata.len;
122} 123}
123 124
124const struct net_user_info pcap_user_info = { 125const struct net_user_info pcap_user_info = {
@@ -131,14 +132,3 @@ const struct net_user_info pcap_user_info = {
131 .delete_address = NULL, 132 .delete_address = NULL,
132 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 133 .max_packet = MAX_PACKET - ETH_HEADER_OTHER
133}; 134};
134
135/*
136 * Overrides for Emacs so that we follow Linus's tabbing style.
137 * Emacs will notice this stuff at the end of the file and automatically
138 * adjust the settings for this buffer only. This must remain at the end
139 * of the file.
140 * ---------------------------------------------------------------------------
141 * Local variables:
142 * c-file-style: "linux"
143 * End:
144 */
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index 80508023054f..3f6357d24bee 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -13,7 +13,6 @@
13#include <sys/socket.h> 13#include <sys/socket.h>
14#include <sys/un.h> 14#include <sys/un.h>
15#include <netinet/in.h> 15#include <netinet/in.h>
16#include "user_util.h"
17#include "kern_util.h" 16#include "kern_util.h"
18#include "user.h" 17#include "user.h"
19#include "chan_user.h" 18#include "chan_user.h"
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 829a5eca8c07..df4976c9eef2 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -4,13 +4,13 @@
4 */ 4 */
5 5
6#include <stdio.h> 6#include <stdio.h>
7#include <stdlib.h>
7#include <unistd.h> 8#include <unistd.h>
8#include <string.h> 9#include <string.h>
9#include <errno.h> 10#include <errno.h>
10#include <termios.h> 11#include <termios.h>
11#include "chan_user.h" 12#include "chan_user.h"
12#include "user.h" 13#include "user.h"
13#include "user_util.h"
14#include "kern_util.h" 14#include "kern_util.h"
15#include "os.h" 15#include "os.h"
16#include "um_malloc.h" 16#include "um_malloc.h"
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 7eddacc53b6e..78f0e515da8f 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -8,7 +8,6 @@
8#include <sys/termios.h> 8#include <sys/termios.h>
9#include <sys/wait.h> 9#include <sys/wait.h>
10#include <sys/signal.h> 10#include <sys/signal.h>
11#include "user_util.h"
12#include "kern_util.h" 11#include "kern_util.h"
13#include "user.h" 12#include "user.h"
14#include "net_user.h" 13#include "net_user.h"
@@ -16,12 +15,14 @@
16#include "slip_common.h" 15#include "slip_common.h"
17#include "os.h" 16#include "os.h"
18#include "um_malloc.h" 17#include "um_malloc.h"
18#include "kern_constants.h"
19 19
20void slip_user_init(void *data, void *dev) 20static int slip_user_init(void *data, void *dev)
21{ 21{
22 struct slip_data *pri = data; 22 struct slip_data *pri = data;
23 23
24 pri->dev = dev; 24 pri->dev = dev;
25 return 0;
25} 26}
26 27
27static int set_up_tty(int fd) 28static int set_up_tty(int fd)
@@ -89,7 +90,7 @@ static int slip_tramp(char **argv, int fd)
89 goto out_close; 90 goto out_close;
90 pid = err; 91 pid = err;
91 92
92 output_len = page_size(); 93 output_len = UM_KERN_PAGE_SIZE;
93 output = um_kmalloc(output_len); 94 output = um_kmalloc(output_len);
94 if(output == NULL){ 95 if(output == NULL){
95 printk("slip_tramp : failed to allocate output buffer\n"); 96 printk("slip_tramp : failed to allocate output buffer\n");
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index ce5e85d1de3d..39f889fe9949 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -7,7 +7,6 @@
7#include <errno.h> 7#include <errno.h>
8#include <sys/wait.h> 8#include <sys/wait.h>
9#include <sys/signal.h> 9#include <sys/signal.h>
10#include "user_util.h"
11#include "kern_util.h" 10#include "kern_util.h"
12#include "user.h" 11#include "user.h"
13#include "net_user.h" 12#include "net_user.h"
@@ -15,11 +14,12 @@
15#include "slip_common.h" 14#include "slip_common.h"
16#include "os.h" 15#include "os.h"
17 16
18void slirp_user_init(void *data, void *dev) 17static int slirp_user_init(void *data, void *dev)
19{ 18{
20 struct slirp_data *pri = data; 19 struct slirp_data *pri = data;
21 20
22 pri->dev = dev; 21 pri->dev = dev;
22 return 0;
23} 23}
24 24
25struct slirp_pre_exec_data { 25struct slirp_pre_exec_data {
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 4b382a6e710f..fd09ad9e9c0a 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -15,7 +15,6 @@
15#include "line.h" 15#include "line.h"
16#include "ssl.h" 16#include "ssl.h"
17#include "chan_kern.h" 17#include "chan_kern.h"
18#include "user_util.h"
19#include "kern_util.h" 18#include "kern_util.h"
20#include "kern.h" 19#include "kern.h"
21#include "init.h" 20#include "init.h"
@@ -192,12 +191,12 @@ static int ssl_init(void)
192 ssl_driver = register_lines(&driver, &ssl_ops, serial_lines, 191 ssl_driver = register_lines(&driver, &ssl_ops, serial_lines,
193 ARRAY_SIZE(serial_lines)); 192 ARRAY_SIZE(serial_lines));
194 193
195 lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts);
196
197 new_title = add_xterm_umid(opts.xterm_title); 194 new_title = add_xterm_umid(opts.xterm_title);
198 if (new_title != NULL) 195 if (new_title != NULL)
199 opts.xterm_title = new_title; 196 opts.xterm_title = new_title;
200 197
198 lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts);
199
201 ssl_init_done = 1; 200 ssl_init_done = 1;
202 register_console(&ssl_cons); 201 register_console(&ssl_cons);
203 return 0; 202 return 0;
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 76d1f1c980ef..2bb4193ac1aa 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -22,7 +22,6 @@
22#include "stdio_console.h" 22#include "stdio_console.h"
23#include "line.h" 23#include "line.h"
24#include "chan_kern.h" 24#include "chan_kern.h"
25#include "user_util.h"
26#include "kern_util.h" 25#include "kern_util.h"
27#include "irq_user.h" 26#include "irq_user.h"
28#include "mconsole_kern.h" 27#include "mconsole_kern.h"
@@ -167,12 +166,12 @@ int stdio_init(void)
167 return -1; 166 return -1;
168 printk(KERN_INFO "Initialized stdio console driver\n"); 167 printk(KERN_INFO "Initialized stdio console driver\n");
169 168
170 lines_init(vts, ARRAY_SIZE(vts), &opts);
171
172 new_title = add_xterm_umid(opts.xterm_title); 169 new_title = add_xterm_umid(opts.xterm_title);
173 if(new_title != NULL) 170 if(new_title != NULL)
174 opts.xterm_title = new_title; 171 opts.xterm_title = new_title;
175 172
173 lines_init(vts, ARRAY_SIZE(vts), &opts);
174
176 con_init_done = 1; 175 con_init_done = 1;
177 register_console(&stdiocons); 176 register_console(&stdiocons);
178 return 0; 177 return 0;
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index d95d64309eaf..c07d0d562780 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -8,7 +8,6 @@
8#include <errno.h> 8#include <errno.h>
9#include <unistd.h> 9#include <unistd.h>
10#include "chan_user.h" 10#include "chan_user.h"
11#include "user_util.h"
12#include "user.h" 11#include "user.h"
13#include "os.h" 12#include "os.h"
14#include "um_malloc.h" 13#include "um_malloc.h"
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 8bd9204ac1ab..70509ddaac03 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -39,7 +39,6 @@
39#include "asm/irq.h" 39#include "asm/irq.h"
40#include "asm/types.h" 40#include "asm/types.h"
41#include "asm/tlbflush.h" 41#include "asm/tlbflush.h"
42#include "user_util.h"
43#include "mem_user.h" 42#include "mem_user.h"
44#include "kern_util.h" 43#include "kern_util.h"
45#include "kern.h" 44#include "kern.h"
@@ -90,7 +89,7 @@ static inline int ubd_test_bit(__u64 bit, unsigned char *data)
90 bits = sizeof(data[0]) * 8; 89 bits = sizeof(data[0]) * 8;
91 n = bit / bits; 90 n = bit / bits;
92 off = bit % bits; 91 off = bit % bits;
93 return((data[n] & (1 << off)) != 0); 92 return (data[n] & (1 << off)) != 0;
94} 93}
95 94
96static inline void ubd_set_bit(__u64 bit, unsigned char *data) 95static inline void ubd_set_bit(__u64 bit, unsigned char *data)
@@ -147,10 +146,13 @@ struct cow {
147 unsigned long *bitmap; 146 unsigned long *bitmap;
148 unsigned long bitmap_len; 147 unsigned long bitmap_len;
149 int bitmap_offset; 148 int bitmap_offset;
150 int data_offset; 149 int data_offset;
151}; 150};
152 151
152#define MAX_SG 64
153
153struct ubd { 154struct ubd {
155 struct list_head restart;
154 /* name (and fd, below) of the file opened for writing, either the 156 /* name (and fd, below) of the file opened for writing, either the
155 * backing or the cow file. */ 157 * backing or the cow file. */
156 char *file; 158 char *file;
@@ -165,15 +167,17 @@ struct ubd {
165 struct platform_device pdev; 167 struct platform_device pdev;
166 struct request_queue *queue; 168 struct request_queue *queue;
167 spinlock_t lock; 169 spinlock_t lock;
168 int active; 170 struct scatterlist sg[MAX_SG];
171 struct request *request;
172 int start_sg, end_sg;
169}; 173};
170 174
171#define DEFAULT_COW { \ 175#define DEFAULT_COW { \
172 .file = NULL, \ 176 .file = NULL, \
173 .fd = -1, \ 177 .fd = -1, \
174 .bitmap = NULL, \ 178 .bitmap = NULL, \
175 .bitmap_offset = 0, \ 179 .bitmap_offset = 0, \
176 .data_offset = 0, \ 180 .data_offset = 0, \
177} 181}
178 182
179#define DEFAULT_UBD { \ 183#define DEFAULT_UBD { \
@@ -183,11 +187,13 @@ struct ubd {
183 .size = -1, \ 187 .size = -1, \
184 .boot_openflags = OPEN_FLAGS, \ 188 .boot_openflags = OPEN_FLAGS, \
185 .openflags = OPEN_FLAGS, \ 189 .openflags = OPEN_FLAGS, \
186 .no_cow = 0, \ 190 .no_cow = 0, \
187 .shared = 0, \ 191 .shared = 0, \
188 .cow = DEFAULT_COW, \ 192 .cow = DEFAULT_COW, \
189 .lock = SPIN_LOCK_UNLOCKED, \ 193 .lock = SPIN_LOCK_UNLOCKED, \
190 .active = 0, \ 194 .request = NULL, \
195 .start_sg = 0, \
196 .end_sg = 0, \
191} 197}
192 198
193/* Protected by ubd_lock */ 199/* Protected by ubd_lock */
@@ -243,7 +249,7 @@ static void make_ide_entries(char *dev_name)
243static int fake_ide_setup(char *str) 249static int fake_ide_setup(char *str)
244{ 250{
245 fake_ide = 1; 251 fake_ide = 1;
246 return(1); 252 return 1;
247} 253}
248 254
249__setup("fake_ide", fake_ide_setup); 255__setup("fake_ide", fake_ide_setup);
@@ -261,7 +267,7 @@ static int parse_unit(char **ptr)
261 if(isdigit(*str)) { 267 if(isdigit(*str)) {
262 n = simple_strtoul(str, &end, 0); 268 n = simple_strtoul(str, &end, 0);
263 if(end == str) 269 if(end == str)
264 return(-1); 270 return -1;
265 *ptr = end; 271 *ptr = end;
266 } 272 }
267 else if (('a' <= *str) && (*str <= 'z')) { 273 else if (('a' <= *str) && (*str <= 'z')) {
@@ -269,7 +275,7 @@ static int parse_unit(char **ptr)
269 str++; 275 str++;
270 *ptr = str; 276 *ptr = str;
271 } 277 }
272 return(n); 278 return n;
273} 279}
274 280
275/* If *index_out == -1 at exit, the passed option was a general one; 281/* If *index_out == -1 at exit, the passed option was a general one;
@@ -436,7 +442,7 @@ static int udb_setup(char *str)
436{ 442{
437 printk("udb%s specified on command line is almost certainly a ubd -> " 443 printk("udb%s specified on command line is almost certainly a ubd -> "
438 "udb TYPO\n", str); 444 "udb TYPO\n", str);
439 return(1); 445 return 1;
440} 446}
441 447
442__setup("udb", udb_setup); 448__setup("udb", udb_setup);
@@ -467,66 +473,75 @@ static void do_ubd_request(request_queue_t * q);
467/* Only changed by ubd_init, which is an initcall. */ 473/* Only changed by ubd_init, which is an initcall. */
468int thread_fd = -1; 474int thread_fd = -1;
469 475
470/* call ubd_finish if you need to serialize */ 476static void ubd_end_request(struct request *req, int bytes, int uptodate)
471static void __ubd_finish(struct request *req, int error)
472{ 477{
473 int nsect; 478 if (!end_that_request_first(req, uptodate, bytes >> 9)) {
474 479 struct ubd *dev = req->rq_disk->private_data;
475 if(error){ 480 unsigned long flags;
476 end_request(req, 0); 481
477 return; 482 add_disk_randomness(req->rq_disk);
483 spin_lock_irqsave(&dev->lock, flags);
484 end_that_request_last(req, uptodate);
485 spin_unlock_irqrestore(&dev->lock, flags);
478 } 486 }
479 nsect = req->current_nr_sectors;
480 req->sector += nsect;
481 req->buffer += nsect << 9;
482 req->errors = 0;
483 req->nr_sectors -= nsect;
484 req->current_nr_sectors = 0;
485 end_request(req, 1);
486} 487}
487 488
488/* Callable only from interrupt context - otherwise you need to do 489/* Callable only from interrupt context - otherwise you need to do
489 * spin_lock_irq()/spin_lock_irqsave() */ 490 * spin_lock_irq()/spin_lock_irqsave() */
490static inline void ubd_finish(struct request *req, int error) 491static inline void ubd_finish(struct request *req, int bytes)
491{ 492{
492 struct ubd *dev = req->rq_disk->private_data; 493 if(bytes < 0){
493 494 ubd_end_request(req, 0, 0);
494 spin_lock(&dev->lock); 495 return;
495 __ubd_finish(req, error); 496 }
496 spin_unlock(&dev->lock); 497 ubd_end_request(req, bytes, 1);
497} 498}
498 499
500static LIST_HEAD(restart);
501
499/* XXX - move this inside ubd_intr. */ 502/* XXX - move this inside ubd_intr. */
500/* Called without dev->lock held, and only in interrupt context. */ 503/* Called without dev->lock held, and only in interrupt context. */
501static void ubd_handler(void) 504static void ubd_handler(void)
502{ 505{
503 struct io_thread_req req; 506 struct io_thread_req *req;
504 struct request *rq; 507 struct request *rq;
505 struct ubd *dev; 508 struct ubd *ubd;
509 struct list_head *list, *next_ele;
510 unsigned long flags;
506 int n; 511 int n;
507 512
508 n = os_read_file(thread_fd, &req, sizeof(req)); 513 while(1){
509 if(n != sizeof(req)){ 514 n = os_read_file(thread_fd, &req,
510 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " 515 sizeof(struct io_thread_req *));
511 "err = %d\n", os_getpid(), -n); 516 if(n != sizeof(req)){
512 return; 517 if(n == -EAGAIN)
513 } 518 break;
514 519 printk(KERN_ERR "spurious interrupt in ubd_handler, "
515 rq = req.req; 520 "err = %d\n", -n);
516 dev = rq->rq_disk->private_data; 521 return;
517 dev->active = 0; 522 }
518 523
519 ubd_finish(rq, req.error); 524 rq = req->req;
525 rq->nr_sectors -= req->length >> 9;
526 if(rq->nr_sectors == 0)
527 ubd_finish(rq, rq->hard_nr_sectors << 9);
528 kfree(req);
529 }
520 reactivate_fd(thread_fd, UBD_IRQ); 530 reactivate_fd(thread_fd, UBD_IRQ);
521 spin_lock(&dev->lock); 531
522 do_ubd_request(dev->queue); 532 list_for_each_safe(list, next_ele, &restart){
523 spin_unlock(&dev->lock); 533 ubd = container_of(list, struct ubd, restart);
534 list_del_init(&ubd->restart);
535 spin_lock_irqsave(&ubd->lock, flags);
536 do_ubd_request(ubd->queue);
537 spin_unlock_irqrestore(&ubd->lock, flags);
538 }
524} 539}
525 540
526static irqreturn_t ubd_intr(int irq, void *dev) 541static irqreturn_t ubd_intr(int irq, void *dev)
527{ 542{
528 ubd_handler(); 543 ubd_handler();
529 return(IRQ_HANDLED); 544 return IRQ_HANDLED;
530} 545}
531 546
532/* Only changed by ubd_init, which is an initcall. */ 547/* Only changed by ubd_init, which is an initcall. */
@@ -545,7 +560,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
545 char *file; 560 char *file;
546 561
547 file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; 562 file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
548 return(os_file_size(file, size_out)); 563 return os_file_size(file, size_out);
549} 564}
550 565
551static void ubd_close_dev(struct ubd *ubd_dev) 566static void ubd_close_dev(struct ubd *ubd_dev)
@@ -617,10 +632,18 @@ static int ubd_open_dev(struct ubd *ubd_dev)
617 if(err < 0) goto error; 632 if(err < 0) goto error;
618 ubd_dev->cow.fd = err; 633 ubd_dev->cow.fd = err;
619 } 634 }
620 return(0); 635 return 0;
621 error: 636 error:
622 os_close_file(ubd_dev->fd); 637 os_close_file(ubd_dev->fd);
623 return(err); 638 return err;
639}
640
641static void ubd_device_release(struct device *dev)
642{
643 struct ubd *ubd_dev = dev->driver_data;
644
645 blk_cleanup_queue(ubd_dev->queue);
646 *ubd_dev = ((struct ubd) DEFAULT_UBD);
624} 647}
625 648
626static int ubd_disk_register(int major, u64 size, int unit, 649static int ubd_disk_register(int major, u64 size, int unit,
@@ -630,7 +653,7 @@ static int ubd_disk_register(int major, u64 size, int unit,
630 653
631 disk = alloc_disk(1 << UBD_SHIFT); 654 disk = alloc_disk(1 << UBD_SHIFT);
632 if(disk == NULL) 655 if(disk == NULL)
633 return(-ENOMEM); 656 return -ENOMEM;
634 657
635 disk->major = major; 658 disk->major = major;
636 disk->first_minor = unit << UBD_SHIFT; 659 disk->first_minor = unit << UBD_SHIFT;
@@ -645,6 +668,8 @@ static int ubd_disk_register(int major, u64 size, int unit,
645 if (major == MAJOR_NR) { 668 if (major == MAJOR_NR) {
646 ubd_devs[unit].pdev.id = unit; 669 ubd_devs[unit].pdev.id = unit;
647 ubd_devs[unit].pdev.name = DRIVER_NAME; 670 ubd_devs[unit].pdev.name = DRIVER_NAME;
671 ubd_devs[unit].pdev.dev.release = ubd_device_release;
672 ubd_devs[unit].pdev.dev.driver_data = &ubd_devs[unit];
648 platform_device_register(&ubd_devs[unit].pdev); 673 platform_device_register(&ubd_devs[unit].pdev);
649 disk->driverfs_dev = &ubd_devs[unit].pdev.dev; 674 disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
650 } 675 }
@@ -675,6 +700,8 @@ static int ubd_add(int n, char **error_out)
675 700
676 ubd_dev->size = ROUND_BLOCK(ubd_dev->size); 701 ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
677 702
703 INIT_LIST_HEAD(&ubd_dev->restart);
704
678 err = -ENOMEM; 705 err = -ENOMEM;
679 ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock); 706 ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
680 if (ubd_dev->queue == NULL) { 707 if (ubd_dev->queue == NULL) {
@@ -683,6 +710,7 @@ static int ubd_add(int n, char **error_out)
683 } 710 }
684 ubd_dev->queue->queuedata = ubd_dev; 711 ubd_dev->queue->queuedata = ubd_dev;
685 712
713 blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
686 err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); 714 err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
687 if(err){ 715 if(err){
688 *error_out = "Failed to register device"; 716 *error_out = "Failed to register device";
@@ -730,14 +758,14 @@ static int ubd_config(char *str, char **error_out)
730 goto err_free; 758 goto err_free;
731 } 759 }
732 760
733 mutex_lock(&ubd_lock); 761 mutex_lock(&ubd_lock);
734 ret = ubd_add(n, error_out); 762 ret = ubd_add(n, error_out);
735 if (ret) 763 if (ret)
736 ubd_devs[n].file = NULL; 764 ubd_devs[n].file = NULL;
737 mutex_unlock(&ubd_lock); 765 mutex_unlock(&ubd_lock);
738 766
739out: 767out:
740 return ret; 768 return ret;
741 769
742err_free: 770err_free:
743 kfree(str); 771 kfree(str);
@@ -752,7 +780,7 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
752 n = parse_unit(&name); 780 n = parse_unit(&name);
753 if((n >= MAX_DEV) || (n < 0)){ 781 if((n >= MAX_DEV) || (n < 0)){
754 *error_out = "ubd_get_config : device number out of range"; 782 *error_out = "ubd_get_config : device number out of range";
755 return(-1); 783 return -1;
756 } 784 }
757 785
758 ubd_dev = &ubd_devs[n]; 786 ubd_dev = &ubd_devs[n];
@@ -773,29 +801,27 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
773 801
774 out: 802 out:
775 mutex_unlock(&ubd_lock); 803 mutex_unlock(&ubd_lock);
776 return(len); 804 return len;
777} 805}
778 806
779static int ubd_id(char **str, int *start_out, int *end_out) 807static int ubd_id(char **str, int *start_out, int *end_out)
780{ 808{
781 int n; 809 int n;
782 810
783 n = parse_unit(str); 811 n = parse_unit(str);
784 *start_out = 0; 812 *start_out = 0;
785 *end_out = MAX_DEV - 1; 813 *end_out = MAX_DEV - 1;
786 return n; 814 return n;
787} 815}
788 816
789static int ubd_remove(int n, char **error_out) 817static int ubd_remove(int n, char **error_out)
790{ 818{
819 struct gendisk *disk = ubd_gendisk[n];
791 struct ubd *ubd_dev; 820 struct ubd *ubd_dev;
792 int err = -ENODEV; 821 int err = -ENODEV;
793 822
794 mutex_lock(&ubd_lock); 823 mutex_lock(&ubd_lock);
795 824
796 if(ubd_gendisk[n] == NULL)
797 goto out;
798
799 ubd_dev = &ubd_devs[n]; 825 ubd_dev = &ubd_devs[n];
800 826
801 if(ubd_dev->file == NULL) 827 if(ubd_dev->file == NULL)
@@ -806,9 +832,11 @@ static int ubd_remove(int n, char **error_out)
806 if(ubd_dev->count > 0) 832 if(ubd_dev->count > 0)
807 goto out; 833 goto out;
808 834
809 del_gendisk(ubd_gendisk[n]);
810 put_disk(ubd_gendisk[n]);
811 ubd_gendisk[n] = NULL; 835 ubd_gendisk[n] = NULL;
836 if(disk != NULL){
837 del_gendisk(disk);
838 put_disk(disk);
839 }
812 840
813 if(fake_gendisk[n] != NULL){ 841 if(fake_gendisk[n] != NULL){
814 del_gendisk(fake_gendisk[n]); 842 del_gendisk(fake_gendisk[n]);
@@ -816,10 +844,8 @@ static int ubd_remove(int n, char **error_out)
816 fake_gendisk[n] = NULL; 844 fake_gendisk[n] = NULL;
817 } 845 }
818 846
819 blk_cleanup_queue(ubd_dev->queue);
820 platform_device_unregister(&ubd_dev->pdev);
821 *ubd_dev = ((struct ubd) DEFAULT_UBD);
822 err = 0; 847 err = 0;
848 platform_device_unregister(&ubd_dev->pdev);
823out: 849out:
824 mutex_unlock(&ubd_lock); 850 mutex_unlock(&ubd_lock);
825 return err; 851 return err;
@@ -832,7 +858,7 @@ static struct mc_device ubd_mc = {
832 .list = LIST_HEAD_INIT(ubd_mc.list), 858 .list = LIST_HEAD_INIT(ubd_mc.list),
833 .name = "ubd", 859 .name = "ubd",
834 .config = ubd_config, 860 .config = ubd_config,
835 .get_config = ubd_get_config, 861 .get_config = ubd_get_config,
836 .id = ubd_id, 862 .id = ubd_id,
837 .remove = ubd_remove, 863 .remove = ubd_remove,
838}; 864};
@@ -854,7 +880,7 @@ static int __init ubd0_init(void)
854 ubd_dev->file = "root_fs"; 880 ubd_dev->file = "root_fs";
855 mutex_unlock(&ubd_lock); 881 mutex_unlock(&ubd_lock);
856 882
857 return(0); 883 return 0;
858} 884}
859 885
860__initcall(ubd0_init); 886__initcall(ubd0_init);
@@ -882,14 +908,14 @@ static int __init ubd_init(void)
882 return -1; 908 return -1;
883 } 909 }
884 platform_driver_register(&ubd_driver); 910 platform_driver_register(&ubd_driver);
885 mutex_lock(&ubd_lock); 911 mutex_lock(&ubd_lock);
886 for (i = 0; i < MAX_DEV; i++){ 912 for (i = 0; i < MAX_DEV; i++){
887 err = ubd_add(i, &error); 913 err = ubd_add(i, &error);
888 if(err) 914 if(err)
889 printk(KERN_ERR "Failed to initialize ubd device %d :" 915 printk(KERN_ERR "Failed to initialize ubd device %d :"
890 "%s\n", i, error); 916 "%s\n", i, error);
891 } 917 }
892 mutex_unlock(&ubd_lock); 918 mutex_unlock(&ubd_lock);
893 return 0; 919 return 0;
894} 920}
895 921
@@ -913,7 +939,7 @@ static int __init ubd_driver_init(void){
913 "ubd : Failed to start I/O thread (errno = %d) - " 939 "ubd : Failed to start I/O thread (errno = %d) - "
914 "falling back to synchronous I/O\n", -io_pid); 940 "falling back to synchronous I/O\n", -io_pid);
915 io_pid = -1; 941 io_pid = -1;
916 return(0); 942 return 0;
917 } 943 }
918 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 944 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
919 IRQF_DISABLED, "ubd", ubd_devs); 945 IRQF_DISABLED, "ubd", ubd_devs);
@@ -948,7 +974,7 @@ static int ubd_open(struct inode *inode, struct file *filp)
948 err = -EROFS; 974 err = -EROFS;
949 }*/ 975 }*/
950 out: 976 out:
951 return(err); 977 return err;
952} 978}
953 979
954static int ubd_release(struct inode * inode, struct file * file) 980static int ubd_release(struct inode * inode, struct file * file)
@@ -958,7 +984,7 @@ static int ubd_release(struct inode * inode, struct file * file)
958 984
959 if(--ubd_dev->count == 0) 985 if(--ubd_dev->count == 0)
960 ubd_close_dev(ubd_dev); 986 ubd_close_dev(ubd_dev);
961 return(0); 987 return 0;
962} 988}
963 989
964static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, 990static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
@@ -1014,7 +1040,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
1014 if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) 1040 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
1015 ubd_set_bit(i, (unsigned char *) 1041 ubd_set_bit(i, (unsigned char *)
1016 &req->sector_mask); 1042 &req->sector_mask);
1017 } 1043 }
1018 } 1044 }
1019 else cowify_bitmap(req->offset, req->length, &req->sector_mask, 1045 else cowify_bitmap(req->offset, req->length, &req->sector_mask,
1020 &req->cow_offset, bitmap, bitmap_offset, 1046 &req->cow_offset, bitmap, bitmap_offset,
@@ -1022,26 +1048,16 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
1022} 1048}
1023 1049
1024/* Called with dev->lock held */ 1050/* Called with dev->lock held */
1025static int prepare_request(struct request *req, struct io_thread_req *io_req) 1051static void prepare_request(struct request *req, struct io_thread_req *io_req,
1052 unsigned long long offset, int page_offset,
1053 int len, struct page *page)
1026{ 1054{
1027 struct gendisk *disk = req->rq_disk; 1055 struct gendisk *disk = req->rq_disk;
1028 struct ubd *ubd_dev = disk->private_data; 1056 struct ubd *ubd_dev = disk->private_data;
1029 __u64 offset;
1030 int len;
1031
1032 /* This should be impossible now */
1033 if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){
1034 printk("Write attempted on readonly ubd device %s\n",
1035 disk->disk_name);
1036 end_request(req, 0);
1037 return(1);
1038 }
1039
1040 offset = ((__u64) req->sector) << 9;
1041 len = req->current_nr_sectors << 9;
1042 1057
1043 io_req->req = req; 1058 io_req->req = req;
1044 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd; 1059 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
1060 ubd_dev->fd;
1045 io_req->fds[1] = ubd_dev->fd; 1061 io_req->fds[1] = ubd_dev->fd;
1046 io_req->cow_offset = -1; 1062 io_req->cow_offset = -1;
1047 io_req->offset = offset; 1063 io_req->offset = offset;
@@ -1052,45 +1068,66 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
1052 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; 1068 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
1053 io_req->offsets[0] = 0; 1069 io_req->offsets[0] = 0;
1054 io_req->offsets[1] = ubd_dev->cow.data_offset; 1070 io_req->offsets[1] = ubd_dev->cow.data_offset;
1055 io_req->buffer = req->buffer; 1071 io_req->buffer = page_address(page) + page_offset;
1056 io_req->sectorsize = 1 << 9; 1072 io_req->sectorsize = 1 << 9;
1057 1073
1058 if(ubd_dev->cow.file != NULL) 1074 if(ubd_dev->cow.file != NULL)
1059 cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset, 1075 cowify_req(io_req, ubd_dev->cow.bitmap,
1060 ubd_dev->cow.bitmap_len); 1076 ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len);
1061 1077
1062 return(0);
1063} 1078}
1064 1079
1065/* Called with dev->lock held */ 1080/* Called with dev->lock held */
1066static void do_ubd_request(request_queue_t *q) 1081static void do_ubd_request(request_queue_t *q)
1067{ 1082{
1068 struct io_thread_req io_req; 1083 struct io_thread_req *io_req;
1069 struct request *req; 1084 struct request *req;
1070 int err, n; 1085 int n;
1071 1086
1072 if(thread_fd == -1){ 1087 while(1){
1073 while((req = elv_next_request(q)) != NULL){
1074 err = prepare_request(req, &io_req);
1075 if(!err){
1076 do_io(&io_req);
1077 __ubd_finish(req, io_req.error);
1078 }
1079 }
1080 }
1081 else {
1082 struct ubd *dev = q->queuedata; 1088 struct ubd *dev = q->queuedata;
1083 if(dev->active || (req = elv_next_request(q)) == NULL) 1089 if(dev->end_sg == 0){
1084 return; 1090 struct request *req = elv_next_request(q);
1085 err = prepare_request(req, &io_req); 1091 if(req == NULL)
1086 if(!err){ 1092 return;
1087 dev->active = 1; 1093
1088 n = os_write_file(thread_fd, (char *) &io_req, 1094 dev->request = req;
1089 sizeof(io_req)); 1095 blkdev_dequeue_request(req);
1090 if(n != sizeof(io_req)) 1096 dev->start_sg = 0;
1091 printk("write to io thread failed, " 1097 dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
1092 "errno = %d\n", -n);
1093 } 1098 }
1099
1100 req = dev->request;
1101 while(dev->start_sg < dev->end_sg){
1102 struct scatterlist *sg = &dev->sg[dev->start_sg];
1103
1104 io_req = kmalloc(sizeof(struct io_thread_req),
1105 GFP_ATOMIC);
1106 if(io_req == NULL){
1107 if(list_empty(&dev->restart))
1108 list_add(&dev->restart, &restart);
1109 return;
1110 }
1111 prepare_request(req, io_req,
1112 (unsigned long long) req->sector << 9,
1113 sg->offset, sg->length, sg->page);
1114
1115 n = os_write_file(thread_fd, &io_req,
1116 sizeof(struct io_thread_req *));
1117 if(n != sizeof(struct io_thread_req *)){
1118 if(n != -EAGAIN)
1119 printk("write to io thread failed, "
1120 "errno = %d\n", -n);
1121 else if(list_empty(&dev->restart))
1122 list_add(&dev->restart, &restart);
1123 return;
1124 }
1125
1126 req->sector += sg->length >> 9;
1127 dev->start_sg++;
1128 }
1129 dev->end_sg = 0;
1130 dev->request = NULL;
1094 } 1131 }
1095} 1132}
1096 1133
@@ -1120,21 +1157,21 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
1120 ubd_id.cyls = ubd_dev->size / (128 * 32 * 512); 1157 ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
1121 if(copy_to_user((char __user *) arg, (char *) &ubd_id, 1158 if(copy_to_user((char __user *) arg, (char *) &ubd_id,
1122 sizeof(ubd_id))) 1159 sizeof(ubd_id)))
1123 return(-EFAULT); 1160 return -EFAULT;
1124 return(0); 1161 return 0;
1125 1162
1126 case CDROMVOLREAD: 1163 case CDROMVOLREAD:
1127 if(copy_from_user(&volume, (char __user *) arg, sizeof(volume))) 1164 if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
1128 return(-EFAULT); 1165 return -EFAULT;
1129 volume.channel0 = 255; 1166 volume.channel0 = 255;
1130 volume.channel1 = 255; 1167 volume.channel1 = 255;
1131 volume.channel2 = 255; 1168 volume.channel2 = 255;
1132 volume.channel3 = 255; 1169 volume.channel3 = 255;
1133 if(copy_to_user((char __user *) arg, &volume, sizeof(volume))) 1170 if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
1134 return(-EFAULT); 1171 return -EFAULT;
1135 return(0); 1172 return 0;
1136 } 1173 }
1137 return(-EINVAL); 1174 return -EINVAL;
1138} 1175}
1139 1176
1140static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow) 1177static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
@@ -1176,29 +1213,29 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
1176 if(err < 0){ 1213 if(err < 0){
1177 printk("Failed to get modification time of backing file " 1214 printk("Failed to get modification time of backing file "
1178 "\"%s\", err = %d\n", file, -err); 1215 "\"%s\", err = %d\n", file, -err);
1179 return(err); 1216 return err;
1180 } 1217 }
1181 1218
1182 err = os_file_size(file, &actual); 1219 err = os_file_size(file, &actual);
1183 if(err < 0){ 1220 if(err < 0){
1184 printk("Failed to get size of backing file \"%s\", " 1221 printk("Failed to get size of backing file \"%s\", "
1185 "err = %d\n", file, -err); 1222 "err = %d\n", file, -err);
1186 return(err); 1223 return err;
1187 } 1224 }
1188 1225
1189 if(actual != size){ 1226 if(actual != size){
1190 /*__u64 can be a long on AMD64 and with %lu GCC complains; so 1227 /*__u64 can be a long on AMD64 and with %lu GCC complains; so
1191 * the typecast.*/ 1228 * the typecast.*/
1192 printk("Size mismatch (%llu vs %llu) of COW header vs backing " 1229 printk("Size mismatch (%llu vs %llu) of COW header vs backing "
1193 "file\n", (unsigned long long) size, actual); 1230 "file\n", (unsigned long long) size, actual);
1194 return(-EINVAL); 1231 return -EINVAL;
1195 } 1232 }
1196 if(modtime != mtime){ 1233 if(modtime != mtime){
1197 printk("mtime mismatch (%ld vs %ld) of COW header vs backing " 1234 printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
1198 "file\n", mtime, modtime); 1235 "file\n", mtime, modtime);
1199 return(-EINVAL); 1236 return -EINVAL;
1200 } 1237 }
1201 return(0); 1238 return 0;
1202} 1239}
1203 1240
1204int read_cow_bitmap(int fd, void *buf, int offset, int len) 1241int read_cow_bitmap(int fd, void *buf, int offset, int len)
@@ -1207,13 +1244,13 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len)
1207 1244
1208 err = os_seek_file(fd, offset); 1245 err = os_seek_file(fd, offset);
1209 if(err < 0) 1246 if(err < 0)
1210 return(err); 1247 return err;
1211 1248
1212 err = os_read_file(fd, buf, len); 1249 err = os_read_file(fd, buf, len);
1213 if(err < 0) 1250 if(err < 0)
1214 return(err); 1251 return err;
1215 1252
1216 return(0); 1253 return 0;
1217} 1254}
1218 1255
1219int open_ubd_file(char *file, struct openflags *openflags, int shared, 1256int open_ubd_file(char *file, struct openflags *openflags, int shared,
@@ -1231,14 +1268,14 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
1231 if (fd < 0) { 1268 if (fd < 0) {
1232 if ((fd == -ENOENT) && (create_cow_out != NULL)) 1269 if ((fd == -ENOENT) && (create_cow_out != NULL))
1233 *create_cow_out = 1; 1270 *create_cow_out = 1;
1234 if (!openflags->w || 1271 if (!openflags->w ||
1235 ((fd != -EROFS) && (fd != -EACCES))) 1272 ((fd != -EROFS) && (fd != -EACCES)))
1236 return fd; 1273 return fd;
1237 openflags->w = 0; 1274 openflags->w = 0;
1238 fd = os_open_file(file, *openflags, mode); 1275 fd = os_open_file(file, *openflags, mode);
1239 if (fd < 0) 1276 if (fd < 0)
1240 return fd; 1277 return fd;
1241 } 1278 }
1242 1279
1243 if(shared) 1280 if(shared)
1244 printk("Not locking \"%s\" on the host\n", file); 1281 printk("Not locking \"%s\" on the host\n", file);
@@ -1252,7 +1289,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
1252 1289
1253 /* Successful return case! */ 1290 /* Successful return case! */
1254 if(backing_file_out == NULL) 1291 if(backing_file_out == NULL)
1255 return(fd); 1292 return fd;
1256 1293
1257 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, 1294 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
1258 &size, &sectorsize, &align, bitmap_offset_out); 1295 &size, &sectorsize, &align, bitmap_offset_out);
@@ -1262,7 +1299,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
1262 goto out_close; 1299 goto out_close;
1263 } 1300 }
1264 if(err) 1301 if(err)
1265 return(fd); 1302 return fd;
1266 1303
1267 asked_switch = path_requires_switch(*backing_file_out, backing_file, file); 1304 asked_switch = path_requires_switch(*backing_file_out, backing_file, file);
1268 1305
@@ -1285,7 +1322,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
1285 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, 1322 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
1286 bitmap_len_out, data_offset_out); 1323 bitmap_len_out, data_offset_out);
1287 1324
1288 return fd; 1325 return fd;
1289 out_close: 1326 out_close:
1290 os_close_file(fd); 1327 os_close_file(fd);
1291 return err; 1328 return err;
@@ -1310,10 +1347,10 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
1310 bitmap_offset_out, bitmap_len_out, 1347 bitmap_offset_out, bitmap_len_out,
1311 data_offset_out); 1348 data_offset_out);
1312 if(!err) 1349 if(!err)
1313 return(fd); 1350 return fd;
1314 os_close_file(fd); 1351 os_close_file(fd);
1315 out: 1352 out:
1316 return(err); 1353 return err;
1317} 1354}
1318 1355
1319static int update_bitmap(struct io_thread_req *req) 1356static int update_bitmap(struct io_thread_req *req)
@@ -1321,23 +1358,23 @@ static int update_bitmap(struct io_thread_req *req)
1321 int n; 1358 int n;
1322 1359
1323 if(req->cow_offset == -1) 1360 if(req->cow_offset == -1)
1324 return(0); 1361 return 0;
1325 1362
1326 n = os_seek_file(req->fds[1], req->cow_offset); 1363 n = os_seek_file(req->fds[1], req->cow_offset);
1327 if(n < 0){ 1364 if(n < 0){
1328 printk("do_io - bitmap lseek failed : err = %d\n", -n); 1365 printk("do_io - bitmap lseek failed : err = %d\n", -n);
1329 return(1); 1366 return 1;
1330 } 1367 }
1331 1368
1332 n = os_write_file(req->fds[1], &req->bitmap_words, 1369 n = os_write_file(req->fds[1], &req->bitmap_words,
1333 sizeof(req->bitmap_words)); 1370 sizeof(req->bitmap_words));
1334 if(n != sizeof(req->bitmap_words)){ 1371 if(n != sizeof(req->bitmap_words)){
1335 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, 1372 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
1336 req->fds[1]); 1373 req->fds[1]);
1337 return(1); 1374 return 1;
1338 } 1375 }
1339 1376
1340 return(0); 1377 return 0;
1341} 1378}
1342 1379
1343void do_io(struct io_thread_req *req) 1380void do_io(struct io_thread_req *req)
@@ -1409,13 +1446,14 @@ static int io_count = 0;
1409 1446
1410int io_thread(void *arg) 1447int io_thread(void *arg)
1411{ 1448{
1412 struct io_thread_req req; 1449 struct io_thread_req *req;
1413 int n; 1450 int n;
1414 1451
1415 ignore_sigwinch_sig(); 1452 ignore_sigwinch_sig();
1416 while(1){ 1453 while(1){
1417 n = os_read_file(kernel_fd, &req, sizeof(req)); 1454 n = os_read_file(kernel_fd, &req,
1418 if(n != sizeof(req)){ 1455 sizeof(struct io_thread_req *));
1456 if(n != sizeof(struct io_thread_req *)){
1419 if(n < 0) 1457 if(n < 0)
1420 printk("io_thread - read failed, fd = %d, " 1458 printk("io_thread - read failed, fd = %d, "
1421 "err = %d\n", kernel_fd, -n); 1459 "err = %d\n", kernel_fd, -n);
@@ -1426,9 +1464,10 @@ int io_thread(void *arg)
1426 continue; 1464 continue;
1427 } 1465 }
1428 io_count++; 1466 io_count++;
1429 do_io(&req); 1467 do_io(req);
1430 n = os_write_file(kernel_fd, &req, sizeof(req)); 1468 n = os_write_file(kernel_fd, &req,
1431 if(n != sizeof(req)) 1469 sizeof(struct io_thread_req *));
1470 if(n != sizeof(struct io_thread_req *))
1432 printk("io_thread - write failed, fd = %d, err = %d\n", 1471 printk("io_thread - write failed, fd = %d, err = %d\n",
1433 kernel_fd, -n); 1472 kernel_fd, -n);
1434 } 1473 }
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
index b94d2bc4fe06..4707b3f14c2f 100644
--- a/arch/um/drivers/ubd_user.c
+++ b/arch/um/drivers/ubd_user.c
@@ -16,7 +16,6 @@
16#include <sys/mman.h> 16#include <sys/mman.h>
17#include <sys/param.h> 17#include <sys/param.h>
18#include "asm/types.h" 18#include "asm/types.h"
19#include "user_util.h"
20#include "kern_util.h" 19#include "kern_util.h"
21#include "user.h" 20#include "user.h"
22#include "ubd_user.h" 21#include "ubd_user.h"
@@ -47,8 +46,8 @@ int start_io_thread(unsigned long sp, int *fd_out)
47 pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD, 46 pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
48 NULL); 47 NULL);
49 if(pid < 0){ 48 if(pid < 0){
50 printk("start_io_thread - clone failed : errno = %d\n", errno);
51 err = -errno; 49 err = -errno;
50 printk("start_io_thread - clone failed : errno = %d\n", errno);
52 goto out_close; 51 goto out_close;
53 } 52 }
54 53
@@ -60,16 +59,5 @@ int start_io_thread(unsigned long sp, int *fd_out)
60 kernel_fd = -1; 59 kernel_fd = -1;
61 *fd_out = -1; 60 *fd_out = -1;
62 out: 61 out:
63 return(err); 62 return err;
64} 63}
65
66/*
67 * Overrides for Emacs so that we follow Linus's tabbing style.
68 * Emacs will notice this stuff at the end of the file and automatically
69 * adjust the settings for this buffer only. This must remain at the end
70 * of the file.
71 * ---------------------------------------------------------------------------
72 * Local variables:
73 * c-file-style: "linux"
74 * End:
75 */
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 850221d9b4c9..571c2b3325d5 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -14,7 +14,6 @@
14#include <sys/socket.h> 14#include <sys/socket.h>
15#include "kern_util.h" 15#include "kern_util.h"
16#include "chan_user.h" 16#include "chan_user.h"
17#include "user_util.h"
18#include "user.h" 17#include "user.h"
19#include "os.h" 18#include "os.h"
20#include "xterm.h" 19#include "xterm.h"