summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2009-12-09 22:39:53 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2009-12-09 22:39:53 +0000
commit9ecce3445894367d96d4b821b88bbb1d5a78a33f (patch)
treedbabbfcfde2196f066693288207d3c072e49b4f9 /sys/arch/sparc64
parentaeb589705a0137fde8a58ec77c9fef00a2e757f9 (diff)
Resubmit any pending SCSI commands when we sucessfully (re)connect to
a vDisk server. This makes OpenBSD running in a guest domain survive a reboot of a control domain or service domain.
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r--sys/arch/sparc64/dev/vdsk.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/sys/arch/sparc64/dev/vdsk.c b/sys/arch/sparc64/dev/vdsk.c
index feac87ff3f9..c8120ed7f7d 100644
--- a/sys/arch/sparc64/dev/vdsk.c
+++ b/sys/arch/sparc64/dev/vdsk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vdsk.c,v 1.14 2009/12/09 18:41:14 kettenis Exp $ */
+/* $OpenBSD: vdsk.c,v 1.15 2009/12/09 22:39:52 kettenis Exp $ */
/*
* Copyright (c) 2009 Mark Kettenis
*
@@ -414,7 +414,6 @@ vdsk_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;
@@ -621,13 +620,34 @@ vdsk_rx_vio_rdx(struct vdsk_softc *sc, struct vio_msg_tag *tag)
break;
case VIO_SUBTYPE_ACK:
+ {
+ int prod;
+
DPRINTF(("CTRL/ACK/RDX\n"));
if (!ISSET(sc->sc_vio_state, VIO_SND_RDX)) {
ldc_reset(&sc->sc_lc);
break;
}
sc->sc_vio_state |= VIO_ACK_RDX;
+
+ /*
+ * If this ACK is the result of a reconnect, we may
+ * have pending I/O that we need to resubmit. We need
+ * to rebuild the ring descriptors though since the
+ * vDisk server on the other side may have touched
+ * them already. So we just clean up the ring and the
+ * LDC map and resubmit the SCSI commands based on our
+ * soft descriptors.
+ */
+ prod = sc->sc_tx_prod;
+ sc->sc_tx_prod = sc->sc_tx_cons;
+ sc->sc_tx_cnt = 0;
+ sc->sc_lm->lm_next = 1;
+ sc->sc_lm->lm_count = 1;
+ while (sc->sc_tx_prod != prod)
+ vdsk_scsi_cmd(sc->sc_vsd[sc->sc_tx_prod].vsd_xs);
break;
+ }
default:
DPRINTF(("CTRL/0x%02x/RDX (VIO)\n", tag->stype));
@@ -716,7 +736,6 @@ vdsk_ldc_reset(struct ldc_conn *lc)
{
struct vdsk_softc *sc = lc->lc_sc;
- sc->sc_tx_cnt = sc->sc_tx_prod = sc->sc_tx_cons = 0;
sc->sc_vio_state = 0;
}
@@ -1125,4 +1144,3 @@ vdsk_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flags,
printf("%s\n", __func__);
return (ENOTTY);
}
-