summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2009-12-14 22:38:04 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2009-12-14 22:38:04 +0000
commit6f88cc9f62f2daf3baf359d75837cf5dc5347888 (patch)
treed93a0f274345b5bb94fb643fc20ba16740b3709a /sys
parent3fca349cd41b3a4efc1a1adfac9baafce44d7e2a (diff)
Sanitize the code that resets the state when the LDC channel link state
changes. Don't initiate the handshake when the LDC channel link state comes up, to avoid a race where both sides initiate the handshake simultaniously, which leads to a guaranteed failure. Instead rely on the handshake done as a result of ifconfig up on the interface to succeed. Some retry logic may be needed there... This makes it possible to run OpenBSD (diskless) in a guest domain on a machine running OpenBSD in its control domain.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc64/dev/vnet.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/sys/arch/sparc64/dev/vnet.c b/sys/arch/sparc64/dev/vnet.c
index 2c28ae8a257..ceeef574742 100644
--- a/sys/arch/sparc64/dev/vnet.c
+++ b/sys/arch/sparc64/dev/vnet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnet.c,v 1.20 2009/12/14 21:08:45 kettenis Exp $ */
+/* $OpenBSD: vnet.c,v 1.21 2009/12/14 22:38:03 kettenis Exp $ */
/*
* Copyright (c) 2009 Mark Kettenis
*
@@ -377,20 +377,21 @@ vnet_rx_intr(void *arg)
}
if (rx_state != lc->lc_rx_state) {
- sc->sc_tx_cnt = sc->sc_tx_prod = sc->sc_tx_cons = 0;
- sc->sc_vio_state = 0;
- lc->lc_tx_seqid = 0;
- lc->lc_state = 0;
switch (rx_state) {
case LDC_CHANNEL_DOWN:
DPRINTF(("Rx link down\n"));
+ lc->lc_tx_seqid = 0;
+ lc->lc_state = 0;
+ lc->lc_reset(lc);
break;
case LDC_CHANNEL_UP:
DPRINTF(("Rx link up\n"));
- ldc_send_vers(lc);
break;
case LDC_CHANNEL_RESET:
DPRINTF(("Rx link reset\n"));
+ lc->lc_tx_seqid = 0;
+ lc->lc_state = 0;
+ lc->lc_reset(lc);
break;
}
lc->lc_rx_state = rx_state;
@@ -887,6 +888,7 @@ vnet_ldc_reset(struct ldc_conn *lc)
{
struct vnet_softc *sc = lc->lc_sc;
+ sc->sc_tx_cnt = sc->sc_tx_prod = sc->sc_tx_cons = 0;
sc->sc_vio_state = 0;
vnet_link_state(sc);
}