svn commit: r274390 - head/sys/dev/rp

John Baldwin jhb at FreeBSD.org
Tue Nov 11 18:15:07 UTC 2014


Author: jhb
Date: Tue Nov 11 18:15:05 2014
New Revision: 274390
URL: https://svnweb.freebsd.org/changeset/base/274390

Log:
  Use the callout(9) API instead of timeout(9).  To do this more cleanly,
  convert a global timer to a per-controller timer.  This works much better
  with locking and removes the need for several global lookup tables.
  
  Tested by:	ambrisko

Modified:
  head/sys/dev/rp/rp.c
  head/sys/dev/rp/rp_pci.c
  head/sys/dev/rp/rpreg.h
  head/sys/dev/rp/rpvar.h

Modified: head/sys/dev/rp/rp.c
==============================================================================
--- head/sys/dev/rp/rp.c	Tue Nov 11 17:18:51 2014	(r274389)
+++ head/sys/dev/rp/rp.c	Tue Nov 11 18:15:05 2014	(r274390)
@@ -552,24 +552,12 @@ void sDisInterrupts(CHANNEL_T *ChP,Word_
   Begin FreeBsd-specific driver code
 **********************************************************************/
 
-struct callout_handle rp_callout_handle;
-
-static int	rp_num_ports_open = 0;
-static int	rp_ndevs = 0;
-
-static int rp_num_ports[4];	/* Number of ports on each controller */
-
-#define POLL_INTERVAL 1
+#define POLL_INTERVAL		(hz / 100)
 
 #define RP_ISMULTIPORT(dev)	((dev)->id_flags & 0x1)
 #define RP_MPMASTER(dev)	(((dev)->id_flags >> 8) & 0xff)
 #define RP_NOTAST4(dev) 	((dev)->id_flags & 0x04)
 
-static	struct	rp_port *p_rp_addr[4];
-static	struct	rp_port *p_rp_table[MAX_RP_PORTS];
-#define rp_addr(unit)	(p_rp_addr[unit])
-#define rp_table(port)	(p_rp_table[port])
-
 /*
  * The top-level routines begin here
  */
@@ -676,46 +664,31 @@ static void rp_handle_port(struct rp_por
 */
 }
 
-static void rp_do_poll(void *not_used)
+static void rp_do_poll(void *arg)
 {
 	CONTROLLER_t	*ctl;
 	struct rp_port	*rp;
 	struct tty	*tp;
-	int	unit, aiop, ch, line, count;
+	int	count;
 	unsigned char	CtlMask, AiopMask;
 
-	for(unit = 0; unit < rp_ndevs; unit++) {
-	rp = rp_addr(unit);
+	rp = arg;
+	tp = rp->rp_tty;
+	tty_lock_assert(tp, MA_OWNED);
 	ctl = rp->rp_ctlp;
 	CtlMask = ctl->ctlmask(ctl);
-	for(aiop=0; CtlMask; CtlMask >>=1, aiop++) {
-		if(CtlMask & 1) {
-			AiopMask = sGetAiopIntStatus(ctl, aiop);
-			for(ch = 0; AiopMask; AiopMask >>=1, ch++) {
-				if(AiopMask & 1) {
-					line = (unit << 5) | (aiop << 3) | ch;
-					rp = rp_table(line);
-					rp_handle_port(rp);
-				}
-			}
+	if (CtlMask & (1 << rp->rp_aiop)) {
+		AiopMask = sGetAiopIntStatus(ctl, rp->rp_aiop);
+		if (AiopMask & (1 << rp->rp_chan)) {
+			rp_handle_port(rp);
 		}
 	}
 
-	for(line = 0, rp = rp_addr(unit); line < rp_num_ports[unit];
-			line++, rp++) {
-		tp = rp->rp_tty;
-		tty_lock(tp);
-		count = sGetTxCnt(&rp->rp_channel);
-		if (count >= 0  &&
-		    (count <= rp->rp_restart)) {
-			rpstart(tp);
-		}
-		tty_unlock(tp);
+	count = sGetTxCnt(&rp->rp_channel);
+	if (count >= 0  && (count <= rp->rp_restart)) {
+		rpstart(tp);
 	}
-	}
-	if(rp_num_ports_open)
-		rp_callout_handle = timeout(rp_do_poll, 
-					    (void *)NULL, POLL_INTERVAL);
+	callout_schedule(&rp->rp_timer, POLL_INTERVAL);
 }
 
 static struct ttydevsw rp_tty_class = {
@@ -745,7 +718,7 @@ rp_attachcommon(CONTROLLER_T *ctlp, int 
 	int	unit;
 	int	num_chan;
 	int	aiop, chan, port;
-	int	ChanStatus, line, count;
+	int	ChanStatus;
 	int	retval;
 	struct	rp_port *rp;
 	struct tty *tp;
@@ -754,9 +727,8 @@ rp_attachcommon(CONTROLLER_T *ctlp, int 
 
 	printf("RocketPort%d (Version %s) %d ports.\n", unit,
 		RocketPortVersion, num_ports);
-	rp_num_ports[unit] = num_ports;
-	callout_handle_init(&rp_callout_handle);
 
+	ctlp->num_ports = num_ports;
 	ctlp->rp = rp = (struct rp_port *)
 		malloc(sizeof(struct rp_port) * num_ports, M_DEVBUF, M_NOWAIT | M_ZERO);
 	if (rp == NULL) {
@@ -765,16 +737,12 @@ rp_attachcommon(CONTROLLER_T *ctlp, int 
 		goto nogo;
 	}
 
-	count = unit * 32;      /* board times max ports per card SG */
-
-	bzero(rp, sizeof(struct rp_port) * num_ports);
-	rp_addr(unit) = rp;
-
 	port = 0;
 	for(aiop=0; aiop < num_aiops; aiop++) {
 		num_chan = sGetAiopNumChan(ctlp, aiop);
 		for(chan=0; chan < num_chan; chan++, port++, rp++) {
 			rp->rp_tty = tp = tty_alloc(&rp_tty_class, rp);
+			callout_init_mtx(&rp->rp_timer, tty_getlock(tp), 0);
 			rp->rp_port = port;
 			rp->rp_ctlp = ctlp;
 			rp->rp_unit = unit;
@@ -794,13 +762,10 @@ rp_attachcommon(CONTROLLER_T *ctlp, int 
 			}
 			ChanStatus = sGetChanStatus(&rp->rp_channel);
 			rp->rp_cts = (ChanStatus & CTS_ACT) != 0;
-			line = (unit << 5) | (aiop << 3) | chan;
-			rp_table(line) = rp;
 			tty_makedev(tp, NULL, "R%r%r", unit, port);
 		}
 	}
 
-	rp_ndevs++;
 	mtx_init(&ctlp->hwmtx, "rp_hwmtx", NULL, MTX_DEF);
 	ctlp->hwmtx_init = 1;
 	return (0);
@@ -814,40 +779,26 @@ nogo:
 void
 rp_releaseresource(CONTROLLER_t *ctlp)
 {
-	int i, unit;
 	struct	rp_port *rp;
+	int i;
 
-
-	unit = device_get_unit(ctlp->dev);
-	if (rp_addr(unit) != NULL) {
-		for (i = 0; i < rp_num_ports[unit]; i++) {
-			rp = rp_addr(unit) + i;
+	if (ctlp->rp != NULL) {
+		for (i = 0; i < ctlp->num_ports; i++) {
+			rp = ctlp->rp + i;
 			atomic_add_32(&ctlp->free, 1);
 			tty_lock(rp->rp_tty);
 			tty_rel_gone(rp->rp_tty);
 		}
+                free(ctlp->rp, M_DEVBUF);
+                ctlp->rp = NULL;
 	}
 
 	while (ctlp->free != 0) {
 		pause("rpwt", hz / 10);
 	}
 
-	if (ctlp->rp != NULL) {
-		for (i = 0 ; i < sizeof(p_rp_addr) / sizeof(*p_rp_addr) ; i++)
-			if (p_rp_addr[i] == ctlp->rp)
-				p_rp_addr[i] = NULL;
-		for (i = 0 ; i < sizeof(p_rp_table) / sizeof(*p_rp_table) ; i++)
-			if (p_rp_table[i] == ctlp->rp)
-				p_rp_table[i] = NULL;
-                free(ctlp->rp, M_DEVBUF);
-                ctlp->rp = NULL;
-	}
-}
-
-void
-rp_untimeout(void)
-{
-	untimeout(rp_do_poll, (void *)NULL, rp_callout_handle);
+	if (ctlp->hwmtx_init)
+		mtx_destroy(&ctlp->hwmtx);
 }
 
 static int
@@ -893,15 +844,11 @@ rpopen(struct tty *tp)
 	sSetRTS(&rp->rp_channel);
 */
 
-	rp_num_ports_open++;
-
 	IntMask = sGetChanIntID(&rp->rp_channel);
 	IntMask = IntMask & rp->rp_intmask;
 	ChanStatus = sGetChanStatus(&rp->rp_channel);
 
-	if(rp_num_ports_open == 1)
-		rp_callout_handle = timeout(rp_do_poll, 
-					    (void *)NULL, POLL_INTERVAL);
+	callout_reset(&rp->rp_timer, POLL_INTERVAL, rp_do_poll, rp);
 
 	device_busy(rp->rp_ctlp->dev);
 	return(0);
@@ -913,6 +860,7 @@ rpclose(struct tty *tp)
 	struct	rp_port	*rp;
 
 	rp = tty_softc(tp);
+	callout_stop(&rp->rp_timer);
 	rphardclose(tp);
 	device_unbusy(rp->rp_ctlp->dev);
 }

Modified: head/sys/dev/rp/rp_pci.c
==============================================================================
--- head/sys/dev/rp/rp_pci.c	Tue Nov 11 17:18:51 2014	(r274389)
+++ head/sys/dev/rp/rp_pci.c	Tue Nov 11 18:15:05 2014	(r274390)
@@ -237,7 +237,7 @@ rp_pcishutdown(device_t dev)
 static void
 rp_pcireleaseresource(CONTROLLER_t *ctlp)
 {
-	rp_untimeout();
+	rp_releaseresource(ctlp);
 	if (ctlp->io != NULL) {
 		if (ctlp->io[0] != NULL)
 			bus_release_resource(ctlp->dev, SYS_RES_IOPORT, ctlp->io_rid[0], ctlp->io[0]);
@@ -248,7 +248,6 @@ rp_pcireleaseresource(CONTROLLER_t *ctlp
 		free(ctlp->io_rid, M_DEVBUF);
 		ctlp->io = NULL;
 	}
-	rp_releaseresource(ctlp);
 }
 
 static int

Modified: head/sys/dev/rp/rpreg.h
==============================================================================
--- head/sys/dev/rp/rpreg.h	Tue Nov 11 17:18:51 2014	(r274389)
+++ head/sys/dev/rp/rpreg.h	Tue Nov 11 18:15:05 2014	(r274390)
@@ -364,6 +364,7 @@ struct CONTROLLER_str
         struct mtx	hwmtx;     /* Spinlock protecting hardware. */
 	int		hwmtx_init;
 	int		free;
+	int		num_ports;
 
 	/* Device and resource management */
 	device_t		dev;		/* device */
@@ -1008,18 +1009,17 @@ void sEnInterrupts(CHANNEL_T *ChP,Word_t
 void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags);
 int rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports);
 void rp_releaseresource(CONTROLLER_t *ctlp);
-void rp_untimeout(void);
 static __inline void
 rp_lock(CONTROLLER_T *CtlP)
 {
         if (CtlP->hwmtx_init != 0)
-                mtx_lock_spin(&CtlP->hwmtx);
+                mtx_lock(&CtlP->hwmtx);
 }
 static __inline void
 rp_unlock(CONTROLLER_T *CtlP)
 {
         if (CtlP->hwmtx_init != 0)
-                mtx_unlock_spin(&CtlP->hwmtx);
+                mtx_unlock(&CtlP->hwmtx);
 }
 
 #ifndef ROCKET_C

Modified: head/sys/dev/rp/rpvar.h
==============================================================================
--- head/sys/dev/rp/rpvar.h	Tue Nov 11 17:18:51 2014	(r274389)
+++ head/sys/dev/rp/rpvar.h	Tue Nov 11 18:15:05 2014	(r274390)
@@ -43,6 +43,7 @@
 
 struct rp_port {
 	struct tty *		rp_tty; /* cross reference */
+	struct callout		rp_timer;
 
 	unsigned char		state;	/* state of dtr */
 


More information about the svn-src-head mailing list