Merge branch 'fixes-davem' of master.kernel.org:/pub/scm/linux/kernel/git/linville...
[sfrench/cifs-2.6.git] / arch / um / drivers / vde_user.c
1 /*
2  * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org).
3  * Licensed under the GPL.
4  */
5
6 #include <stddef.h>
7 #include <errno.h>
8 #include <libvdeplug.h>
9 #include "kern_constants.h"
10 #include "net_user.h"
11 #include "um_malloc.h"
12 #include "user.h"
13 #include "vde.h"
14
15 static int vde_user_init(void *data, void *dev)
16 {
17         struct vde_data *pri = data;
18         VDECONN *conn = NULL;
19         int err = -EINVAL;
20
21         pri->dev = dev;
22
23         conn = vde_open(pri->vde_switch, pri->descr, pri->args);
24
25         if (conn == NULL) {
26                 err = -errno;
27                 printk(UM_KERN_ERR "vde_user_init: vde_open failed, "
28                        "errno = %d\n", errno);
29                 return err;
30         }
31
32         printk(UM_KERN_INFO "vde backend - connection opened\n");
33
34         pri->conn = conn;
35
36         return 0;
37 }
38
39 static int vde_user_open(void *data)
40 {
41         struct vde_data *pri = data;
42
43         if (pri->conn != NULL)
44                 return vde_datafd(pri->conn);
45
46         printk(UM_KERN_WARNING "vde_open - we have no VDECONN to open");
47         return -EINVAL;
48 }
49
50 static void vde_remove(void *data)
51 {
52         struct vde_data *pri = data;
53
54         if (pri->conn != NULL) {
55                 printk(UM_KERN_INFO "vde backend - closing connection\n");
56                 vde_close(pri->conn);
57                 pri->conn = NULL;
58                 kfree(pri->args);
59                 pri->args = NULL;
60                 return;
61         }
62
63         printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove");
64 }
65
66 const struct net_user_info vde_user_info = {
67         .init           = vde_user_init,
68         .open           = vde_user_open,
69         .close          = NULL,
70         .remove         = vde_remove,
71         .add_address    = NULL,
72         .delete_address = NULL,
73         .mtu            = ETH_MAX_PACKET,
74         .max_packet     = ETH_MAX_PACKET + ETH_HEADER_OTHER,
75 };
76
77 void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init)
78 {
79         struct vde_open_args *args;
80
81         vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL);
82         if (vpri->args == NULL) {
83                 printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args"
84                        "allocation failed");
85                 return;
86         }
87
88         args = vpri->args;
89
90         args->port = init->port;
91         args->group = init->group;
92         args->mode = init->mode ? init->mode : 0700;
93
94         args->port ?  printk(UM_KERN_INFO "port %d", args->port) :
95                 printk(UM_KERN_INFO "undefined port");
96 }
97
98 int vde_user_read(void *conn, void *buf, int len)
99 {
100         VDECONN *vconn = conn;
101         int rv;
102
103         if (vconn == NULL)
104                 return 0;
105
106         rv = vde_recv(vconn, buf, len, 0);
107         if (rv < 0) {
108                 if (errno == EAGAIN)
109                         return 0;
110                 return -errno;
111         }
112         else if (rv == 0)
113                 return -ENOTCONN;
114
115         return rv;
116 }
117
118 int vde_user_write(void *conn, void *buf, int len)
119 {
120         VDECONN *vconn = conn;
121
122         if (vconn == NULL)
123                 return 0;
124
125         return vde_send(vconn, buf, len, 0);
126 }
127