Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Nov 2013 05:26:11 +0000 (UTC)
From:      Andreas Tobler <andreast@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r258615 - head/sys/powerpc/pseries
Message-ID:  <201311260526.rAQ5QBgQ012981@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andreast
Date: Tue Nov 26 05:26:10 2013
New Revision: 258615
URL: http://svnweb.freebsd.org/changeset/base/258615

Log:
  Take care to handle the full 16 byte buffer in the get/put routines. Also,
  skip the VTERM header once when receiving data from the hypervisor call when
  we have a HVTERMPROT connection.
  
  MFC after:	1 week

Modified:
  head/sys/powerpc/pseries/phyp_console.c

Modified: head/sys/powerpc/pseries/phyp_console.c
==============================================================================
--- head/sys/powerpc/pseries/phyp_console.c	Tue Nov 26 03:00:54 2013	(r258614)
+++ head/sys/powerpc/pseries/phyp_console.c	Tue Nov 26 05:26:10 2013	(r258615)
@@ -286,6 +286,7 @@ static int
 uart_phyp_get(struct uart_phyp_softc *sc, void *buffer, size_t bufsize)
 {
 	int err;
+	int hdr = 0;
 
 	uart_lock(&sc->sc_mtx);
 	if (sc->inbuflen == 0) {
@@ -296,6 +297,7 @@ uart_phyp_get(struct uart_phyp_softc *sc
 			uart_unlock(&sc->sc_mtx);
 			return (-1);
 		}
+		hdr = 1; 
 	}
 
 	if (sc->inbuflen == 0) {
@@ -305,6 +307,14 @@ uart_phyp_get(struct uart_phyp_softc *sc
 
 	if (bufsize > sc->inbuflen)
 		bufsize = sc->inbuflen;
+
+	if ((sc->protocol == HVTERMPROT) && (hdr == 1)) {
+		sc->inbuflen = sc->inbuflen - 4;
+		/* The VTERM protocol has a 4 byte header, skip it here. */
+		memmove(&sc->phyp_inbuf.str[0], &sc->phyp_inbuf.str[4],
+		    sc->inbuflen);
+	}
+
 	memcpy(buffer, sc->phyp_inbuf.str, bufsize);
 	sc->inbuflen -= bufsize;
 	if (sc->inbuflen > 0)
@@ -320,32 +330,40 @@ uart_phyp_put(struct uart_phyp_softc *sc
 {
 	uint16_t seqno;
 	uint64_t len = 0;
+	int	err;
+
 	union {
-		uint64_t u64;
-		char bytes[8];
+		uint64_t u64[2];
+		char bytes[16];
 	} cbuf;
 
 	uart_lock(&sc->sc_mtx);
 	switch (sc->protocol) {
 	case HVTERM1:
-		if (bufsize > 8)
-			bufsize = 8;
+		if (bufsize > 16)
+			bufsize = 16;
 		memcpy(&cbuf, buffer, bufsize);
 		len = bufsize;
 		break;
 	case HVTERMPROT:
-		if (bufsize > 4)
-			bufsize = 4;
+		if (bufsize > 12)
+			bufsize = 12;
 		seqno = sc->outseqno++;
 		cbuf.bytes[0] = VS_DATA_PACKET_HEADER;
-		cbuf.bytes[1] = 4 + bufsize; /* total length */
+		cbuf.bytes[1] = 4 + bufsize; /* total length, max 16 bytes */
 		cbuf.bytes[2] = (seqno >> 8) & 0xff;
 		cbuf.bytes[3] = seqno & 0xff;
 		memcpy(&cbuf.bytes[4], buffer, bufsize);
 		len = 4 + bufsize;
 		break;
 	}
-	phyp_hcall(H_PUT_TERM_CHAR, sc->vtermid, len, cbuf.u64, 0);
+
+	do {
+	    err = phyp_hcall(H_PUT_TERM_CHAR, sc->vtermid, len, cbuf.u64[0],
+			    cbuf.u64[1]);
+		DELAY(100);
+	} while (err == H_BUSY);
+
 	uart_unlock(&sc->sc_mtx);
 
 	return (bufsize);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201311260526.rAQ5QBgQ012981>