[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Clean up and re-indent netback driver.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 7fbaf67a0af5048f94640ea0e44b88408b21b791
# Parent  8bb3f2567b8c5c4b0d93dd1a8e2ee5ea0ea9f103
Clean up and re-indent netback driver.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 8bb3f2567b8c -r 7fbaf67a0af5 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Sep 16 13:06:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Sep 16 13:27:01 2005
@@ -18,16 +18,10 @@
 #include <asm-xen/xen-public/io/netif.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
-
-#ifdef CONFIG_XEN_NETDEV_GRANT
 #include <asm-xen/xen-public/grant_table.h>
 #include <asm-xen/gnttab.h>
 
 #define GRANT_INVALID_REF (0xFFFF)
-
-#endif
-
-
 
 #if 0
 #define ASSERT(_p) \
@@ -44,74 +38,73 @@
 #define WPRINTK(fmt, args...) \
     printk(KERN_WARNING "xen_net: " fmt, ##args)
 
+typedef struct netif_st {
+       /* Unique identifier for this interface. */
+       domid_t          domid;
+       unsigned int     handle;
 
-typedef struct netif_st {
-    /* Unique identifier for this interface. */
-    domid_t          domid;
-    unsigned int     handle;
+       u8               fe_dev_addr[6];
 
-    u8               fe_dev_addr[6];
+       /* Physical parameters of the comms window. */
+       unsigned long    tx_shmem_frame;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       u16              tx_shmem_handle;
+       unsigned long    tx_shmem_vaddr; 
+       grant_ref_t      tx_shmem_ref; 
+#endif
+       unsigned long    rx_shmem_frame;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       u16              rx_shmem_handle;
+       unsigned long    rx_shmem_vaddr; 
+       grant_ref_t      rx_shmem_ref; 
+#endif
+       unsigned int     evtchn;
+       unsigned int     remote_evtchn;
 
-    /* Physical parameters of the comms window. */
-    unsigned long    tx_shmem_frame;
+       /* The shared rings and indexes. */
+       netif_tx_interface_t *tx;
+       netif_rx_interface_t *rx;
+
+       /* Private indexes into shared ring. */
+       NETIF_RING_IDX rx_req_cons;
+       NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */
 #ifdef CONFIG_XEN_NETDEV_GRANT
-    u16              tx_shmem_handle;
-    unsigned long    tx_shmem_vaddr; 
-    grant_ref_t      tx_shmem_ref; 
+       NETIF_RING_IDX rx_resp_prod_copy;
 #endif
-    unsigned long    rx_shmem_frame;
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    u16              rx_shmem_handle;
-    unsigned long    rx_shmem_vaddr; 
-    grant_ref_t      rx_shmem_ref; 
-#endif
-    unsigned int     evtchn;
-    unsigned int     remote_evtchn;
+       NETIF_RING_IDX tx_req_cons;
+       NETIF_RING_IDX tx_resp_prod; /* private version of shared variable */
 
-    /* The shared rings and indexes. */
-    netif_tx_interface_t *tx;
-    netif_rx_interface_t *rx;
+       /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */
+       unsigned long   credit_bytes;
+       unsigned long   credit_usec;
+       unsigned long   remaining_credit;
+       struct timer_list credit_timeout;
 
-    /* Private indexes into shared ring. */
-    NETIF_RING_IDX rx_req_cons;
-    NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    NETIF_RING_IDX rx_resp_prod_copy; /* private version of shared variable */
-#endif
-    NETIF_RING_IDX tx_req_cons;
-    NETIF_RING_IDX tx_resp_prod; /* private version of shared variable */
+       /* Miscellaneous private stuff. */
+       enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
+       int active;
+       struct list_head list;  /* scheduling list */
+       atomic_t         refcnt;
+       struct net_device *dev;
+       struct net_device_stats stats;
 
-    /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */
-    unsigned long   credit_bytes;
-    unsigned long   credit_usec;
-    unsigned long   remaining_credit;
-    struct timer_list credit_timeout;
-
-    /* Miscellaneous private stuff. */
-    enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
-    int active;
-    struct list_head list;  /* scheduling list */
-    atomic_t         refcnt;
-    struct net_device *dev;
-    struct net_device_stats stats;
-
-    struct work_struct free_work;
+       struct work_struct free_work;
 } netif_t;
 
 void netif_creditlimit(netif_t *netif);
 int  netif_disconnect(netif_t *netif);
 
 netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
-void free_netif_callback(netif_t *netif);
+void free_netif(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) ) \
-            free_netif_callback(_b);              \
-    } while (0)
+#define netif_put(_b)                                          \
+       do {                                                    \
+               if ( atomic_dec_and_test(&(_b)->refcnt) )       \
+                       free_netif(_b);                         \
+       } while (0)
 
 void netif_xenbus_init(void);
 
@@ -123,3 +116,13 @@
 irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs);
 
 #endif /* __NETIF__BACKEND__COMMON_H__ */
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 8bb3f2567b8c -r 7fbaf67a0af5 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Fri Sep 16 
13:06:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Fri Sep 16 
13:27:01 2005
@@ -11,104 +11,105 @@
 
 static void __netif_up(netif_t *netif)
 {
-    struct net_device *dev = netif->dev;
-    spin_lock_bh(&dev->xmit_lock);
-    netif->active = 1;
-    spin_unlock_bh(&dev->xmit_lock);
-    (void)bind_evtchn_to_irqhandler(
-        netif->evtchn, netif_be_int, 0, dev->name, netif);
-    netif_schedule_work(netif);
+       struct net_device *dev = netif->dev;
+       spin_lock_bh(&dev->xmit_lock);
+       netif->active = 1;
+       spin_unlock_bh(&dev->xmit_lock);
+       (void)bind_evtchn_to_irqhandler(
+               netif->evtchn, netif_be_int, 0, dev->name, netif);
+       netif_schedule_work(netif);
 }
 
 static void __netif_down(netif_t *netif)
 {
-    struct net_device *dev = netif->dev;
-    spin_lock_bh(&dev->xmit_lock);
-    netif->active = 0;
-    spin_unlock_bh(&dev->xmit_lock);
-    unbind_evtchn_from_irqhandler(netif->evtchn, netif);
-    netif_deschedule_work(netif);
+       struct net_device *dev = netif->dev;
+       spin_lock_bh(&dev->xmit_lock);
+       netif->active = 0;
+       spin_unlock_bh(&dev->xmit_lock);
+       unbind_evtchn_from_irqhandler(netif->evtchn, netif);
+       netif_deschedule_work(netif);
 }
 
 static int net_open(struct net_device *dev)
 {
-    netif_t *netif = netdev_priv(dev);
-    if (netif->status == CONNECTED)
-        __netif_up(netif);
-    netif_start_queue(dev);
-    return 0;
+       netif_t *netif = netdev_priv(dev);
+       if (netif->status == CONNECTED)
+               __netif_up(netif);
+       netif_start_queue(dev);
+       return 0;
 }
 
 static int net_close(struct net_device *dev)
 {
-    netif_t *netif = netdev_priv(dev);
-    netif_stop_queue(dev);
-    if (netif->status == CONNECTED)
-        __netif_down(netif);
-    return 0;
+       netif_t *netif = netdev_priv(dev);
+       netif_stop_queue(dev);
+       if (netif->status == CONNECTED)
+               __netif_down(netif);
+       return 0;
 }
 
 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 *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");
-        return NULL;
-    }
-
-    netif = netdev_priv(dev);
-    memset(netif, 0, sizeof(*netif));
-    netif->domid  = domid;
-    netif->handle = handle;
-    netif->status = DISCONNECTED;
-    atomic_set(&netif->refcnt, 0);
-    netif->dev = dev;
-
-    netif->credit_bytes = netif->remaining_credit = ~0UL;
-    netif->credit_usec  = 0UL;
-    init_timer(&netif->credit_timeout);
-
-    dev->hard_start_xmit = netif_be_start_xmit;
-    dev->get_stats       = netif_be_get_stats;
-    dev->open            = net_open;
-    dev->stop            = net_close;
-    dev->features        = NETIF_F_NO_CSUM;
-
-    /* Disable queuing. */
-    dev->tx_queue_len = 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
-         * non-broadcast address to prevent the address getting stolen by an
-         * Ethernet bridge for STP purposes. (FE:FF:FF:FF:FF:FF)
-         */ 
-        memset(dev->dev_addr, 0xFF, ETH_ALEN);
-        dev->dev_addr[0] &= ~0x01;
-    } else
-        memcpy(dev->dev_addr, be_mac, ETH_ALEN);
-
-    rtnl_lock();
-    err = register_netdevice(dev);
-    rtnl_unlock();
-    if (err) {
-        DPRINTK("Could not register new net device %s: err=%d\n",
-                dev->name, err);
-        free_netdev(dev);
-        return NULL;
-    }
-
-    DPRINTK("Successfully created netif\n");
-    return netif;
+       int err = 0, i;
+       struct net_device *dev;
+       netif_t *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");
+               return NULL;
+       }
+
+       netif = netdev_priv(dev);
+       memset(netif, 0, sizeof(*netif));
+       netif->domid  = domid;
+       netif->handle = handle;
+       netif->status = DISCONNECTED;
+       atomic_set(&netif->refcnt, 0);
+       netif->dev = dev;
+
+       netif->credit_bytes = netif->remaining_credit = ~0UL;
+       netif->credit_usec  = 0UL;
+       init_timer(&netif->credit_timeout);
+
+       dev->hard_start_xmit = netif_be_start_xmit;
+       dev->get_stats       = netif_be_get_stats;
+       dev->open            = net_open;
+       dev->stop            = net_close;
+       dev->features        = NETIF_F_NO_CSUM;
+
+       /* Disable queuing. */
+       dev->tx_queue_len = 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 non-broadcast address to prevent the address getting
+                * stolen by an Ethernet bridge for STP purposes.
+                 * (FE:FF:FF:FF:FF:FF) 
+                */ 
+               memset(dev->dev_addr, 0xFF, ETH_ALEN);
+               dev->dev_addr[0] &= ~0x01;
+       } else
+               memcpy(dev->dev_addr, be_mac, ETH_ALEN);
+
+       rtnl_lock();
+       err = register_netdevice(dev);
+       rtnl_unlock();
+       if (err) {
+               DPRINTK("Could not register new net device %s: err=%d\n",
+                       dev->name, err);
+               free_netdev(dev);
+               return NULL;
+       }
+
+       DPRINTK("Successfully created netif\n");
+       return netif;
 }
 
 static int map_frontend_pages(netif_t *netif, unsigned long localaddr,
@@ -116,191 +117,204 @@
                               unsigned long rx_ring_ref)
 {
 #ifdef CONFIG_XEN_NETDEV_GRANT
-    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;
+       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 mapping tx_ring_ref!\n");
-        return op.handle;
-    }
-
-    netif->tx_shmem_ref    = tx_ring_ref;
-    netif->tx_shmem_handle = op.handle;
-    netif->tx_shmem_vaddr  = localaddr;
-
-    /* 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 mapping rx_ring_ref!\n");
-        return op.handle;
-    }
-
-    netif->rx_shmem_ref    = rx_ring_ref;
-    netif->rx_shmem_handle = op.handle;
-    netif->rx_shmem_vaddr  = localaddr + PAGE_SIZE;
+       BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+       if (op.handle < 0) { 
+               DPRINTK(" Gnttab failure mapping tx_ring_ref!\n");
+               return op.handle;
+       }
+
+       netif->tx_shmem_ref    = tx_ring_ref;
+       netif->tx_shmem_handle = op.handle;
+       netif->tx_shmem_vaddr  = localaddr;
+
+       /* 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(" Gnttab failure mapping rx_ring_ref!\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
-    pgprot_t      prot = __pgprot(_KERNPG_TABLE);
-    int           err;
-
-    err = direct_remap_pfn_range(&init_mm, localaddr,
-                                 tx_ring_ref, PAGE_SIZE,
-                                 prot, netif->domid); 
+       pgprot_t prot = __pgprot(_KERNPG_TABLE);
+       int      err;
+
+       err = direct_remap_pfn_range(
+               &init_mm, localaddr,
+               tx_ring_ref, PAGE_SIZE,
+               prot, netif->domid); 
     
-    err |= direct_remap_pfn_range(&init_mm, localaddr + PAGE_SIZE,
-                                 rx_ring_ref, PAGE_SIZE,
-                                 prot, netif->domid);
-
-    if (err)
-       return err;
+       err |= direct_remap_pfn_range(
+               &init_mm, localaddr + PAGE_SIZE,
+               rx_ring_ref, PAGE_SIZE,
+               prot, netif->domid);
+
+       if (err)
+               return err;
 #endif
 
-    return 0;
+       return 0;
 }
 
 static void unmap_frontend_pages(netif_t *netif)
 {
 #ifdef CONFIG_XEN_NETDEV_GRANT
-    struct gnttab_unmap_grant_ref op;
-
-    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));
-
-    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));
+       struct gnttab_unmap_grant_ref op;
+
+       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));
+
+       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
 
-    return; 
+       return; 
 }
 
 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;
-
-    vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP);
-    if (vma == NULL)
-        return -ENOMEM;
-
-    err = map_frontend_pages(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_pages(netif);
-       vfree(vma->addr);
-       return err;
-    }
-
-    netif->evtchn = op.u.bind_interdomain.port1;
-    netif->remote_evtchn = evtchn;
-
-    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();
-
-    return 0;
-}
-
-static void free_netif(void *arg)
-{
-    evtchn_op_t op = { .cmd = EVTCHNOP_close };
-    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.
-     */
-
-    op.u.close.port = netif->evtchn;
-    op.u.close.dom = DOMID_SELF;
-    HYPERVISOR_event_channel_op(&op);
-    op.u.close.port = netif->remote_evtchn;
-    op.u.close.dom = netif->domid;
-    HYPERVISOR_event_channel_op(&op);
-
-    unregister_netdev(netif->dev);
-
-    if (netif->tx) {
-       unmap_frontend_pages(netif);
-       vfree(netif->tx); /* Frees netif->rx as well. */
-    }
-
-    free_netdev(netif->dev);
-}
-
-void free_netif_callback(netif_t *netif)
-{
-    INIT_WORK(&netif->free_work, free_netif, (void *)netif);
-    schedule_work(&netif->free_work);
+       struct vm_struct *vma;
+       evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
+       int err;
+
+       vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP);
+       if (vma == NULL)
+               return -ENOMEM;
+
+       err = map_frontend_pages(
+               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_pages(netif);
+               vfree(vma->addr);
+               return err;
+       }
+
+       netif->evtchn = op.u.bind_interdomain.port1;
+       netif->remote_evtchn = evtchn;
+
+       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();
+
+       return 0;
+}
+
+static void free_netif_callback(void *arg)
+{
+       evtchn_op_t op = { .cmd = EVTCHNOP_close };
+       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.
+        */
+
+       op.u.close.port = netif->evtchn;
+       op.u.close.dom = DOMID_SELF;
+       HYPERVISOR_event_channel_op(&op);
+       op.u.close.port = netif->remote_evtchn;
+       op.u.close.dom = netif->domid;
+       HYPERVISOR_event_channel_op(&op);
+
+       unregister_netdev(netif->dev);
+
+       if (netif->tx) {
+               unmap_frontend_pages(netif);
+               vfree(netif->tx); /* Frees netif->rx as well. */
+       }
+
+       free_netdev(netif->dev);
+}
+
+void free_netif(netif_t *netif)
+{
+       INIT_WORK(&netif->free_work, free_netif_callback, (void *)netif);
+       schedule_work(&netif->free_work);
 }
 
 void netif_creditlimit(netif_t *netif)
 {
 #if 0
-    /* Set the credit limit (reset remaining credit to new limit). */
-    netif->credit_bytes = netif->remaining_credit = creditlimit->credit_bytes;
-    netif->credit_usec = creditlimit->period_usec;
-
-    if (netif->status == CONNECTED) {
-        /*
-         * Schedule work so that any packets waiting under previous credit 
-         * limit are dealt with (acts like a replenishment point).
-         */
-        netif->credit_timeout.expires = jiffies;
-        netif_schedule_work(netif);
-    }
+       /* Set the credit limit (reset remaining credit to new limit). */
+       netif->credit_bytes     = creditlimit->credit_bytes;
+       netif->remaining_credit = creditlimit->credit_bytes;
+       netif->credit_usec      = creditlimit->period_usec;
+
+       if (netif->status == CONNECTED) {
+               /*
+                * Schedule work so that any packets waiting under previous
+                * credit limit are dealt with (acts as a replenishment point).
+                */
+               netif->credit_timeout.expires = jiffies;
+               netif_schedule_work(netif);
+       }
 #endif
 }
 
 int netif_disconnect(netif_t *netif)
 {
 
-    if (netif->status == CONNECTED) {
-        rtnl_lock();
-        netif->status = DISCONNECTING;
-        wmb();
-        if (netif_running(netif->dev))
-            __netif_down(netif);
-        rtnl_unlock();
-        netif_put(netif);
-        return 0; /* Caller should not send response message. */
-    }
-
-    return 1;
-}
+       if (netif->status == CONNECTED) {
+               rtnl_lock();
+               netif->status = DISCONNECTING;
+               wmb();
+               if (netif_running(netif->dev))
+                       __netif_down(netif);
+               rtnl_unlock();
+               netif_put(netif);
+               return 0; /* Caller should not send response message. */
+       }
+
+       return 1;
+}
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 8bb3f2567b8c -r 7fbaf67a0af5 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Fri Sep 16 
13:06:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Fri Sep 16 
13:27:01 2005
@@ -57,8 +57,8 @@
 #define PKT_PROT_LEN 64
 
 static struct {
-    netif_tx_request_t req;
-    netif_t *netif;
+       netif_tx_request_t req;
+       netif_t *netif;
 } pending_tx_info[MAX_PENDING_REQS];
 static u16 pending_ring[MAX_PENDING_REQS];
 typedef unsigned int PEND_RING_IDX;
@@ -91,49 +91,49 @@
 
 static unsigned long alloc_mfn(void)
 {
-    unsigned long mfn = 0, flags;
-    struct xen_memory_reservation reservation = {
-        .extent_start = mfn_list,
-        .nr_extents   = MAX_MFN_ALLOC,
-        .extent_order = 0,
-        .domid        = DOMID_SELF
-    };
-    spin_lock_irqsave(&mfn_lock, flags);
-    if ( unlikely(alloc_index == 0) )
-        alloc_index = HYPERVISOR_memory_op(
-            XENMEM_increase_reservation, &reservation);
-    if ( alloc_index != 0 )
-        mfn = mfn_list[--alloc_index];
-    spin_unlock_irqrestore(&mfn_lock, flags);
-    return mfn;
+       unsigned long mfn = 0, flags;
+       struct xen_memory_reservation reservation = {
+               .extent_start = mfn_list,
+               .nr_extents   = MAX_MFN_ALLOC,
+               .extent_order = 0,
+               .domid        = DOMID_SELF
+       };
+       spin_lock_irqsave(&mfn_lock, flags);
+       if ( unlikely(alloc_index == 0) )
+               alloc_index = HYPERVISOR_memory_op(
+                       XENMEM_increase_reservation, &reservation);
+       if ( alloc_index != 0 )
+               mfn = mfn_list[--alloc_index];
+       spin_unlock_irqrestore(&mfn_lock, flags);
+       return mfn;
 }
 
 #ifndef CONFIG_XEN_NETDEV_GRANT
 static void free_mfn(unsigned long mfn)
 {
-    unsigned long flags;
-    struct xen_memory_reservation reservation = {
-        .extent_start = &mfn,
-        .nr_extents   = 1,
-        .extent_order = 0,
-        .domid        = DOMID_SELF
-    };
-    spin_lock_irqsave(&mfn_lock, flags);
-    if ( alloc_index != MAX_MFN_ALLOC )
-        mfn_list[alloc_index++] = mfn;
-    else if ( HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation)
-              != 1 )
-        BUG();
-    spin_unlock_irqrestore(&mfn_lock, flags);
+       unsigned long flags;
+       struct xen_memory_reservation reservation = {
+               .extent_start = &mfn,
+               .nr_extents   = 1,
+               .extent_order = 0,
+               .domid        = DOMID_SELF
+       };
+       spin_lock_irqsave(&mfn_lock, flags);
+       if ( alloc_index != MAX_MFN_ALLOC )
+               mfn_list[alloc_index++] = mfn;
+       else
+               BUG_ON(HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+                                           &reservation) != 1);
+       spin_unlock_irqrestore(&mfn_lock, flags);
 }
 #endif
 
 static inline void maybe_schedule_tx_action(void)
 {
-    smp_mb();
-    if ( (NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
-         !list_empty(&net_schedule_list) )
-        tasklet_schedule(&net_tx_tasklet);
+       smp_mb();
+       if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
+           !list_empty(&net_schedule_list))
+               tasklet_schedule(&net_tx_tasklet);
 }
 
 /*
@@ -142,77 +142,77 @@
  */
 static inline int is_xen_skb(struct sk_buff *skb)
 {
-    extern kmem_cache_t *skbuff_cachep;
-    kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next;
-    return (cp == skbuff_cachep);
+       extern kmem_cache_t *skbuff_cachep;
+       kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next;
+       return (cp == skbuff_cachep);
 }
 
 int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-    netif_t *netif = netdev_priv(dev);
-
-    ASSERT(skb->dev == dev);
-
-    /* Drop the packet if the target domain has no receive buffers. */
-    if ( !netif->active || 
-         (netif->rx_req_cons == netif->rx->req_prod) ||
-         ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE) )
-        goto drop;
-
-    /*
-     * We do not copy the packet unless:
-     *  1. The data is shared; or
-     *  2. The data is not allocated from our special cache.
-     * NB. We also couldn't cope with fragmented packets, but we won't get
-     *     any because we not advertise the NETIF_F_SG feature.
-     */
-    if ( skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb) )
-    {
-        int hlen = skb->data - skb->head;
-        struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len);
-        if ( unlikely(nskb == NULL) )
-            goto drop;
-        skb_reserve(nskb, hlen);
-        __skb_put(nskb, skb->len);
-        if (skb_copy_bits(skb, -hlen, nskb->data - hlen, skb->len + hlen))
-            BUG();
-        nskb->dev = skb->dev;
-        nskb->proto_csum_valid = skb->proto_csum_valid;
-        dev_kfree_skb(skb);
-        skb = nskb;
-    }
+       netif_t *netif = netdev_priv(dev);
+
+       ASSERT(skb->dev == dev);
+
+       /* Drop the packet if the target domain has no receive buffers. */
+       if (!netif->active || 
+           (netif->rx_req_cons == netif->rx->req_prod) ||
+           ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE))
+               goto drop;
+
+       /*
+        * We do not copy the packet unless:
+        *  1. The data is shared; or
+        *  2. The data is not allocated from our special cache.
+        * NB. We also couldn't cope with fragmented packets, but we won't get
+        *     any because we not advertise the NETIF_F_SG feature.
+        */
+       if (skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb)) {
+               int hlen = skb->data - skb->head;
+               struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len);
+               if ( unlikely(nskb == NULL) )
+                       goto drop;
+               skb_reserve(nskb, hlen);
+               __skb_put(nskb, skb->len);
+               BUG_ON(skb_copy_bits(skb, -hlen, nskb->data - hlen,
+                                    skb->len + hlen));
+               nskb->dev = skb->dev;
+               nskb->proto_csum_valid = skb->proto_csum_valid;
+               dev_kfree_skb(skb);
+               skb = nskb;
+       }
 #ifdef CONFIG_XEN_NETDEV_GRANT
 #ifdef DEBUG_GRANT
-    printk(KERN_ALERT "#### be_xmit: req_prod=%d req_cons=%d id=%04x 
gr=%04x\n",
-           netif->rx->req_prod,
-           netif->rx_req_cons,
-           netif->rx->ring[
-                  MASK_NETIF_RX_IDX(netif->rx_req_cons)].req.id,
-           netif->rx->ring[
-                  MASK_NETIF_RX_IDX(netif->rx_req_cons)].req.gref);
-#endif
-#endif
-    netif->rx_req_cons++;
-    netif_get(netif);
-
-    skb_queue_tail(&rx_queue, skb);
-    tasklet_schedule(&net_rx_tasklet);
-
-    return 0;
+       printk(KERN_ALERT "#### be_xmit: req_prod=%d req_cons=%d "
+              "id=%04x gr=%04x\n",
+              netif->rx->req_prod,
+              netif->rx_req_cons,
+              netif->rx->ring[
+                      MASK_NETIF_RX_IDX(netif->rx_req_cons)].req.id,
+              netif->rx->ring[
+                      MASK_NETIF_RX_IDX(netif->rx_req_cons)].req.gref);
+#endif
+#endif
+       netif->rx_req_cons++;
+       netif_get(netif);
+
+       skb_queue_tail(&rx_queue, skb);
+       tasklet_schedule(&net_rx_tasklet);
+
+       return 0;
 
  drop:
-    netif->stats.tx_dropped++;
-    dev_kfree_skb(skb);
-    return 0;
+       netif->stats.tx_dropped++;
+       dev_kfree_skb(skb);
+       return 0;
 }
 
 #if 0
 static void xen_network_done_notify(void)
 {
-    static struct net_device *eth0_dev = NULL;
-    if ( unlikely(eth0_dev == NULL) )
-        eth0_dev = __dev_get_by_name("eth0");
-    netif_rx_schedule(eth0_dev);
+       static struct net_device *eth0_dev = NULL;
+       if (unlikely(eth0_dev == NULL))
+               eth0_dev = __dev_get_by_name("eth0");
+       netif_rx_schedule(eth0_dev);
 }
 /* 
  * Add following to poll() function in NAPI driver (Tigon3 is example):
@@ -221,658 +221,654 @@
  */
 int xen_network_done(void)
 {
-    return skb_queue_empty(&rx_queue);
+       return skb_queue_empty(&rx_queue);
 }
 #endif
 
 static void net_rx_action(unsigned long unused)
 {
-    netif_t *netif = NULL; 
-    s8 status;
-    u16 size, id, evtchn;
-    multicall_entry_t *mcl;
-    mmu_update_t *mmu;
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    gnttab_transfer_t *gop;
-#else
-    struct mmuext_op *mmuext;
-#endif
-    unsigned long vdata, old_mfn, new_mfn;
-    struct sk_buff_head rxq;
-    struct sk_buff *skb;
-    u16 notify_list[NETIF_RX_RING_SIZE];
-    int notify_nr = 0;
-
-    skb_queue_head_init(&rxq);
-
-    mcl = rx_mcl;
-    mmu = rx_mmu;
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    gop = grant_rx_op;
-#else
-    mmuext = rx_mmuext;
-#endif
-
-    while ( (skb = skb_dequeue(&rx_queue)) != NULL )
-    {
-        netif   = netdev_priv(skb->dev);
-        vdata   = (unsigned long)skb->data;
-        old_mfn = virt_to_mfn(vdata);
-
-        /* Memory squeeze? Back off for an arbitrary while. */
-        if ( (new_mfn = alloc_mfn()) == 0 )
-        {
-            if ( net_ratelimit() )
-                WPRINTK("Memory squeeze in netback driver.\n");
-            mod_timer(&net_timer, jiffies + HZ);
-            skb_queue_head(&rx_queue, skb);
-            break;
-        }
-        /*
-         * Set the new P2M table entry before reassigning the old data page.
-         * Heed the comment in pgtable-2level.h:pte_page(). :-)
-         */
-        phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn;
-
-        MULTI_update_va_mapping(mcl, vdata,
-                               pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
-        mcl++;
-
-#ifdef CONFIG_XEN_NETDEV_GRANT
-        gop->mfn = old_mfn;
-        gop->domid = netif->domid;
-        gop->ref = netif->rx->ring[
-        MASK_NETIF_RX_IDX(netif->rx_resp_prod_copy)].req.gref;
-        netif->rx_resp_prod_copy++;
-        gop++;
-#else
-        mcl->op = __HYPERVISOR_mmuext_op;
-        mcl->args[0] = (unsigned long)mmuext;
-        mcl->args[1] = 1;
-        mcl->args[2] = 0;
-        mcl->args[3] = netif->domid;
-        mcl++;
-
-        mmuext->cmd = MMUEXT_REASSIGN_PAGE;
-        mmuext->arg1.mfn = old_mfn;
-        mmuext++;
-#endif
-        mmu->ptr = ((unsigned long long)new_mfn << PAGE_SHIFT) | 
MMU_MACHPHYS_UPDATE;
-        mmu->val = __pa(vdata) >> PAGE_SHIFT;  
-        mmu++;
-
-        __skb_queue_tail(&rxq, skb);
+       netif_t *netif = NULL; 
+       s8 status;
+       u16 size, id, evtchn;
+       multicall_entry_t *mcl;
+       mmu_update_t *mmu;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       gnttab_transfer_t *gop;
+#else
+       struct mmuext_op *mmuext;
+#endif
+       unsigned long vdata, old_mfn, new_mfn;
+       struct sk_buff_head rxq;
+       struct sk_buff *skb;
+       u16 notify_list[NETIF_RX_RING_SIZE];
+       int notify_nr = 0;
+
+       skb_queue_head_init(&rxq);
+
+       mcl = rx_mcl;
+       mmu = rx_mmu;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       gop = grant_rx_op;
+#else
+       mmuext = rx_mmuext;
+#endif
+
+       while ((skb = skb_dequeue(&rx_queue)) != NULL) {
+               netif   = netdev_priv(skb->dev);
+               vdata   = (unsigned long)skb->data;
+               old_mfn = virt_to_mfn(vdata);
+
+               /* Memory squeeze? Back off for an arbitrary while. */
+               if ((new_mfn = alloc_mfn()) == 0) {
+                       if ( net_ratelimit() )
+                               WPRINTK("Memory squeeze in netback driver.\n");
+                       mod_timer(&net_timer, jiffies + HZ);
+                       skb_queue_head(&rx_queue, skb);
+                       break;
+               }
+               /*
+                * Set the new P2M table entry before reassigning the old data
+                * page. Heed the comment in pgtable-2level.h:pte_page(). :-)
+                */
+               phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] =
+                       new_mfn;
+
+               MULTI_update_va_mapping(mcl, vdata,
+                                       pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
+               mcl++;
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
+               gop->mfn = old_mfn;
+               gop->domid = netif->domid;
+               gop->ref = netif->rx->ring[
+                       MASK_NETIF_RX_IDX(netif->rx_resp_prod_copy)].req.gref;
+               netif->rx_resp_prod_copy++;
+               gop++;
+#else
+               mcl->op = __HYPERVISOR_mmuext_op;
+               mcl->args[0] = (unsigned long)mmuext;
+               mcl->args[1] = 1;
+               mcl->args[2] = 0;
+               mcl->args[3] = netif->domid;
+               mcl++;
+
+               mmuext->cmd = MMUEXT_REASSIGN_PAGE;
+               mmuext->arg1.mfn = old_mfn;
+               mmuext++;
+#endif
+               mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
+                       MMU_MACHPHYS_UPDATE;
+               mmu->val = __pa(vdata) >> PAGE_SHIFT;  
+               mmu++;
+
+               __skb_queue_tail(&rxq, skb);
 
 #ifdef DEBUG_GRANT
-        dump_packet('a', old_mfn, vdata);
-#endif
-        /* Filled the batch queue? */
-        if ( (mcl - rx_mcl) == ARRAY_SIZE(rx_mcl) )
-            break;
-    }
-
-    if ( mcl == rx_mcl )
-        return;
-
-    mcl->op = __HYPERVISOR_mmu_update;
-    mcl->args[0] = (unsigned long)rx_mmu;
-    mcl->args[1] = mmu - rx_mmu;
-    mcl->args[2] = 0;
-    mcl->args[3] = DOMID_SELF;
-    mcl++;
-
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
-#else
-    mcl[-3].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
-#endif
-    if ( unlikely(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0) )
-        BUG();
-
-    mcl = rx_mcl;
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    if(HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, 
-                                 gop - grant_rx_op)) { 
-        /* 
-        ** The other side has given us a bad grant ref, or has no headroom, 
-        ** or has gone away. Unfortunately the current grant table code 
-        ** doesn't inform us which is the case, so not much we can do. 
-        */
-        DPRINTK("net_rx: transfer to DOM%u failed; dropping (up to) %d "
-                "packets.\n", grant_rx_op[0].domid, gop - grant_rx_op); 
-    }
-    gop = grant_rx_op;
-#else
-    mmuext = rx_mmuext;
-#endif
-    while ( (skb = __skb_dequeue(&rxq)) != NULL )
-    {
-        netif   = netdev_priv(skb->dev);
-        size    = skb->tail - skb->data;
-
-        /* Rederive the machine addresses. */
-        new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
-#ifdef CONFIG_XEN_NETDEV_GRANT
-        old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */
-#else
-        old_mfn = mmuext[0].arg1.mfn;
-#endif
-        atomic_set(&(skb_shinfo(skb)->dataref), 1);
-        skb_shinfo(skb)->nr_frags = 0;
-        skb_shinfo(skb)->frag_list = NULL;
-
-        netif->stats.tx_bytes += size;
-        netif->stats.tx_packets++;
-
-        /* The update_va_mapping() must not fail. */
-        BUG_ON(mcl[0].result != 0);
-
-        /* Check the reassignment error code. */
-        status = NETIF_RSP_OKAY;
-#ifdef CONFIG_XEN_NETDEV_GRANT
-        if(gop->status != 0) { 
-            DPRINTK("Bad status %d from grant transfer to DOM%u\n", 
-                    gop->status, netif->domid);
-            /* XXX SMH: should free 'old_mfn' here */
-            status = NETIF_RSP_ERROR; 
-        } 
-#else
-        if ( unlikely(mcl[1].result != 0) )
-        {
-            DPRINTK("Failed MMU update transferring to DOM%u\n", netif->domid);
-            free_mfn(old_mfn);
-            status = NETIF_RSP_ERROR;
-        }
-#endif
-        evtchn = netif->evtchn;
-        id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
-        if ( make_rx_response(netif, id, status,
-                              (old_mfn << PAGE_SHIFT) | /* XXX */
-                              ((unsigned long)skb->data & ~PAGE_MASK),
-                              size, skb->proto_csum_valid) &&
-             (rx_notify[evtchn] == 0) )
-        {
-            rx_notify[evtchn] = 1;
-            notify_list[notify_nr++] = evtchn;
-        }
-
-        netif_put(netif);
-        dev_kfree_skb(skb);
-#ifdef CONFIG_XEN_NETDEV_GRANT
-        mcl++;
-        gop++;
-#else
-        mcl += 2;
-        mmuext += 1;
-#endif
-    }
-
-    while ( notify_nr != 0 )
-    {
-        evtchn = notify_list[--notify_nr];
-        rx_notify[evtchn] = 0;
-        notify_via_evtchn(evtchn);
-    }
-
-  out: 
-    /* More work to do? */
-    if ( !skb_queue_empty(&rx_queue) && !timer_pending(&net_timer) )
-        tasklet_schedule(&net_rx_tasklet);
+               dump_packet('a', old_mfn, vdata);
+#endif
+               /* Filled the batch queue? */
+               if ((mcl - rx_mcl) == ARRAY_SIZE(rx_mcl))
+                       break;
+       }
+
+       if (mcl == rx_mcl)
+               return;
+
+       mcl->op = __HYPERVISOR_mmu_update;
+       mcl->args[0] = (unsigned long)rx_mmu;
+       mcl->args[1] = mmu - rx_mmu;
+       mcl->args[2] = 0;
+       mcl->args[3] = DOMID_SELF;
+       mcl++;
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
+#else
+       mcl[-3].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
+#endif
+       BUG_ON(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0);
+
+       mcl = rx_mcl;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       if(HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, 
+                                    gop - grant_rx_op)) { 
+               /*
+                * The other side has given us a bad grant ref, or has no 
+                * headroom, or has gone away. Unfortunately the current grant
+                * table code doesn't inform us which is the case, so not much
+                * we can do. 
+                */
+               DPRINTK("net_rx: transfer to DOM%u failed; dropping (up to) "
+                       "%d packets.\n",
+                       grant_rx_op[0].domid, gop - grant_rx_op); 
+       }
+       gop = grant_rx_op;
+#else
+       mmuext = rx_mmuext;
+#endif
+       while ((skb = __skb_dequeue(&rxq)) != NULL) {
+               netif   = netdev_priv(skb->dev);
+               size    = skb->tail - skb->data;
+
+               /* Rederive the machine addresses. */
+               new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+               old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */
+#else
+               old_mfn = mmuext[0].arg1.mfn;
+#endif
+               atomic_set(&(skb_shinfo(skb)->dataref), 1);
+               skb_shinfo(skb)->nr_frags = 0;
+               skb_shinfo(skb)->frag_list = NULL;
+
+               netif->stats.tx_bytes += size;
+               netif->stats.tx_packets++;
+
+               /* The update_va_mapping() must not fail. */
+               BUG_ON(mcl[0].result != 0);
+
+               /* Check the reassignment error code. */
+               status = NETIF_RSP_OKAY;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+               if(gop->status != 0) { 
+                       DPRINTK("Bad status %d from grant transfer to DOM%u\n",
+                               gop->status, netif->domid);
+                       /* XXX SMH: should free 'old_mfn' here */
+                       status = NETIF_RSP_ERROR; 
+               } 
+#else
+               if (unlikely(mcl[1].result != 0)) {
+                       DPRINTK("Failed MMU update transferring to DOM%u\n",
+                               netif->domid);
+                       free_mfn(old_mfn);
+                       status = NETIF_RSP_ERROR;
+               }
+#endif
+               evtchn = netif->evtchn;
+               id = netif->rx->ring[
+                       MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
+               if (make_rx_response(netif, id, status,
+                                    (old_mfn << PAGE_SHIFT) | /* XXX */
+                                    ((unsigned long)skb->data & ~PAGE_MASK),
+                                    size, skb->proto_csum_valid) &&
+                   (rx_notify[evtchn] == 0)) {
+                       rx_notify[evtchn] = 1;
+                       notify_list[notify_nr++] = evtchn;
+               }
+
+               netif_put(netif);
+               dev_kfree_skb(skb);
+#ifdef CONFIG_XEN_NETDEV_GRANT
+               mcl++;
+               gop++;
+#else
+               mcl += 2;
+               mmuext += 1;
+#endif
+       }
+
+       while (notify_nr != 0) {
+               evtchn = notify_list[--notify_nr];
+               rx_notify[evtchn] = 0;
+               notify_via_evtchn(evtchn);
+       }
+
+       /* More work to do? */
+       if (!skb_queue_empty(&rx_queue) && !timer_pending(&net_timer))
+               tasklet_schedule(&net_rx_tasklet);
 #if 0
-    else
-        xen_network_done_notify();
+       else
+               xen_network_done_notify();
 #endif
 }
 
 static void net_alarm(unsigned long unused)
 {
-    tasklet_schedule(&net_rx_tasklet);
+       tasklet_schedule(&net_rx_tasklet);
 }
 
 struct net_device_stats *netif_be_get_stats(struct net_device *dev)
 {
-    netif_t *netif = netdev_priv(dev);
-    return &netif->stats;
+       netif_t *netif = netdev_priv(dev);
+       return &netif->stats;
 }
 
 static int __on_net_schedule_list(netif_t *netif)
 {
-    return netif->list.next != NULL;
+       return netif->list.next != NULL;
 }
 
 static void remove_from_net_schedule_list(netif_t *netif)
 {
-    spin_lock_irq(&net_schedule_list_lock);
-    if ( likely(__on_net_schedule_list(netif)) )
-    {
-        list_del(&netif->list);
-        netif->list.next = NULL;
-        netif_put(netif);
-    }
-    spin_unlock_irq(&net_schedule_list_lock);
+       spin_lock_irq(&net_schedule_list_lock);
+       if (likely(__on_net_schedule_list(netif))) {
+               list_del(&netif->list);
+               netif->list.next = NULL;
+               netif_put(netif);
+       }
+       spin_unlock_irq(&net_schedule_list_lock);
 }
 
 static void add_to_net_schedule_list_tail(netif_t *netif)
 {
-    if ( __on_net_schedule_list(netif) )
-        return;
-
-    spin_lock_irq(&net_schedule_list_lock);
-    if ( !__on_net_schedule_list(netif) && netif->active )
-    {
-        list_add_tail(&netif->list, &net_schedule_list);
-        netif_get(netif);
-    }
-    spin_unlock_irq(&net_schedule_list_lock);
+       if (__on_net_schedule_list(netif))
+               return;
+
+       spin_lock_irq(&net_schedule_list_lock);
+       if (!__on_net_schedule_list(netif) && netif->active) {
+               list_add_tail(&netif->list, &net_schedule_list);
+               netif_get(netif);
+       }
+       spin_unlock_irq(&net_schedule_list_lock);
 }
 
 void netif_schedule_work(netif_t *netif)
 {
-    if ( (netif->tx_req_cons != netif->tx->req_prod) &&
-         ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE) )
-    {
-        add_to_net_schedule_list_tail(netif);
-        maybe_schedule_tx_action();
-    }
+       if ((netif->tx_req_cons != netif->tx->req_prod) &&
+           ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE)) {
+               add_to_net_schedule_list_tail(netif);
+               maybe_schedule_tx_action();
+       }
 }
 
 void netif_deschedule_work(netif_t *netif)
 {
-    remove_from_net_schedule_list(netif);
+       remove_from_net_schedule_list(netif);
 }
 
 
 static void tx_credit_callback(unsigned long data)
 {
-    netif_t *netif = (netif_t *)data;
-    netif->remaining_credit = netif->credit_bytes;
-    netif_schedule_work(netif);
+       netif_t *netif = (netif_t *)data;
+       netif->remaining_credit = netif->credit_bytes;
+       netif_schedule_work(netif);
 }
 
 inline static void net_tx_action_dealloc(void)
 {
 #ifdef CONFIG_XEN_NETDEV_GRANT
-    gnttab_unmap_grant_ref_t *gop;
-#else
-    multicall_entry_t *mcl;
-#endif
-    u16 pending_idx;
-    PEND_RING_IDX dc, dp;
-    netif_t *netif;
-
-    dc = dealloc_cons;
-    dp = dealloc_prod;
-
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    /*
-     * Free up any grants we have finished using
-     */
-    gop = tx_unmap_ops;
-    while ( dc != dp )
-    {
-        pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
-        gop->host_addr    = MMAP_VADDR(pending_idx);
-        gop->dev_bus_addr = 0;
-        gop->handle       = grant_tx_ref[pending_idx];
-        grant_tx_ref[pending_idx] = GRANT_INVALID_REF;
-        gop++;
-    }
-    BUG_ON(HYPERVISOR_grant_table_op(
-               GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops));
-#else
-    mcl = tx_mcl;
-    while ( dc != dp )
-    {
-        pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
-       MULTI_update_va_mapping(mcl, MMAP_VADDR(pending_idx),
-                               __pte(0), 0);
-        mcl++;     
-    }
-
-    mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
-    if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) )
-        BUG();
-
-    mcl = tx_mcl;
-#endif
-    while ( dealloc_cons != dp )
-    {
+       gnttab_unmap_grant_ref_t *gop;
+#else
+       multicall_entry_t *mcl;
+#endif
+       u16 pending_idx;
+       PEND_RING_IDX dc, dp;
+       netif_t *netif;
+
+       dc = dealloc_cons;
+       dp = dealloc_prod;
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       /*
+        * Free up any grants we have finished using
+        */
+       gop = tx_unmap_ops;
+       while (dc != dp) {
+               pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
+               gop->host_addr    = MMAP_VADDR(pending_idx);
+               gop->dev_bus_addr = 0;
+               gop->handle       = grant_tx_ref[pending_idx];
+               grant_tx_ref[pending_idx] = GRANT_INVALID_REF;
+               gop++;
+       }
+       BUG_ON(HYPERVISOR_grant_table_op(
+               GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops));
+#else
+       mcl = tx_mcl;
+       while (dc != dp) {
+               pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
+               MULTI_update_va_mapping(mcl, MMAP_VADDR(pending_idx),
+                                       __pte(0), 0);
+               mcl++;     
+       }
+
+       mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
+       BUG_ON(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0);
+
+       mcl = tx_mcl;
+#endif
+       while (dealloc_cons != dp) {
 #ifndef CONFIG_XEN_NETDEV_GRANT
-        /* The update_va_mapping() must not fail. */
-        BUG_ON(mcl[0].result != 0);
-#endif
-
-        pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)];
-
-        netif = pending_tx_info[pending_idx].netif;
-
-        make_tx_response(netif, pending_tx_info[pending_idx].req.id, 
-                         NETIF_RSP_OKAY);
+               /* The update_va_mapping() must not fail. */
+               BUG_ON(mcl[0].result != 0);
+#endif
+
+               pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)];
+
+               netif = pending_tx_info[pending_idx].netif;
+
+               make_tx_response(netif, pending_tx_info[pending_idx].req.id, 
+                                NETIF_RSP_OKAY);
         
-        pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
-
-        /*
-         * Scheduling checks must happen after the above response is posted.
-         * This avoids a possible race with a guest OS on another CPU if that
-         * guest is testing against 'resp_prod' when deciding whether to notify
-         * us when it queues additional packets.
-         */
-        mb();
-        if ( (netif->tx_req_cons != netif->tx->req_prod) &&
-             ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE) )
-            add_to_net_schedule_list_tail(netif);
+               pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
+
+               /*
+                * Scheduling checks must happen after the above response is
+                * posted. This avoids a possible race with a guest OS on
+                * another CPU if that guest is testing against 'resp_prod'
+                * when deciding whether to notify us when it queues additional
+                 * packets.
+                */
+               mb();
+               if ((netif->tx_req_cons != netif->tx->req_prod) &&
+                   ((netif->tx_req_cons-netif->tx_resp_prod) !=
+                    NETIF_TX_RING_SIZE))
+                       add_to_net_schedule_list_tail(netif);
         
-        netif_put(netif);
+               netif_put(netif);
 
 #ifndef CONFIG_XEN_NETDEV_GRANT
-        mcl++;
-#endif
-    }
-
+               mcl++;
+#endif
+       }
 }
 
 /* Called after netfront has transmitted */
 static void net_tx_action(unsigned long unused)
 {
-    struct list_head *ent;
-    struct sk_buff *skb;
-    netif_t *netif;
-    netif_tx_request_t txreq;
-    u16 pending_idx;
-    NETIF_RING_IDX i;
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    gnttab_map_grant_ref_t *mop;
-#else
-    multicall_entry_t *mcl;
-#endif
-    unsigned int data_len;
-
-    if ( dealloc_cons != dealloc_prod )
-        net_tx_action_dealloc();
-
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    mop = tx_map_ops;
-#else
-    mcl = tx_mcl;
-#endif
-    while ( (NR_PENDING_REQS < MAX_PENDING_REQS) &&
-            !list_empty(&net_schedule_list) )
-    {
-        /* Get a netif from the list with work to do. */
-        ent = net_schedule_list.next;
-        netif = list_entry(ent, netif_t, list);
-        netif_get(netif);
-        remove_from_net_schedule_list(netif);
-
-        /* Work to do? */
-        i = netif->tx_req_cons;
-        if ( (i == netif->tx->req_prod) ||
-             ((i-netif->tx_resp_prod) == NETIF_TX_RING_SIZE) )
-        {
-            netif_put(netif);
-            continue;
-        }
-
-        rmb(); /* Ensure that we see the request before we copy it. */
-        memcpy(&txreq, &netif->tx->ring[MASK_NETIF_TX_IDX(i)].req, 
-               sizeof(txreq));
-        /* Credit-based scheduling. */
-        if ( txreq.size > netif->remaining_credit )
-        {
-            unsigned long now = jiffies;
-            unsigned long next_credit = 
-                netif->credit_timeout.expires +
-                msecs_to_jiffies(netif->credit_usec / 1000);
-
-            /* Timer could already be pending in some rare cases. */
-            if ( timer_pending(&netif->credit_timeout) )
-                break;
-
-            /* Already passed the point at which we can replenish credit? */
-            if ( time_after_eq(now, next_credit) )
-            {
-                netif->credit_timeout.expires = now;
-                netif->remaining_credit = netif->credit_bytes;
-            }
-
-            /* Still too big to send right now? Then set a timer callback. */
-            if ( txreq.size > netif->remaining_credit )
-            {
-                netif->remaining_credit = 0;
-                netif->credit_timeout.expires  = next_credit;
-                netif->credit_timeout.data     = (unsigned long)netif;
-                netif->credit_timeout.function = tx_credit_callback;
-                add_timer_on(&netif->credit_timeout, smp_processor_id());
-                break;
-            }
-        }
-        netif->remaining_credit -= txreq.size;
-
-        /*
-         * Why the barrier? It ensures that the frontend sees updated req_cons
-         * before we check for more work to schedule.
-         */
-        netif->tx->req_cons = ++netif->tx_req_cons;
-        mb();
-
-        netif_schedule_work(netif);
-
-        if ( unlikely(txreq.size < ETH_HLEN) || 
-             unlikely(txreq.size > ETH_FRAME_LEN) )
-        {
-            DPRINTK("Bad packet size: %d\n", txreq.size);
-            make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-            netif_put(netif);
-            continue; 
-        }
-
-        /* No crossing a page boundary as the payload mustn't fragment. */
-        if ( unlikely(((txreq.addr & ~PAGE_MASK) + txreq.size) >= PAGE_SIZE) ) 
-        {
-            DPRINTK("txreq.addr: %lx, size: %u, end: %lu\n", 
-                    txreq.addr, txreq.size, 
-                    (txreq.addr &~PAGE_MASK) + txreq.size);
-            make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-            netif_put(netif);
-            continue;
-        }
-
-        pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
-
-        data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size;
-
-        if ( unlikely((skb = alloc_skb(data_len+16, GFP_ATOMIC)) == NULL) )
-        {
-            DPRINTK("Can't allocate a skb in start_xmit.\n");
-            make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-            netif_put(netif);
-            break;
-        }
-
-        /* Packets passed to netif_rx() must have some headroom. */
-        skb_reserve(skb, 16);
-#ifdef CONFIG_XEN_NETDEV_GRANT
-        mop->host_addr = MMAP_VADDR(pending_idx);
-        mop->dom       = netif->domid;
-        mop->ref       = txreq.addr >> PAGE_SHIFT;
-        mop->flags     = GNTMAP_host_map | GNTMAP_readonly;
-        mop++;
-#else
-       MULTI_update_va_mapping_otherdomain(
-           mcl, MMAP_VADDR(pending_idx),
-           pfn_pte_ma(txreq.addr >> PAGE_SHIFT, PAGE_KERNEL),
-           0, netif->domid);
-
-        mcl++;
-#endif
-
-        memcpy(&pending_tx_info[pending_idx].req, &txreq, sizeof(txreq));
-        pending_tx_info[pending_idx].netif = netif;
-        *((u16 *)skb->data) = pending_idx;
-
-        __skb_queue_tail(&tx_queue, skb);
-
-        pending_cons++;
-
-#ifdef CONFIG_XEN_NETDEV_GRANT
-        if ( (mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops) )
-            break;
-#else
-        /* Filled the batch queue? */
-        if ( (mcl - tx_mcl) == ARRAY_SIZE(tx_mcl) )
-            break;
-#endif
-    }
-
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    if ( mop == tx_map_ops )
-        return;
-
-    BUG_ON(HYPERVISOR_grant_table_op(
-        GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops));
-
-    mop = tx_map_ops;
-#else
-    if ( mcl == tx_mcl )
-        return;
-
-    BUG_ON(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0);
-
-    mcl = tx_mcl;
-#endif
-    while ( (skb = __skb_dequeue(&tx_queue)) != NULL )
-    {
-        pending_idx = *((u16 *)skb->data);
-        netif       = pending_tx_info[pending_idx].netif;
-        memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq));
-
-        /* Check the remap error code. */
-#ifdef CONFIG_XEN_NETDEV_GRANT
-        if ( unlikely(mop->handle < 0) )
-        {
-            printk(KERN_ALERT "#### netback grant fails\n");
-            make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-            netif_put(netif);
-            kfree_skb(skb);
-            mop++;
-            pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
-            continue;
-        }
-        phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] =
-                             FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT);
-        grant_tx_ref[pending_idx] = mop->handle;
-#else
-        if ( unlikely(mcl[0].result != 0) )
-        {
-            DPRINTK("Bad page frame\n");
-            make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-            netif_put(netif);
-            kfree_skb(skb);
-            mcl++;
-            pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
-            continue;
-        }
-
-        phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] =
-            FOREIGN_FRAME(txreq.addr >> PAGE_SHIFT);
-#endif
-
-        data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size;
-
-        __skb_put(skb, data_len);
-        memcpy(skb->data, 
-               (void *)(MMAP_VADDR(pending_idx)|(txreq.addr&~PAGE_MASK)),
-               data_len);
-        if ( data_len < txreq.size )
-        {
-            /* Append the packet payload as a fragment. */
-            skb_shinfo(skb)->frags[0].page        = 
-                virt_to_page(MMAP_VADDR(pending_idx));
-            skb_shinfo(skb)->frags[0].size        = txreq.size - data_len;
-            skb_shinfo(skb)->frags[0].page_offset = 
-                (txreq.addr + data_len) & ~PAGE_MASK;
-            skb_shinfo(skb)->nr_frags = 1;
-        }
-        else
-        {
-            /* Schedule a response immediately. */
-            netif_idx_release(pending_idx);
-        }
-
-        skb->data_len  = txreq.size - data_len;
-        skb->len      += skb->data_len;
-
-        skb->dev      = netif->dev;
-        skb->protocol = eth_type_trans(skb, skb->dev);
-
-        /* No checking needed on localhost, but remember the field is blank. */
-        skb->ip_summed        = CHECKSUM_UNNECESSARY;
-        skb->proto_csum_valid = 1;
-        skb->proto_csum_blank = txreq.csum_blank;
-
-        netif->stats.rx_bytes += txreq.size;
-        netif->stats.rx_packets++;
-
-        netif_rx(skb);
-        netif->dev->last_rx = jiffies;
-
-#ifdef CONFIG_XEN_NETDEV_GRANT
-        mop++;
-#else
-        mcl++;
-#endif
-    }
+       struct list_head *ent;
+       struct sk_buff *skb;
+       netif_t *netif;
+       netif_tx_request_t txreq;
+       u16 pending_idx;
+       NETIF_RING_IDX i;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       gnttab_map_grant_ref_t *mop;
+#else
+       multicall_entry_t *mcl;
+#endif
+       unsigned int data_len;
+
+       if (dealloc_cons != dealloc_prod)
+               net_tx_action_dealloc();
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       mop = tx_map_ops;
+#else
+       mcl = tx_mcl;
+#endif
+       while ((NR_PENDING_REQS < MAX_PENDING_REQS) &&
+               !list_empty(&net_schedule_list)) {
+               /* Get a netif from the list with work to do. */
+               ent = net_schedule_list.next;
+               netif = list_entry(ent, netif_t, list);
+               netif_get(netif);
+               remove_from_net_schedule_list(netif);
+
+               /* Work to do? */
+               i = netif->tx_req_cons;
+               if ((i == netif->tx->req_prod) ||
+                   ((i-netif->tx_resp_prod) == NETIF_TX_RING_SIZE)) {
+                       netif_put(netif);
+                       continue;
+               }
+
+               rmb(); /* Ensure that we see the request before we copy it. */
+               memcpy(&txreq, &netif->tx->ring[MASK_NETIF_TX_IDX(i)].req, 
+                      sizeof(txreq));
+               /* Credit-based scheduling. */
+               if (txreq.size > netif->remaining_credit) {
+                       unsigned long now = jiffies;
+                       unsigned long next_credit = 
+                               netif->credit_timeout.expires +
+                               msecs_to_jiffies(netif->credit_usec / 1000);
+
+                       /* Timer could already be pending in rare cases. */
+                       if (timer_pending(&netif->credit_timeout))
+                               break;
+
+                       /* Passed the point where we can replenish credit? */
+                       if (time_after_eq(now, next_credit)) {
+                               netif->credit_timeout.expires = now;
+                               netif->remaining_credit = netif->credit_bytes;
+                       }
+
+                       /* Still too big to send right now? Set a callback. */
+                       if (txreq.size > netif->remaining_credit) {
+                               netif->remaining_credit = 0;
+                               netif->credit_timeout.expires  = 
+                                       next_credit;
+                               netif->credit_timeout.data     =
+                                       (unsigned long)netif;
+                               netif->credit_timeout.function =
+                                       tx_credit_callback;
+                               add_timer_on(&netif->credit_timeout,
+                                            smp_processor_id());
+                               break;
+                       }
+               }
+               netif->remaining_credit -= txreq.size;
+
+               /*
+                * Why the barrier? It ensures that the frontend sees updated
+                * req_cons before we check for more work to schedule.
+                */
+               netif->tx->req_cons = ++netif->tx_req_cons;
+               mb();
+
+               netif_schedule_work(netif);
+
+               if (unlikely(txreq.size < ETH_HLEN) || 
+                   unlikely(txreq.size > ETH_FRAME_LEN)) {
+                       DPRINTK("Bad packet size: %d\n", txreq.size);
+                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
+                       netif_put(netif);
+                       continue; 
+               }
+
+               /* No crossing a page as the payload mustn't fragment. */
+               if (unlikely(((txreq.addr & ~PAGE_MASK) + txreq.size) >=
+                            PAGE_SIZE)) {
+                       DPRINTK("txreq.addr: %lx, size: %u, end: %lu\n", 
+                               txreq.addr, txreq.size, 
+                               (txreq.addr &~PAGE_MASK) + txreq.size);
+                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
+                       netif_put(netif);
+                       continue;
+               }
+
+               pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
+
+               data_len = (txreq.size > PKT_PROT_LEN) ?
+                       PKT_PROT_LEN : txreq.size;
+
+               skb = alloc_skb(data_len+16, GFP_ATOMIC);
+               if (unlikely(skb == NULL)) {
+                       DPRINTK("Can't allocate a skb in start_xmit.\n");
+                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
+                       netif_put(netif);
+                       break;
+               }
+
+               /* Packets passed to netif_rx() must have some headroom. */
+               skb_reserve(skb, 16);
+#ifdef CONFIG_XEN_NETDEV_GRANT
+               mop->host_addr = MMAP_VADDR(pending_idx);
+               mop->dom       = netif->domid;
+               mop->ref       = txreq.addr >> PAGE_SHIFT;
+               mop->flags     = GNTMAP_host_map | GNTMAP_readonly;
+               mop++;
+#else
+               MULTI_update_va_mapping_otherdomain(
+                       mcl, MMAP_VADDR(pending_idx),
+                       pfn_pte_ma(txreq.addr >> PAGE_SHIFT, PAGE_KERNEL),
+                       0, netif->domid);
+
+               mcl++;
+#endif
+
+               memcpy(&pending_tx_info[pending_idx].req,
+                      &txreq, sizeof(txreq));
+               pending_tx_info[pending_idx].netif = netif;
+               *((u16 *)skb->data) = pending_idx;
+
+               __skb_queue_tail(&tx_queue, skb);
+
+               pending_cons++;
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
+               if ((mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops))
+                       break;
+#else
+               /* Filled the batch queue? */
+               if ((mcl - tx_mcl) == ARRAY_SIZE(tx_mcl))
+                       break;
+#endif
+       }
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       if (mop == tx_map_ops)
+               return;
+
+       BUG_ON(HYPERVISOR_grant_table_op(
+               GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops));
+
+       mop = tx_map_ops;
+#else
+       if (mcl == tx_mcl)
+               return;
+
+       BUG_ON(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0);
+
+       mcl = tx_mcl;
+#endif
+       while ((skb = __skb_dequeue(&tx_queue)) != NULL) {
+               pending_idx = *((u16 *)skb->data);
+               netif       = pending_tx_info[pending_idx].netif;
+               memcpy(&txreq, &pending_tx_info[pending_idx].req,
+                      sizeof(txreq));
+
+               /* Check the remap error code. */
+#ifdef CONFIG_XEN_NETDEV_GRANT
+               if (unlikely(mop->handle < 0)) {
+                       printk(KERN_ALERT "#### netback grant fails\n");
+                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
+                       netif_put(netif);
+                       kfree_skb(skb);
+                       mop++;
+                       pending_ring[MASK_PEND_IDX(pending_prod++)] =
+                               pending_idx;
+                       continue;
+               }
+               phys_to_machine_mapping[
+                       __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] =
+                       FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT);
+               grant_tx_ref[pending_idx] = mop->handle;
+#else
+               if (unlikely(mcl[0].result != 0)) {
+                       DPRINTK("Bad page frame\n");
+                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
+                       netif_put(netif);
+                       kfree_skb(skb);
+                       mcl++;
+                       pending_ring[MASK_PEND_IDX(pending_prod++)] =
+                               pending_idx;
+                       continue;
+               }
+
+               phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >>
+                                      PAGE_SHIFT] =
+                       FOREIGN_FRAME(txreq.addr >> PAGE_SHIFT);
+#endif
+
+               data_len = (txreq.size > PKT_PROT_LEN) ?
+                       PKT_PROT_LEN : txreq.size;
+
+               __skb_put(skb, data_len);
+               memcpy(skb->data, 
+                      (void *)(MMAP_VADDR(pending_idx)|
+                               (txreq.addr&~PAGE_MASK)),
+                      data_len);
+               if (data_len < txreq.size) {
+                       /* Append the packet payload as a fragment. */
+                       skb_shinfo(skb)->frags[0].page        = 
+                               virt_to_page(MMAP_VADDR(pending_idx));
+                       skb_shinfo(skb)->frags[0].size        =
+                               txreq.size - data_len;
+                       skb_shinfo(skb)->frags[0].page_offset = 
+                               (txreq.addr + data_len) & ~PAGE_MASK;
+                       skb_shinfo(skb)->nr_frags = 1;
+               } else {
+                       /* Schedule a response immediately. */
+                       netif_idx_release(pending_idx);
+               }
+
+               skb->data_len  = txreq.size - data_len;
+               skb->len      += skb->data_len;
+
+               skb->dev      = netif->dev;
+               skb->protocol = eth_type_trans(skb, skb->dev);
+
+               /*
+                 * No checking needed on localhost, but remember the field is
+                 * blank. 
+                 */
+               skb->ip_summed        = CHECKSUM_UNNECESSARY;
+               skb->proto_csum_valid = 1;
+               skb->proto_csum_blank = txreq.csum_blank;
+
+               netif->stats.rx_bytes += txreq.size;
+               netif->stats.rx_packets++;
+
+               netif_rx(skb);
+               netif->dev->last_rx = jiffies;
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
+               mop++;
+#else
+               mcl++;
+#endif
+       }
 }
 
 static void netif_idx_release(u16 pending_idx)
 {
-    static spinlock_t _lock = SPIN_LOCK_UNLOCKED;
-    unsigned long flags;
-
-    spin_lock_irqsave(&_lock, flags);
-    dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx;
-    spin_unlock_irqrestore(&_lock, flags);
-
-    tasklet_schedule(&net_tx_tasklet);
+       static spinlock_t _lock = SPIN_LOCK_UNLOCKED;
+       unsigned long flags;
+
+       spin_lock_irqsave(&_lock, flags);
+       dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx;
+       spin_unlock_irqrestore(&_lock, flags);
+
+       tasklet_schedule(&net_tx_tasklet);
 }
 
 static void netif_page_release(struct page *page)
 {
-    u16 pending_idx = page - virt_to_page(mmap_vstart);
-
-    /* Ready for next use. */
-    set_page_count(page, 1);
-
-    netif_idx_release(pending_idx);
+       u16 pending_idx = page - virt_to_page(mmap_vstart);
+
+       /* Ready for next use. */
+       set_page_count(page, 1);
+
+       netif_idx_release(pending_idx);
 }
 
 irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
 {
-    netif_t *netif = dev_id;
-    if ( tx_work_exists(netif) )
-    {
-        add_to_net_schedule_list_tail(netif);
-        maybe_schedule_tx_action();
-    }
-    return IRQ_HANDLED;
+       netif_t *netif = dev_id;
+       if (tx_work_exists(netif)) {
+               add_to_net_schedule_list_tail(netif);
+               maybe_schedule_tx_action();
+       }
+       return IRQ_HANDLED;
 }
 
 static void make_tx_response(netif_t *netif, 
                              u16      id,
                              s8       st)
 {
-    NETIF_RING_IDX i = netif->tx_resp_prod;
-    netif_tx_response_t *resp;
-
-    resp = &netif->tx->ring[MASK_NETIF_TX_IDX(i)].resp;
-    resp->id     = id;
-    resp->status = st;
-    wmb();
-    netif->tx->resp_prod = netif->tx_resp_prod = ++i;
-
-    mb(); /* Update producer before checking event threshold. */
-    if ( i == netif->tx->event )
-        notify_via_evtchn(netif->evtchn);
+       NETIF_RING_IDX i = netif->tx_resp_prod;
+       netif_tx_response_t *resp;
+
+       resp = &netif->tx->ring[MASK_NETIF_TX_IDX(i)].resp;
+       resp->id     = id;
+       resp->status = st;
+       wmb();
+       netif->tx->resp_prod = netif->tx_resp_prod = ++i;
+
+       mb(); /* Update producer before checking event threshold. */
+       if (i == netif->tx->event)
+               notify_via_evtchn(netif->evtchn);
 }
 
 static int make_rx_response(netif_t *netif, 
@@ -882,110 +878,120 @@
                             u16      size,
                             u16      csum_valid)
 {
-    NETIF_RING_IDX i = netif->rx_resp_prod;
-    netif_rx_response_t *resp;
-
-    resp = &netif->rx->ring[MASK_NETIF_RX_IDX(i)].resp;
-    resp->addr       = addr;
-    resp->csum_valid = csum_valid;
-    resp->id         = id;
-    resp->status     = (s16)size;
-    if ( st < 0 )
-        resp->status = (s16)st;
-    wmb();
-    netif->rx->resp_prod = netif->rx_resp_prod = ++i;
-
-    mb(); /* Update producer before checking event threshold. */
-    return (i == netif->rx->event);
+       NETIF_RING_IDX i = netif->rx_resp_prod;
+       netif_rx_response_t *resp;
+
+       resp = &netif->rx->ring[MASK_NETIF_RX_IDX(i)].resp;
+       resp->addr       = addr;
+       resp->csum_valid = csum_valid;
+       resp->id         = id;
+       resp->status     = (s16)size;
+       if (st < 0)
+               resp->status = (s16)st;
+       wmb();
+       netif->rx->resp_prod = netif->rx_resp_prod = ++i;
+
+       mb(); /* Update producer before checking event threshold. */
+       return (i == netif->rx->event);
 }
 
 static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs)
 {
-    struct list_head *ent;
-    netif_t *netif;
-    int i = 0;
-
-    printk(KERN_ALERT "netif_schedule_list:\n");
-    spin_lock_irq(&net_schedule_list_lock);
-
-    list_for_each ( ent, &net_schedule_list )
-    {
-        netif = list_entry(ent, netif_t, list);
-        printk(KERN_ALERT " %d: private(rx_req_cons=%08x rx_resp_prod=%08x\n",
-               i, netif->rx_req_cons, netif->rx_resp_prod);               
-        printk(KERN_ALERT "   tx_req_cons=%08x tx_resp_prod=%08x)\n",
-               netif->tx_req_cons, netif->tx_resp_prod);
-        printk(KERN_ALERT "   shared(rx_req_prod=%08x rx_resp_prod=%08x\n",
-               netif->rx->req_prod, netif->rx->resp_prod);
-        printk(KERN_ALERT "   rx_event=%08x tx_req_prod=%08x\n",
-               netif->rx->event, netif->tx->req_prod);
-        printk(KERN_ALERT "   tx_resp_prod=%08x, tx_event=%08x)\n",
-               netif->tx->resp_prod, netif->tx->event);
-        i++;
-    }
-
-    spin_unlock_irq(&net_schedule_list_lock);
-    printk(KERN_ALERT " ** End of netif_schedule_list **\n");
-
-    return IRQ_HANDLED;
+       struct list_head *ent;
+       netif_t *netif;
+       int i = 0;
+
+       printk(KERN_ALERT "netif_schedule_list:\n");
+       spin_lock_irq(&net_schedule_list_lock);
+
+       list_for_each (ent, &net_schedule_list) {
+               netif = list_entry(ent, netif_t, list);
+               printk(KERN_ALERT " %d: private(rx_req_cons=%08x "
+                      "rx_resp_prod=%08x\n",
+                      i, netif->rx_req_cons, netif->rx_resp_prod);
+               printk(KERN_ALERT "   tx_req_cons=%08x tx_resp_prod=%08x)\n",
+                      netif->tx_req_cons, netif->tx_resp_prod);
+               printk(KERN_ALERT "   shared(rx_req_prod=%08x "
+                      "rx_resp_prod=%08x\n",
+                      netif->rx->req_prod, netif->rx->resp_prod);
+               printk(KERN_ALERT "   rx_event=%08x tx_req_prod=%08x\n",
+                      netif->rx->event, netif->tx->req_prod);
+               printk(KERN_ALERT "   tx_resp_prod=%08x, tx_event=%08x)\n",
+                      netif->tx->resp_prod, netif->tx->event);
+               i++;
+       }
+
+       spin_unlock_irq(&net_schedule_list_lock);
+       printk(KERN_ALERT " ** End of netif_schedule_list **\n");
+
+       return IRQ_HANDLED;
 }
 
 static int __init netback_init(void)
 {
-    int i;
-    struct page *page;
-
-    if ( !(xen_start_info->flags & SIF_NET_BE_DOMAIN) &&
-         !(xen_start_info->flags & SIF_INITDOMAIN) )
-        return 0;
-
-    IPRINTK("Initialising Xen netif backend.\n");
-#ifdef CONFIG_XEN_NETDEV_GRANT
-    IPRINTK("Using grant tables.\n");
-#endif
-
-    /* We can increase reservation by this much in net_rx_action(). */
-    balloon_update_driver_allowance(NETIF_RX_RING_SIZE);
-
-    skb_queue_head_init(&rx_queue);
-    skb_queue_head_init(&tx_queue);
-
-    init_timer(&net_timer);
-    net_timer.data = 0;
-    net_timer.function = net_alarm;
+       int i;
+       struct page *page;
+
+       if (!(xen_start_info->flags & SIF_NET_BE_DOMAIN) &&
+           !(xen_start_info->flags & SIF_INITDOMAIN))
+               return 0;
+
+       IPRINTK("Initialising Xen netif backend.\n");
+#ifdef CONFIG_XEN_NETDEV_GRANT
+       IPRINTK("Using grant tables.\n");
+#endif
+
+       /* We can increase reservation by this much in net_rx_action(). */
+       balloon_update_driver_allowance(NETIF_RX_RING_SIZE);
+
+       skb_queue_head_init(&rx_queue);
+       skb_queue_head_init(&tx_queue);
+
+       init_timer(&net_timer);
+       net_timer.data = 0;
+       net_timer.function = net_alarm;
     
-    page = balloon_alloc_empty_page_range(MAX_PENDING_REQS);
-    BUG_ON(page == NULL);
-    mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
-
-    for ( i = 0; i < MAX_PENDING_REQS; i++ )
-    {
-        page = virt_to_page(MMAP_VADDR(i));
-        set_page_count(page, 1);
-        SetPageForeign(page, netif_page_release);
-    }
-
-    pending_cons = 0;
-    pending_prod = MAX_PENDING_REQS;
-    for ( i = 0; i < MAX_PENDING_REQS; i++ )
-        pending_ring[i] = i;
-
-    spin_lock_init(&net_schedule_list_lock);
-    INIT_LIST_HEAD(&net_schedule_list);
-
-    netif_xenbus_init();
-
-    (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG),
-                      netif_be_dbg, SA_SHIRQ, 
-                      "net-be-dbg", &netif_be_dbg);
-
-    return 0;
+       page = balloon_alloc_empty_page_range(MAX_PENDING_REQS);
+       BUG_ON(page == NULL);
+       mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+
+       for (i = 0; i < MAX_PENDING_REQS; i++) {
+               page = virt_to_page(MMAP_VADDR(i));
+               set_page_count(page, 1);
+               SetPageForeign(page, netif_page_release);
+       }
+
+       pending_cons = 0;
+       pending_prod = MAX_PENDING_REQS;
+       for (i = 0; i < MAX_PENDING_REQS; i++)
+               pending_ring[i] = i;
+
+       spin_lock_init(&net_schedule_list_lock);
+       INIT_LIST_HEAD(&net_schedule_list);
+
+       netif_xenbus_init();
+
+       (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG),
+                         netif_be_dbg, SA_SHIRQ, 
+                         "net-be-dbg", &netif_be_dbg);
+
+       return 0;
 }
 
 static void netback_cleanup(void)
 {
-    BUG();
+       BUG();
 }
 
 module_init(netback_init);
 module_exit(netback_cleanup);
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 8bb3f2567b8c -r 7fbaf67a0af5 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Sep 16 13:06:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Sep 16 13:27:01 2005
@@ -294,3 +294,13 @@
 {
        xenbus_register_backend(&netback);
 }
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.