Module Name: src
Committed By: jym
Date: Fri Apr 29 22:58:46 UTC 2011
Modified Files:
src/sys/arch/xen/xen: xbdback_xenbus.c xennetback_xenbus.c
Log Message:
Move the connection code of xbdback(4) and xvif(4) backends in separate
functions. The frontend watch function is easier to read, and mixing
switch() with goto's error paths is rather error-prone.
While here, sprinkle some aprint_*.
Tested under amd64 dom0 with i386 PAE and amd64 domUs.
To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/sys/arch/xen/xen/xbdback_xenbus.c
cvs rdiff -u -r1.44 -r1.45 src/sys/arch/xen/xen/xennetback_xenbus.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/xen/xen/xbdback_xenbus.c
diff -u src/sys/arch/xen/xen/xbdback_xenbus.c:1.33 src/sys/arch/xen/xen/xbdback_xenbus.c:1.34
--- src/sys/arch/xen/xen/xbdback_xenbus.c:1.33 Sat Mar 5 15:12:16 2011
+++ src/sys/arch/xen/xen/xbdback_xenbus.c Fri Apr 29 22:58:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: xbdback_xenbus.c,v 1.33 2011/03/05 15:12:16 bouyer Exp $ */
+/* $NetBSD: xbdback_xenbus.c,v 1.34 2011/04/29 22:58:46 jym Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xbdback_xenbus.c,v 1.33 2011/03/05 15:12:16 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xbdback_xenbus.c,v 1.34 2011/04/29 22:58:46 jym Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -479,20 +479,152 @@
return 0;
}
-static void
-xbdback_frontend_changed(void *arg, XenbusState new_state)
+static int
+xbdback_connect(struct xbdback_instance *xbdi)
{
- struct xbdback_instance *xbdi = arg;
- struct xenbus_device *xbusd = xbdi->xbdi_xbusd;
- u_long ring_ref, revtchn;
+ int len, err;
struct gnttab_map_grant_ref grop;
struct gnttab_unmap_grant_ref ungrop;
evtchn_op_t evop;
+ u_long ring_ref, revtchn;
+ char *xsproto;
char evname[16];
const char *proto;
- char *xsproto;
- int len;
- int err, s;
+ struct xenbus_device *xbusd = xbdi->xbdi_xbusd;
+
+ /* read comunication informations */
+ err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
+ "ring-ref", &ring_ref, 10);
+ if (err) {
+ xenbus_dev_fatal(xbusd, err, "reading %s/ring-ref",
+ xbusd->xbusd_otherend);
+ return -1;
+ }
+ err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
+ "event-channel", &revtchn, 10);
+ if (err) {
+ xenbus_dev_fatal(xbusd, err, "reading %s/event-channel",
+ xbusd->xbusd_otherend);
+ return -1;
+ }
+ err = xenbus_read(NULL, xbusd->xbusd_otherend, "protocol",
+ &len, &xsproto);
+ if (err) {
+ xbdi->xbdi_proto = XBDIP_NATIVE;
+ proto = "unspecified";
+ } else {
+ if (strcmp(xsproto, XEN_IO_PROTO_ABI_NATIVE) == 0) {
+ xbdi->xbdi_proto = XBDIP_NATIVE;
+ proto = XEN_IO_PROTO_ABI_NATIVE;
+ } else if (strcmp(xsproto, XEN_IO_PROTO_ABI_X86_32) == 0) {
+ xbdi->xbdi_proto = XBDIP_32;
+ proto = XEN_IO_PROTO_ABI_X86_32;
+ } else if (strcmp(xsproto, XEN_IO_PROTO_ABI_X86_64) == 0) {
+ xbdi->xbdi_proto = XBDIP_64;
+ proto = XEN_IO_PROTO_ABI_X86_64;
+ } else {
+ aprint_error("xbd domain %d: unknown proto %s\n",
+ xbdi->xbdi_domid, xsproto);
+ free(xsproto, M_DEVBUF);
+ return -1;
+ }
+ }
+ free(xsproto, M_DEVBUF);
+
+ /* allocate VA space and map rings */
+ xbdi->xbdi_ring_va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
+ UVM_KMF_VAONLY);
+ if (xbdi->xbdi_ring_va == 0) {
+ xenbus_dev_fatal(xbusd, ENOMEM,
+ "can't get VA for ring", xbusd->xbusd_otherend);
+ return -1;
+ }
+
+ grop.host_addr = xbdi->xbdi_ring_va;
+ grop.flags = GNTMAP_host_map;
+ grop.ref = ring_ref;
+ grop.dom = xbdi->xbdi_domid;
+ err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
+ &grop, 1);
+ if (err || grop.status) {
+ aprint_error("xbdback %s: can't map grant ref: %d/%d\n",
+ xbusd->xbusd_path, err, grop.status);
+ xenbus_dev_fatal(xbusd, EINVAL,
+ "can't map ring", xbusd->xbusd_otherend);
+ goto err;
+ }
+ xbdi->xbdi_ring_handle = grop.handle;
+
+ switch(xbdi->xbdi_proto) {
+ case XBDIP_NATIVE:
+ {
+ blkif_sring_t *sring = (void *)xbdi->xbdi_ring_va;
+ BACK_RING_INIT(&xbdi->xbdi_ring.ring_n, sring, PAGE_SIZE);
+ break;
+ }
+ case XBDIP_32:
+ {
+ blkif_x86_32_sring_t *sring = (void *)xbdi->xbdi_ring_va;
+ BACK_RING_INIT(&xbdi->xbdi_ring.ring_32, sring, PAGE_SIZE);
+ break;
+ }
+ case XBDIP_64:
+ {
+ blkif_x86_64_sring_t *sring = (void *)xbdi->xbdi_ring_va;
+ BACK_RING_INIT(&xbdi->xbdi_ring.ring_64, sring, PAGE_SIZE);
+ break;
+ }
+ }
+
+ evop.cmd = EVTCHNOP_bind_interdomain;
+ evop.u.bind_interdomain.remote_dom = xbdi->xbdi_domid;
+ evop.u.bind_interdomain.remote_port = revtchn;
+ err = HYPERVISOR_event_channel_op(&evop);
+ if (err) {
+ aprint_error("blkback %s: "
+ "can't get event channel: %d\n",
+ xbusd->xbusd_otherend, err);
+ xenbus_dev_fatal(xbusd, err,
+ "can't bind event channel", xbusd->xbusd_otherend);
+ goto err2;
+ }
+ xbdi->xbdi_evtchn = evop.u.bind_interdomain.local_port;
+
+ snprintf(evname, sizeof(evname), "xbd%d.%d",
+ xbdi->xbdi_domid, xbdi->xbdi_handle);
+ event_set_handler(xbdi->xbdi_evtchn, xbdback_evthandler,
+ xbdi, IPL_BIO, evname);
+ aprint_verbose("xbd backend 0x%x for domain %d "
+ "using event channel %d, protocol %s\n", xbdi->xbdi_handle,
+ xbdi->xbdi_domid, xbdi->xbdi_evtchn, proto);
+ hypervisor_enable_event(xbdi->xbdi_evtchn);
+ hypervisor_notify_via_evtchn(xbdi->xbdi_evtchn);
+ xbdi->xbdi_status = CONNECTED;
+ return 0;
+
+err2:
+ /* unmap ring */
+ ungrop.host_addr = xbdi->xbdi_ring_va;
+ ungrop.handle = xbdi->xbdi_ring_handle;
+ ungrop.dev_bus_addr = 0;
+ err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
+ &ungrop, 1);
+ if (err)
+ aprint_error("xbdback %s: unmap_grant_ref failed: %d\n",
+ xbusd->xbusd_path, err);
+
+err:
+ /* free ring VA space */
+ uvm_km_free(kernel_map, xbdi->xbdi_ring_va, PAGE_SIZE, UVM_KMF_VAONLY);
+ return -1;
+}
+
+static void
+xbdback_frontend_changed(void *arg, XenbusState new_state)
+{
+ struct xbdback_instance *xbdi = arg;
+ struct xenbus_device *xbusd = xbdi->xbdi_xbusd;
+ int s;
XENPRINTF(("xbdback %s: new state %d\n", xbusd->xbusd_path, new_state));
switch(new_state) {
@@ -502,114 +634,7 @@
case XenbusStateConnected:
if (xbdi->xbdi_status == CONNECTED)
break;
- /* read comunication informations */
- err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
- "ring-ref", &ring_ref, 10);
- if (err) {
- xenbus_dev_fatal(xbusd, err, "reading %s/ring-ref",
- xbusd->xbusd_otherend);
- break;
- }
- err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
- "event-channel", &revtchn, 10);
- if (err) {
- xenbus_dev_fatal(xbusd, err, "reading %s/event-channel",
- xbusd->xbusd_otherend);
- break;
- }
- err = xenbus_read(NULL, xbusd->xbusd_otherend, "protocol",
- &len, &xsproto);
- if (err) {
- proto = "unspecified";
- xbdi->xbdi_proto = XBDIP_NATIVE;
- } else {
- if(strcmp(xsproto, XEN_IO_PROTO_ABI_NATIVE) == 0) {
- xbdi->xbdi_proto = XBDIP_NATIVE;
- proto = XEN_IO_PROTO_ABI_NATIVE;
- } else if(strcmp(xsproto, XEN_IO_PROTO_ABI_X86_32) == 0) {
- xbdi->xbdi_proto = XBDIP_32;
- proto = XEN_IO_PROTO_ABI_X86_32;
- } else if(strcmp(xsproto, XEN_IO_PROTO_ABI_X86_64) == 0) {
- xbdi->xbdi_proto = XBDIP_64;
- proto = XEN_IO_PROTO_ABI_X86_64;
- } else {
- printf("xbd domain %d: unknown proto %s\n",
- xbdi->xbdi_domid, xsproto);
- free(xsproto, M_DEVBUF);
- return;
- }
- free(xsproto, M_DEVBUF);
- }
- /* allocate VA space and map rings */
- xbdi->xbdi_ring_va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
- UVM_KMF_VAONLY);
- if (xbdi->xbdi_ring_va == 0) {
- xenbus_dev_fatal(xbusd, ENOMEM,
- "can't get VA for ring", xbusd->xbusd_otherend);
- break;
- }
- grop.host_addr = xbdi->xbdi_ring_va;
- grop.flags = GNTMAP_host_map;
- grop.ref = ring_ref;
- grop.dom = xbdi->xbdi_domid;
- err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
- &grop, 1);
- if (err || grop.status) {
- printf("xbdback %s: can't map grant ref: %d/%d\n",
- xbusd->xbusd_path, err, grop.status);
- xenbus_dev_fatal(xbusd, EINVAL,
- "can't map ring", xbusd->xbusd_otherend);
- goto err;
- }
- xbdi->xbdi_ring_handle = grop.handle;
- switch(xbdi->xbdi_proto) {
- case XBDIP_NATIVE:
- {
- blkif_sring_t *sring = (void *)xbdi->xbdi_ring_va;
- BACK_RING_INIT(&xbdi->xbdi_ring.ring_n,
- sring, PAGE_SIZE);
- break;
- }
- case XBDIP_32:
- {
- blkif_x86_32_sring_t *sring =
- (void *)xbdi->xbdi_ring_va;
- BACK_RING_INIT(&xbdi->xbdi_ring.ring_32,
- sring, PAGE_SIZE);
- break;
- }
- case XBDIP_64:
- {
- blkif_x86_64_sring_t *sring =
- (void *)xbdi->xbdi_ring_va;
- BACK_RING_INIT(&xbdi->xbdi_ring.ring_64,
- sring, PAGE_SIZE);
- break;
- }
- }
- evop.cmd = EVTCHNOP_bind_interdomain;
- evop.u.bind_interdomain.remote_dom = xbdi->xbdi_domid;
- evop.u.bind_interdomain.remote_port = revtchn;
- err = HYPERVISOR_event_channel_op(&evop);
- if (err) {
- aprint_error("blkback %s: "
- "can't get event channel: %d\n",
- xbusd->xbusd_otherend, err);
- xenbus_dev_fatal(xbusd, err,
- "can't bind event channel", xbusd->xbusd_otherend);
- goto err2;
- }
- xbdi->xbdi_evtchn = evop.u.bind_interdomain.local_port;
- snprintf(evname, sizeof(evname), "xbd%d.%d",
- xbdi->xbdi_domid, xbdi->xbdi_handle);
- event_set_handler(xbdi->xbdi_evtchn, xbdback_evthandler,
- xbdi, IPL_BIO, evname);
- aprint_verbose("xbd backend 0x%x for domain %d "
- "using event channel %d, protocol %s\n", xbdi->xbdi_handle,
- xbdi->xbdi_domid, xbdi->xbdi_evtchn, proto);
- hypervisor_enable_event(xbdi->xbdi_evtchn);
- hypervisor_notify_via_evtchn(xbdi->xbdi_evtchn);
- xbdi->xbdi_status = CONNECTED;
+ xbdback_connect(xbdi);
break;
case XenbusStateClosing:
hypervisor_mask_event(xbdi->xbdi_evtchn);
@@ -634,19 +659,6 @@
xbusd->xbusd_path, new_state);
}
return;
-err2:
- /* unmap ring */
- ungrop.host_addr = xbdi->xbdi_ring_va;
- ungrop.handle = xbdi->xbdi_ring_handle;
- ungrop.dev_bus_addr = 0;
- err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
- &ungrop, 1);
- if (err)
- printf("xbdback %s: unmap_grant_ref failed: %d\n",
- xbusd->xbusd_path, err);
-err:
- uvm_km_free(kernel_map, xbdi->xbdi_ring_va, PAGE_SIZE, UVM_KMF_VAONLY);
- return;
}
static void
Index: src/sys/arch/xen/xen/xennetback_xenbus.c
diff -u src/sys/arch/xen/xen/xennetback_xenbus.c:1.44 src/sys/arch/xen/xen/xennetback_xenbus.c:1.45
--- src/sys/arch/xen/xen/xennetback_xenbus.c:1.44 Mon Apr 25 00:22:37 2011
+++ src/sys/arch/xen/xen/xennetback_xenbus.c Fri Apr 29 22:58:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: xennetback_xenbus.c,v 1.44 2011/04/25 00:22:37 jym Exp $ */
+/* $NetBSD: xennetback_xenbus.c,v 1.45 2011/04/29 22:58:46 jym Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.44 2011/04/25 00:22:37 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xennetback_xenbus.c,v 1.45 2011/04/29 22:58:46 jym Exp $");
#include "opt_xen.h"
@@ -427,11 +427,9 @@
return 0;
}
-static void
-xennetback_frontend_changed(void *arg, XenbusState new_state)
+static int
+xennetback_connect(struct xnetback_instance *xneti)
{
- struct xnetback_instance *xneti = arg;
- struct xenbus_device *xbusd = xneti->xni_xbusd;
int err;
netif_tx_sring_t *tx_ring;
netif_rx_sring_t *rx_ring;
@@ -440,6 +438,166 @@
evtchn_op_t evop;
u_long tx_ring_ref, rx_ring_ref;
u_long revtchn, rx_copy;
+ struct xenbus_device *xbusd = xneti->xni_xbusd;
+
+ /* read comunication informations */
+ err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
+ "tx-ring-ref", &tx_ring_ref, 10);
+ if (err) {
+ xenbus_dev_fatal(xbusd, err, "reading %s/tx-ring-ref",
+ xbusd->xbusd_otherend);
+ return -1;
+ }
+ err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
+ "rx-ring-ref", &rx_ring_ref, 10);
+ if (err) {
+ xenbus_dev_fatal(xbusd, err, "reading %s/rx-ring-ref",
+ xbusd->xbusd_otherend);
+ return -1;
+ }
+ err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
+ "event-channel", &revtchn, 10);
+ if (err) {
+ xenbus_dev_fatal(xbusd, err, "reading %s/event-channel",
+ xbusd->xbusd_otherend);
+ return -1;
+ }
+ err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
+ "request-rx-copy", &rx_copy, 10);
+ if (err == ENOENT)
+ rx_copy = 0;
+ else if (err) {
+ xenbus_dev_fatal(xbusd, err, "reading %s/request-rx-copy",
+ xbusd->xbusd_otherend);
+ return -1;
+ }
+
+ if (rx_copy)
+ xneti->xni_softintr = softint_establish(SOFTINT_NET,
+ xennetback_ifsoftstart_copy, xneti);
+ else
+ xneti->xni_softintr = softint_establish(SOFTINT_NET,
+ xennetback_ifsoftstart_transfer, xneti);
+
+ if (xneti->xni_softintr == NULL) {
+ err = ENOMEM;
+ xenbus_dev_fatal(xbusd, ENOMEM,
+ "can't allocate softint", xbusd->xbusd_otherend);
+ return -1;
+ }
+
+ /* allocate VA space and map rings */
+ xneti->xni_tx_ring_va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
+ UVM_KMF_VAONLY);
+ if (xneti->xni_tx_ring_va == 0) {
+ xenbus_dev_fatal(xbusd, ENOMEM,
+ "can't get VA for TX ring", xbusd->xbusd_otherend);
+ goto err1;
+ }
+ tx_ring = (void *)xneti->xni_tx_ring_va;
+
+ xneti->xni_rx_ring_va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
+ UVM_KMF_VAONLY);
+ if (xneti->xni_rx_ring_va == 0) {
+ xenbus_dev_fatal(xbusd, ENOMEM,
+ "can't get VA for RX ring", xbusd->xbusd_otherend);
+ goto err1;
+ }
+ rx_ring = (void *)xneti->xni_rx_ring_va;
+
+ op.host_addr = xneti->xni_tx_ring_va;
+ op.flags = GNTMAP_host_map;
+ op.ref = tx_ring_ref;
+ op.dom = xneti->xni_domid;
+ err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
+ if (err || op.status) {
+ aprint_error_ifnet(&xneti->xni_if,
+ "can't map TX grant ref: err %d status %d\n",
+ err, op.status);
+ goto err2;
+ }
+ xneti->xni_tx_ring_handle = op.handle;
+ BACK_RING_INIT(&xneti->xni_txring, tx_ring, PAGE_SIZE);
+
+ op.host_addr = xneti->xni_rx_ring_va;
+ op.flags = GNTMAP_host_map;
+ op.ref = rx_ring_ref;
+ op.dom = xneti->xni_domid;
+ err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
+ if (err || op.status) {
+ aprint_error_ifnet(&xneti->xni_if,
+ "can't map RX grant ref: err %d status %d\n",
+ err, op.status);
+ goto err2;
+ }
+ xneti->xni_rx_ring_handle = op.handle;
+ BACK_RING_INIT(&xneti->xni_rxring, rx_ring, PAGE_SIZE);
+
+ evop.cmd = EVTCHNOP_bind_interdomain;
+ evop.u.bind_interdomain.remote_dom = xneti->xni_domid;
+ evop.u.bind_interdomain.remote_port = revtchn;
+ err = HYPERVISOR_event_channel_op(&evop);
+ if (err) {
+ aprint_error_ifnet(&xneti->xni_if,
+ "can't get event channel: %d\n", err);
+ goto err2;
+ }
+ xneti->xni_evtchn = evop.u.bind_interdomain.local_port;
+ xen_wmb();
+ xneti->xni_status = CONNECTED;
+ xen_wmb();
+
+ event_set_handler(xneti->xni_evtchn, xennetback_evthandler,
+ xneti, IPL_NET, xneti->xni_if.if_xname);
+ xennetback_ifinit(&xneti->xni_if);
+ hypervisor_enable_event(xneti->xni_evtchn);
+ hypervisor_notify_via_evtchn(xneti->xni_evtchn);
+ return 0;
+
+err2:
+ /* unmap rings */
+ if (xneti->xni_tx_ring_handle != 0) {
+ uop.host_addr = xneti->xni_tx_ring_va;
+ uop.handle = xneti->xni_tx_ring_handle;
+ uop.dev_bus_addr = 0;
+ err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
+ &uop, 1);
+ if (err)
+ aprint_error_ifnet(&xneti->xni_if,
+ "unmap_grant_ref failed: %d\n", err);
+ }
+
+ if (xneti->xni_rx_ring_handle != 0) {
+ uop.host_addr = xneti->xni_rx_ring_va;
+ uop.handle = xneti->xni_rx_ring_handle;
+ uop.dev_bus_addr = 0;
+ err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
+ &uop, 1);
+ if (err)
+ aprint_error_ifnet(&xneti->xni_if,
+ "unmap_grant_ref failed: %d\n", err);
+ }
+
+err1:
+ /* free rings VA space */
+ if (xneti->xni_rx_ring_va != 0)
+ uvm_km_free(kernel_map, xneti->xni_rx_ring_va,
+ PAGE_SIZE, UVM_KMF_VAONLY);
+
+ if (xneti->xni_tx_ring_va != 0)
+ uvm_km_free(kernel_map, xneti->xni_tx_ring_va,
+ PAGE_SIZE, UVM_KMF_VAONLY);
+
+ softint_disestablish(xneti->xni_softintr);
+ return -1;
+
+}
+
+static void
+xennetback_frontend_changed(void *arg, XenbusState new_state)
+{
+ struct xnetback_instance *xneti = arg;
+ struct xenbus_device *xbusd = xneti->xni_xbusd;
XENPRINTF(("%s: new state %d\n", xneti->xni_if.if_xname, new_state));
switch(new_state) {
@@ -450,112 +608,8 @@
case XenbusStateConnected:
if (xneti->xni_status == CONNECTED)
break;
- /* read comunication informations */
- err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
- "tx-ring-ref", &tx_ring_ref, 10);
- if (err) {
- xenbus_dev_fatal(xbusd, err, "reading %s/tx-ring-ref",
- xbusd->xbusd_otherend);
- break;
- }
- err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
- "rx-ring-ref", &rx_ring_ref, 10);
- if (err) {
- xenbus_dev_fatal(xbusd, err, "reading %s/rx-ring-ref",
- xbusd->xbusd_otherend);
- break;
- }
- err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
- "event-channel", &revtchn, 10);
- if (err) {
- xenbus_dev_fatal(xbusd, err, "reading %s/event-channel",
- xbusd->xbusd_otherend);
- break;
- }
- err = xenbus_read_ul(NULL, xbusd->xbusd_otherend,
- "request-rx-copy", &rx_copy, 10);
- if (err == ENOENT)
- rx_copy = 0;
- else if (err) {
- xenbus_dev_fatal(xbusd, err, "reading %s/request-rx-copy",
- xbusd->xbusd_otherend);
- break;
- }
-
- if (rx_copy)
- xneti->xni_softintr = softint_establish(SOFTINT_NET,
- xennetback_ifsoftstart_copy, xneti);
- else
- xneti->xni_softintr = softint_establish(SOFTINT_NET,
- xennetback_ifsoftstart_transfer, xneti);
- if (xneti->xni_softintr == NULL) {
- err = ENOMEM;
- xenbus_dev_fatal(xbusd, ENOMEM,
- "can't allocate softint", xbusd->xbusd_otherend);
- break;
- }
-
- /* allocate VA space and map rings */
- xneti->xni_tx_ring_va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
- UVM_KMF_VAONLY);
- if (xneti->xni_tx_ring_va == 0) {
- xenbus_dev_fatal(xbusd, ENOMEM,
- "can't get VA for tx ring", xbusd->xbusd_otherend);
- goto err0;
- }
- tx_ring = (void *)xneti->xni_tx_ring_va;
- xneti->xni_rx_ring_va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
- UVM_KMF_VAONLY);
- if (xneti->xni_rx_ring_va == 0) {
- xenbus_dev_fatal(xbusd, ENOMEM,
- "can't get VA for rx ring", xbusd->xbusd_otherend);
- goto err1;
- }
- rx_ring = (void *)xneti->xni_rx_ring_va;
- op.host_addr = xneti->xni_tx_ring_va;
- op.flags = GNTMAP_host_map;
- op.ref = tx_ring_ref;
- op.dom = xneti->xni_domid;
- err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
- if (err || op.status) {
- printf("%s: can't map TX grant ref: %d/%d\n",
- xneti->xni_if.if_xname, err, op.status);
- goto err2;
- }
- xneti->xni_tx_ring_handle = op.handle;
-
- op.host_addr = xneti->xni_rx_ring_va;
- op.flags = GNTMAP_host_map;
- op.ref = rx_ring_ref;
- op.dom = xneti->xni_domid;
- err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
- if (err || op.status) {
- printf("%s: can't map RX grant ref: %d/%d\n",
- xneti->xni_if.if_xname, err, op.status);
- goto err2;
- }
- xneti->xni_rx_ring_handle = op.handle;
- BACK_RING_INIT(&xneti->xni_txring, tx_ring, PAGE_SIZE);
- BACK_RING_INIT(&xneti->xni_rxring, rx_ring, PAGE_SIZE);
- evop.cmd = EVTCHNOP_bind_interdomain;
- evop.u.bind_interdomain.remote_dom = xneti->xni_domid;
- evop.u.bind_interdomain.remote_port = revtchn;
- err = HYPERVISOR_event_channel_op(&evop);
- if (err) {
- printf("%s: can't get event channel: %d\n",
- xneti->xni_if.if_xname, err);
- goto err3;
- }
- xneti->xni_evtchn = evop.u.bind_interdomain.local_port;
- xen_wmb();
- xneti->xni_status = CONNECTED;
- xenbus_switch_state(xbusd, NULL, XenbusStateConnected);
- xen_wmb();
- event_set_handler(xneti->xni_evtchn, xennetback_evthandler,
- xneti, IPL_NET, xneti->xni_if.if_xname);
- xennetback_ifinit(&xneti->xni_if);
- hypervisor_enable_event(xneti->xni_evtchn);
- hypervisor_notify_via_evtchn(xneti->xni_evtchn);
+ if (xennetback_connect(xneti) == 0)
+ xenbus_switch_state(xbusd, NULL, XenbusStateConnected);
break;
case XenbusStateClosing:
@@ -577,33 +631,6 @@
}
return;
-err3:
- uop.dev_bus_addr = 0;
-
- uop.host_addr = xneti->xni_rx_ring_va;
- uop.handle = xneti->xni_rx_ring_handle;
- err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
- &uop, 1);
- if (err)
- aprint_error_ifnet(&xneti->xni_if,
- "unmap_grant_ref failed: %d\n", err);
-
- uop.host_addr = xneti->xni_tx_ring_va;
- uop.handle = xneti->xni_tx_ring_handle;
- err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
- &uop, 1);
- if (err)
- aprint_error_ifnet(&xneti->xni_if,
- "unmap_grant_ref failed: %d\n", err);
-
-err2:
- uvm_km_free(kernel_map, xneti->xni_rx_ring_va,
- PAGE_SIZE, UVM_KMF_VAONLY);
-err1:
- uvm_km_free(kernel_map, xneti->xni_tx_ring_va,
- PAGE_SIZE, UVM_KMF_VAONLY);
-err0:
- softint_disestablish(xneti->xni_softintr);
}
/* lookup a xneti based on domain id and interface handle */