diff options
author | jhb <jhb@FreeBSD.org> | 2014-11-11 18:15:05 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2014-11-11 18:15:05 +0000 |
commit | 1929b21119d6af0991d957701f166768e0f49d0a (patch) | |
tree | 9674138805b23cf14d9e594fb2e24b9e332fde07 /sys/dev/rp | |
parent | 2326e023197afa75bb7c543bc94c11fcbe7cc4f6 (diff) | |
download | FreeBSD-src-1929b21119d6af0991d957701f166768e0f49d0a.zip FreeBSD-src-1929b21119d6af0991d957701f166768e0f49d0a.tar.gz |
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
Diffstat (limited to 'sys/dev/rp')
-rw-r--r-- | sys/dev/rp/rp.c | 106 | ||||
-rw-r--r-- | sys/dev/rp/rp_pci.c | 3 | ||||
-rw-r--r-- | sys/dev/rp/rpreg.h | 6 | ||||
-rw-r--r-- | sys/dev/rp/rpvar.h | 1 |
4 files changed, 32 insertions, 84 deletions
diff --git a/sys/dev/rp/rp.c b/sys/dev/rp/rp.c index 520ca80..5027694 100644 --- a/sys/dev/rp/rp.c +++ b/sys/dev/rp/rp.c @@ -552,24 +552,12 @@ void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags) 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_port *rp) */ } -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 num_aiops, int num_ports) 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 num_aiops, int num_ports) 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 num_aiops, int num_ports) 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 num_aiops, int num_ports) } 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); } diff --git a/sys/dev/rp/rp_pci.c b/sys/dev/rp/rp_pci.c index e7b9832..3479ab7 100644 --- a/sys/dev/rp/rp_pci.c +++ b/sys/dev/rp/rp_pci.c @@ -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 diff --git a/sys/dev/rp/rpreg.h b/sys/dev/rp/rpreg.h index c8960eb..c5a8cac 100644 --- a/sys/dev/rp/rpreg.h +++ b/sys/dev/rp/rpreg.h @@ -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 Flags); 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 diff --git a/sys/dev/rp/rpvar.h b/sys/dev/rp/rpvar.h index f7f28aa..fd5faf3 100644 --- a/sys/dev/rp/rpvar.h +++ b/sys/dev/rp/rpvar.h @@ -43,6 +43,7 @@ struct rp_port { struct tty * rp_tty; /* cross reference */ + struct callout rp_timer; unsigned char state; /* state of dtr */ |