WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Switch network setup over to xenbus.

# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID b402e77aac4674f938591dd718fb1259bb9e2100
# Parent  d4ce28d819a8297ba3c82f3053c24ee125476dd5
Switch network setup over to xenbus.
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r d4ce28d819a8 -r b402e77aac46 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Wed Aug 24 22:21:24 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Wed Aug 24 22:22:11 2005
@@ -128,14 +128,6 @@
 
     /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
        /* XXX SMH: yes it would :-( */ 
-
-#ifdef CONFIG_XEN_NETDEV_FRONTEND
-    extern void netif_suspend(void);
-    extern void netif_resume(void);  
-#else
-#define netif_suspend() do{}while(0)
-#define netif_resume()  do{}while(0)
-#endif
 
 #ifdef CONFIG_XEN_USB_FRONTEND
     extern void usbif_resume();
@@ -218,8 +210,6 @@
     kmem_cache_shrink(pgd_cache);
 #endif
 
-    netif_suspend();
-
     time_suspend();
 
 #ifdef CONFIG_SMP
@@ -276,8 +266,6 @@
 #endif
 
     time_resume();
-
-    netif_resume();
 
     usbif_resume();
 
diff -r d4ce28d819a8 -r b402e77aac46 
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c        Wed Aug 24 
22:21:24 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c        Wed Aug 24 
22:22:11 2005
@@ -240,7 +240,11 @@
 #endif
 
 /*** Useful function for console debugging -- goes straight to Xen. ***/
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
 asmlinkage int xprintk(const char *fmt, ...)
+#else
+asmlinkage int xprintk(const char *fmt, ...)
+#endif
 {
     va_list args;
     int printk_len;
diff -r d4ce28d819a8 -r b402e77aac46 
linux-2.6-xen-sparse/drivers/xen/netback/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/netback/Makefile Wed Aug 24 22:21:24 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/Makefile Wed Aug 24 22:22:11 2005
@@ -1,2 +1,2 @@
 
-obj-y  := netback.o control.o interface.o loopback.o
+obj-y  := netback.o xenbus.o interface.o loopback.o
diff -r d4ce28d819a8 -r b402e77aac46 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Wed Aug 24 22:21:24 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Wed Aug 24 22:22:11 2005
@@ -59,6 +59,7 @@
     grant_ref_t      rx_shmem_ref; 
 #endif
     unsigned int     evtchn;
+    unsigned int     remote_evtchn;
 
     /* The shared rings and indexes. */
     netif_tx_interface_t *tx;
@@ -93,21 +94,26 @@
     struct net_device *dev;
     struct net_device_stats stats;
 
-    struct work_struct work;
+    struct work_struct free_work;
 } netif_t;
 
-void netif_create(netif_be_create_t *create);
+int netif_create(netif_t *netif);
 void netif_destroy(netif_be_destroy_t *destroy);
 void netif_creditlimit(netif_be_creditlimit_t *creditlimit);
-void netif_connect(netif_be_connect_t *connect);
 int  netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id);
 void netif_disconnect_complete(netif_t *netif);
 netif_t *netif_find_by_handle(domid_t domid, unsigned int handle);
+
+netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
+void free_netif_callback(netif_t *netif);
+int netif_map(netif_t *netif, unsigned long tx_ring_ref,
+             unsigned long rx_ring_ref, unsigned int evtchn);
+
 #define netif_get(_b) (atomic_inc(&(_b)->refcnt))
 #define netif_put(_b)                             \
     do {                                          \
         if ( atomic_dec_and_test(&(_b)->refcnt) ) \
-            netif_disconnect_complete(_b);        \
+            free_netif_callback(_b);              \
     } while (0)
 
 void netif_interface_init(void);
diff -r d4ce28d819a8 -r b402e77aac46 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Wed Aug 24 
22:21:24 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Wed Aug 24 
22:22:11 2005
@@ -9,10 +9,6 @@
 #include "common.h"
 #include <linux/rtnetlink.h>
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#endif
-
 #define NETIF_HASHSZ 1024
 #define NETIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(NETIF_HASHSZ-1))
 
@@ -66,87 +62,20 @@
     return 0;
 }
 
-static void __netif_disconnect_complete(void *arg)
-{
-    netif_t              *netif = (netif_t *)arg;
-    ctrl_msg_t            cmsg;
-    netif_be_disconnect_t disc;
-#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX)
-    struct gnttab_unmap_grant_ref op;
-#endif
-
-    /*
-     * These can't be done in netif_disconnect() because at that point there
-     * may be outstanding requests in the network stack whose asynchronous
-     * responses must still be notified to the remote driver.
-     */
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    op.host_addr    = netif->tx_shmem_vaddr;
-    op.handle       = netif->tx_shmem_handle;
-    op.dev_bus_addr = 0;
-    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    op.host_addr    = netif->rx_shmem_vaddr;
-    op.handle       = netif->rx_shmem_handle;
-    op.dev_bus_addr = 0;
-    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-#endif
-
-
-    vfree(netif->tx); /* Frees netif->rx as well. */
-
-    /* Construct the deferred response message. */
-    cmsg.type         = CMSG_NETIF_BE;
-    cmsg.subtype      = CMSG_NETIF_BE_DISCONNECT;
-    cmsg.id           = netif->disconnect_rspid;
-    cmsg.length       = sizeof(netif_be_disconnect_t);
-    disc.domid        = netif->domid;
-    disc.netif_handle = netif->handle;
-    disc.status       = NETIF_BE_STATUS_OKAY;
-    memcpy(cmsg.msg, &disc, sizeof(disc));
-
-    /*
-     * Make sure message is constructed /before/ status change, because
-     * after the status change the 'netif' structure could be deallocated at
-     * any time. Also make sure we send the response /after/ status change,
-     * as otherwise a subsequent CONNECT request could spuriously fail if
-     * another CPU doesn't see the status change yet.
-     */
-    mb();
-    if ( netif->status != DISCONNECTING )
-        BUG();
-    netif->status = DISCONNECTED;
-    mb();
-
-    /* Send the successful response. */
-    ctrl_if_send_response(&cmsg);
-}
-
-void netif_disconnect_complete(netif_t *netif)
-{
-    INIT_WORK(&netif->work, __netif_disconnect_complete, (void *)netif);
-    schedule_work(&netif->work);
-}
-
-void netif_create(netif_be_create_t *create)
-{
-    int                err = 0;
-    domid_t            domid  = create->domid;
-    unsigned int       handle = create->netif_handle;
+netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
+{
+    int err = 0, i;
     struct net_device *dev;
-    netif_t          **pnetif, *netif;
-    char               name[IFNAMSIZ] = {};
+    netif_t **pnetif, *netif;
+    char name[IFNAMSIZ] = {};
 
     snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
     dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
     if ( dev == NULL )
     {
         DPRINTK("Could not create netif: out of memory\n");
-        create->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
-        return;
+        // create->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
+        return NULL;
     }
 
     netif = netdev_priv(dev);
@@ -167,9 +96,9 @@
         if ( ((*pnetif)->domid == domid) && ((*pnetif)->handle == handle) )
         {
             DPRINTK("Could not create netif: already exists\n");
-            create->status = NETIF_BE_STATUS_INTERFACE_EXISTS;
+            // create->status = NETIF_BE_STATUS_INTERFACE_EXISTS;
             free_netdev(dev);
-            return;
+            return NULL;
         }
         pnetif = &(*pnetif)->hash_next;
     }
@@ -183,9 +112,10 @@
     /* Disable queuing. */
     dev->tx_queue_len = 0;
 
-    if ( (create->be_mac[0] == 0) && (create->be_mac[1] == 0) &&
-         (create->be_mac[2] == 0) && (create->be_mac[3] == 0) &&
-         (create->be_mac[4] == 0) && (create->be_mac[5] == 0) )
+    for (i = 0; i < ETH_ALEN; i++)
+       if (be_mac[i] != 0)
+           break;
+    if (i == ETH_ALEN)
     {
         /*
          * Initialise a dummy MAC address. We choose the numerically largest
@@ -197,10 +127,8 @@
     }
     else
     {
-        memcpy(dev->dev_addr, create->be_mac, ETH_ALEN);
-    }
-
-    memcpy(netif->fe_dev_addr, create->mac, ETH_ALEN);
+        memcpy(dev->dev_addr, be_mac, ETH_ALEN);
+    }
 
     rtnl_lock();
     err = register_netdevice(dev);
@@ -210,16 +138,187 @@
     {
         DPRINTK("Could not register new net device %s: err=%d\n",
                 dev->name, err);
-        create->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
+        // create->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
         free_netdev(dev);
-        return;
+        return NULL;
     }
 
     netif->hash_next = *pnetif;
     *pnetif = netif;
 
     DPRINTK("Successfully created netif\n");
-    create->status = NETIF_BE_STATUS_OKAY;
+    // create->status = NETIF_BE_STATUS_OKAY;
+    return netif;
+}
+
+static int map_frontend_page(netif_t *netif, unsigned long localaddr,
+                            unsigned long tx_ring_ref, unsigned long 
rx_ring_ref)
+{
+#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX)
+    pgprot_t      prot = __pgprot(_KERNPG_TABLE);
+    int           err;
+#endif
+#if defined(CONFIG_XEN_NETDEV_GRANT_TX)
+    {
+        struct gnttab_map_grant_ref op;
+
+        /* Map: Use the Grant table reference */
+        op.host_addr = localaddr;
+        op.flags     = GNTMAP_host_map;
+        op.ref       = tx_ring_ref;
+        op.dom       = netif->domid;
+       
+       BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+        if (op.handle < 0) { 
+            DPRINTK(" Grant table operation failure !\n");
+            return op.handle;
+        }
+
+        netif->tx_shmem_ref    = tx_ring_ref;
+        netif->tx_shmem_handle = op.handle;
+        netif->tx_shmem_vaddr  = localaddr;
+    }
+#else 
+    err = direct_remap_area_pages(&init_mm, localaddr,
+                                 tx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
+                                 prot, netif->domid); 
+    if (err)
+       return err;
+#endif
+
+#if defined(CONFIG_XEN_NETDEV_GRANT_RX)
+    {
+        struct gnttab_map_grant_ref op;
+
+        /* Map: Use the Grant table reference */
+        op.host_addr = localaddr + PAGE_SIZE;
+        op.flags     = GNTMAP_host_map;
+        op.ref       = rx_ring_ref;
+        op.dom       = netif->domid;
+
+       BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+        if (op.handle < 0) { 
+            DPRINTK(" Grant table operation failure !\n");
+            return op.handle;
+        }
+
+        netif->rx_shmem_ref    = rx_ring_ref;
+        netif->rx_shmem_handle = op.handle;
+        netif->rx_shmem_vaddr  = localaddr + PAGE_SIZE;
+    }
+#else 
+    err = direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE,
+                                 rx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
+                                 prot, netif->domid);
+    if (err)
+       return err;
+#endif
+
+    return 0;
+}
+
+static void unmap_frontend_page(netif_t *netif)
+{
+#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX)
+    struct gnttab_unmap_grant_ref op;
+#endif
+
+#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+    op.host_addr    = netif->tx_shmem_vaddr;
+    op.handle       = netif->tx_shmem_handle;
+    op.dev_bus_addr = 0;
+    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+#endif
+
+#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+    op.host_addr    = netif->rx_shmem_vaddr;
+    op.handle       = netif->rx_shmem_handle;
+    op.dev_bus_addr = 0;
+    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+#endif
+}
+
+int netif_map(netif_t *netif, unsigned long tx_ring_ref,
+             unsigned long rx_ring_ref, unsigned int evtchn)
+{
+    struct vm_struct *vma;
+    evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
+    int err;
+
+#if 0
+    if ( netif->status != DISCONNECTED ) {
+        connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED;
+        return;
+    }
+#endif
+
+    if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) {
+        // connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
+        return -ENOMEM;
+    }
+
+    err = map_frontend_page(netif, (unsigned long)vma->addr, tx_ring_ref,
+                           rx_ring_ref);
+    if (err) {
+        vfree(vma->addr);
+       return err;
+    }
+
+    op.u.bind_interdomain.dom1 = DOMID_SELF;
+    op.u.bind_interdomain.dom2 = netif->domid;
+    op.u.bind_interdomain.port1 = 0;
+    op.u.bind_interdomain.port2 = evtchn;
+    err = HYPERVISOR_event_channel_op(&op);
+    if (err) {
+       unmap_frontend_page(netif);
+       vfree(vma->addr);
+       return err;
+    }
+
+    netif->evtchn = op.u.bind_interdomain.port1;
+    netif->remote_evtchn = evtchn;
+
+    netif->tx_shmem_frame = tx_ring_ref;
+    netif->rx_shmem_frame = rx_ring_ref;
+    netif->tx             = 
+        (netif_tx_interface_t *)vma->addr;
+    netif->rx             = 
+        (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE);
+    netif->tx->resp_prod = netif->rx->resp_prod = 0;
+    netif_get(netif);
+    wmb(); /* Other CPUs see new state before interface is started. */
+
+    rtnl_lock();
+    netif->status = CONNECTED;
+    wmb();
+    if ( netif_running(netif->dev) )
+        __netif_up(netif);
+    rtnl_unlock();
+
+    // connect->status = NETIF_BE_STATUS_OKAY;
+    return 0;
+}
+
+static void free_netif(void *arg)
+{
+    netif_t              *netif = (netif_t *)arg;
+
+    /*
+     * These can't be done in netif_disconnect() because at that point there
+     * may be outstanding requests in the network stack whose asynchronous
+     * responses must still be notified to the remote driver.
+     */
+
+    unmap_frontend_page(netif);
+    vfree(netif->tx); /* Frees netif->rx as well. */
+
+    netif->status = DISCONNECTED;
+}
+
+void free_netif_callback(netif_t *netif)
+{
+    INIT_WORK(&netif->free_work, free_netif, (void *)netif);
+    schedule_work(&netif->free_work);
 }
 
 void netif_destroy(netif_be_destroy_t *destroy)
@@ -284,147 +383,6 @@
     }
     
     creditlimit->status = NETIF_BE_STATUS_OKAY;
-}
-
-void netif_connect(netif_be_connect_t *connect)
-{
-    domid_t       domid  = connect->domid;
-    unsigned int  handle = connect->netif_handle;
-    unsigned int  evtchn = connect->evtchn;
-    unsigned long tx_shmem_frame = connect->tx_shmem_frame;
-    unsigned long rx_shmem_frame = connect->rx_shmem_frame;
-    struct vm_struct *vma;
-#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX)
-    pgprot_t      prot = __pgprot(_KERNPG_TABLE);
-    int           error;
-#endif
-    netif_t      *netif;
-
-    netif = netif_find_by_handle(domid, handle);
-    if ( unlikely(netif == NULL) ) {
-        DPRINTK("netif_connect attempted for non-existent netif (%u,%u)\n", 
-                connect->domid, connect->netif_handle); 
-        connect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
-        return;
-    }
-
-    if ( netif->status != DISCONNECTED ) {
-        connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED;
-        return;
-    }
-
-    if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) {
-        connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
-        return;
-    }
-
-
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX)
-    {
-        struct gnttab_map_grant_ref op;
-        int tx_ref = connect->tx_shmem_ref; 
-
-        /* Map: Use the Grant table reference */
-        op.host_addr = VMALLOC_VMADDR(vma->addr);
-        op.flags     = GNTMAP_host_map;
-        op.ref       = tx_ref;
-        op.dom       = domid;
-       
-        if ((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) < 0) || 
-            (op.handle < 0)) { 
-            DPRINTK(" Grant table operation failure !\n");
-            connect->status = NETIF_BE_STATUS_MAPPING_ERROR;
-            vfree(vma->addr);
-            return;
-        }
-
-        netif->tx_shmem_ref    = tx_ref;
-        netif->tx_shmem_handle = op.handle;
-        netif->tx_shmem_vaddr  = VMALLOC_VMADDR(vma->addr);
-    }
-        
-
-#else 
-    error = direct_remap_area_pages(&init_mm, 
-                                    VMALLOC_VMADDR(vma->addr),
-                                    tx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
-                                    prot, domid); 
-    if ( error != 0 )
-    {
-        if ( error == -ENOMEM )
-            connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
-        else if ( error == -EFAULT )
-            connect->status = NETIF_BE_STATUS_MAPPING_ERROR;
-        else
-            connect->status = NETIF_BE_STATUS_ERROR;
-        vfree(vma->addr);
-        return;
-    }
-#endif
-
-
-#if defined(CONFIG_XEN_NETDEV_GRANT_RX)
-    {
-        struct gnttab_map_grant_ref op;
-        int rx_ref = connect->rx_shmem_ref; 
-
-
-        /* Map: Use the Grant table reference */
-        op.host_addr = VMALLOC_VMADDR(vma->addr) + PAGE_SIZE;
-        op.flags     = GNTMAP_host_map;
-        op.ref       = rx_ref;
-        op.dom       = domid;
-
-        if ((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) < 0) || 
-            (op.handle < 0)) { 
-            DPRINTK(" Grant table operation failure !\n");
-            connect->status = NETIF_BE_STATUS_MAPPING_ERROR;
-            vfree(vma->addr);
-            return;
-        }
-
-        netif->rx_shmem_ref    = rx_ref;
-        netif->rx_shmem_handle = handle;
-        netif->rx_shmem_vaddr  = VMALLOC_VMADDR(vma->addr) + PAGE_SIZE;
-    }
-#else 
-    error = direct_remap_area_pages(&init_mm, 
-                                     VMALLOC_VMADDR(vma->addr) + PAGE_SIZE,
-                                     rx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
-                                     prot, domid);
-    if ( error != 0 )
-    {
-        if ( error == -ENOMEM )
-            connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
-        else if ( error == -EFAULT )
-            connect->status = NETIF_BE_STATUS_MAPPING_ERROR;
-        else
-            connect->status = NETIF_BE_STATUS_ERROR;
-        vfree(vma->addr);
-        return;
-    }
-
-#endif
-
-    netif->evtchn         = evtchn;
-    netif->tx_shmem_frame = tx_shmem_frame;
-    netif->rx_shmem_frame = rx_shmem_frame;
-    netif->tx             = 
-        (netif_tx_interface_t *)vma->addr;
-    netif->rx             = 
-        (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE);
-    netif->tx->resp_prod = netif->rx->resp_prod = 0;
-    netif_get(netif);
-    wmb(); /* Other CPUs see new state before interface is started. */
-
-    rtnl_lock();
-    netif->status = CONNECTED;
-    wmb();
-    if ( netif_running(netif->dev) )
-        __netif_up(netif);
-    rtnl_unlock();
-
-    connect->status = NETIF_BE_STATUS_OKAY;
 }
 
 int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id)
diff -r d4ce28d819a8 -r b402e77aac46 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Aug 24 
22:21:24 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Aug 24 
22:22:11 2005
@@ -987,7 +987,7 @@
     spin_lock_init(&net_schedule_list_lock);
     INIT_LIST_HEAD(&net_schedule_list);
 
-    netif_ctrlif_init();
+    netif_xenbus_init();
 
     (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG),
                       netif_be_dbg, SA_SHIRQ, 
diff -r d4ce28d819a8 -r b402e77aac46 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Aug 24 
22:21:24 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Aug 24 
22:22:11 2005
@@ -48,7 +48,7 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm-xen/evtchn.h>
-#include <asm-xen/ctrl_if.h>
+#include <asm-xen/xenbus.h>
 #include <asm-xen/xen-public/io/netif.h>
 #include <asm-xen/balloon.h>
 #include <asm/page.h>
@@ -112,7 +112,6 @@
 #endif
 
 #if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-static domid_t rdomid = 0;
 #define GRANT_INVALID_REF      (0xFFFF)
 #endif
 
@@ -135,10 +134,11 @@
 
 static struct list_head dev_list;
 
+#define netfront_info net_private
 struct net_private
 {
     struct list_head list;
-    struct net_device *dev;
+    struct net_device *netdev;
 
     struct net_device_stats stats;
     NETIF_RING_IDX rx_resp_cons, tx_resp_cons;
@@ -176,6 +176,14 @@
      */
     struct sk_buff *tx_skbs[NETIF_TX_RING_SIZE+1];
     struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1];
+
+       struct xenbus_device *xbdev;
+       char *backend;
+       int backend_id;
+       struct xenbus_watch watch;
+       int tx_ring_ref;
+       int rx_ring_ref;
+       u8 mac[ETH_ALEN];
 };
 
 /* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */
@@ -187,13 +195,6 @@
     (_list)[0]  = (_list)[_id];                    \
     (unsigned short)_id; })
 
-static char *status_name[] = {
-    [NETIF_INTERFACE_STATUS_CLOSED]       = "closed",
-    [NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected",
-    [NETIF_INTERFACE_STATUS_CONNECTED]    = "connected",
-    [NETIF_INTERFACE_STATUS_CHANGED]      = "changed",
-};
-
 static char *be_state_name[] = {
     [BEST_CLOSED]       = "closed",
     [BEST_DISCONNECTED] = "disconnected",
@@ -219,7 +220,7 @@
     list_for_each (ent, &dev_list) {
         np = list_entry(ent, struct net_private, list);
         if (np->handle == handle)
-            return np->dev;
+            return np->netdev;
     }
     return NULL;
 }
@@ -448,7 +449,7 @@
             BUG();
         }
         grant_rx_ref[id] = ref;
-        gnttab_grant_foreign_transfer_ref(ref, rdomid,
+        gnttab_grant_foreign_transfer_ref(ref, np->backend_id,
                                           virt_to_mfn(skb->head));
         np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.gref = ref;
 #endif
@@ -544,7 +545,7 @@
         BUG();
     }
     mfn = virt_to_mfn(skb->data);
-    gnttab_grant_foreign_access_ref(ref, rdomid, mfn, GNTMAP_readonly);
+    gnttab_grant_foreign_access_ref(ref, np->backend_id, mfn, GNTMAP_readonly);
     tx->addr = ref << PAGE_SHIFT;
     grant_tx_ref[id] = ref;
 #else
@@ -809,7 +810,7 @@
 {
     struct net_private *np = netdev_priv(dev);
     np->user_state = UST_CLOSED;
-    netif_stop_queue(np->dev);
+    netif_stop_queue(np->netdev);
     return 0;
 }
 
@@ -821,8 +822,7 @@
 }
 
 
-static void network_connect(struct net_device *dev,
-                            netif_fe_interface_status_t *status)
+static void network_connect(struct net_device *dev)
 {
     struct net_private *np;
     int i, requeue_idx;
@@ -890,7 +890,7 @@
      */
     np->backend_state = BEST_CONNECTED;
     wmb();
-    notify_via_evtchn(status->evtchn);  
+    notify_via_evtchn(np->evtchn);  
     network_tx_buf_gc(dev);
 
     if (np->user_state == UST_OPEN)
@@ -900,108 +900,57 @@
     spin_unlock_irq(&np->tx_lock);
 }
 
-static void vif_show(struct net_private *np)
+static void show_device(struct net_private *np)
 {
 #ifdef DEBUG
-    if (np) {
-        IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n",
-               np->handle,
-               be_state_name[np->backend_state],
-               np->user_state ? "open" : "closed",
-               np->evtchn,
-               np->tx,
-               np->rx);
-    } else {
-        IPRINTK("<vif NULL>\n");
-    }
-#endif
-}
-
-/* Send a connect message to xend to tell it to bring up the interface. */
-static void send_interface_connect(struct net_private *np)
-{
-    int err;
-    ctrl_msg_t cmsg = {
-        .type    = CMSG_NETIF_FE,
-        .subtype = CMSG_NETIF_FE_INTERFACE_CONNECT,
-        .length  = sizeof(netif_fe_interface_connect_t),
-    };
-    netif_fe_interface_connect_t *msg = (void*)cmsg.msg;
-
-    msg->handle = np->handle;
-    msg->tx_shmem_frame = virt_to_mfn(np->tx);
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    err = gnttab_grant_foreign_access(rdomid, msg->tx_shmem_frame, 0);
-    if (err < 0) {
-        printk(KERN_ALERT "#### netfront can't grant access to tx_shmem\n");
-        BUG();
-    }
-    msg->tx_shmem_ref = err;
-#endif
-
-    msg->rx_shmem_frame = virt_to_mfn(np->rx);
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    err = gnttab_grant_foreign_access(rdomid, msg->rx_shmem_frame, 0);
-    if (err < 0) {
-        printk(KERN_ALERT "#### netfront can't grant access to rx_shmem\n");
-        BUG();
-    }
-    msg->rx_shmem_ref = err;
-#endif
-
-    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-}
-
-/* Send a driver status notification to the domain controller. */
-static int send_driver_status(int ok)
-{
-    int err = 0;
-    ctrl_msg_t cmsg = {
-        .type    = CMSG_NETIF_FE,
-        .subtype = CMSG_NETIF_FE_DRIVER_STATUS,
-        .length  = sizeof(netif_fe_driver_status_t),
-    };
-    netif_fe_driver_status_t *msg = (void*)cmsg.msg;
-
-    msg->status = (ok ? NETIF_DRIVER_STATUS_UP : NETIF_DRIVER_STATUS_DOWN);
-    err = ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-    return err;
+       if (np) {
+               IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n",
+                       np->handle,
+                       be_state_name[np->backend_state],
+                       np->user_state ? "open" : "closed",
+                       np->evtchn,
+                       np->tx,
+                       np->rx);
+       } else {
+               IPRINTK("<vif NULL>\n");
+       }
+#endif
 }
 
 /* Stop network device and free tx/rx queues and irq.
  */
-static void vif_release(struct net_private *np)
-{
-    /* Stop old i/f to prevent errors whilst we rebuild the state. */
-    spin_lock_irq(&np->tx_lock);
-    spin_lock(&np->rx_lock);
-    netif_stop_queue(np->dev);
-    /* np->backend_state = BEST_DISCONNECTED; */
-    spin_unlock(&np->rx_lock);
-    spin_unlock_irq(&np->tx_lock);
+static void shutdown_device(struct net_private *np)
+{
+       /* Stop old i/f to prevent errors whilst we rebuild the state. */
+       spin_lock_irq(&np->tx_lock);
+       spin_lock(&np->rx_lock);
+       netif_stop_queue(np->netdev);
+       /* np->backend_state = BEST_DISCONNECTED; */
+       spin_unlock(&np->rx_lock);
+       spin_unlock_irq(&np->tx_lock);
     
-    /* Free resources. */
-    if ( np->tx != NULL )
-    {
-        unbind_evtchn_from_irqhandler(np->evtchn, np->dev);
-        free_page((unsigned long)np->tx);
-        free_page((unsigned long)np->rx);
-        np->evtchn = 0;
-        np->tx = NULL;
-        np->rx = NULL;
-    }
+       /* Free resources. */
+       if (np->tx) {
+               unbind_evtchn_from_irqhandler(np->evtchn, np->netdev);
+               np->evtchn = 0;
+               free_page((unsigned long)np->tx);
+               free_page((unsigned long)np->rx);
+               np->tx = NULL;
+               np->rx = NULL;
+       }
 }
 
 /* Release vif resources and close it down completely.
  */
 static void vif_close(struct net_private *np)
 {
+       BUG();
     WPRINTK("Unexpected netif-CLOSED message in state %s\n",
             be_state_name[np->backend_state]);
-    vif_release(np);
+    shutdown_device(np);
     np->backend_state = BEST_CLOSED;
     /* todo: take dev down and free. */
-    vif_show(np);
+    show_device(np);
 }
 
 /* Move the vif into disconnected state.
@@ -1010,6 +959,7 @@
  */
 static void vif_disconnect(struct net_private *np)
 {
+       BUG();
     if(np->tx) free_page((unsigned long)np->tx);
     if(np->rx) free_page((unsigned long)np->rx);
     // Before this np->tx and np->rx had better be null.
@@ -1018,8 +968,8 @@
     memset(np->tx, 0, PAGE_SIZE);
     memset(np->rx, 0, PAGE_SIZE);
     np->backend_state = BEST_DISCONNECTED;
-    send_interface_connect(np);
-    vif_show(np);
+    // send_interface_connect(np);
+    show_device(np);
 }
 
 /* Begin interface recovery.
@@ -1037,11 +987,12 @@
  */
 static void vif_reset(struct net_private *np)
 {
+       BUG();
     IPRINTK("Attempting to reconnect network interface: handle=%u\n",
             np->handle);    
-    vif_release(np);
+    shutdown_device(np);
     vif_disconnect(np);
-    vif_show(np);
+    show_device(np);
 }
 
 /* Move the vif into connected state.
@@ -1049,20 +1000,17 @@
  * Binds the irq to the event channel.
  */
 static void 
-vif_connect(struct net_private *np, netif_fe_interface_status_t *status)
-{
-    struct net_device *dev = np->dev;
-    memcpy(dev->dev_addr, status->mac, ETH_ALEN);
-    network_connect(dev, status);
-    np->evtchn = status->evtchn;
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-    rdomid = status->domid;
-#endif
+connect_device(struct net_private *np, unsigned int evtchn)
+{
+    struct net_device *dev = np->netdev;
+    memcpy(dev->dev_addr, np->mac, ETH_ALEN);
+    np->evtchn = evtchn;
+    network_connect(dev);
     (void)bind_evtchn_to_irqhandler(
         np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
     netctrl_connected_count();
     (void)send_fake_arp(dev);
-    vif_show(np);
+    show_device(np);
 }
 
 static struct ethtool_ops network_ethtool_ops =
@@ -1076,22 +1024,24 @@
  * @param val return parameter for created device
  * @return 0 on success, error code otherwise
  */
-static int create_netdev(int handle, struct net_device **val)
+static int create_netdev(int handle, struct xenbus_device *dev,
+                        struct net_device **val)
 {
     int i, err = 0;
-    struct net_device *dev = NULL;
+    struct net_device *netdev = NULL;
     struct net_private *np = NULL;
 
-    if ((dev = alloc_etherdev(sizeof(struct net_private))) == NULL) {
+    if ((netdev = alloc_etherdev(sizeof(struct net_private))) == NULL) {
         printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__);
         err = -ENOMEM;
         goto exit;
     }
 
-    np                = netdev_priv(dev);
+    np                = netdev_priv(netdev);
     np->backend_state = BEST_CLOSED;
     np->user_state    = UST_CLOSED;
     np->handle        = handle;
+    np->xbdev         = dev;
     
     spin_lock_init(&np->tx_lock);
     spin_lock_init(&np->rx_lock);
@@ -1115,149 +1065,53 @@
 #endif
     }
 
-    dev->open            = network_open;
-    dev->hard_start_xmit = network_start_xmit;
-    dev->stop            = network_close;
-    dev->get_stats       = network_get_stats;
-    dev->poll            = netif_poll;
-    dev->weight          = 64;
-    dev->features        = NETIF_F_IP_CSUM;
-
-    SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
-
-    if ((err = register_netdev(dev)) != 0) {
+    netdev->open            = network_open;
+    netdev->hard_start_xmit = network_start_xmit;
+    netdev->stop            = network_close;
+    netdev->get_stats       = network_get_stats;
+    netdev->poll            = netif_poll;
+    netdev->weight          = 64;
+    netdev->features        = NETIF_F_IP_CSUM;
+
+    SET_ETHTOOL_OPS(netdev, &network_ethtool_ops);
+
+    if ((err = register_netdev(netdev)) != 0) {
         printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err);
         goto exit;
     }
 
-    if ((err = xennet_proc_addif(dev)) != 0) {
-        unregister_netdev(dev);
+    if ((err = xennet_proc_addif(netdev)) != 0) {
+        unregister_netdev(netdev);
         goto exit;
     }
 
-    np->dev = dev;
+    np->netdev = netdev;
     list_add(&np->list, &dev_list);
 
   exit:
-    if ((err != 0) && (dev != NULL))
-        kfree(dev);
+    if ((err != 0) && (netdev != NULL))
+        kfree(netdev);
     else if (val != NULL)
-        *val = dev;
+        *val = netdev;
     return err;
 }
 
-/* Get the target interface for a status message.
- * Creates the interface when it makes sense.
- * The returned interface may be null when there is no error.
- *
- * @param status status message
- * @param np return parameter for interface state
- * @return 0 on success, error code otherwise
- */
-static int 
-target_vif(netif_fe_interface_status_t *status, struct net_private **np)
-{
-    int err = 0;
-    struct net_device *dev;
-
-    DPRINTK("> handle=%d\n", status->handle);
-    if (status->handle < 0) {
-        err = -EINVAL;
-        goto exit;
-    }
-
-    if ((dev = find_dev_by_handle(status->handle)) != NULL)
-        goto exit;
-
-    if (status->status == NETIF_INTERFACE_STATUS_CLOSED)
-        goto exit;
-    if (status->status == NETIF_INTERFACE_STATUS_CHANGED)
-        goto exit;
-
-    /* It's a new interface in a good state - create it. */
-    DPRINTK("> create device...\n");
-    if ((err = create_netdev(status->handle, &dev)) != 0)
-        goto exit;
-
-    netctrl.interface_n++;
-
-  exit:
-    if (np != NULL)
-        *np = ((dev && !err) ? netdev_priv(dev) : NULL);
-    DPRINTK("< err=%d\n", err);
-    return err;
-}
-
-/* Handle an interface status message. */
-static void netif_interface_status(netif_fe_interface_status_t *status)
-{
-    int err = 0;
-    struct net_private *np = NULL;
-    
-    DPRINTK("> status=%s handle=%d\n",
-            status_name[status->status], status->handle);
-
-    if ((err = target_vif(status, &np)) != 0) {
-        WPRINTK("Invalid netif: handle=%u\n", status->handle);
-        return;
-    }
-
-    if (np == NULL) {
-        DPRINTK("> no vif\n");
-        return;
-    }
-
-    switch (status->status) {
-    case NETIF_INTERFACE_STATUS_CLOSED:
-        switch (np->backend_state) {
-        case BEST_CLOSED:
-        case BEST_DISCONNECTED:
-        case BEST_CONNECTED:
-            vif_close(np);
-            break;
-        }
-        break;
-
-    case NETIF_INTERFACE_STATUS_DISCONNECTED:
-        switch (np->backend_state) {
-        case BEST_CLOSED:
-            vif_disconnect(np);
-            break;
-        case BEST_DISCONNECTED:
-        case BEST_CONNECTED:
-            vif_reset(np);
-            break;
-        }
-        break;
-
-    case NETIF_INTERFACE_STATUS_CONNECTED:
-        switch (np->backend_state) {
-        case BEST_CLOSED:
-            WPRINTK("Unexpected netif status %s in state %s\n",
-                    status_name[status->status],
-                    be_state_name[np->backend_state]);
-            vif_disconnect(np);
-            vif_connect(np, status);
-            break;
-        case BEST_DISCONNECTED:
-            vif_connect(np, status);
-            break;
-        }
-        break;
-
-    case NETIF_INTERFACE_STATUS_CHANGED:
-        /*
-         * The domain controller is notifying us that a device has been
-         * added or removed.
-         */
-        break;
-
-    default:
-        WPRINTK("Invalid netif status code %d\n", status->status);
-        break;
-    }
-
-    vif_show(np);
+static int destroy_netdev(struct net_device *netdev)
+{
+       struct net_private *np = NULL;
+
+#ifdef CONFIG_PROC_FS
+       xennet_proc_delif(netdev);
+#endif
+
+        unregister_netdev(netdev);
+
+       np = netdev_priv(netdev);
+       list_del(&np->list);
+
+       kfree(netdev);
+
+       return 0;
 }
 
 /*
@@ -1268,115 +1122,6 @@
     netctrl.up = status->status;
     netctrl_connected_count();
 }
-
-/* Receive handler for control messages. */
-static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
-{
-
-    switch (msg->subtype) {
-    case CMSG_NETIF_FE_INTERFACE_STATUS:
-        netif_interface_status((netif_fe_interface_status_t *) &msg->msg[0]);
-        break;
-
-    case CMSG_NETIF_FE_DRIVER_STATUS:
-        netif_driver_status((netif_fe_driver_status_t *) &msg->msg[0]);
-        break;
-
-    default:
-        msg->length = 0;
-        break;
-    }
-
-    ctrl_if_send_response(msg);
-}
-
-
-#if 1
-/* Wait for all interfaces to be connected.
- *
- * This works OK, but we'd like to use the probing mode (see below).
- */
-static int probe_interfaces(void)
-{
-    int err = 0, conn = 0;
-    int wait_i, wait_n = 100;
-
-    DPRINTK(">\n");
-
-    for (wait_i = 0; wait_i < wait_n; wait_i++) { 
-        DPRINTK("> wait_i=%d\n", wait_i);
-        conn = netctrl_connected();
-        if(conn) break;
-        DPRINTK("> schedule_timeout...\n");
-        set_current_state(TASK_INTERRUPTIBLE);
-        schedule_timeout(10);
-    }
-
-    DPRINTK("> wait finished...\n");
-    if (conn <= 0) {
-        err = netctrl_err(-ENETDOWN);
-        WPRINTK("Failed to connect all virtual interfaces: err=%d\n", err);
-    }
-
-    DPRINTK("< err=%d\n", err);
-
-    return err;
-}
-#else
-/* Probe for interfaces until no more are found.
- *
- * This is the mode we'd like to use, but at the moment it panics the kernel.
-*/
-static int probe_interfaces(void)
-{
-    int err = 0;
-    int wait_i, wait_n = 100;
-    ctrl_msg_t cmsg = {
-        .type    = CMSG_NETIF_FE,
-        .subtype = CMSG_NETIF_FE_INTERFACE_STATUS,
-        .length  = sizeof(netif_fe_interface_status_t),
-    };
-    netif_fe_interface_status_t msg = {};
-    ctrl_msg_t rmsg = {};
-    netif_fe_interface_status_t *reply = (void*)rmsg.msg;
-    int state = TASK_UNINTERRUPTIBLE;
-    u32 query = -1;
-
-    DPRINTK(">\n");
-
-    netctrl.interface_n = 0;
-    for (wait_i = 0; wait_i < wait_n; wait_i++) { 
-        DPRINTK("> wait_i=%d query=%d\n", wait_i, query);
-        msg.handle = query;
-        memcpy(cmsg.msg, &msg, sizeof(msg));
-        DPRINTK("> set_current_state...\n");
-        set_current_state(state);
-        DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply);
-        DPRINTK("> sending...\n");
-        err = ctrl_if_send_message_and_get_response(&cmsg, &rmsg, state);
-        DPRINTK("> err=%d\n", err);
-        if(err) goto exit;
-        DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply);
-        if((int)reply->handle < 0) {
-            // No more interfaces.
-            break;
-        }
-        query = -reply->handle - 2;
-        DPRINTK(">netif_interface_status ...\n");
-        netif_interface_status(reply);
-    }
-
-  exit:
-    if (err) {
-        err = netctrl_err(-ENETDOWN);
-        WPRINTK("Connecting virtual network interfaces failed: err=%d\n", err);
-    }
-
-    DPRINTK("< err=%d\n", err);
-    return err;
-}
-
-#endif
 
 /*
  * We use this notifier to send out a fake ARP reply to reset switches and
@@ -1395,7 +1140,7 @@
 
     list_for_each (ent, &dev_list) {
         np = list_entry(ent, struct net_private, list);
-        if (np->dev == dev)
+        if (np->netdev == dev)
             (void)send_fake_arp(dev);
     }
         
@@ -1409,67 +1154,317 @@
     .priority       = 0
 };
 
-static int __init netif_init(void)
-{
-    int err = 0;
-
-    if (xen_start_info.flags & SIF_INITDOMAIN)
-        return 0;
+static struct xenbus_device_id netfront_ids[] = {
+       { "vif" },
+       { "" }
+};
+
+static void watch_for_status(struct xenbus_watch *watch, const char *node)
+{
+#if 0
+       struct netfront_info *info;
+       unsigned int binfo;
+       unsigned long sectors, sector_size;
+       int err;
+
+       info = container_of(watch, struct netfront_info, watch);
+       node += strlen(watch->node);
+
+       /* FIXME: clean up when error on the other end. */
+       if (info->connected == BLKIF_STATE_CONNECTED)
+               return;
+
+       err = xenbus_gather(watch->node,
+                           "sectors", "%lu", &sectors,
+                           "info", "%u", &binfo,
+                           "sector-size", "%lu", &sector_size,
+                           NULL);
+       if (err) {
+               xenbus_dev_error(info->xbdev, err, "reading backend fields");
+               return;
+       }
+
+       xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
+       info->connected = BLKIF_STATE_CONNECTED;
+
+       blkif_state = BLKIF_STATE_CONNECTED;
+
+       xenbus_dev_ok(info->xbdev);
+
+       /* Kick pending requests. */
+       spin_lock_irq(&blkif_io_lock);
+       kick_pending_request_queues(info);
+       spin_unlock_irq(&blkif_io_lock);
+#endif
+}
+
+static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
+{
+       evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
+       int err;
+
 #ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    /* A grant for every ring slot */
-    if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE,
-                                      &gref_tx_head) < 0) {
-        printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
-        return 1;
-    }
-    printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n"); 
+       info->tx_ring_ref = GRANT_INVALID_REF;
 #endif
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    /* A grant for every ring slot */
-    if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE,
-                                      &gref_rx_head) < 0) {
-        printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
-        return 1;
-    }
-    printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n"); 
-#endif
-
-    if ((err = xennet_proc_init()) != 0)
-        return err;
-
-    IPRINTK("Initialising virtual ethernet driver.\n");
-    INIT_LIST_HEAD(&dev_list);
-    (void)register_inetaddr_notifier(&notifier_inetdev);
-    netctrl_init();
-    (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx,
-                                    CALLBACK_IN_BLOCKING_CONTEXT);
-    send_driver_status(1);
-    err = probe_interfaces();
-    if (err)
-        ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx);
-
-    DPRINTK("< err=%d\n", err);
-    return err;
-}
-
-static void netif_exit(void)
-{
+       info->rx_ring_ref = GRANT_INVALID_REF;
+#endif
+
+       info->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
+       if (info->tx == 0) {
+               err = -ENOMEM;
+               xenbus_dev_error(dev, err, "allocating tx ring page");
+               goto out;
+       }
+       info->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
+       if (info->rx == 0) {
+               err = -ENOMEM;
+               xenbus_dev_error(dev, err, "allocating rx ring page");
+               goto out;
+       }
+       memset(info->tx, 0, PAGE_SIZE);
+       memset(info->rx, 0, PAGE_SIZE);
+       info->backend_state = BEST_DISCONNECTED;
+
 #ifdef CONFIG_XEN_NETDEV_GRANT_TX
-    gnttab_free_grant_references(gref_tx_head);
-#endif
+       err = gnttab_grant_foreign_access(info->backend_id,
+                                         virt_to_mfn(info->tx), 0);
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "granting access to tx ring page");
+               goto out;
+       }
+       info->tx_ring_ref = err;
+#else
+       info->tx_ring_ref = virt_to_mfn(info->tx);
+#endif
+
 #ifdef CONFIG_XEN_NETDEV_GRANT_RX
-    gnttab_free_grant_references(gref_rx_head);
-#endif
-}
-
-static void vif_suspend(struct net_private *np)
-{
+       err = gnttab_grant_foreign_access(info->backend_id,
+                                         virt_to_mfn(info->rx), 0);
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "granting access to rx ring page");
+               goto out;
+       }
+       info->rx_ring_ref = err;
+#else
+       info->rx_ring_ref = virt_to_mfn(info->rx);
+#endif
+
+       op.u.alloc_unbound.dom = info->backend_id;
+       err = HYPERVISOR_event_channel_op(&op);
+       if (err) {
+               xenbus_dev_error(dev, err, "allocating event channel");
+               goto out;
+       }
+       connect_device(info, op.u.alloc_unbound.port);
+       return 0;
+
+ out:
+       if (info->tx)
+               free_page((unsigned long)info->tx);
+       info->tx = 0;
+       if (info->rx)
+               free_page((unsigned long)info->rx);
+       info->rx = 0;
+#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+       if (info->tx_ring_ref != GRANT_INVALID_REF)
+               gnttab_end_foreign_access(info->tx_ring_ref, 0);
+       info->tx_ring_ref = GRANT_INVALID_REF;
+#endif
+#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+       if (info->rx_ring_ref != GRANT_INVALID_REF)
+               gnttab_end_foreign_access(info->rx_ring_ref, 0);
+       info->rx_ring_ref = GRANT_INVALID_REF;
+#endif
+       return err;
+}
+
+/* Common code used when first setting up, and when resuming. */
+static int talk_to_backend(struct xenbus_device *dev,
+                          struct netfront_info *info)
+{
+       char *backend, *mac, *e, *s;
+       const char *message;
+       int err, i;
+
+       backend = NULL;
+       err = xenbus_gather(dev->nodename,
+                           "backend-id", "%i", &info->backend_id,
+                           "backend", NULL, &backend,
+                           NULL);
+       if (XENBUS_EXIST_ERR(err))
+               goto out;
+       if (backend && strlen(backend) == 0) {
+               err = -ENOENT;
+               goto out;
+       }
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading %s/backend or backend-id",
+                                dev->nodename);
+               goto out;
+       }
+
+       mac = xenbus_read(dev->nodename, "mac", NULL);
+       if (IS_ERR(mac)) {
+               err = PTR_ERR(mac);
+               xenbus_dev_error(dev, err, "reading %s/mac",
+                                dev->nodename);
+               goto out;
+       }
+       s = mac;
+       for (i = 0; i < ETH_ALEN; i++) {
+               info->mac[i] = simple_strtoul(s, &e, 16);
+               if (s == e || (e[0] != ':' && e[0] != 0)) {
+                       kfree(mac);
+                       err = -ENOENT;
+                       xenbus_dev_error(dev, err, "parsing %s/mac",
+                                        dev->nodename);
+                       goto out;
+               }
+               s = &e[1];
+       }
+       kfree(mac);
+
+       /* Create shared ring, alloc event channel. */
+       err = setup_device(dev, info);
+       if (err) {
+               xenbus_dev_error(dev, err, "setting up ring");
+               goto out;
+       }
+
+       err = xenbus_transaction_start(dev->nodename);
+       if (err) {
+               xenbus_dev_error(dev, err, "starting transaction");
+               goto destroy_ring;
+       }
+
+       err = xenbus_printf(dev->nodename, "tx-ring-ref","%u",
+                           info->tx_ring_ref);
+       if (err) {
+               message = "writing tx ring-ref";
+               goto abort_transaction;
+       }
+       err = xenbus_printf(dev->nodename, "rx-ring-ref","%u",
+                           info->rx_ring_ref);
+       if (err) {
+               message = "writing rx ring-ref";
+               goto abort_transaction;
+       }
+       err = xenbus_printf(dev->nodename,
+                           "event-channel", "%u", info->evtchn);
+       if (err) {
+               message = "writing event-channel";
+               goto abort_transaction;
+       }
+
+       info->backend = backend;
+       backend = NULL;
+
+       info->watch.node = info->backend;
+       info->watch.callback = watch_for_status;
+       err = register_xenbus_watch(&info->watch);
+       if (err) {
+               message = "registering watch on backend";
+               goto abort_transaction;
+       }
+
+       err = xenbus_transaction_end(0);
+       if (err) {
+               xenbus_dev_error(dev, err, "completing transaction");
+               goto destroy_ring;
+       }
+
+ out:
+       if (backend)
+               kfree(backend);
+       return err;
+
+ abort_transaction:
+       xenbus_transaction_end(1);
+       /* Have to do this *outside* transaction.  */
+       xenbus_dev_error(dev, err, "%s", message);
+ destroy_ring:
+       shutdown_device(info);
+       goto out;
+}
+
+/* Setup supplies the backend dir, virtual device.
+
+   We place an event channel and shared frame entries.
+   We watch backend to wait if it's ok. */
+static int netfront_probe(struct xenbus_device *dev,
+                         const struct xenbus_device_id *id)
+{
+       int err;
+       struct net_device *netdev;
+       unsigned int handle;
+
+       printk("netfront_probe %p\n", dev);
+       err = xenbus_scanf(dev->nodename, "handle", "%u", &handle);
+       if (XENBUS_EXIST_ERR(err))
+               return err;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading handle");
+               return err;
+       }
+
+       printk("netfront_probe handle %d\n", handle);
+       netdev = find_dev_by_handle(handle);
+       printk("netfront_probe found netdev %p\n", netdev);
+       if (netdev)
+               return 0;
+
+       err = create_netdev(handle, dev, &netdev);
+       if (err) {
+               xenbus_dev_error(dev, err, "creating netdev");
+               return err;
+       }
+
+       printk("netfront_probe netdev %p\n", netdev);
+       err = talk_to_backend(dev, netdev_priv(netdev));
+       if (err) {
+               destroy_netdev(netdev);
+               return err;
+       }
+
+#if 0
+       /* Call once in case entries already there. */
+       watch_for_status(&info->watch, info->watch.node);
+#endif
+       return 0;
+}
+
+static int netfront_remove(struct xenbus_device *dev)
+{
+       struct netfront_info *info = dev->data;
+
+#if 0
+       if (info->backend)
+               unregister_xenbus_watch(&info->watch);
+
+       if (info->mi)
+               xlvbd_del(info);
+
+       blkif_free(info);
+
+       kfree(info->backend);
+#endif
+       kfree(info);
+
+       return 0;
+}
+
+static int netfront_suspend(struct xenbus_device *dev)
+{
+    struct net_private *np = dev->data;
     /* Avoid having tx/rx stuff happen until we're ready. */
-    unbind_evtchn_from_irqhandler(np->evtchn, np->dev);
-}
-
-static void vif_resume(struct net_private *np)
-{
+    unbind_evtchn_from_irqhandler(np->evtchn, np->netdev);
+    return 0;
+}
+
+static int netfront_resume(struct xenbus_device *dev)
+{
+    struct net_private *np = dev->data;
     /*
      * Connect regardless of whether IFF_UP flag set.
      * Stop bad things from happening until we're back up.
@@ -1478,29 +1473,101 @@
     memset(np->tx, 0, PAGE_SIZE);
     memset(np->rx, 0, PAGE_SIZE);
     
-    send_interface_connect(np);
-}
-
-void netif_suspend(void)
-{
-    struct list_head *ent;
-    struct net_private *np;
-    
-    list_for_each (ent, &dev_list) {
-        np = list_entry(ent, struct net_private, list);
-        vif_suspend(np);
-    }
-}
-
-void netif_resume(void)
-{
-    struct list_head *ent;
-    struct net_private *np;
-
-    list_for_each (ent, &dev_list) {
-        np = list_entry(ent, struct net_private, list);
-        vif_resume(np);
-    }
+    // send_interface_connect(np);
+    return 0;
+}
+
+static struct xenbus_driver netfront = {
+       .name = "vif",
+       .owner = THIS_MODULE,
+       .ids = netfront_ids,
+       .probe = netfront_probe,
+       .remove = netfront_remove,
+       .resume = netfront_resume,
+       .suspend = netfront_suspend,
+};
+
+static void __init init_net_xenbus(void)
+{
+       xenbus_register_device(&netfront);
+}
+
+static int wait_for_netif(void)
+{
+    int err = 0, conn = 0;
+    int i;
+
+    /*
+     * We should figure out how many and which devices we need to
+     * proceed and only wait for those.  For now, continue once the
+     * first device is around.
+     */
+    for ( i=0; i < 10*HZ; i++ )
+    {
+        conn = netctrl_connected();
+        if (conn)
+           break;
+        set_current_state(TASK_INTERRUPTIBLE);
+        schedule_timeout(1);
+    }
+
+    if (conn <= 0) {
+        err = netctrl_err(-ENETDOWN);
+        WPRINTK("Timeout connecting to device!\n");
+    }
+    return err;
+}
+
+static int __init netif_init(void)
+{
+    int err = 0;
+
+    if (xen_start_info.flags & SIF_INITDOMAIN)
+        return 0;
+
+#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+    /* A grant for every ring slot */
+    if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE,
+                                      &gref_tx_head) < 0) {
+        printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
+        return 1;
+    }
+    printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n"); 
+#endif
+#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+    /* A grant for every ring slot */
+    if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE,
+                                      &gref_rx_head) < 0) {
+        printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
+        return 1;
+    }
+    printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n"); 
+#endif
+
+    if ((err = xennet_proc_init()) != 0)
+        return err;
+
+    IPRINTK("Initialising virtual ethernet driver.\n");
+
+    INIT_LIST_HEAD(&dev_list);
+    (void)register_inetaddr_notifier(&notifier_inetdev);
+    netctrl_init();
+
+    init_net_xenbus();
+
+    wait_for_netif();
+
+    return err;
+}
+
+static void netif_exit(void)
+{
+#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+    gnttab_free_grant_references(gref_tx_head);
+#endif
+#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+    gnttab_free_grant_references(gref_rx_head);
+#endif
 }
 
 #ifdef CONFIG_PROC_FS
diff -r d4ce28d819a8 -r b402e77aac46 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Aug 24 22:21:24 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Aug 24 22:22:11 2005
@@ -265,6 +265,8 @@
         self.info = None
         self.blkif_backend = False
         self.netif_backend = False
+        self.netif_idx = 0
+        
         #todo: state: running, suspended
         self.state = STATE_VM_OK
         self.state_updated = threading.Condition()
@@ -400,8 +402,7 @@
             db['virtual-device'] = "%i" % devnum
             #db['backend'] = sxp.child_value(devconfig, 'backend', '0')
             db['backend'] = backdb.getPath()
-            db['backend-id'] = "%i" % int(sxp.child_value(devconfig,
-                                                          'backend', '0'))
+            db['backend-id'] = "%i" % backdom.id
 
             backdb['frontend'] = db.getPath()
             (type, params) = string.split(sxp.child_value(devconfig, 'uname'), 
':', 1)
@@ -417,6 +418,37 @@
             db.saveDB(save=True)
             
             return
+
+        if type == 'vif':
+            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
+
+            log.error(devconfig)
+            
+            devnum = self.netif_idx
+            self.netif_idx += 1
+
+            # create backend db
+            backdb = backdom.db.addChild("/backend/%s/%s/%d" %
+                                         (type, self.uuid, devnum))
+
+            # create frontend db
+            db = self.db.addChild("/device/%s/%d" % (type, devnum))
+            
+            backdb['frontend'] = db.getPath()
+            backdb['frontend-id'] = "%i" % self.id
+            backdb['handle'] = "%i" % devnum
+            backdb.saveDB(save=True)
+
+            db['backend'] = backdb.getPath()
+            db['backend-id'] = "%i" % backdom.id
+            db['handle'] = "%i" % devnum
+            log.error(sxp.child_value(devconfig, 'mac'))
+            db['mac'] = sxp.child_value(devconfig, 'mac')
+
+            db.saveDB(save=True)
+
+            return
+        
         ctrl = self.findDeviceController(type)
         return ctrl.createDevice(devconfig, recreate=self.recreate,
                                  change=change)
diff -r d4ce28d819a8 -r b402e77aac46 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- /dev/null   Wed Aug 24 22:21:24 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Aug 24 22:22:11 2005
@@ -0,0 +1,323 @@
+/*  Xenbus code for netif backend
+    Copyright (C) 2005 Rusty Russell <rusty@xxxxxxxxxxxxxxx>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <stdarg.h>
+#include <linux/module.h>
+#include <asm-xen/xenbus.h>
+#include "common.h"
+
+struct backend_info
+{
+       struct xenbus_device *dev;
+
+       /* our communications channel */
+       netif_t *netif;
+
+       long int frontend_id;
+#if 0
+       long int pdev;
+       long int readonly;
+#endif
+
+       /* watch back end for changes */
+       struct xenbus_watch backend_watch;
+
+       /* watch front end for changes */
+       struct xenbus_watch watch;
+       char *frontpath;
+};
+
+static int netback_remove(struct xenbus_device *dev)
+{
+       struct backend_info *be = dev->data;
+
+       if (be->watch.node)
+               unregister_xenbus_watch(&be->watch);
+       unregister_xenbus_watch(&be->backend_watch);
+#if 0
+       if (be->blkif)
+               blkif_put(be->blkif);
+#endif
+       if (be->frontpath)
+               kfree(be->frontpath);
+       kfree(be);
+       return 0;
+}
+
+/* Front end tells us frame. */
+static void frontend_changed(struct xenbus_watch *watch, const char *node)
+{
+       unsigned long tx_ring_ref, rx_ring_ref;
+       unsigned int evtchn;
+       int err;
+       struct backend_info *be
+               = container_of(watch, struct backend_info, watch);
+       char *mac, *e, *s;
+       int i;
+
+       /* If other end is gone, delete ourself. */
+       if (node && !xenbus_exists(be->frontpath, "")) {
+               xenbus_rm(be->dev->nodename, "");
+               device_unregister(&be->dev->dev);
+               return;
+       }
+       if (be->netif == NULL || be->netif->status == CONNECTED)
+               return;
+
+       mac = xenbus_read(be->frontpath, "mac", NULL);
+       if (IS_ERR(mac)) {
+               err = PTR_ERR(mac);
+               xenbus_dev_error(be->dev, err, "reading %s/mac",
+                                be->dev->nodename);
+               return;
+       }
+       s = mac;
+       for (i = 0; i < ETH_ALEN; i++) {
+               be->netif->fe_dev_addr[i] = simple_strtoul(s, &e, 16);
+               if (s == e || (e[0] != ':' && e[0] != 0)) {
+                       kfree(mac);
+                       err = -ENOENT;
+                       xenbus_dev_error(be->dev, err, "parsing %s/mac",
+                                        be->dev->nodename);
+                       return;
+               }
+               s = &e[1];
+       }
+       kfree(mac);
+
+       err = xenbus_gather(be->frontpath, "tx-ring-ref", "%lu", &tx_ring_ref,
+                           "rx-ring-ref", "%lu", &rx_ring_ref,
+                           "event-channel", "%u", &evtchn, NULL);
+       if (err) {
+               xenbus_dev_error(be->dev, err,
+                                "reading %s/ring-ref and event-channel",
+                                be->frontpath);
+               return;
+       }
+
+#if 0
+       /* Supply the information about the device the frontend needs */
+       err = xenbus_transaction_start(be->dev->nodename);
+       if (err) {
+               xenbus_dev_error(be->dev, err, "starting transaction");
+               return;
+       }
+
+       err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
+                           vbd_size(&be->blkif->vbd));
+       if (err) {
+               xenbus_dev_error(be->dev, err, "writing %s/sectors",
+                                be->dev->nodename);
+               goto abort;
+       }
+
+       /* FIXME: use a typename instead */
+       err = xenbus_printf(be->dev->nodename, "info", "%u",
+                           vbd_info(&be->blkif->vbd));
+       if (err) {
+               xenbus_dev_error(be->dev, err, "writing %s/info",
+                                be->dev->nodename);
+               goto abort;
+       }
+       err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
+                           vbd_secsize(&be->blkif->vbd));
+       if (err) {
+               xenbus_dev_error(be->dev, err, "writing %s/sector-size",
+                                be->dev->nodename);
+               goto abort;
+       }
+#endif
+
+       /* Map the shared frame, irq etc. */
+       err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn);
+       if (err) {
+               xenbus_dev_error(be->dev, err,
+                                "mapping shared-frames %lu/%lu port %u",
+                                tx_ring_ref, rx_ring_ref, evtchn);
+               goto abort;
+       }
+
+#if 0
+       xenbus_transaction_end(0);
+#endif
+       xenbus_dev_ok(be->dev);
+
+       return;
+
+abort:
+       // xenbus_transaction_end(1);
+       ;
+}
+
+/* 
+   Setup supplies physical device.  
+   We provide event channel and device details to front end.
+   Frontend supplies shared frame and event channel.
+ */
+static void backend_changed(struct xenbus_watch *watch, const char *node)
+{
+       int err;
+       char *p;
+       long int handle, pdev;
+       struct backend_info *be
+               = container_of(watch, struct backend_info, backend_watch);
+       struct xenbus_device *dev = be->dev;
+       u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+
+       err = xenbus_scanf(dev->nodename, "handle", "%li", &handle);
+       if (XENBUS_EXIST_ERR(err))
+               return;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading handle");
+               return;
+       }
+
+#if 0
+       err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev);
+       if (XENBUS_EXIST_ERR(err))
+               return;
+       if (err < 0) {
+               xenbus_dev_error(dev, err, "reading physical-device");
+               return;
+       }
+       if (be->pdev && be->pdev != pdev) {
+               printk(KERN_WARNING
+                      "changing physical-device not supported\n");
+               return;
+       }
+       be->pdev = pdev;
+
+       /* If there's a read-only node, we're read only. */
+       p = xenbus_read(dev->nodename, "read-only", NULL);
+       if (!IS_ERR(p)) {
+               be->readonly = 1;
+               kfree(p);
+       }
+#endif
+
+       if (be->netif == NULL) {
+               be->netif = alloc_netif(be->frontend_id, handle, be_mac);
+               if (IS_ERR(be->netif)) {
+                       err = PTR_ERR(be->netif);
+                       be->netif = NULL;
+                       xenbus_dev_error(dev, err, "creating interface");
+                       return;
+               }
+
+#if 0
+               err = vbd_create(be->netif, handle, be->pdev, be->readonly);
+               if (err) {
+                       xenbus_dev_error(dev, err, "creating vbd structure");
+                       return;
+               }
+#endif
+
+               /* Pass in NULL node to skip exist test. */
+               frontend_changed(&be->watch, NULL);
+       }
+}
+
+static int netback_probe(struct xenbus_device *dev,
+                        const struct xenbus_device_id *id)
+{
+       struct backend_info *be;
+       char *frontend;
+       int err;
+
+       be = kmalloc(sizeof(*be), GFP_KERNEL);
+       if (!be) {
+               xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
+               return -ENOMEM;
+       }
+       memset(be, 0, sizeof(*be));
+
+       frontend = NULL;
+       err = xenbus_gather(dev->nodename,
+                           "frontend-id", "%li", &be->frontend_id,
+                           "frontend", NULL, &frontend,
+                           NULL);
+       if (XENBUS_EXIST_ERR(err))
+               goto free_be;
+       if (err < 0) {
+               xenbus_dev_error(dev, err,
+                                "reading %s/frontend or frontend-id",
+                                dev->nodename);
+               goto free_be;
+       }
+       if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
+               /* If we can't get a frontend path and a frontend-id,
+                * then our bus-id is no longer valid and we need to
+                * destroy the backend device.
+                */
+               err = -ENOENT;
+               goto free_be;
+       }
+
+       be->dev = dev;
+       be->backend_watch.node = dev->nodename;
+       be->backend_watch.callback = backend_changed;
+       err = register_xenbus_watch(&be->backend_watch);
+       if (err) {
+               be->backend_watch.node = NULL;
+               xenbus_dev_error(dev, err, "adding backend watch on %s",
+                                dev->nodename);
+               goto free_be;
+       }
+
+       be->frontpath = frontend;
+       be->watch.node = be->frontpath;
+       be->watch.callback = frontend_changed;
+       err = register_xenbus_watch(&be->watch);
+       if (err) {
+               be->watch.node = NULL;
+               xenbus_dev_error(dev, err,
+                                "adding frontend watch on %s",
+                                be->frontpath);
+               goto free_be;
+       }
+
+       dev->data = be;
+
+       backend_changed(&be->backend_watch, dev->nodename);
+       return 0;
+
+ free_be:
+       if (be->backend_watch.node)
+               unregister_xenbus_watch(&be->backend_watch);
+       if (frontend)
+               kfree(frontend);
+       kfree(be);
+       return err;
+}
+
+static struct xenbus_device_id netback_ids[] = {
+       { "vif" },
+       { "" }
+};
+
+static struct xenbus_driver netback = {
+       .name = "vif",
+       .owner = THIS_MODULE,
+       .ids = netback_ids,
+       .probe = netback_probe,
+       .remove = netback_remove,
+};
+
+void netif_xenbus_init(void)
+{
+       xenbus_register_backend(&netback);
+}
diff -r d4ce28d819a8 -r b402e77aac46 
linux-2.6-xen-sparse/drivers/xen/netback/control.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/control.c        Wed Aug 24 
22:21:24 2005
+++ /dev/null   Wed Aug 24 22:22:11 2005
@@ -1,58 +0,0 @@
-/******************************************************************************
- * arch/xen/drivers/netif/backend/control.c
- * 
- * Routines for interfacing with the control plane.
- * 
- * Copyright (c) 2004, Keir Fraser
- */
-
-#include "common.h"
-
-static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
-{
-    DPRINTK("Received netif backend message, subtype=%d\n", msg->subtype);
-    
-    switch ( msg->subtype )
-    {
-    case CMSG_NETIF_BE_CREATE:
-        netif_create((netif_be_create_t *)&msg->msg[0]);
-        break;        
-    case CMSG_NETIF_BE_DESTROY:
-        netif_destroy((netif_be_destroy_t *)&msg->msg[0]);
-        break;  
-    case CMSG_NETIF_BE_CREDITLIMIT:
-        netif_creditlimit((netif_be_creditlimit_t *)&msg->msg[0]);
-        break;       
-    case CMSG_NETIF_BE_CONNECT:
-        netif_connect((netif_be_connect_t *)&msg->msg[0]);
-        break; 
-    case CMSG_NETIF_BE_DISCONNECT:
-        if ( !netif_disconnect((netif_be_disconnect_t *)&msg->msg[0],msg->id) )
-            return; /* Sending the response is deferred until later. */
-        break;        
-    default:
-        DPRINTK("Parse error while reading message subtype %d, len %d\n",
-                msg->subtype, msg->length);
-        msg->length = 0;
-        break;
-    }
-
-    ctrl_if_send_response(msg);
-}
-
-void netif_ctrlif_init(void)
-{
-    ctrl_msg_t cmsg;
-    netif_be_driver_status_t st;
-
-    (void)ctrl_if_register_receiver(CMSG_NETIF_BE, netif_ctrlif_rx,
-                                    CALLBACK_IN_BLOCKING_CONTEXT);
-
-    /* Send a driver-UP notification to the domain controller. */
-    cmsg.type      = CMSG_NETIF_BE;
-    cmsg.subtype   = CMSG_NETIF_BE_DRIVER_STATUS;
-    cmsg.length    = sizeof(netif_be_driver_status_t);
-    st.status      = NETIF_DRIVER_STATUS_UP;
-    memcpy(cmsg.msg, &st, sizeof(st));
-    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Switch network setup over to xenbus., Xen patchbot -unstable <=