aboutsummaryrefslogtreecommitdiffstats
path: root/linux-2.6-xen-sparse/drivers/xen/netback/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-2.6-xen-sparse/drivers/xen/netback/interface.c')
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/netback/interface.c117
1 files changed, 104 insertions, 13 deletions
diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c
index df0f43b3b2..acf5f80540 100644
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c
@@ -71,12 +71,31 @@ 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. */
@@ -275,37 +294,107 @@ void netif_connect(netif_be_connect_t *connect)
unsigned long tx_shmem_frame = connect->tx_shmem_frame;
unsigned long rx_shmem_frame = connect->rx_shmem_frame;
struct vm_struct *vma;
- pgprot_t prot;
+#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) )
- {
+ 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 )
- {
+ if ( netif->status != DISCONNECTED ) {
connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED;
return;
}
- if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL )
- {
+ if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) {
connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
return;
}
- prot = __pgprot(_KERNPG_TABLE);
- error = direct_remap_area_pages(&init_mm,
- VMALLOC_VMADDR(vma->addr),
- tx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
- prot, domid);
- error |= direct_remap_area_pages(&init_mm,
+
+#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;
+ }
+
+ 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);
@@ -321,6 +410,8 @@ void netif_connect(netif_be_connect_t *connect)
return;
}
+#endif
+
netif->evtchn = evtchn;
netif->tx_shmem_frame = tx_shmem_frame;
netif->rx_shmem_frame = rx_shmem_frame;