Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Sep 2012 14:31:59 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r240137 - head/sys/dev/twe
Message-ID:  <201209051431.q85EVxqm053471@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Wed Sep  5 14:31:58 2012
New Revision: 240137
URL: http://svn.freebsd.org/changeset/base/240137

Log:
  - Explicitly call twe_done() to poll the hardware when looping in
    twe_start() to simulate the behavior on 4.x where the driver dropped
    spl to allow interrupts to run to free up space in the command
    queue.  Be careful to only poll if we are going to make at least
    one more attempt to queue the current command.  Also, when polling,
    be careful to not call twe_startio() to queue more commands to avoid
    recursion.
  - Move the buffer for formatting AEN messages into the softc instead of
    using a single driver-wide static buffer.
  
  Requested by:	scottl (1)
  Tested by:	Mike Tancsa @ Sentex

Modified:
  head/sys/dev/twe/twe.c
  head/sys/dev/twe/twevar.h

Modified: head/sys/dev/twe/twe.c
==============================================================================
--- head/sys/dev/twe/twe.c	Wed Sep  5 13:51:36 2012	(r240136)
+++ head/sys/dev/twe/twe.c	Wed Sep  5 14:31:58 2012	(r240137)
@@ -68,7 +68,7 @@ static int	twe_del_unit(struct twe_softc
 /*
  * Command I/O to controller.
  */
-static void	twe_done(struct twe_softc *sc);
+static void	twe_done(struct twe_softc *sc, int startio);
 static void	twe_complete(struct twe_softc *sc);
 static int	twe_wait_status(struct twe_softc *sc, u_int32_t status, int timeout);
 static int	twe_drain_response_queue(struct twe_softc *sc);
@@ -388,7 +388,7 @@ twe_intr(struct twe_softc *sc)
     if (status_reg & TWE_STATUS_COMMAND_INTERRUPT)
 	twe_command_intr(sc);
     if (status_reg & TWE_STATUS_RESPONSE_INTERRUPT)
-	twe_done(sc);
+	twe_done(sc, 1);
 };
 
 /********************************************************************************
@@ -996,7 +996,7 @@ twe_immediate_request(struct twe_request
     /* Wait up to 5 seconds for the command to complete */
     while ((count++ < 5000) && (tr->tr_status == TWE_CMD_BUSY)){
 	DELAY(1000);
-	twe_done(sc);
+	twe_done(sc, 1);
     }
     if (usetmp && (tr->tr_data != NULL))
 	bcopy(sc->twe_immediate, tr->tr_data, tr->tr_length);
@@ -1144,7 +1144,8 @@ twe_start(struct twe_request *tr)
 	    }
 #endif
 	    return(0);
-	}
+	} else if (!(status_reg & TWE_STATUS_RESPONSE_QUEUE_EMPTY) && i > 1)
+	    twe_done(sc, 0);
     }
 
     /* 
@@ -1162,7 +1163,7 @@ twe_start(struct twe_request *tr)
  * Can be called at any interrupt level, with or without interrupts enabled.
  */
 static void
-twe_done(struct twe_softc *sc)
+twe_done(struct twe_softc *sc, int startio)
 {
     TWE_Response_Queue	rq;
     TWE_Command		*cmd;
@@ -1198,7 +1199,7 @@ twe_done(struct twe_softc *sc)
     }
 
     /* if we've completed any commands, try posting some more */
-    if (found)
+    if (found && startio)
 	twe_startio(sc);
 
     /* handle completion and timeouts */
@@ -1768,7 +1769,6 @@ twe_check_bits(struct twe_softc *sc, u_i
 static char *
 twe_format_aen(struct twe_softc *sc, u_int16_t aen)
 {
-    static char	buf[80];
     device_t	child;
     char	*code, *msg;
 
@@ -1785,25 +1785,28 @@ twe_format_aen(struct twe_softc *sc, u_i
 
     case 'c':
 	if ((child = sc->twe_drive[TWE_AEN_UNIT(aen)].td_disk) != NULL) {
-	    sprintf(buf, "twed%d: %s", device_get_unit(child), msg);
+	    snprintf(sc->twe_aen_buf, sizeof(sc->twe_aen_buf), "twed%d: %s",
+		device_get_unit(child), msg);
 	} else {
-	    sprintf(buf, "twe%d: %s for unknown unit %d", device_get_unit(sc->twe_dev),
-		    msg, TWE_AEN_UNIT(aen));
+	    snprintf(sc->twe_aen_buf, sizeof(sc->twe_aen_buf),
+		"twe%d: %s for unknown unit %d", device_get_unit(sc->twe_dev),
+		msg, TWE_AEN_UNIT(aen));
 	}
-	return(buf);
+	return(sc->twe_aen_buf);
 
     case 'p':
-	sprintf(buf, "twe%d: port %d: %s", device_get_unit(sc->twe_dev), TWE_AEN_UNIT(aen),
-		msg);
-	return(buf);
+	snprintf(sc->twe_aen_buf, sizeof(sc->twe_aen_buf),
+	    "twe%d: port %d: %s", device_get_unit(sc->twe_dev),
+	    TWE_AEN_UNIT(aen), msg);
+	return(sc->twe_aen_buf);
 
 	
     case 'x':
     default:
 	break;
     }
-    sprintf(buf, "unknown AEN 0x%x", aen);
-    return(buf);
+    snprintf(sc->twe_aen_buf, sizeof(sc->twe_aen_buf), "unknown AEN 0x%x", aen);
+    return(sc->twe_aen_buf);
 }
 
 /********************************************************************************

Modified: head/sys/dev/twe/twevar.h
==============================================================================
--- head/sys/dev/twe/twevar.h	Wed Sep  5 13:51:36 2012	(r240136)
+++ head/sys/dev/twe/twevar.h	Wed Sep  5 14:31:58 2012	(r240137)
@@ -125,6 +125,7 @@ struct twe_softc 
     u_int16_t		twe_aen_queue[TWE_Q_LENGTH];	/* AENs queued for userland tool(s) */
     int			twe_aen_head, twe_aen_tail;	/* ringbuffer pointers for AEN queue */
     int			twe_wait_aen;    		/* wait-for-aen notification */
+    char		twe_aen_buf[80];		/* AEN format buffer */
 
     /* controller status */
     int			twe_state;



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