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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to