direct-io.hg
changeset 6404:b402e77aac46
Switch network setup over to xenbus.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Wed Aug 24 22:22:11 2005 +0000 (2005-08-24) |
parents | d4ce28d819a8 |
children | 630feabe7ed6 |
files | linux-2.6-xen-sparse/arch/xen/kernel/reboot.c linux-2.6-xen-sparse/drivers/xen/console/console.c linux-2.6-xen-sparse/drivers/xen/netback/Makefile linux-2.6-xen-sparse/drivers/xen/netback/common.h linux-2.6-xen-sparse/drivers/xen/netback/interface.c linux-2.6-xen-sparse/drivers/xen/netback/netback.c linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c tools/python/xen/xend/XendDomainInfo.py |
line diff
1.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Wed Aug 24 22:21:24 2005 +0000 1.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Wed Aug 24 22:22:11 2005 +0000 1.3 @@ -129,14 +129,6 @@ static int __do_suspend(void *ignore) 1.4 /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */ 1.5 /* XXX SMH: yes it would :-( */ 1.6 1.7 -#ifdef CONFIG_XEN_NETDEV_FRONTEND 1.8 - extern void netif_suspend(void); 1.9 - extern void netif_resume(void); 1.10 -#else 1.11 -#define netif_suspend() do{}while(0) 1.12 -#define netif_resume() do{}while(0) 1.13 -#endif 1.14 - 1.15 #ifdef CONFIG_XEN_USB_FRONTEND 1.16 extern void usbif_resume(); 1.17 #else 1.18 @@ -218,8 +210,6 @@ static int __do_suspend(void *ignore) 1.19 kmem_cache_shrink(pgd_cache); 1.20 #endif 1.21 1.22 - netif_suspend(); 1.23 - 1.24 time_suspend(); 1.25 1.26 #ifdef CONFIG_SMP 1.27 @@ -277,8 +267,6 @@ static int __do_suspend(void *ignore) 1.28 1.29 time_resume(); 1.30 1.31 - netif_resume(); 1.32 - 1.33 usbif_resume(); 1.34 1.35 for_each_cpu_mask(i, prev_present_cpus) {
2.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Wed Aug 24 22:21:24 2005 +0000 2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Wed Aug 24 22:22:11 2005 +0000 2.3 @@ -240,7 +240,11 @@ console_initcall(xen_console_init); 2.4 #endif 2.5 2.6 /*** Useful function for console debugging -- goes straight to Xen. ***/ 2.7 +#ifdef CONFIG_XEN_PRIVILEGED_GUEST 2.8 asmlinkage int xprintk(const char *fmt, ...) 2.9 +#else 2.10 +asmlinkage int xprintk(const char *fmt, ...) 2.11 +#endif 2.12 { 2.13 va_list args; 2.14 int printk_len;
3.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/Makefile Wed Aug 24 22:21:24 2005 +0000 3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/Makefile Wed Aug 24 22:22:11 2005 +0000 3.3 @@ -1,2 +1,2 @@ 3.4 3.5 -obj-y := netback.o control.o interface.o loopback.o 3.6 +obj-y := netback.o xenbus.o interface.o loopback.o
4.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Wed Aug 24 22:21:24 2005 +0000 4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Wed Aug 24 22:22:11 2005 +0000 4.3 @@ -59,6 +59,7 @@ typedef struct netif_st { 4.4 grant_ref_t rx_shmem_ref; 4.5 #endif 4.6 unsigned int evtchn; 4.7 + unsigned int remote_evtchn; 4.8 4.9 /* The shared rings and indexes. */ 4.10 netif_tx_interface_t *tx; 4.11 @@ -93,21 +94,26 @@ typedef struct netif_st { 4.12 struct net_device *dev; 4.13 struct net_device_stats stats; 4.14 4.15 - struct work_struct work; 4.16 + struct work_struct free_work; 4.17 } netif_t; 4.18 4.19 -void netif_create(netif_be_create_t *create); 4.20 +int netif_create(netif_t *netif); 4.21 void netif_destroy(netif_be_destroy_t *destroy); 4.22 void netif_creditlimit(netif_be_creditlimit_t *creditlimit); 4.23 -void netif_connect(netif_be_connect_t *connect); 4.24 int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id); 4.25 void netif_disconnect_complete(netif_t *netif); 4.26 netif_t *netif_find_by_handle(domid_t domid, unsigned int handle); 4.27 + 4.28 +netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]); 4.29 +void free_netif_callback(netif_t *netif); 4.30 +int netif_map(netif_t *netif, unsigned long tx_ring_ref, 4.31 + unsigned long rx_ring_ref, unsigned int evtchn); 4.32 + 4.33 #define netif_get(_b) (atomic_inc(&(_b)->refcnt)) 4.34 #define netif_put(_b) \ 4.35 do { \ 4.36 if ( atomic_dec_and_test(&(_b)->refcnt) ) \ 4.37 - netif_disconnect_complete(_b); \ 4.38 + free_netif_callback(_b); \ 4.39 } while (0) 4.40 4.41 void netif_interface_init(void);
5.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/control.c Wed Aug 24 22:21:24 2005 +0000 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,58 +0,0 @@ 5.4 -/****************************************************************************** 5.5 - * arch/xen/drivers/netif/backend/control.c 5.6 - * 5.7 - * Routines for interfacing with the control plane. 5.8 - * 5.9 - * Copyright (c) 2004, Keir Fraser 5.10 - */ 5.11 - 5.12 -#include "common.h" 5.13 - 5.14 -static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) 5.15 -{ 5.16 - DPRINTK("Received netif backend message, subtype=%d\n", msg->subtype); 5.17 - 5.18 - switch ( msg->subtype ) 5.19 - { 5.20 - case CMSG_NETIF_BE_CREATE: 5.21 - netif_create((netif_be_create_t *)&msg->msg[0]); 5.22 - break; 5.23 - case CMSG_NETIF_BE_DESTROY: 5.24 - netif_destroy((netif_be_destroy_t *)&msg->msg[0]); 5.25 - break; 5.26 - case CMSG_NETIF_BE_CREDITLIMIT: 5.27 - netif_creditlimit((netif_be_creditlimit_t *)&msg->msg[0]); 5.28 - break; 5.29 - case CMSG_NETIF_BE_CONNECT: 5.30 - netif_connect((netif_be_connect_t *)&msg->msg[0]); 5.31 - break; 5.32 - case CMSG_NETIF_BE_DISCONNECT: 5.33 - if ( !netif_disconnect((netif_be_disconnect_t *)&msg->msg[0],msg->id) ) 5.34 - return; /* Sending the response is deferred until later. */ 5.35 - break; 5.36 - default: 5.37 - DPRINTK("Parse error while reading message subtype %d, len %d\n", 5.38 - msg->subtype, msg->length); 5.39 - msg->length = 0; 5.40 - break; 5.41 - } 5.42 - 5.43 - ctrl_if_send_response(msg); 5.44 -} 5.45 - 5.46 -void netif_ctrlif_init(void) 5.47 -{ 5.48 - ctrl_msg_t cmsg; 5.49 - netif_be_driver_status_t st; 5.50 - 5.51 - (void)ctrl_if_register_receiver(CMSG_NETIF_BE, netif_ctrlif_rx, 5.52 - CALLBACK_IN_BLOCKING_CONTEXT); 5.53 - 5.54 - /* Send a driver-UP notification to the domain controller. */ 5.55 - cmsg.type = CMSG_NETIF_BE; 5.56 - cmsg.subtype = CMSG_NETIF_BE_DRIVER_STATUS; 5.57 - cmsg.length = sizeof(netif_be_driver_status_t); 5.58 - st.status = NETIF_DRIVER_STATUS_UP; 5.59 - memcpy(cmsg.msg, &st, sizeof(st)); 5.60 - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 5.61 -}
6.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Aug 24 22:21:24 2005 +0000 6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Aug 24 22:22:11 2005 +0000 6.3 @@ -9,10 +9,6 @@ 6.4 #include "common.h" 6.5 #include <linux/rtnetlink.h> 6.6 6.7 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 6.8 -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) 6.9 -#endif 6.10 - 6.11 #define NETIF_HASHSZ 1024 6.12 #define NETIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(NETIF_HASHSZ-1)) 6.13 6.14 @@ -66,87 +62,20 @@ static int net_close(struct net_device * 6.15 return 0; 6.16 } 6.17 6.18 -static void __netif_disconnect_complete(void *arg) 6.19 +netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]) 6.20 { 6.21 - netif_t *netif = (netif_t *)arg; 6.22 - ctrl_msg_t cmsg; 6.23 - netif_be_disconnect_t disc; 6.24 -#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX) 6.25 - struct gnttab_unmap_grant_ref op; 6.26 -#endif 6.27 - 6.28 - /* 6.29 - * These can't be done in netif_disconnect() because at that point there 6.30 - * may be outstanding requests in the network stack whose asynchronous 6.31 - * responses must still be notified to the remote driver. 6.32 - */ 6.33 - 6.34 -#ifdef CONFIG_XEN_NETDEV_GRANT_TX 6.35 - op.host_addr = netif->tx_shmem_vaddr; 6.36 - op.handle = netif->tx_shmem_handle; 6.37 - op.dev_bus_addr = 0; 6.38 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); 6.39 -#endif 6.40 - 6.41 -#ifdef CONFIG_XEN_NETDEV_GRANT_RX 6.42 - op.host_addr = netif->rx_shmem_vaddr; 6.43 - op.handle = netif->rx_shmem_handle; 6.44 - op.dev_bus_addr = 0; 6.45 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); 6.46 -#endif 6.47 - 6.48 - 6.49 - vfree(netif->tx); /* Frees netif->rx as well. */ 6.50 - 6.51 - /* Construct the deferred response message. */ 6.52 - cmsg.type = CMSG_NETIF_BE; 6.53 - cmsg.subtype = CMSG_NETIF_BE_DISCONNECT; 6.54 - cmsg.id = netif->disconnect_rspid; 6.55 - cmsg.length = sizeof(netif_be_disconnect_t); 6.56 - disc.domid = netif->domid; 6.57 - disc.netif_handle = netif->handle; 6.58 - disc.status = NETIF_BE_STATUS_OKAY; 6.59 - memcpy(cmsg.msg, &disc, sizeof(disc)); 6.60 - 6.61 - /* 6.62 - * Make sure message is constructed /before/ status change, because 6.63 - * after the status change the 'netif' structure could be deallocated at 6.64 - * any time. Also make sure we send the response /after/ status change, 6.65 - * as otherwise a subsequent CONNECT request could spuriously fail if 6.66 - * another CPU doesn't see the status change yet. 6.67 - */ 6.68 - mb(); 6.69 - if ( netif->status != DISCONNECTING ) 6.70 - BUG(); 6.71 - netif->status = DISCONNECTED; 6.72 - mb(); 6.73 - 6.74 - /* Send the successful response. */ 6.75 - ctrl_if_send_response(&cmsg); 6.76 -} 6.77 - 6.78 -void netif_disconnect_complete(netif_t *netif) 6.79 -{ 6.80 - INIT_WORK(&netif->work, __netif_disconnect_complete, (void *)netif); 6.81 - schedule_work(&netif->work); 6.82 -} 6.83 - 6.84 -void netif_create(netif_be_create_t *create) 6.85 -{ 6.86 - int err = 0; 6.87 - domid_t domid = create->domid; 6.88 - unsigned int handle = create->netif_handle; 6.89 + int err = 0, i; 6.90 struct net_device *dev; 6.91 - netif_t **pnetif, *netif; 6.92 - char name[IFNAMSIZ] = {}; 6.93 + netif_t **pnetif, *netif; 6.94 + char name[IFNAMSIZ] = {}; 6.95 6.96 snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); 6.97 dev = alloc_netdev(sizeof(netif_t), name, ether_setup); 6.98 if ( dev == NULL ) 6.99 { 6.100 DPRINTK("Could not create netif: out of memory\n"); 6.101 - create->status = NETIF_BE_STATUS_OUT_OF_MEMORY; 6.102 - return; 6.103 + // create->status = NETIF_BE_STATUS_OUT_OF_MEMORY; 6.104 + return NULL; 6.105 } 6.106 6.107 netif = netdev_priv(dev); 6.108 @@ -167,9 +96,9 @@ void netif_create(netif_be_create_t *cre 6.109 if ( ((*pnetif)->domid == domid) && ((*pnetif)->handle == handle) ) 6.110 { 6.111 DPRINTK("Could not create netif: already exists\n"); 6.112 - create->status = NETIF_BE_STATUS_INTERFACE_EXISTS; 6.113 + // create->status = NETIF_BE_STATUS_INTERFACE_EXISTS; 6.114 free_netdev(dev); 6.115 - return; 6.116 + return NULL; 6.117 } 6.118 pnetif = &(*pnetif)->hash_next; 6.119 } 6.120 @@ -183,9 +112,10 @@ void netif_create(netif_be_create_t *cre 6.121 /* Disable queuing. */ 6.122 dev->tx_queue_len = 0; 6.123 6.124 - if ( (create->be_mac[0] == 0) && (create->be_mac[1] == 0) && 6.125 - (create->be_mac[2] == 0) && (create->be_mac[3] == 0) && 6.126 - (create->be_mac[4] == 0) && (create->be_mac[5] == 0) ) 6.127 + for (i = 0; i < ETH_ALEN; i++) 6.128 + if (be_mac[i] != 0) 6.129 + break; 6.130 + if (i == ETH_ALEN) 6.131 { 6.132 /* 6.133 * Initialise a dummy MAC address. We choose the numerically largest 6.134 @@ -197,11 +127,9 @@ void netif_create(netif_be_create_t *cre 6.135 } 6.136 else 6.137 { 6.138 - memcpy(dev->dev_addr, create->be_mac, ETH_ALEN); 6.139 + memcpy(dev->dev_addr, be_mac, ETH_ALEN); 6.140 } 6.141 6.142 - memcpy(netif->fe_dev_addr, create->mac, ETH_ALEN); 6.143 - 6.144 rtnl_lock(); 6.145 err = register_netdevice(dev); 6.146 rtnl_unlock(); 6.147 @@ -210,16 +138,187 @@ void netif_create(netif_be_create_t *cre 6.148 { 6.149 DPRINTK("Could not register new net device %s: err=%d\n", 6.150 dev->name, err); 6.151 - create->status = NETIF_BE_STATUS_OUT_OF_MEMORY; 6.152 + // create->status = NETIF_BE_STATUS_OUT_OF_MEMORY; 6.153 free_netdev(dev); 6.154 - return; 6.155 + return NULL; 6.156 } 6.157 6.158 netif->hash_next = *pnetif; 6.159 *pnetif = netif; 6.160 6.161 DPRINTK("Successfully created netif\n"); 6.162 - create->status = NETIF_BE_STATUS_OKAY; 6.163 + // create->status = NETIF_BE_STATUS_OKAY; 6.164 + return netif; 6.165 +} 6.166 + 6.167 +static int map_frontend_page(netif_t *netif, unsigned long localaddr, 6.168 + unsigned long tx_ring_ref, unsigned long rx_ring_ref) 6.169 +{ 6.170 +#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX) 6.171 + pgprot_t prot = __pgprot(_KERNPG_TABLE); 6.172 + int err; 6.173 +#endif 6.174 +#if defined(CONFIG_XEN_NETDEV_GRANT_TX) 6.175 + { 6.176 + struct gnttab_map_grant_ref op; 6.177 + 6.178 + /* Map: Use the Grant table reference */ 6.179 + op.host_addr = localaddr; 6.180 + op.flags = GNTMAP_host_map; 6.181 + op.ref = tx_ring_ref; 6.182 + op.dom = netif->domid; 6.183 + 6.184 + BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); 6.185 + if (op.handle < 0) { 6.186 + DPRINTK(" Grant table operation failure !\n"); 6.187 + return op.handle; 6.188 + } 6.189 + 6.190 + netif->tx_shmem_ref = tx_ring_ref; 6.191 + netif->tx_shmem_handle = op.handle; 6.192 + netif->tx_shmem_vaddr = localaddr; 6.193 + } 6.194 +#else 6.195 + err = direct_remap_area_pages(&init_mm, localaddr, 6.196 + tx_ring_ref<<PAGE_SHIFT, PAGE_SIZE, 6.197 + prot, netif->domid); 6.198 + if (err) 6.199 + return err; 6.200 +#endif 6.201 + 6.202 +#if defined(CONFIG_XEN_NETDEV_GRANT_RX) 6.203 + { 6.204 + struct gnttab_map_grant_ref op; 6.205 + 6.206 + /* Map: Use the Grant table reference */ 6.207 + op.host_addr = localaddr + PAGE_SIZE; 6.208 + op.flags = GNTMAP_host_map; 6.209 + op.ref = rx_ring_ref; 6.210 + op.dom = netif->domid; 6.211 + 6.212 + BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); 6.213 + if (op.handle < 0) { 6.214 + DPRINTK(" Grant table operation failure !\n"); 6.215 + return op.handle; 6.216 + } 6.217 + 6.218 + netif->rx_shmem_ref = rx_ring_ref; 6.219 + netif->rx_shmem_handle = op.handle; 6.220 + netif->rx_shmem_vaddr = localaddr + PAGE_SIZE; 6.221 + } 6.222 +#else 6.223 + err = direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE, 6.224 + rx_ring_ref<<PAGE_SHIFT, PAGE_SIZE, 6.225 + prot, netif->domid); 6.226 + if (err) 6.227 + return err; 6.228 +#endif 6.229 + 6.230 + return 0; 6.231 +} 6.232 + 6.233 +static void unmap_frontend_page(netif_t *netif) 6.234 +{ 6.235 +#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX) 6.236 + struct gnttab_unmap_grant_ref op; 6.237 +#endif 6.238 + 6.239 +#ifdef CONFIG_XEN_NETDEV_GRANT_TX 6.240 + op.host_addr = netif->tx_shmem_vaddr; 6.241 + op.handle = netif->tx_shmem_handle; 6.242 + op.dev_bus_addr = 0; 6.243 + BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); 6.244 +#endif 6.245 + 6.246 +#ifdef CONFIG_XEN_NETDEV_GRANT_RX 6.247 + op.host_addr = netif->rx_shmem_vaddr; 6.248 + op.handle = netif->rx_shmem_handle; 6.249 + op.dev_bus_addr = 0; 6.250 + BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); 6.251 +#endif 6.252 +} 6.253 + 6.254 +int netif_map(netif_t *netif, unsigned long tx_ring_ref, 6.255 + unsigned long rx_ring_ref, unsigned int evtchn) 6.256 +{ 6.257 + struct vm_struct *vma; 6.258 + evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain }; 6.259 + int err; 6.260 + 6.261 +#if 0 6.262 + if ( netif->status != DISCONNECTED ) { 6.263 + connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED; 6.264 + return; 6.265 + } 6.266 +#endif 6.267 + 6.268 + if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) { 6.269 + // connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY; 6.270 + return -ENOMEM; 6.271 + } 6.272 + 6.273 + err = map_frontend_page(netif, (unsigned long)vma->addr, tx_ring_ref, 6.274 + rx_ring_ref); 6.275 + if (err) { 6.276 + vfree(vma->addr); 6.277 + return err; 6.278 + } 6.279 + 6.280 + op.u.bind_interdomain.dom1 = DOMID_SELF; 6.281 + op.u.bind_interdomain.dom2 = netif->domid; 6.282 + op.u.bind_interdomain.port1 = 0; 6.283 + op.u.bind_interdomain.port2 = evtchn; 6.284 + err = HYPERVISOR_event_channel_op(&op); 6.285 + if (err) { 6.286 + unmap_frontend_page(netif); 6.287 + vfree(vma->addr); 6.288 + return err; 6.289 + } 6.290 + 6.291 + netif->evtchn = op.u.bind_interdomain.port1; 6.292 + netif->remote_evtchn = evtchn; 6.293 + 6.294 + netif->tx_shmem_frame = tx_ring_ref; 6.295 + netif->rx_shmem_frame = rx_ring_ref; 6.296 + netif->tx = 6.297 + (netif_tx_interface_t *)vma->addr; 6.298 + netif->rx = 6.299 + (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE); 6.300 + netif->tx->resp_prod = netif->rx->resp_prod = 0; 6.301 + netif_get(netif); 6.302 + wmb(); /* Other CPUs see new state before interface is started. */ 6.303 + 6.304 + rtnl_lock(); 6.305 + netif->status = CONNECTED; 6.306 + wmb(); 6.307 + if ( netif_running(netif->dev) ) 6.308 + __netif_up(netif); 6.309 + rtnl_unlock(); 6.310 + 6.311 + // connect->status = NETIF_BE_STATUS_OKAY; 6.312 + return 0; 6.313 +} 6.314 + 6.315 +static void free_netif(void *arg) 6.316 +{ 6.317 + netif_t *netif = (netif_t *)arg; 6.318 + 6.319 + /* 6.320 + * These can't be done in netif_disconnect() because at that point there 6.321 + * may be outstanding requests in the network stack whose asynchronous 6.322 + * responses must still be notified to the remote driver. 6.323 + */ 6.324 + 6.325 + unmap_frontend_page(netif); 6.326 + vfree(netif->tx); /* Frees netif->rx as well. */ 6.327 + 6.328 + netif->status = DISCONNECTED; 6.329 +} 6.330 + 6.331 +void free_netif_callback(netif_t *netif) 6.332 +{ 6.333 + INIT_WORK(&netif->free_work, free_netif, (void *)netif); 6.334 + schedule_work(&netif->free_work); 6.335 } 6.336 6.337 void netif_destroy(netif_be_destroy_t *destroy) 6.338 @@ -286,147 +385,6 @@ void netif_creditlimit(netif_be_creditli 6.339 creditlimit->status = NETIF_BE_STATUS_OKAY; 6.340 } 6.341 6.342 -void netif_connect(netif_be_connect_t *connect) 6.343 -{ 6.344 - domid_t domid = connect->domid; 6.345 - unsigned int handle = connect->netif_handle; 6.346 - unsigned int evtchn = connect->evtchn; 6.347 - unsigned long tx_shmem_frame = connect->tx_shmem_frame; 6.348 - unsigned long rx_shmem_frame = connect->rx_shmem_frame; 6.349 - struct vm_struct *vma; 6.350 -#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX) 6.351 - pgprot_t prot = __pgprot(_KERNPG_TABLE); 6.352 - int error; 6.353 -#endif 6.354 - netif_t *netif; 6.355 - 6.356 - netif = netif_find_by_handle(domid, handle); 6.357 - if ( unlikely(netif == NULL) ) { 6.358 - DPRINTK("netif_connect attempted for non-existent netif (%u,%u)\n", 6.359 - connect->domid, connect->netif_handle); 6.360 - connect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND; 6.361 - return; 6.362 - } 6.363 - 6.364 - if ( netif->status != DISCONNECTED ) { 6.365 - connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED; 6.366 - return; 6.367 - } 6.368 - 6.369 - if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) { 6.370 - connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY; 6.371 - return; 6.372 - } 6.373 - 6.374 - 6.375 -#if defined(CONFIG_XEN_NETDEV_GRANT_TX) 6.376 - { 6.377 - struct gnttab_map_grant_ref op; 6.378 - int tx_ref = connect->tx_shmem_ref; 6.379 - 6.380 - /* Map: Use the Grant table reference */ 6.381 - op.host_addr = VMALLOC_VMADDR(vma->addr); 6.382 - op.flags = GNTMAP_host_map; 6.383 - op.ref = tx_ref; 6.384 - op.dom = domid; 6.385 - 6.386 - if ((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) < 0) || 6.387 - (op.handle < 0)) { 6.388 - DPRINTK(" Grant table operation failure !\n"); 6.389 - connect->status = NETIF_BE_STATUS_MAPPING_ERROR; 6.390 - vfree(vma->addr); 6.391 - return; 6.392 - } 6.393 - 6.394 - netif->tx_shmem_ref = tx_ref; 6.395 - netif->tx_shmem_handle = op.handle; 6.396 - netif->tx_shmem_vaddr = VMALLOC_VMADDR(vma->addr); 6.397 - } 6.398 - 6.399 - 6.400 -#else 6.401 - error = direct_remap_area_pages(&init_mm, 6.402 - VMALLOC_VMADDR(vma->addr), 6.403 - tx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE, 6.404 - prot, domid); 6.405 - if ( error != 0 ) 6.406 - { 6.407 - if ( error == -ENOMEM ) 6.408 - connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY; 6.409 - else if ( error == -EFAULT ) 6.410 - connect->status = NETIF_BE_STATUS_MAPPING_ERROR; 6.411 - else 6.412 - connect->status = NETIF_BE_STATUS_ERROR; 6.413 - vfree(vma->addr); 6.414 - return; 6.415 - } 6.416 -#endif 6.417 - 6.418 - 6.419 -#if defined(CONFIG_XEN_NETDEV_GRANT_RX) 6.420 - { 6.421 - struct gnttab_map_grant_ref op; 6.422 - int rx_ref = connect->rx_shmem_ref; 6.423 - 6.424 - 6.425 - /* Map: Use the Grant table reference */ 6.426 - op.host_addr = VMALLOC_VMADDR(vma->addr) + PAGE_SIZE; 6.427 - op.flags = GNTMAP_host_map; 6.428 - op.ref = rx_ref; 6.429 - op.dom = domid; 6.430 - 6.431 - if ((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) < 0) || 6.432 - (op.handle < 0)) { 6.433 - DPRINTK(" Grant table operation failure !\n"); 6.434 - connect->status = NETIF_BE_STATUS_MAPPING_ERROR; 6.435 - vfree(vma->addr); 6.436 - return; 6.437 - } 6.438 - 6.439 - netif->rx_shmem_ref = rx_ref; 6.440 - netif->rx_shmem_handle = handle; 6.441 - netif->rx_shmem_vaddr = VMALLOC_VMADDR(vma->addr) + PAGE_SIZE; 6.442 - } 6.443 -#else 6.444 - error = direct_remap_area_pages(&init_mm, 6.445 - VMALLOC_VMADDR(vma->addr) + PAGE_SIZE, 6.446 - rx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE, 6.447 - prot, domid); 6.448 - if ( error != 0 ) 6.449 - { 6.450 - if ( error == -ENOMEM ) 6.451 - connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY; 6.452 - else if ( error == -EFAULT ) 6.453 - connect->status = NETIF_BE_STATUS_MAPPING_ERROR; 6.454 - else 6.455 - connect->status = NETIF_BE_STATUS_ERROR; 6.456 - vfree(vma->addr); 6.457 - return; 6.458 - } 6.459 - 6.460 -#endif 6.461 - 6.462 - netif->evtchn = evtchn; 6.463 - netif->tx_shmem_frame = tx_shmem_frame; 6.464 - netif->rx_shmem_frame = rx_shmem_frame; 6.465 - netif->tx = 6.466 - (netif_tx_interface_t *)vma->addr; 6.467 - netif->rx = 6.468 - (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE); 6.469 - netif->tx->resp_prod = netif->rx->resp_prod = 0; 6.470 - netif_get(netif); 6.471 - wmb(); /* Other CPUs see new state before interface is started. */ 6.472 - 6.473 - rtnl_lock(); 6.474 - netif->status = CONNECTED; 6.475 - wmb(); 6.476 - if ( netif_running(netif->dev) ) 6.477 - __netif_up(netif); 6.478 - rtnl_unlock(); 6.479 - 6.480 - connect->status = NETIF_BE_STATUS_OKAY; 6.481 -} 6.482 - 6.483 int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id) 6.484 { 6.485 domid_t domid = disconnect->domid;
7.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Aug 24 22:21:24 2005 +0000 7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Aug 24 22:22:11 2005 +0000 7.3 @@ -987,7 +987,7 @@ static int __init netback_init(void) 7.4 spin_lock_init(&net_schedule_list_lock); 7.5 INIT_LIST_HEAD(&net_schedule_list); 7.6 7.7 - netif_ctrlif_init(); 7.8 + netif_xenbus_init(); 7.9 7.10 (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG), 7.11 netif_be_dbg, SA_SHIRQ,
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Aug 24 22:22:11 2005 +0000 8.3 @@ -0,0 +1,323 @@ 8.4 +/* Xenbus code for netif backend 8.5 + Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au> 8.6 + 8.7 + This program is free software; you can redistribute it and/or modify 8.8 + it under the terms of the GNU General Public License as published by 8.9 + the Free Software Foundation; either version 2 of the License, or 8.10 + (at your option) any later version. 8.11 + 8.12 + This program is distributed in the hope that it will be useful, 8.13 + but WITHOUT ANY WARRANTY; without even the implied warranty of 8.14 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.15 + GNU General Public License for more details. 8.16 + 8.17 + You should have received a copy of the GNU General Public License 8.18 + along with this program; if not, write to the Free Software 8.19 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 8.20 +*/ 8.21 +#include <stdarg.h> 8.22 +#include <linux/module.h> 8.23 +#include <asm-xen/xenbus.h> 8.24 +#include "common.h" 8.25 + 8.26 +struct backend_info 8.27 +{ 8.28 + struct xenbus_device *dev; 8.29 + 8.30 + /* our communications channel */ 8.31 + netif_t *netif; 8.32 + 8.33 + long int frontend_id; 8.34 +#if 0 8.35 + long int pdev; 8.36 + long int readonly; 8.37 +#endif 8.38 + 8.39 + /* watch back end for changes */ 8.40 + struct xenbus_watch backend_watch; 8.41 + 8.42 + /* watch front end for changes */ 8.43 + struct xenbus_watch watch; 8.44 + char *frontpath; 8.45 +}; 8.46 + 8.47 +static int netback_remove(struct xenbus_device *dev) 8.48 +{ 8.49 + struct backend_info *be = dev->data; 8.50 + 8.51 + if (be->watch.node) 8.52 + unregister_xenbus_watch(&be->watch); 8.53 + unregister_xenbus_watch(&be->backend_watch); 8.54 +#if 0 8.55 + if (be->blkif) 8.56 + blkif_put(be->blkif); 8.57 +#endif 8.58 + if (be->frontpath) 8.59 + kfree(be->frontpath); 8.60 + kfree(be); 8.61 + return 0; 8.62 +} 8.63 + 8.64 +/* Front end tells us frame. */ 8.65 +static void frontend_changed(struct xenbus_watch *watch, const char *node) 8.66 +{ 8.67 + unsigned long tx_ring_ref, rx_ring_ref; 8.68 + unsigned int evtchn; 8.69 + int err; 8.70 + struct backend_info *be 8.71 + = container_of(watch, struct backend_info, watch); 8.72 + char *mac, *e, *s; 8.73 + int i; 8.74 + 8.75 + /* If other end is gone, delete ourself. */ 8.76 + if (node && !xenbus_exists(be->frontpath, "")) { 8.77 + xenbus_rm(be->dev->nodename, ""); 8.78 + device_unregister(&be->dev->dev); 8.79 + return; 8.80 + } 8.81 + if (be->netif == NULL || be->netif->status == CONNECTED) 8.82 + return; 8.83 + 8.84 + mac = xenbus_read(be->frontpath, "mac", NULL); 8.85 + if (IS_ERR(mac)) { 8.86 + err = PTR_ERR(mac); 8.87 + xenbus_dev_error(be->dev, err, "reading %s/mac", 8.88 + be->dev->nodename); 8.89 + return; 8.90 + } 8.91 + s = mac; 8.92 + for (i = 0; i < ETH_ALEN; i++) { 8.93 + be->netif->fe_dev_addr[i] = simple_strtoul(s, &e, 16); 8.94 + if (s == e || (e[0] != ':' && e[0] != 0)) { 8.95 + kfree(mac); 8.96 + err = -ENOENT; 8.97 + xenbus_dev_error(be->dev, err, "parsing %s/mac", 8.98 + be->dev->nodename); 8.99 + return; 8.100 + } 8.101 + s = &e[1]; 8.102 + } 8.103 + kfree(mac); 8.104 + 8.105 + err = xenbus_gather(be->frontpath, "tx-ring-ref", "%lu", &tx_ring_ref, 8.106 + "rx-ring-ref", "%lu", &rx_ring_ref, 8.107 + "event-channel", "%u", &evtchn, NULL); 8.108 + if (err) { 8.109 + xenbus_dev_error(be->dev, err, 8.110 + "reading %s/ring-ref and event-channel", 8.111 + be->frontpath); 8.112 + return; 8.113 + } 8.114 + 8.115 +#if 0 8.116 + /* Supply the information about the device the frontend needs */ 8.117 + err = xenbus_transaction_start(be->dev->nodename); 8.118 + if (err) { 8.119 + xenbus_dev_error(be->dev, err, "starting transaction"); 8.120 + return; 8.121 + } 8.122 + 8.123 + err = xenbus_printf(be->dev->nodename, "sectors", "%lu", 8.124 + vbd_size(&be->blkif->vbd)); 8.125 + if (err) { 8.126 + xenbus_dev_error(be->dev, err, "writing %s/sectors", 8.127 + be->dev->nodename); 8.128 + goto abort; 8.129 + } 8.130 + 8.131 + /* FIXME: use a typename instead */ 8.132 + err = xenbus_printf(be->dev->nodename, "info", "%u", 8.133 + vbd_info(&be->blkif->vbd)); 8.134 + if (err) { 8.135 + xenbus_dev_error(be->dev, err, "writing %s/info", 8.136 + be->dev->nodename); 8.137 + goto abort; 8.138 + } 8.139 + err = xenbus_printf(be->dev->nodename, "sector-size", "%lu", 8.140 + vbd_secsize(&be->blkif->vbd)); 8.141 + if (err) { 8.142 + xenbus_dev_error(be->dev, err, "writing %s/sector-size", 8.143 + be->dev->nodename); 8.144 + goto abort; 8.145 + } 8.146 +#endif 8.147 + 8.148 + /* Map the shared frame, irq etc. */ 8.149 + err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn); 8.150 + if (err) { 8.151 + xenbus_dev_error(be->dev, err, 8.152 + "mapping shared-frames %lu/%lu port %u", 8.153 + tx_ring_ref, rx_ring_ref, evtchn); 8.154 + goto abort; 8.155 + } 8.156 + 8.157 +#if 0 8.158 + xenbus_transaction_end(0); 8.159 +#endif 8.160 + xenbus_dev_ok(be->dev); 8.161 + 8.162 + return; 8.163 + 8.164 +abort: 8.165 + // xenbus_transaction_end(1); 8.166 + ; 8.167 +} 8.168 + 8.169 +/* 8.170 + Setup supplies physical device. 8.171 + We provide event channel and device details to front end. 8.172 + Frontend supplies shared frame and event channel. 8.173 + */ 8.174 +static void backend_changed(struct xenbus_watch *watch, const char *node) 8.175 +{ 8.176 + int err; 8.177 + char *p; 8.178 + long int handle, pdev; 8.179 + struct backend_info *be 8.180 + = container_of(watch, struct backend_info, backend_watch); 8.181 + struct xenbus_device *dev = be->dev; 8.182 + u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; 8.183 + 8.184 + err = xenbus_scanf(dev->nodename, "handle", "%li", &handle); 8.185 + if (XENBUS_EXIST_ERR(err)) 8.186 + return; 8.187 + if (err < 0) { 8.188 + xenbus_dev_error(dev, err, "reading handle"); 8.189 + return; 8.190 + } 8.191 + 8.192 +#if 0 8.193 + err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev); 8.194 + if (XENBUS_EXIST_ERR(err)) 8.195 + return; 8.196 + if (err < 0) { 8.197 + xenbus_dev_error(dev, err, "reading physical-device"); 8.198 + return; 8.199 + } 8.200 + if (be->pdev && be->pdev != pdev) { 8.201 + printk(KERN_WARNING 8.202 + "changing physical-device not supported\n"); 8.203 + return; 8.204 + } 8.205 + be->pdev = pdev; 8.206 + 8.207 + /* If there's a read-only node, we're read only. */ 8.208 + p = xenbus_read(dev->nodename, "read-only", NULL); 8.209 + if (!IS_ERR(p)) { 8.210 + be->readonly = 1; 8.211 + kfree(p); 8.212 + } 8.213 +#endif 8.214 + 8.215 + if (be->netif == NULL) { 8.216 + be->netif = alloc_netif(be->frontend_id, handle, be_mac); 8.217 + if (IS_ERR(be->netif)) { 8.218 + err = PTR_ERR(be->netif); 8.219 + be->netif = NULL; 8.220 + xenbus_dev_error(dev, err, "creating interface"); 8.221 + return; 8.222 + } 8.223 + 8.224 +#if 0 8.225 + err = vbd_create(be->netif, handle, be->pdev, be->readonly); 8.226 + if (err) { 8.227 + xenbus_dev_error(dev, err, "creating vbd structure"); 8.228 + return; 8.229 + } 8.230 +#endif 8.231 + 8.232 + /* Pass in NULL node to skip exist test. */ 8.233 + frontend_changed(&be->watch, NULL); 8.234 + } 8.235 +} 8.236 + 8.237 +static int netback_probe(struct xenbus_device *dev, 8.238 + const struct xenbus_device_id *id) 8.239 +{ 8.240 + struct backend_info *be; 8.241 + char *frontend; 8.242 + int err; 8.243 + 8.244 + be = kmalloc(sizeof(*be), GFP_KERNEL); 8.245 + if (!be) { 8.246 + xenbus_dev_error(dev, -ENOMEM, "allocating backend structure"); 8.247 + return -ENOMEM; 8.248 + } 8.249 + memset(be, 0, sizeof(*be)); 8.250 + 8.251 + frontend = NULL; 8.252 + err = xenbus_gather(dev->nodename, 8.253 + "frontend-id", "%li", &be->frontend_id, 8.254 + "frontend", NULL, &frontend, 8.255 + NULL); 8.256 + if (XENBUS_EXIST_ERR(err)) 8.257 + goto free_be; 8.258 + if (err < 0) { 8.259 + xenbus_dev_error(dev, err, 8.260 + "reading %s/frontend or frontend-id", 8.261 + dev->nodename); 8.262 + goto free_be; 8.263 + } 8.264 + if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) { 8.265 + /* If we can't get a frontend path and a frontend-id, 8.266 + * then our bus-id is no longer valid and we need to 8.267 + * destroy the backend device. 8.268 + */ 8.269 + err = -ENOENT; 8.270 + goto free_be; 8.271 + } 8.272 + 8.273 + be->dev = dev; 8.274 + be->backend_watch.node = dev->nodename; 8.275 + be->backend_watch.callback = backend_changed; 8.276 + err = register_xenbus_watch(&be->backend_watch); 8.277 + if (err) { 8.278 + be->backend_watch.node = NULL; 8.279 + xenbus_dev_error(dev, err, "adding backend watch on %s", 8.280 + dev->nodename); 8.281 + goto free_be; 8.282 + } 8.283 + 8.284 + be->frontpath = frontend; 8.285 + be->watch.node = be->frontpath; 8.286 + be->watch.callback = frontend_changed; 8.287 + err = register_xenbus_watch(&be->watch); 8.288 + if (err) { 8.289 + be->watch.node = NULL; 8.290 + xenbus_dev_error(dev, err, 8.291 + "adding frontend watch on %s", 8.292 + be->frontpath); 8.293 + goto free_be; 8.294 + } 8.295 + 8.296 + dev->data = be; 8.297 + 8.298 + backend_changed(&be->backend_watch, dev->nodename); 8.299 + return 0; 8.300 + 8.301 + free_be: 8.302 + if (be->backend_watch.node) 8.303 + unregister_xenbus_watch(&be->backend_watch); 8.304 + if (frontend) 8.305 + kfree(frontend); 8.306 + kfree(be); 8.307 + return err; 8.308 +} 8.309 + 8.310 +static struct xenbus_device_id netback_ids[] = { 8.311 + { "vif" }, 8.312 + { "" } 8.313 +}; 8.314 + 8.315 +static struct xenbus_driver netback = { 8.316 + .name = "vif", 8.317 + .owner = THIS_MODULE, 8.318 + .ids = netback_ids, 8.319 + .probe = netback_probe, 8.320 + .remove = netback_remove, 8.321 +}; 8.322 + 8.323 +void netif_xenbus_init(void) 8.324 +{ 8.325 + xenbus_register_backend(&netback); 8.326 +}
9.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Aug 24 22:21:24 2005 +0000 9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Aug 24 22:22:11 2005 +0000 9.3 @@ -48,7 +48,7 @@ 9.4 #include <asm/io.h> 9.5 #include <asm/uaccess.h> 9.6 #include <asm-xen/evtchn.h> 9.7 -#include <asm-xen/ctrl_if.h> 9.8 +#include <asm-xen/xenbus.h> 9.9 #include <asm-xen/xen-public/io/netif.h> 9.10 #include <asm-xen/balloon.h> 9.11 #include <asm/page.h> 9.12 @@ -112,7 +112,6 @@ static grant_ref_t grant_rx_ref[NETIF_RX 9.13 #endif 9.14 9.15 #if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) 9.16 -static domid_t rdomid = 0; 9.17 #define GRANT_INVALID_REF (0xFFFF) 9.18 #endif 9.19 9.20 @@ -135,10 +134,11 @@ static void xennet_proc_delif(struct net 9.21 9.22 static struct list_head dev_list; 9.23 9.24 +#define netfront_info net_private 9.25 struct net_private 9.26 { 9.27 struct list_head list; 9.28 - struct net_device *dev; 9.29 + struct net_device *netdev; 9.30 9.31 struct net_device_stats stats; 9.32 NETIF_RING_IDX rx_resp_cons, tx_resp_cons; 9.33 @@ -176,6 +176,14 @@ struct net_private 9.34 */ 9.35 struct sk_buff *tx_skbs[NETIF_TX_RING_SIZE+1]; 9.36 struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1]; 9.37 + 9.38 + struct xenbus_device *xbdev; 9.39 + char *backend; 9.40 + int backend_id; 9.41 + struct xenbus_watch watch; 9.42 + int tx_ring_ref; 9.43 + int rx_ring_ref; 9.44 + u8 mac[ETH_ALEN]; 9.45 }; 9.46 9.47 /* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */ 9.48 @@ -187,13 +195,6 @@ struct net_private 9.49 (_list)[0] = (_list)[_id]; \ 9.50 (unsigned short)_id; }) 9.51 9.52 -static char *status_name[] = { 9.53 - [NETIF_INTERFACE_STATUS_CLOSED] = "closed", 9.54 - [NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected", 9.55 - [NETIF_INTERFACE_STATUS_CONNECTED] = "connected", 9.56 - [NETIF_INTERFACE_STATUS_CHANGED] = "changed", 9.57 -}; 9.58 - 9.59 static char *be_state_name[] = { 9.60 [BEST_CLOSED] = "closed", 9.61 [BEST_DISCONNECTED] = "disconnected", 9.62 @@ -219,7 +220,7 @@ static struct net_device *find_dev_by_ha 9.63 list_for_each (ent, &dev_list) { 9.64 np = list_entry(ent, struct net_private, list); 9.65 if (np->handle == handle) 9.66 - return np->dev; 9.67 + return np->netdev; 9.68 } 9.69 return NULL; 9.70 } 9.71 @@ -448,7 +449,7 @@ static void network_alloc_rx_buffers(str 9.72 BUG(); 9.73 } 9.74 grant_rx_ref[id] = ref; 9.75 - gnttab_grant_foreign_transfer_ref(ref, rdomid, 9.76 + gnttab_grant_foreign_transfer_ref(ref, np->backend_id, 9.77 virt_to_mfn(skb->head)); 9.78 np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.gref = ref; 9.79 #endif 9.80 @@ -544,7 +545,7 @@ static int network_start_xmit(struct sk_ 9.81 BUG(); 9.82 } 9.83 mfn = virt_to_mfn(skb->data); 9.84 - gnttab_grant_foreign_access_ref(ref, rdomid, mfn, GNTMAP_readonly); 9.85 + gnttab_grant_foreign_access_ref(ref, np->backend_id, mfn, GNTMAP_readonly); 9.86 tx->addr = ref << PAGE_SHIFT; 9.87 grant_tx_ref[id] = ref; 9.88 #else 9.89 @@ -809,7 +810,7 @@ static int network_close(struct net_devi 9.90 { 9.91 struct net_private *np = netdev_priv(dev); 9.92 np->user_state = UST_CLOSED; 9.93 - netif_stop_queue(np->dev); 9.94 + netif_stop_queue(np->netdev); 9.95 return 0; 9.96 } 9.97 9.98 @@ -821,8 +822,7 @@ static struct net_device_stats *network_ 9.99 } 9.100 9.101 9.102 -static void network_connect(struct net_device *dev, 9.103 - netif_fe_interface_status_t *status) 9.104 +static void network_connect(struct net_device *dev) 9.105 { 9.106 struct net_private *np; 9.107 int i, requeue_idx; 9.108 @@ -890,7 +890,7 @@ static void network_connect(struct net_d 9.109 */ 9.110 np->backend_state = BEST_CONNECTED; 9.111 wmb(); 9.112 - notify_via_evtchn(status->evtchn); 9.113 + notify_via_evtchn(np->evtchn); 9.114 network_tx_buf_gc(dev); 9.115 9.116 if (np->user_state == UST_OPEN) 9.117 @@ -900,108 +900,57 @@ static void network_connect(struct net_d 9.118 spin_unlock_irq(&np->tx_lock); 9.119 } 9.120 9.121 -static void vif_show(struct net_private *np) 9.122 +static void show_device(struct net_private *np) 9.123 { 9.124 #ifdef DEBUG 9.125 - if (np) { 9.126 - IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n", 9.127 - np->handle, 9.128 - be_state_name[np->backend_state], 9.129 - np->user_state ? "open" : "closed", 9.130 - np->evtchn, 9.131 - np->tx, 9.132 - np->rx); 9.133 - } else { 9.134 - IPRINTK("<vif NULL>\n"); 9.135 - } 9.136 + if (np) { 9.137 + IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n", 9.138 + np->handle, 9.139 + be_state_name[np->backend_state], 9.140 + np->user_state ? "open" : "closed", 9.141 + np->evtchn, 9.142 + np->tx, 9.143 + np->rx); 9.144 + } else { 9.145 + IPRINTK("<vif NULL>\n"); 9.146 + } 9.147 #endif 9.148 } 9.149 9.150 -/* Send a connect message to xend to tell it to bring up the interface. */ 9.151 -static void send_interface_connect(struct net_private *np) 9.152 -{ 9.153 - int err; 9.154 - ctrl_msg_t cmsg = { 9.155 - .type = CMSG_NETIF_FE, 9.156 - .subtype = CMSG_NETIF_FE_INTERFACE_CONNECT, 9.157 - .length = sizeof(netif_fe_interface_connect_t), 9.158 - }; 9.159 - netif_fe_interface_connect_t *msg = (void*)cmsg.msg; 9.160 - 9.161 - msg->handle = np->handle; 9.162 - msg->tx_shmem_frame = virt_to_mfn(np->tx); 9.163 -#ifdef CONFIG_XEN_NETDEV_GRANT_TX 9.164 - err = gnttab_grant_foreign_access(rdomid, msg->tx_shmem_frame, 0); 9.165 - if (err < 0) { 9.166 - printk(KERN_ALERT "#### netfront can't grant access to tx_shmem\n"); 9.167 - BUG(); 9.168 - } 9.169 - msg->tx_shmem_ref = err; 9.170 -#endif 9.171 - 9.172 - msg->rx_shmem_frame = virt_to_mfn(np->rx); 9.173 -#ifdef CONFIG_XEN_NETDEV_GRANT_RX 9.174 - err = gnttab_grant_foreign_access(rdomid, msg->rx_shmem_frame, 0); 9.175 - if (err < 0) { 9.176 - printk(KERN_ALERT "#### netfront can't grant access to rx_shmem\n"); 9.177 - BUG(); 9.178 - } 9.179 - msg->rx_shmem_ref = err; 9.180 -#endif 9.181 - 9.182 - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 9.183 -} 9.184 - 9.185 -/* Send a driver status notification to the domain controller. */ 9.186 -static int send_driver_status(int ok) 9.187 -{ 9.188 - int err = 0; 9.189 - ctrl_msg_t cmsg = { 9.190 - .type = CMSG_NETIF_FE, 9.191 - .subtype = CMSG_NETIF_FE_DRIVER_STATUS, 9.192 - .length = sizeof(netif_fe_driver_status_t), 9.193 - }; 9.194 - netif_fe_driver_status_t *msg = (void*)cmsg.msg; 9.195 - 9.196 - msg->status = (ok ? NETIF_DRIVER_STATUS_UP : NETIF_DRIVER_STATUS_DOWN); 9.197 - err = ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 9.198 - return err; 9.199 -} 9.200 - 9.201 /* Stop network device and free tx/rx queues and irq. 9.202 */ 9.203 -static void vif_release(struct net_private *np) 9.204 +static void shutdown_device(struct net_private *np) 9.205 { 9.206 - /* Stop old i/f to prevent errors whilst we rebuild the state. */ 9.207 - spin_lock_irq(&np->tx_lock); 9.208 - spin_lock(&np->rx_lock); 9.209 - netif_stop_queue(np->dev); 9.210 - /* np->backend_state = BEST_DISCONNECTED; */ 9.211 - spin_unlock(&np->rx_lock); 9.212 - spin_unlock_irq(&np->tx_lock); 9.213 + /* Stop old i/f to prevent errors whilst we rebuild the state. */ 9.214 + spin_lock_irq(&np->tx_lock); 9.215 + spin_lock(&np->rx_lock); 9.216 + netif_stop_queue(np->netdev); 9.217 + /* np->backend_state = BEST_DISCONNECTED; */ 9.218 + spin_unlock(&np->rx_lock); 9.219 + spin_unlock_irq(&np->tx_lock); 9.220 9.221 - /* Free resources. */ 9.222 - if ( np->tx != NULL ) 9.223 - { 9.224 - unbind_evtchn_from_irqhandler(np->evtchn, np->dev); 9.225 - free_page((unsigned long)np->tx); 9.226 - free_page((unsigned long)np->rx); 9.227 - np->evtchn = 0; 9.228 - np->tx = NULL; 9.229 - np->rx = NULL; 9.230 - } 9.231 + /* Free resources. */ 9.232 + if (np->tx) { 9.233 + unbind_evtchn_from_irqhandler(np->evtchn, np->netdev); 9.234 + np->evtchn = 0; 9.235 + free_page((unsigned long)np->tx); 9.236 + free_page((unsigned long)np->rx); 9.237 + np->tx = NULL; 9.238 + np->rx = NULL; 9.239 + } 9.240 } 9.241 9.242 /* Release vif resources and close it down completely. 9.243 */ 9.244 static void vif_close(struct net_private *np) 9.245 { 9.246 + BUG(); 9.247 WPRINTK("Unexpected netif-CLOSED message in state %s\n", 9.248 be_state_name[np->backend_state]); 9.249 - vif_release(np); 9.250 + shutdown_device(np); 9.251 np->backend_state = BEST_CLOSED; 9.252 /* todo: take dev down and free. */ 9.253 - vif_show(np); 9.254 + show_device(np); 9.255 } 9.256 9.257 /* Move the vif into disconnected state. 9.258 @@ -1010,6 +959,7 @@ static void vif_close(struct net_private 9.259 */ 9.260 static void vif_disconnect(struct net_private *np) 9.261 { 9.262 + BUG(); 9.263 if(np->tx) free_page((unsigned long)np->tx); 9.264 if(np->rx) free_page((unsigned long)np->rx); 9.265 // Before this np->tx and np->rx had better be null. 9.266 @@ -1018,8 +968,8 @@ static void vif_disconnect(struct net_pr 9.267 memset(np->tx, 0, PAGE_SIZE); 9.268 memset(np->rx, 0, PAGE_SIZE); 9.269 np->backend_state = BEST_DISCONNECTED; 9.270 - send_interface_connect(np); 9.271 - vif_show(np); 9.272 + // send_interface_connect(np); 9.273 + show_device(np); 9.274 } 9.275 9.276 /* Begin interface recovery. 9.277 @@ -1037,11 +987,12 @@ static void vif_disconnect(struct net_pr 9.278 */ 9.279 static void vif_reset(struct net_private *np) 9.280 { 9.281 + BUG(); 9.282 IPRINTK("Attempting to reconnect network interface: handle=%u\n", 9.283 np->handle); 9.284 - vif_release(np); 9.285 + shutdown_device(np); 9.286 vif_disconnect(np); 9.287 - vif_show(np); 9.288 + show_device(np); 9.289 } 9.290 9.291 /* Move the vif into connected state. 9.292 @@ -1049,20 +1000,17 @@ static void vif_reset(struct net_private 9.293 * Binds the irq to the event channel. 9.294 */ 9.295 static void 9.296 -vif_connect(struct net_private *np, netif_fe_interface_status_t *status) 9.297 +connect_device(struct net_private *np, unsigned int evtchn) 9.298 { 9.299 - struct net_device *dev = np->dev; 9.300 - memcpy(dev->dev_addr, status->mac, ETH_ALEN); 9.301 - network_connect(dev, status); 9.302 - np->evtchn = status->evtchn; 9.303 -#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) 9.304 - rdomid = status->domid; 9.305 -#endif 9.306 + struct net_device *dev = np->netdev; 9.307 + memcpy(dev->dev_addr, np->mac, ETH_ALEN); 9.308 + np->evtchn = evtchn; 9.309 + network_connect(dev); 9.310 (void)bind_evtchn_to_irqhandler( 9.311 np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev); 9.312 netctrl_connected_count(); 9.313 (void)send_fake_arp(dev); 9.314 - vif_show(np); 9.315 + show_device(np); 9.316 } 9.317 9.318 static struct ethtool_ops network_ethtool_ops = 9.319 @@ -1076,22 +1024,24 @@ static struct ethtool_ops network_ethtoo 9.320 * @param val return parameter for created device 9.321 * @return 0 on success, error code otherwise 9.322 */ 9.323 -static int create_netdev(int handle, struct net_device **val) 9.324 +static int create_netdev(int handle, struct xenbus_device *dev, 9.325 + struct net_device **val) 9.326 { 9.327 int i, err = 0; 9.328 - struct net_device *dev = NULL; 9.329 + struct net_device *netdev = NULL; 9.330 struct net_private *np = NULL; 9.331 9.332 - if ((dev = alloc_etherdev(sizeof(struct net_private))) == NULL) { 9.333 + if ((netdev = alloc_etherdev(sizeof(struct net_private))) == NULL) { 9.334 printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__); 9.335 err = -ENOMEM; 9.336 goto exit; 9.337 } 9.338 9.339 - np = netdev_priv(dev); 9.340 + np = netdev_priv(netdev); 9.341 np->backend_state = BEST_CLOSED; 9.342 np->user_state = UST_CLOSED; 9.343 np->handle = handle; 9.344 + np->xbdev = dev; 9.345 9.346 spin_lock_init(&np->tx_lock); 9.347 spin_lock_init(&np->rx_lock); 9.348 @@ -1115,149 +1065,53 @@ static int create_netdev(int handle, str 9.349 #endif 9.350 } 9.351 9.352 - dev->open = network_open; 9.353 - dev->hard_start_xmit = network_start_xmit; 9.354 - dev->stop = network_close; 9.355 - dev->get_stats = network_get_stats; 9.356 - dev->poll = netif_poll; 9.357 - dev->weight = 64; 9.358 - dev->features = NETIF_F_IP_CSUM; 9.359 + netdev->open = network_open; 9.360 + netdev->hard_start_xmit = network_start_xmit; 9.361 + netdev->stop = network_close; 9.362 + netdev->get_stats = network_get_stats; 9.363 + netdev->poll = netif_poll; 9.364 + netdev->weight = 64; 9.365 + netdev->features = NETIF_F_IP_CSUM; 9.366 9.367 - SET_ETHTOOL_OPS(dev, &network_ethtool_ops); 9.368 + SET_ETHTOOL_OPS(netdev, &network_ethtool_ops); 9.369 9.370 - if ((err = register_netdev(dev)) != 0) { 9.371 + if ((err = register_netdev(netdev)) != 0) { 9.372 printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err); 9.373 goto exit; 9.374 } 9.375 9.376 - if ((err = xennet_proc_addif(dev)) != 0) { 9.377 - unregister_netdev(dev); 9.378 + if ((err = xennet_proc_addif(netdev)) != 0) { 9.379 + unregister_netdev(netdev); 9.380 goto exit; 9.381 } 9.382 9.383 - np->dev = dev; 9.384 + np->netdev = netdev; 9.385 list_add(&np->list, &dev_list); 9.386 9.387 exit: 9.388 - if ((err != 0) && (dev != NULL)) 9.389 - kfree(dev); 9.390 + if ((err != 0) && (netdev != NULL)) 9.391 + kfree(netdev); 9.392 else if (val != NULL) 9.393 - *val = dev; 9.394 - return err; 9.395 -} 9.396 - 9.397 -/* Get the target interface for a status message. 9.398 - * Creates the interface when it makes sense. 9.399 - * The returned interface may be null when there is no error. 9.400 - * 9.401 - * @param status status message 9.402 - * @param np return parameter for interface state 9.403 - * @return 0 on success, error code otherwise 9.404 - */ 9.405 -static int 9.406 -target_vif(netif_fe_interface_status_t *status, struct net_private **np) 9.407 -{ 9.408 - int err = 0; 9.409 - struct net_device *dev; 9.410 - 9.411 - DPRINTK("> handle=%d\n", status->handle); 9.412 - if (status->handle < 0) { 9.413 - err = -EINVAL; 9.414 - goto exit; 9.415 - } 9.416 - 9.417 - if ((dev = find_dev_by_handle(status->handle)) != NULL) 9.418 - goto exit; 9.419 - 9.420 - if (status->status == NETIF_INTERFACE_STATUS_CLOSED) 9.421 - goto exit; 9.422 - if (status->status == NETIF_INTERFACE_STATUS_CHANGED) 9.423 - goto exit; 9.424 - 9.425 - /* It's a new interface in a good state - create it. */ 9.426 - DPRINTK("> create device...\n"); 9.427 - if ((err = create_netdev(status->handle, &dev)) != 0) 9.428 - goto exit; 9.429 - 9.430 - netctrl.interface_n++; 9.431 - 9.432 - exit: 9.433 - if (np != NULL) 9.434 - *np = ((dev && !err) ? netdev_priv(dev) : NULL); 9.435 - DPRINTK("< err=%d\n", err); 9.436 + *val = netdev; 9.437 return err; 9.438 } 9.439 9.440 -/* Handle an interface status message. */ 9.441 -static void netif_interface_status(netif_fe_interface_status_t *status) 9.442 +static int destroy_netdev(struct net_device *netdev) 9.443 { 9.444 - int err = 0; 9.445 - struct net_private *np = NULL; 9.446 - 9.447 - DPRINTK("> status=%s handle=%d\n", 9.448 - status_name[status->status], status->handle); 9.449 - 9.450 - if ((err = target_vif(status, &np)) != 0) { 9.451 - WPRINTK("Invalid netif: handle=%u\n", status->handle); 9.452 - return; 9.453 - } 9.454 + struct net_private *np = NULL; 9.455 9.456 - if (np == NULL) { 9.457 - DPRINTK("> no vif\n"); 9.458 - return; 9.459 - } 9.460 - 9.461 - switch (status->status) { 9.462 - case NETIF_INTERFACE_STATUS_CLOSED: 9.463 - switch (np->backend_state) { 9.464 - case BEST_CLOSED: 9.465 - case BEST_DISCONNECTED: 9.466 - case BEST_CONNECTED: 9.467 - vif_close(np); 9.468 - break; 9.469 - } 9.470 - break; 9.471 +#ifdef CONFIG_PROC_FS 9.472 + xennet_proc_delif(netdev); 9.473 +#endif 9.474 9.475 - case NETIF_INTERFACE_STATUS_DISCONNECTED: 9.476 - switch (np->backend_state) { 9.477 - case BEST_CLOSED: 9.478 - vif_disconnect(np); 9.479 - break; 9.480 - case BEST_DISCONNECTED: 9.481 - case BEST_CONNECTED: 9.482 - vif_reset(np); 9.483 - break; 9.484 - } 9.485 - break; 9.486 + unregister_netdev(netdev); 9.487 9.488 - case NETIF_INTERFACE_STATUS_CONNECTED: 9.489 - switch (np->backend_state) { 9.490 - case BEST_CLOSED: 9.491 - WPRINTK("Unexpected netif status %s in state %s\n", 9.492 - status_name[status->status], 9.493 - be_state_name[np->backend_state]); 9.494 - vif_disconnect(np); 9.495 - vif_connect(np, status); 9.496 - break; 9.497 - case BEST_DISCONNECTED: 9.498 - vif_connect(np, status); 9.499 - break; 9.500 - } 9.501 - break; 9.502 + np = netdev_priv(netdev); 9.503 + list_del(&np->list); 9.504 9.505 - case NETIF_INTERFACE_STATUS_CHANGED: 9.506 - /* 9.507 - * The domain controller is notifying us that a device has been 9.508 - * added or removed. 9.509 - */ 9.510 - break; 9.511 + kfree(netdev); 9.512 9.513 - default: 9.514 - WPRINTK("Invalid netif status code %d\n", status->status); 9.515 - break; 9.516 - } 9.517 - 9.518 - vif_show(np); 9.519 + return 0; 9.520 } 9.521 9.522 /* 9.523 @@ -1269,115 +1123,6 @@ static void netif_driver_status(netif_fe 9.524 netctrl_connected_count(); 9.525 } 9.526 9.527 -/* Receive handler for control messages. */ 9.528 -static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) 9.529 -{ 9.530 - 9.531 - switch (msg->subtype) { 9.532 - case CMSG_NETIF_FE_INTERFACE_STATUS: 9.533 - netif_interface_status((netif_fe_interface_status_t *) &msg->msg[0]); 9.534 - break; 9.535 - 9.536 - case CMSG_NETIF_FE_DRIVER_STATUS: 9.537 - netif_driver_status((netif_fe_driver_status_t *) &msg->msg[0]); 9.538 - break; 9.539 - 9.540 - default: 9.541 - msg->length = 0; 9.542 - break; 9.543 - } 9.544 - 9.545 - ctrl_if_send_response(msg); 9.546 -} 9.547 - 9.548 - 9.549 -#if 1 9.550 -/* Wait for all interfaces to be connected. 9.551 - * 9.552 - * This works OK, but we'd like to use the probing mode (see below). 9.553 - */ 9.554 -static int probe_interfaces(void) 9.555 -{ 9.556 - int err = 0, conn = 0; 9.557 - int wait_i, wait_n = 100; 9.558 - 9.559 - DPRINTK(">\n"); 9.560 - 9.561 - for (wait_i = 0; wait_i < wait_n; wait_i++) { 9.562 - DPRINTK("> wait_i=%d\n", wait_i); 9.563 - conn = netctrl_connected(); 9.564 - if(conn) break; 9.565 - DPRINTK("> schedule_timeout...\n"); 9.566 - set_current_state(TASK_INTERRUPTIBLE); 9.567 - schedule_timeout(10); 9.568 - } 9.569 - 9.570 - DPRINTK("> wait finished...\n"); 9.571 - if (conn <= 0) { 9.572 - err = netctrl_err(-ENETDOWN); 9.573 - WPRINTK("Failed to connect all virtual interfaces: err=%d\n", err); 9.574 - } 9.575 - 9.576 - DPRINTK("< err=%d\n", err); 9.577 - 9.578 - return err; 9.579 -} 9.580 -#else 9.581 -/* Probe for interfaces until no more are found. 9.582 - * 9.583 - * This is the mode we'd like to use, but at the moment it panics the kernel. 9.584 -*/ 9.585 -static int probe_interfaces(void) 9.586 -{ 9.587 - int err = 0; 9.588 - int wait_i, wait_n = 100; 9.589 - ctrl_msg_t cmsg = { 9.590 - .type = CMSG_NETIF_FE, 9.591 - .subtype = CMSG_NETIF_FE_INTERFACE_STATUS, 9.592 - .length = sizeof(netif_fe_interface_status_t), 9.593 - }; 9.594 - netif_fe_interface_status_t msg = {}; 9.595 - ctrl_msg_t rmsg = {}; 9.596 - netif_fe_interface_status_t *reply = (void*)rmsg.msg; 9.597 - int state = TASK_UNINTERRUPTIBLE; 9.598 - u32 query = -1; 9.599 - 9.600 - DPRINTK(">\n"); 9.601 - 9.602 - netctrl.interface_n = 0; 9.603 - for (wait_i = 0; wait_i < wait_n; wait_i++) { 9.604 - DPRINTK("> wait_i=%d query=%d\n", wait_i, query); 9.605 - msg.handle = query; 9.606 - memcpy(cmsg.msg, &msg, sizeof(msg)); 9.607 - DPRINTK("> set_current_state...\n"); 9.608 - set_current_state(state); 9.609 - DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply); 9.610 - DPRINTK("> sending...\n"); 9.611 - err = ctrl_if_send_message_and_get_response(&cmsg, &rmsg, state); 9.612 - DPRINTK("> err=%d\n", err); 9.613 - if(err) goto exit; 9.614 - DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply); 9.615 - if((int)reply->handle < 0) { 9.616 - // No more interfaces. 9.617 - break; 9.618 - } 9.619 - query = -reply->handle - 2; 9.620 - DPRINTK(">netif_interface_status ...\n"); 9.621 - netif_interface_status(reply); 9.622 - } 9.623 - 9.624 - exit: 9.625 - if (err) { 9.626 - err = netctrl_err(-ENETDOWN); 9.627 - WPRINTK("Connecting virtual network interfaces failed: err=%d\n", err); 9.628 - } 9.629 - 9.630 - DPRINTK("< err=%d\n", err); 9.631 - return err; 9.632 -} 9.633 - 9.634 -#endif 9.635 - 9.636 /* 9.637 * We use this notifier to send out a fake ARP reply to reset switches and 9.638 * router ARP caches when an IP interface is brought up on a VIF. 9.639 @@ -1395,7 +1140,7 @@ inetdev_notify(struct notifier_block *th 9.640 9.641 list_for_each (ent, &dev_list) { 9.642 np = list_entry(ent, struct net_private, list); 9.643 - if (np->dev == dev) 9.644 + if (np->netdev == dev) 9.645 (void)send_fake_arp(dev); 9.646 } 9.647 9.648 @@ -1409,12 +1154,377 @@ static struct notifier_block notifier_in 9.649 .priority = 0 9.650 }; 9.651 9.652 +static struct xenbus_device_id netfront_ids[] = { 9.653 + { "vif" }, 9.654 + { "" } 9.655 +}; 9.656 + 9.657 +static void watch_for_status(struct xenbus_watch *watch, const char *node) 9.658 +{ 9.659 +#if 0 9.660 + struct netfront_info *info; 9.661 + unsigned int binfo; 9.662 + unsigned long sectors, sector_size; 9.663 + int err; 9.664 + 9.665 + info = container_of(watch, struct netfront_info, watch); 9.666 + node += strlen(watch->node); 9.667 + 9.668 + /* FIXME: clean up when error on the other end. */ 9.669 + if (info->connected == BLKIF_STATE_CONNECTED) 9.670 + return; 9.671 + 9.672 + err = xenbus_gather(watch->node, 9.673 + "sectors", "%lu", §ors, 9.674 + "info", "%u", &binfo, 9.675 + "sector-size", "%lu", §or_size, 9.676 + NULL); 9.677 + if (err) { 9.678 + xenbus_dev_error(info->xbdev, err, "reading backend fields"); 9.679 + return; 9.680 + } 9.681 + 9.682 + xlvbd_add(sectors, info->vdevice, binfo, sector_size, info); 9.683 + info->connected = BLKIF_STATE_CONNECTED; 9.684 + 9.685 + blkif_state = BLKIF_STATE_CONNECTED; 9.686 + 9.687 + xenbus_dev_ok(info->xbdev); 9.688 + 9.689 + /* Kick pending requests. */ 9.690 + spin_lock_irq(&blkif_io_lock); 9.691 + kick_pending_request_queues(info); 9.692 + spin_unlock_irq(&blkif_io_lock); 9.693 +#endif 9.694 +} 9.695 + 9.696 +static int setup_device(struct xenbus_device *dev, struct netfront_info *info) 9.697 +{ 9.698 + evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound }; 9.699 + int err; 9.700 + 9.701 +#ifdef CONFIG_XEN_NETDEV_GRANT_TX 9.702 + info->tx_ring_ref = GRANT_INVALID_REF; 9.703 +#endif 9.704 +#ifdef CONFIG_XEN_NETDEV_GRANT_RX 9.705 + info->rx_ring_ref = GRANT_INVALID_REF; 9.706 +#endif 9.707 + 9.708 + info->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL); 9.709 + if (info->tx == 0) { 9.710 + err = -ENOMEM; 9.711 + xenbus_dev_error(dev, err, "allocating tx ring page"); 9.712 + goto out; 9.713 + } 9.714 + info->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL); 9.715 + if (info->rx == 0) { 9.716 + err = -ENOMEM; 9.717 + xenbus_dev_error(dev, err, "allocating rx ring page"); 9.718 + goto out; 9.719 + } 9.720 + memset(info->tx, 0, PAGE_SIZE); 9.721 + memset(info->rx, 0, PAGE_SIZE); 9.722 + info->backend_state = BEST_DISCONNECTED; 9.723 + 9.724 +#ifdef CONFIG_XEN_NETDEV_GRANT_TX 9.725 + err = gnttab_grant_foreign_access(info->backend_id, 9.726 + virt_to_mfn(info->tx), 0); 9.727 + if (err < 0) { 9.728 + xenbus_dev_error(dev, err, "granting access to tx ring page"); 9.729 + goto out; 9.730 + } 9.731 + info->tx_ring_ref = err; 9.732 +#else 9.733 + info->tx_ring_ref = virt_to_mfn(info->tx); 9.734 +#endif 9.735 + 9.736 +#ifdef CONFIG_XEN_NETDEV_GRANT_RX 9.737 + err = gnttab_grant_foreign_access(info->backend_id, 9.738 + virt_to_mfn(info->rx), 0); 9.739 + if (err < 0) { 9.740 + xenbus_dev_error(dev, err, "granting access to rx ring page"); 9.741 + goto out; 9.742 + } 9.743 + info->rx_ring_ref = err; 9.744 +#else 9.745 + info->rx_ring_ref = virt_to_mfn(info->rx); 9.746 +#endif 9.747 + 9.748 + op.u.alloc_unbound.dom = info->backend_id; 9.749 + err = HYPERVISOR_event_channel_op(&op); 9.750 + if (err) { 9.751 + xenbus_dev_error(dev, err, "allocating event channel"); 9.752 + goto out; 9.753 + } 9.754 + connect_device(info, op.u.alloc_unbound.port); 9.755 + return 0; 9.756 + 9.757 + out: 9.758 + if (info->tx) 9.759 + free_page((unsigned long)info->tx); 9.760 + info->tx = 0; 9.761 + if (info->rx) 9.762 + free_page((unsigned long)info->rx); 9.763 + info->rx = 0; 9.764 +#ifdef CONFIG_XEN_NETDEV_GRANT_TX 9.765 + if (info->tx_ring_ref != GRANT_INVALID_REF) 9.766 + gnttab_end_foreign_access(info->tx_ring_ref, 0); 9.767 + info->tx_ring_ref = GRANT_INVALID_REF; 9.768 +#endif 9.769 +#ifdef CONFIG_XEN_NETDEV_GRANT_RX 9.770 + if (info->rx_ring_ref != GRANT_INVALID_REF) 9.771 + gnttab_end_foreign_access(info->rx_ring_ref, 0); 9.772 + info->rx_ring_ref = GRANT_INVALID_REF; 9.773 +#endif 9.774 + return err; 9.775 +} 9.776 + 9.777 +/* Common code used when first setting up, and when resuming. */ 9.778 +static int talk_to_backend(struct xenbus_device *dev, 9.779 + struct netfront_info *info) 9.780 +{ 9.781 + char *backend, *mac, *e, *s; 9.782 + const char *message; 9.783 + int err, i; 9.784 + 9.785 + backend = NULL; 9.786 + err = xenbus_gather(dev->nodename, 9.787 + "backend-id", "%i", &info->backend_id, 9.788 + "backend", NULL, &backend, 9.789 + NULL); 9.790 + if (XENBUS_EXIST_ERR(err)) 9.791 + goto out; 9.792 + if (backend && strlen(backend) == 0) { 9.793 + err = -ENOENT; 9.794 + goto out; 9.795 + } 9.796 + if (err < 0) { 9.797 + xenbus_dev_error(dev, err, "reading %s/backend or backend-id", 9.798 + dev->nodename); 9.799 + goto out; 9.800 + } 9.801 + 9.802 + mac = xenbus_read(dev->nodename, "mac", NULL); 9.803 + if (IS_ERR(mac)) { 9.804 + err = PTR_ERR(mac); 9.805 + xenbus_dev_error(dev, err, "reading %s/mac", 9.806 + dev->nodename); 9.807 + goto out; 9.808 + } 9.809 + s = mac; 9.810 + for (i = 0; i < ETH_ALEN; i++) { 9.811 + info->mac[i] = simple_strtoul(s, &e, 16); 9.812 + if (s == e || (e[0] != ':' && e[0] != 0)) { 9.813 + kfree(mac); 9.814 + err = -ENOENT; 9.815 + xenbus_dev_error(dev, err, "parsing %s/mac", 9.816 + dev->nodename); 9.817 + goto out; 9.818 + } 9.819 + s = &e[1]; 9.820 + } 9.821 + kfree(mac); 9.822 + 9.823 + /* Create shared ring, alloc event channel. */ 9.824 + err = setup_device(dev, info); 9.825 + if (err) { 9.826 + xenbus_dev_error(dev, err, "setting up ring"); 9.827 + goto out; 9.828 + } 9.829 + 9.830 + err = xenbus_transaction_start(dev->nodename); 9.831 + if (err) { 9.832 + xenbus_dev_error(dev, err, "starting transaction"); 9.833 + goto destroy_ring; 9.834 + } 9.835 + 9.836 + err = xenbus_printf(dev->nodename, "tx-ring-ref","%u", 9.837 + info->tx_ring_ref); 9.838 + if (err) { 9.839 + message = "writing tx ring-ref"; 9.840 + goto abort_transaction; 9.841 + } 9.842 + err = xenbus_printf(dev->nodename, "rx-ring-ref","%u", 9.843 + info->rx_ring_ref); 9.844 + if (err) { 9.845 + message = "writing rx ring-ref"; 9.846 + goto abort_transaction; 9.847 + } 9.848 + err = xenbus_printf(dev->nodename, 9.849 + "event-channel", "%u", info->evtchn); 9.850 + if (err) { 9.851 + message = "writing event-channel"; 9.852 + goto abort_transaction; 9.853 + } 9.854 + 9.855 + info->backend = backend; 9.856 + backend = NULL; 9.857 + 9.858 + info->watch.node = info->backend; 9.859 + info->watch.callback = watch_for_status; 9.860 + err = register_xenbus_watch(&info->watch); 9.861 + if (err) { 9.862 + message = "registering watch on backend"; 9.863 + goto abort_transaction; 9.864 + } 9.865 + 9.866 + err = xenbus_transaction_end(0); 9.867 + if (err) { 9.868 + xenbus_dev_error(dev, err, "completing transaction"); 9.869 + goto destroy_ring; 9.870 + } 9.871 + 9.872 + out: 9.873 + if (backend) 9.874 + kfree(backend); 9.875 + return err; 9.876 + 9.877 + abort_transaction: 9.878 + xenbus_transaction_end(1); 9.879 + /* Have to do this *outside* transaction. */ 9.880 + xenbus_dev_error(dev, err, "%s", message); 9.881 + destroy_ring: 9.882 + shutdown_device(info); 9.883 + goto out; 9.884 +} 9.885 + 9.886 +/* Setup supplies the backend dir, virtual device. 9.887 + 9.888 + We place an event channel and shared frame entries. 9.889 + We watch backend to wait if it's ok. */ 9.890 +static int netfront_probe(struct xenbus_device *dev, 9.891 + const struct xenbus_device_id *id) 9.892 +{ 9.893 + int err; 9.894 + struct net_device *netdev; 9.895 + unsigned int handle; 9.896 + 9.897 + printk("netfront_probe %p\n", dev); 9.898 + err = xenbus_scanf(dev->nodename, "handle", "%u", &handle); 9.899 + if (XENBUS_EXIST_ERR(err)) 9.900 + return err; 9.901 + if (err < 0) { 9.902 + xenbus_dev_error(dev, err, "reading handle"); 9.903 + return err; 9.904 + } 9.905 + 9.906 + printk("netfront_probe handle %d\n", handle); 9.907 + netdev = find_dev_by_handle(handle); 9.908 + printk("netfront_probe found netdev %p\n", netdev); 9.909 + if (netdev) 9.910 + return 0; 9.911 + 9.912 + err = create_netdev(handle, dev, &netdev); 9.913 + if (err) { 9.914 + xenbus_dev_error(dev, err, "creating netdev"); 9.915 + return err; 9.916 + } 9.917 + 9.918 + printk("netfront_probe netdev %p\n", netdev); 9.919 + err = talk_to_backend(dev, netdev_priv(netdev)); 9.920 + if (err) { 9.921 + destroy_netdev(netdev); 9.922 + return err; 9.923 + } 9.924 + 9.925 +#if 0 9.926 + /* Call once in case entries already there. */ 9.927 + watch_for_status(&info->watch, info->watch.node); 9.928 +#endif 9.929 + return 0; 9.930 +} 9.931 + 9.932 +static int netfront_remove(struct xenbus_device *dev) 9.933 +{ 9.934 + struct netfront_info *info = dev->data; 9.935 + 9.936 +#if 0 9.937 + if (info->backend) 9.938 + unregister_xenbus_watch(&info->watch); 9.939 + 9.940 + if (info->mi) 9.941 + xlvbd_del(info); 9.942 + 9.943 + blkif_free(info); 9.944 + 9.945 + kfree(info->backend); 9.946 +#endif 9.947 + kfree(info); 9.948 + 9.949 + return 0; 9.950 +} 9.951 + 9.952 +static int netfront_suspend(struct xenbus_device *dev) 9.953 +{ 9.954 + struct net_private *np = dev->data; 9.955 + /* Avoid having tx/rx stuff happen until we're ready. */ 9.956 + unbind_evtchn_from_irqhandler(np->evtchn, np->netdev); 9.957 + return 0; 9.958 +} 9.959 + 9.960 +static int netfront_resume(struct xenbus_device *dev) 9.961 +{ 9.962 + struct net_private *np = dev->data; 9.963 + /* 9.964 + * Connect regardless of whether IFF_UP flag set. 9.965 + * Stop bad things from happening until we're back up. 9.966 + */ 9.967 + np->backend_state = BEST_DISCONNECTED; 9.968 + memset(np->tx, 0, PAGE_SIZE); 9.969 + memset(np->rx, 0, PAGE_SIZE); 9.970 + 9.971 + // send_interface_connect(np); 9.972 + return 0; 9.973 +} 9.974 + 9.975 +static struct xenbus_driver netfront = { 9.976 + .name = "vif", 9.977 + .owner = THIS_MODULE, 9.978 + .ids = netfront_ids, 9.979 + .probe = netfront_probe, 9.980 + .remove = netfront_remove, 9.981 + .resume = netfront_resume, 9.982 + .suspend = netfront_suspend, 9.983 +}; 9.984 + 9.985 +static void __init init_net_xenbus(void) 9.986 +{ 9.987 + xenbus_register_device(&netfront); 9.988 +} 9.989 + 9.990 +static int wait_for_netif(void) 9.991 +{ 9.992 + int err = 0, conn = 0; 9.993 + int i; 9.994 + 9.995 + /* 9.996 + * We should figure out how many and which devices we need to 9.997 + * proceed and only wait for those. For now, continue once the 9.998 + * first device is around. 9.999 + */ 9.1000 + for ( i=0; i < 10*HZ; i++ ) 9.1001 + { 9.1002 + conn = netctrl_connected(); 9.1003 + if (conn) 9.1004 + break; 9.1005 + set_current_state(TASK_INTERRUPTIBLE); 9.1006 + schedule_timeout(1); 9.1007 + } 9.1008 + 9.1009 + if (conn <= 0) { 9.1010 + err = netctrl_err(-ENETDOWN); 9.1011 + WPRINTK("Timeout connecting to device!\n"); 9.1012 + } 9.1013 + return err; 9.1014 +} 9.1015 + 9.1016 static int __init netif_init(void) 9.1017 { 9.1018 int err = 0; 9.1019 9.1020 if (xen_start_info.flags & SIF_INITDOMAIN) 9.1021 return 0; 9.1022 + 9.1023 #ifdef CONFIG_XEN_NETDEV_GRANT_TX 9.1024 /* A grant for every ring slot */ 9.1025 if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE, 9.1026 @@ -1438,17 +1548,15 @@ static int __init netif_init(void) 9.1027 return err; 9.1028 9.1029 IPRINTK("Initialising virtual ethernet driver.\n"); 9.1030 + 9.1031 INIT_LIST_HEAD(&dev_list); 9.1032 (void)register_inetaddr_notifier(¬ifier_inetdev); 9.1033 netctrl_init(); 9.1034 - (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx, 9.1035 - CALLBACK_IN_BLOCKING_CONTEXT); 9.1036 - send_driver_status(1); 9.1037 - err = probe_interfaces(); 9.1038 - if (err) 9.1039 - ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx); 9.1040 + 9.1041 + init_net_xenbus(); 9.1042 9.1043 - DPRINTK("< err=%d\n", err); 9.1044 + wait_for_netif(); 9.1045 + 9.1046 return err; 9.1047 } 9.1048 9.1049 @@ -1462,47 +1570,6 @@ static void netif_exit(void) 9.1050 #endif 9.1051 } 9.1052 9.1053 -static void vif_suspend(struct net_private *np) 9.1054 -{ 9.1055 - /* Avoid having tx/rx stuff happen until we're ready. */ 9.1056 - unbind_evtchn_from_irqhandler(np->evtchn, np->dev); 9.1057 -} 9.1058 - 9.1059 -static void vif_resume(struct net_private *np) 9.1060 -{ 9.1061 - /* 9.1062 - * Connect regardless of whether IFF_UP flag set. 9.1063 - * Stop bad things from happening until we're back up. 9.1064 - */ 9.1065 - np->backend_state = BEST_DISCONNECTED; 9.1066 - memset(np->tx, 0, PAGE_SIZE); 9.1067 - memset(np->rx, 0, PAGE_SIZE); 9.1068 - 9.1069 - send_interface_connect(np); 9.1070 -} 9.1071 - 9.1072 -void netif_suspend(void) 9.1073 -{ 9.1074 - struct list_head *ent; 9.1075 - struct net_private *np; 9.1076 - 9.1077 - list_for_each (ent, &dev_list) { 9.1078 - np = list_entry(ent, struct net_private, list); 9.1079 - vif_suspend(np); 9.1080 - } 9.1081 -} 9.1082 - 9.1083 -void netif_resume(void) 9.1084 -{ 9.1085 - struct list_head *ent; 9.1086 - struct net_private *np; 9.1087 - 9.1088 - list_for_each (ent, &dev_list) { 9.1089 - np = list_entry(ent, struct net_private, list); 9.1090 - vif_resume(np); 9.1091 - } 9.1092 -} 9.1093 - 9.1094 #ifdef CONFIG_PROC_FS 9.1095 9.1096 #define TARGET_MIN 0UL
10.1 --- a/tools/python/xen/xend/XendDomainInfo.py Wed Aug 24 22:21:24 2005 +0000 10.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Aug 24 22:22:11 2005 +0000 10.3 @@ -265,6 +265,8 @@ class XendDomainInfo: 10.4 self.info = None 10.5 self.blkif_backend = False 10.6 self.netif_backend = False 10.7 + self.netif_idx = 0 10.8 + 10.9 #todo: state: running, suspended 10.10 self.state = STATE_VM_OK 10.11 self.state_updated = threading.Condition() 10.12 @@ -400,8 +402,7 @@ class XendDomainInfo: 10.13 db['virtual-device'] = "%i" % devnum 10.14 #db['backend'] = sxp.child_value(devconfig, 'backend', '0') 10.15 db['backend'] = backdb.getPath() 10.16 - db['backend-id'] = "%i" % int(sxp.child_value(devconfig, 10.17 - 'backend', '0')) 10.18 + db['backend-id'] = "%i" % backdom.id 10.19 10.20 backdb['frontend'] = db.getPath() 10.21 (type, params) = string.split(sxp.child_value(devconfig, 'uname'), ':', 1) 10.22 @@ -417,6 +418,37 @@ class XendDomainInfo: 10.23 db.saveDB(save=True) 10.24 10.25 return 10.26 + 10.27 + if type == 'vif': 10.28 + backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0')) 10.29 + 10.30 + log.error(devconfig) 10.31 + 10.32 + devnum = self.netif_idx 10.33 + self.netif_idx += 1 10.34 + 10.35 + # create backend db 10.36 + backdb = backdom.db.addChild("/backend/%s/%s/%d" % 10.37 + (type, self.uuid, devnum)) 10.38 + 10.39 + # create frontend db 10.40 + db = self.db.addChild("/device/%s/%d" % (type, devnum)) 10.41 + 10.42 + backdb['frontend'] = db.getPath() 10.43 + backdb['frontend-id'] = "%i" % self.id 10.44 + backdb['handle'] = "%i" % devnum 10.45 + backdb.saveDB(save=True) 10.46 + 10.47 + db['backend'] = backdb.getPath() 10.48 + db['backend-id'] = "%i" % backdom.id 10.49 + db['handle'] = "%i" % devnum 10.50 + log.error(sxp.child_value(devconfig, 'mac')) 10.51 + db['mac'] = sxp.child_value(devconfig, 'mac') 10.52 + 10.53 + db.saveDB(save=True) 10.54 + 10.55 + return 10.56 + 10.57 ctrl = self.findDeviceController(type) 10.58 return ctrl.createDevice(devconfig, recreate=self.recreate, 10.59 change=change)