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 */

Reply via email to