ia64/xen-unstable

changeset 6419:b402e77aac46

Switch network setup over to xenbus.
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", &sectors,
   9.674 +			    "info", "%u", &binfo,
   9.675 +			    "sector-size", "%lu", &sector_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(&notifier_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)