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

Reply via email to