diff options
Diffstat (limited to 'usr.sbin/xntpd/parse/parsesolaris.c')
-rw-r--r-- | usr.sbin/xntpd/parse/parsesolaris.c | 1249 |
1 files changed, 0 insertions, 1249 deletions
diff --git a/usr.sbin/xntpd/parse/parsesolaris.c b/usr.sbin/xntpd/parse/parsesolaris.c deleted file mode 100644 index a67f0bf..0000000 --- a/usr.sbin/xntpd/parse/parsesolaris.c +++ /dev/null @@ -1,1249 +0,0 @@ -/* - * /src/NTP/REPOSITORY/v3/parse/parsesolaris.c,v 3.16 1994/05/30 09:57:40 kardel Exp - * - * parsesolaris.c,v 3.16 1994/05/30 09:57:40 kardel Exp - * - * STREAMS module for reference clocks - * (SunOS5.x - not fully tested - buyer beware ! - OS KILLERS may still be - * lurking in the code!) - * - * Copyright (c) 1993,1994 - * derived work from parsestreams.c ((c) 1991-1993, Frank Kardel) and - * dcf77sync.c((c) Frank Kardel) - * Frank Kardel, Friedrich-Alexander Universitaet Erlangen-Nuernberg - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#ifndef lint -static char rcsid[] = "parsesolaris.c,v 3.16 1994/05/30 09:57:40 kardel Exp"; -#endif - -/* - * Well, the man spec says we have to do this junk - the - * header files tell a different story (i like that one more) - */ -#define SAFE_WR(q) (((q)->q_flag & QREADR) ? WR((q)) : (q)) -#define SAFE_RD(q) (((q)->q_flag & QREADR) ? (q) : RD((q))) - -/* - * needed to cope with Solaris 2.3 header file chaos - */ -#include <sys/types.h> -/* - * the Solaris 2.2 include list - */ -#include <sys/conf.h> -#include <sys/errno.h> -#include <sys/time.h> -#include <sys/termios.h> -#include <sys/stream.h> -#include <sys/strtty.h> -#include <sys/stropts.h> -#include <sys/modctl.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/cpu.h> - -#define STREAM /* that's what we are here for */ - -#define HAVE_NO_NICE /* for the NTP headerfiles */ -#include "ntp_fp.h" -#include "parse.h" -#include "sys/parsestreams.h" - -static unsigned int parsebusy = 0; - -/*--------------- loadable driver section -----------------------------*/ - -static struct streamtab parseinfo; - -static struct fmodsw fmod_templ = -{ - "parse", /* module name */ - &parseinfo, /* module information */ - D_NEW|D_MP|D_MTQPAIR, /* exclusive for q pair */ - /* lock ptr */ -}; - -extern struct mod_ops mod_strmodops; - -static struct modlstrmod modlstrmod = -{ - &mod_strmodops, /* a STREAMS module */ - "PARSE - NTP reference", /* name this baby - keep room for revision number */ - &fmod_templ -}; - -static struct modlinkage modlinkage = -{ - MODREV_1, - &modlstrmod, - NULL -}; - -/* - * strings support usually not in kernel - */ -static int Strlen(s) - register char *s; -{ - register int c; - - c = 0; - if (s) - { - while (*s++) - { - c++; - } - } - return c; -} - -static void Strncpy(t, s, c) - register char *t; - register char *s; - register int c; -{ - if (s && t) - { - while ((c-- > 0) && (*t++ = *s++)) - ; - } -} - -int Strcmp(s, t) - register char *s; - register char *t; -{ - register int c = 0; - - if (!s || !t || (s == t)) - { - return 0; - } - - while (!(c = *s++ - *t++) && *s && *t) - /* empty loop */; - - return c; -} - -/* - * module management routines - */ -/*ARGSUSED*/ -int _init(void) -{ - static char revision[] = "3.16"; - char *s, *S, *t; - - /* - * copy RCS revision into Drv_name - * - * are we forcing RCS here to do things it was not built for ? - */ - s = revision; - if (*s == '$') - { - /* - * skip "$Revision: " - * if present. - not necessary on a -kv co (cvs export) - */ - while (*s && (*s != ' ')) - { - s++; - } - if (*s == ' ') s++; - } - - t = modlstrmod.strmod_linkinfo; - while (*t && (*t != ' ')) - { - t++; - } - if (*t == ' ') t++; - - S = s; - while (*S && (((*S >= '0') && (*S <= '9')) || (*S == '.'))) - { - S++; - } - - if (*s && *t && (S > s)) - { - if (Strlen(t) >= (S - s)) - { - (void) Strncpy(t, s, S - s); - } - } - return (mod_install(&modlinkage)); -} - -/*ARGSUSED*/ -int _info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - -/*ARGSUSED*/ -int _fini(void) -{ - if (parsebusy > 0) - { - printf("_fini[%s]: STREAMS module has still %d instances active.\n", modlstrmod.strmod_linkinfo, parsebusy); - return (EBUSY); - } - else - return (mod_remove(&modlinkage)); -} - -/*--------------- stream module definition ----------------------------*/ - -static int parseopen(), parseclose(), parsewput(), parserput(), parsersvc(); - -static struct module_info driverinfo = -{ - 0, /* module ID number */ - fmod_templ.f_name, /* module name - why repeated here ? compat ?*/ - 0, /* minimum accepted packet size */ - INFPSZ, /* maximum accepted packet size */ - 1, /* high water mark - flow control */ - 0 /* low water mark - flow control */ -}; - -static struct qinit rinit = /* read queue definition */ -{ - parserput, /* put procedure */ - parsersvc, /* service procedure */ - parseopen, /* open procedure */ - parseclose, /* close procedure */ - NULL, /* admin procedure - NOT USED FOR NOW */ - &driverinfo, /* information structure */ - NULL /* statistics */ -}; - -static struct qinit winit = /* write queue definition */ -{ - parsewput, /* put procedure */ - NULL, /* service procedure */ - NULL, /* open procedure */ - NULL, /* close procedure */ - NULL, /* admin procedure - NOT USED FOR NOW */ - &driverinfo, /* information structure */ - NULL /* statistics */ -}; - -static struct streamtab parseinfo = /* stream info element for parse driver */ -{ - &rinit, /* read queue */ - &winit, /* write queue */ - NULL, /* read mux */ - NULL /* write mux */ -}; - -/*--------------- driver data structures ----------------------------*/ - -/* - * we usually have an inverted signal - but you - * can change this to suit your needs - */ -int cd_invert = 1; /* invert status of CD line - PPS support via CD input */ - -int parsedebug = ~0; - -extern void uniqtime(); - -/*--------------- module implementation -----------------------------*/ - -#define TIMEVAL_USADD(_X_, _US_) do {\ - (_X_)->tv_usec += (_US_);\ - if ((_X_)->tv_usec >= 1000000)\ - {\ - (_X_)->tv_sec++;\ - (_X_)->tv_usec -= 1000000;\ - }\ - } while (0) - -#if defined(sun4c) && defined(DEBUG_CD) -#include <sun4c/cpu.h> -#include <sun4c/auxio.h> -#define SET_LED(_X_) (((cpu & CPU_ARCH) == SUN4C_ARCH) ? *(u_char *)AUXIO_REG = AUX_MBO|AUX_EJECT|((_X_)?AUX_LED:0) : 0) -#else -#define SET_LED(_X_) -#endif - -static int init_linemon(); -static void close_linemon(); - -/* - * keep here MACHINE AND OS AND ENVIRONMENT DEPENDENT - * timing constants - * - * FOR ABSOLUTE PRECISION YOU NEED TO MEASURE THE TIMING - * SKEW BETWEEN THE HW-PPS SIGNAL AND KERNEL uniqtime() - * YOURSELF. - * - * YOU MUST BE QUALIFIED APPROPRIATELY FOR THESE TYPE - * OF HW MANIPULATION ! - * - * you need an oscilloscope and the permission for HW work - * in order to figure out these timing constants/variables - */ - -static unsigned long xsdelay = 10; /* assume an SS2 */ -static unsigned long stdelay = 350; - -struct delays -{ - unsigned char mask; /* what to check for */ - unsigned char type; /* what to match */ - unsigned long xsdelay; /* external status direct delay in us */ - unsigned long stdelay; /* STREAMS message delay (M_[UN]HANGUP) */ -} isr_delays[] = -{ - /* - * WARNING: must still be measured - currently taken from Craig Leres ppsdev - */ -#ifdef sun4c - {CPU_ARCH|CPU_MACH, CPU_SUN4C_50, 10, 350}, - {CPU_ARCH|CPU_MACH, CPU_SUN4C_65, 15, 700}, - {CPU_ARCH|CPU_MACH, CPU_SUN4C_75, 10, 350}, -#endif -#ifdef sun4m - {CPU_ARCH|CPU_MACH, CPU_SUN4M_50, 8, 250}, - {CPU_ARCH|CPU_MACH, CPU_SUN4M_690, 8, 250}, -#endif - {0,} -}; - -void setup_delays() -{ - register int i; - - if (cputype & OBP_ARCH) - { - printf("parse: WARNING: PPS kernel fudge factors no yet determinable (no dev tree walk yet) - assuming SS2 (Sun4/75)\n", cputype); - return; - } - - for (i = 0; isr_delays[i].mask; i++) - { - if ((cputype & isr_delays[i].mask) == isr_delays[i].type) - { - xsdelay = isr_delays[i].xsdelay; - stdelay = isr_delays[i].stdelay; - return; - } - } - printf("parse: WARNING: PPS kernel fudge factors unknown for this machine (Type 0x%x) - assuming SS2 (Sun4/75)\n", cputype); -} - -#define M_PARSE 0x0001 -#define M_NOPARSE 0x0002 - -static int -setup_stream(queue_t *q, int mode) -{ - register mblk_t *mp; - - parseprintf(DD_OPEN,("parse: SETUP_STREAM - setting up stream for q=%x\n", q)); - - mp = allocb(sizeof(struct stroptions), BPRI_MED); - if (mp) - { - struct stroptions *str = (struct stroptions *)mp->b_wptr; - - str->so_flags = SO_READOPT|SO_HIWAT|SO_LOWAT; - str->so_readopt = (mode == M_PARSE) ? RMSGD : RNORM; - str->so_hiwat = (mode == M_PARSE) ? sizeof(parsetime_t) : 256; - str->so_lowat = 0; - mp->b_datap->db_type = M_SETOPTS; - mp->b_wptr += sizeof(struct stroptions); - if (!q) - panic("NULL q - strange"); - putnext(q, mp); - return putctl1(SAFE_WR(q)->q_next, M_CTL, (mode == M_PARSE) ? MC_SERVICEIMM : - MC_SERVICEDEF); - } - else - { - parseprintf(DD_OPEN,("parse: setup_stream - FAILED - no MEMORY for allocb\n")); - return 0; - } -} - -/*ARGSUSED*/ -static int parseopen(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *credp) -{ - register mblk_t *mp; - register parsestream_t *parse; - static int notice = 0; - - parseprintf(DD_OPEN,("parse: OPEN - q=%x\n", q)); - - if (sflag != MODOPEN) - { /* open only for modules */ - parseprintf(DD_OPEN,("parse: OPEN - FAILED - not MODOPEN\n")); - return EIO; - } - - if (q->q_ptr != (caddr_t)NULL) - { - parseprintf(DD_OPEN,("parse: OPEN - FAILED - EXCLUSIVE ONLY\n")); - return EBUSY; - } - - parsebusy++; - - q->q_ptr = (caddr_t)kmem_alloc(sizeof(parsestream_t), KM_SLEEP); - if (q->q_ptr == (caddr_t)0) - { - return ENOMEM; - } - - parseprintf(DD_OPEN,("parse: OPEN - parse area q=%x, q->q_ptr=%x\n", q, q->q_ptr)); - SAFE_WR(q)->q_ptr = q->q_ptr; - parseprintf(DD_OPEN,("parse: OPEN - WQ parse area q=%x, q->q_ptr=%x\n", SAFE_WR(q), SAFE_WR(q)->q_ptr)); - - parse = (parsestream_t *) q->q_ptr; - bzero((caddr_t)parse, sizeof(*parse)); - parse->parse_queue = q; - parse->parse_status = PARSE_ENABLE; - parse->parse_ppsclockev.tv.tv_sec = 0; - parse->parse_ppsclockev.tv.tv_usec = 0; - parse->parse_ppsclockev.serial = 0; - - qprocson(q); - - parseprintf(DD_OPEN,("parse: OPEN - initializing io subsystem q=%x\n", q)); - - if (!parse_ioinit(&parse->parse_io)) - { - /* - * ok guys - beat it - */ - qprocsoff(q); - - kmem_free((caddr_t)parse, sizeof(parsestream_t)); - - parsebusy--; - - return EIO; - } - - parseprintf(DD_OPEN,("parse: OPEN - initializing stream q=%x\n", q)); - - if (setup_stream(q, M_PARSE)) - { - (void) init_linemon(q); /* hook up PPS ISR routines if possible */ - setup_delays(); - parseprintf(DD_OPEN,("parse: OPEN - SUCCEEDED\n")); - - /* - * I know that you know the delete key, but you didn't write this - * code, did you ? - So, keep the message in here. - */ - if (!notice) - { - printf("%s: Copyright (c) 1991-1994, Frank Kardel\n", modlstrmod.strmod_linkinfo); - notice = 1; - } - - return 0; - } - else - { - qprocsoff(q); - - kmem_free((caddr_t)parse, sizeof(parsestream_t)); - - parsebusy--; - - return EIO; - } -} - -/*ARGSUSED*/ -static int parseclose(queue_t *q, int flags) -{ - register parsestream_t *parse = (parsestream_t *)q->q_ptr; - register unsigned long s; - - parseprintf(DD_CLOSE,("parse: CLOSE\n")); - - qprocsoff(q); - - s = splhigh(); - - if (parse->parse_dqueue) - close_linemon(parse->parse_dqueue, q); - parse->parse_dqueue = (queue_t *)0; - - (void) splx(s); - - parse_ioend(&parse->parse_io); - - kmem_free((caddr_t)parse, sizeof(parsestream_t)); - - q->q_ptr = (caddr_t)NULL; - SAFE_WR(q)->q_ptr = (caddr_t)NULL; - - parsebusy--; -} - -/* - * move unrecognized stuff upward - */ -static parsersvc(queue_t *q) -{ - mblk_t *mp; - - while (mp = getq(q)) - { - if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) - { - putnext(q, mp); - parseprintf(DD_RSVC,("parse: RSVC - putnext\n")); - } - else - { - putbq(q, mp); - parseprintf(DD_RSVC,("parse: RSVC - flow control wait\n")); - break; - } - } -} - -/* - * do ioctls and - * send stuff down - dont care about - * flow control - */ -static int parsewput(queue_t *q, mblk_t *mp) -{ - register int ok = 1; - register mblk_t *datap; - register struct iocblk *iocp; - parsestream_t *parse = (parsestream_t *)q->q_ptr; - - parseprintf(DD_WPUT,("parse: parsewput\n")); - - switch (mp->b_datap->db_type) - { - default: - putnext(q, mp); - break; - - case M_IOCTL: - iocp = (struct iocblk *)mp->b_rptr; - switch (iocp->ioc_cmd) - { - default: - parseprintf(DD_WPUT,("parse: parsewput - forward M_IOCTL\n")); - putnext(q, mp); - break; - - case CIOGETEV: - /* - * taken from Craig Leres ppsclock module (and modified) - */ - datap = allocb(sizeof(struct ppsclockev), BPRI_MED); - if (datap == NULL || mp->b_cont) - { - mp->b_datap->db_type = M_IOCNAK; - iocp->ioc_error = (datap == NULL) ? ENOMEM : EINVAL; - if (datap != NULL) - freeb(datap); - qreply(q, mp); - break; - } - - mp->b_cont = datap; - *(struct ppsclockev *)datap->b_wptr = parse->parse_ppsclockev; - datap->b_wptr += - sizeof(struct ppsclockev) / sizeof(*datap->b_wptr); - mp->b_datap->db_type = M_IOCACK; - iocp->ioc_count = sizeof(struct ppsclockev); - qreply(q, mp); - break; - - case PARSEIOC_ENABLE: - case PARSEIOC_DISABLE: - { - parse->parse_status = (parse->parse_status & ~PARSE_ENABLE) | - (iocp->ioc_cmd == PARSEIOC_ENABLE) ? - PARSE_ENABLE : 0; - if (!setup_stream(SAFE_RD(q), (parse->parse_status & PARSE_ENABLE) ? - M_PARSE : M_NOPARSE)) - { - mp->b_datap->db_type = M_IOCNAK; - } - else - { - mp->b_datap->db_type = M_IOCACK; - } - qreply(q, mp); - break; - } - - case PARSEIOC_SETSTAT: - case PARSEIOC_GETSTAT: - case PARSEIOC_TIMECODE: - case PARSEIOC_SETFMT: - case PARSEIOC_GETFMT: - case PARSEIOC_SETCS: - if (iocp->ioc_count == sizeof(parsectl_t)) - { - parsectl_t *dct = (parsectl_t *)mp->b_cont->b_rptr; - - switch (iocp->ioc_cmd) - { - case PARSEIOC_GETSTAT: - parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_GETSTAT\n")); - ok = parse_getstat(dct, &parse->parse_io); - break; - - case PARSEIOC_SETSTAT: - parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETSTAT\n")); - ok = parse_setstat(dct, &parse->parse_io); - break; - - case PARSEIOC_TIMECODE: - parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_TIMECODE\n")); - ok = parse_timecode(dct, &parse->parse_io); - break; - - case PARSEIOC_SETFMT: - parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETFMT\n")); - ok = parse_setfmt(dct, &parse->parse_io); - break; - - case PARSEIOC_GETFMT: - parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_GETFMT\n")); - ok = parse_getfmt(dct, &parse->parse_io); - break; - - case PARSEIOC_SETCS: - parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETCS\n")); - ok = parse_setcs(dct, &parse->parse_io); - break; - } - mp->b_datap->db_type = ok ? M_IOCACK : M_IOCNAK; - } - else - { - mp->b_datap->db_type = M_IOCNAK; - } - parseprintf(DD_WPUT,("parse: parsewput qreply - %s\n", (mp->b_datap->db_type == M_IOCNAK) ? "M_IOCNAK" : "M_IOCACK")); - qreply(q, mp); - break; - } - } -} - -/* - * read characters from streams buffers - */ -static unsigned long rdchar(mblk_t **mp) -{ - while (*mp != (mblk_t *)NULL) - { - if ((*mp)->b_wptr - (*mp)->b_rptr) - { - return (unsigned long)(*(unsigned char *)((*mp)->b_rptr++)); - } - else - { - register mblk_t *mmp = *mp; - - *mp = (*mp)->b_cont; - freeb(mmp); - } - } - return ~0; -} - -/* - * convert incoming data - */ -static int parserput(queue_t *q, mblk_t *imp) -{ - register unsigned char type; - mblk_t *mp = imp; - - switch (type = mp->b_datap->db_type) - { - default: - /* - * anything we don't know will be put on queue - * the service routine will move it to the next one - */ - parseprintf(DD_RPUT,("parse: parserput - forward type 0x%x\n", type)); - - if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) - { - putnext(q, mp); - } - else - putq(q, mp); - break; - - case M_BREAK: - case M_DATA: - { - register parsestream_t * parse = (parsestream_t *)q->q_ptr; - register mblk_t *nmp; - register unsigned long ch; - timestamp_t ctime; - - /* - * get time on packet delivery - */ - uniqtime(&ctime.tv); - - if (!(parse->parse_status & PARSE_ENABLE)) - { - parseprintf(DD_RPUT,("parse: parserput - parser disabled - forward type 0x%x\n", type)); - if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) - { - putnext(q, mp); - } - else - putq(q, mp); - } - else - { -#if 0 - parseprintf(DD_RPUT,("parse: parserput - M_%s\n", (type == M_DATA) ? "DATA" : "BREAK")); -#endif - if (type == M_DATA) - { - /* - * parse packet looking for start an end characters - */ - while (mp != (mblk_t *)NULL) - { - ch = rdchar(&mp); - if (ch != ~0 && parse_ioread(&parse->parse_io, (char)ch, &ctime)) - { - /* - * up up and away (hopefully ...) - * don't press it if resources are tight or nobody wants it - */ - nmp = (mblk_t *)NULL; - if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED))) - { - bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t)); - nmp->b_wptr += sizeof(parsetime_t); - putnext(parse->parse_queue, nmp); - } - else - if (nmp) freemsg(nmp); - parse_iodone(&parse->parse_io); - } - } - } - else - { - if (parse_ioread(&parse->parse_io, (char)0, &ctime)) - { - /* - * up up and away (hopefully ...) - * don't press it if resources are tight or nobody wants it - */ - nmp = (mblk_t *)NULL; - if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED))) - { - bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t)); - nmp->b_wptr += sizeof(parsetime_t); - putnext(parse->parse_queue, nmp); - } - else - if (nmp) freemsg(nmp); - parse_iodone(&parse->parse_io); - } - freemsg(mp); - } - break; - } - } - - /* - * CD PPS support for non direct ISR hack - */ - case M_HANGUP: - case M_UNHANGUP: - { - register parsestream_t * parse = (parsestream_t *)q->q_ptr; - timestamp_t ctime; - register mblk_t *nmp; - register int status = cd_invert ^ (type == M_HANGUP); - - SET_LED(status); - - uniqtime(&ctime.tv); - - TIMEVAL_USADD(&ctime.tv, stdelay); - - parseprintf(DD_RPUT,("parse: parserput - M_%sHANGUP\n", (type == M_HANGUP) ? "" : "UN")); - - if ((parse->parse_status & PARSE_ENABLE) && - parse_iopps(&parse->parse_io, status ? SYNC_ONE : SYNC_ZERO, &ctime)) - { - nmp = (mblk_t *)NULL; - if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED))) - { - bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t)); - nmp->b_wptr += sizeof(parsetime_t); - putnext(parse->parse_queue, nmp); - } - else - if (nmp) freemsg(nmp); - parse_iodone(&parse->parse_io); - freemsg(mp); - } - else - if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL)) - { - putnext(q, mp); - } - else - putq(q, mp); - - if (status) - { - parse->parse_ppsclockev.tv = ctime.tv; - ++(parse->parse_ppsclockev.serial); - } - } - } -} - -static int init_zs_linemon(); /* handle line monitor for "zs" driver */ -static void close_zs_linemon(); -static void zs_xsisr(); /* zs external status interupt handler */ - -/*-------------------- CD isr status monitor ---------------*/ - -static int init_linemon(queue_t *q) -{ - register queue_t *dq; - - dq = SAFE_WR(q); - /* - * we ARE doing very bad things down here (basically stealing ISR - * hooks) - * - * so we chase down the STREAMS stack searching for the driver - * and if this is a known driver we insert our ISR routine for - * status changes in to the ExternalStatus handling hook - */ - while (dq->q_next) - { - dq = dq->q_next; /* skip down to driver */ - } - - /* - * find appropriate driver dependent routine - */ - if (dq->q_qinfo && dq->q_qinfo->qi_minfo) - { - register char *dname = dq->q_qinfo->qi_minfo->mi_idname; - - parseprintf(DD_INSTALL, ("init_linemon: driver is \"%s\"\n", dname)); - -#ifdef sun - if (dname && !Strcmp(dname, "zs")) - { - return init_zs_linemon(dq, q); - } - else -#endif - { - parseprintf(DD_INSTALL, ("init_linemon: driver \"%s\" not suitable for CD monitoring\n", dname)); - return 0; - } - } - parseprintf(DD_INSTALL, ("init_linemon: cannot find driver\n")); - return 0; -} - -static void close_linemon(queue_t *q, queue_t *my_q) -{ - /* - * find appropriate driver dependent routine - */ - if (q->q_qinfo && q->q_qinfo->qi_minfo) - { - register char *dname = q->q_qinfo->qi_minfo->mi_idname; - -#ifdef sun - if (dname && !Strcmp(dname, "zs")) - { - close_zs_linemon(q, my_q); - return; - } - parseprintf(DD_INSTALL, ("close_linemon: cannot find driver close routine for \"%s\"\n", dname)); -#endif - } - parseprintf(DD_INSTALL, ("close_linemon: cannot find driver name\n")); -} - -#ifdef sun -#include <sys/tty.h> -#include <sys/zsdev.h> -#include <sys/ser_async.h> -#include <sys/ser_zscc.h> - -/* - * there should be some docs telling how to get to - * sz:zs_usec_delay and zs:initzsops() - */ -#define zs_usec_delay 5 - -struct savedzsops -{ - struct zsops zsops; - struct zsops *oldzsops; -}; - -static struct zsops *emergencyzs; - -static int init_zs_linemon(queue_t *q, queue_t *my_q) -{ - register struct zscom *zs; - register struct savedzsops *szs; - register parsestream_t *parsestream = (parsestream_t *)my_q->q_ptr; - /* - * we expect the zsaline pointer in the q_data pointer - * from there on we insert our on EXTERNAL/STATUS ISR routine - * into the interrupt path, before the standard handler - */ - zs = ((struct asyncline *)q->q_ptr)->za_common; - if (!zs) - { - /* - * well - not found on startup - just say no (shouldn't happen though) - */ - return 0; - } - else - { - unsigned long s; - - /* - * we do a direct replacement, in case others fiddle also - * if somebody else grabs our hook and we disconnect - * we are in DEEP trouble - panic is likely to be next, sorry - */ - szs = (struct savedzsops *) kmem_alloc(sizeof(struct savedzsops), KM_SLEEP); - - if (szs == (struct savedzsops *)0) - { - parseprintf(DD_INSTALL, ("init_zs_linemon: CD monitor NOT installed - no memory\n")); - - return 0; - } - else - { - parsestream->parse_data = (void *)szs; - - mutex_enter(zs->zs_excl); - - parsestream->parse_dqueue = q; /* remember driver */ - - szs->zsops = *zs->zs_ops; - szs->zsops.zsop_xsint = (void (*)())zs_xsisr; /* place our bastard */ - szs->oldzsops = zs->zs_ops; - emergencyzs = zs->zs_ops; - - zs->zs_ops = &szs->zsops; /* hook it up */ - /* - * XXX: this is usually done via zsopinit() - * - have yet to find a way to call that routine - */ - zs->zs_xsint = (void (*)())zs_xsisr; - - mutex_exit(zs->zs_excl); - - parseprintf(DD_INSTALL, ("init_zs_linemon: CD monitor installed\n")); - - return 1; - } - } -} - -/* - * unregister our ISR routine - must call under splhigh() - */ -static void close_zs_linemon(queue_t *q, queue_t *my_q) -{ - register struct zscom *zs; - register parsestream_t *parsestream = (parsestream_t *)my_q->q_ptr; - - zs = ((struct asyncline *)q->q_ptr)->za_common; - if (!zs) - { - /* - * well - not found on startup - just say no (shouldn't happen though) - */ - return; - } - else - { - register struct savedzsops *szs = (struct savedzsops *)parsestream->parse_data; - - mutex_enter(zs->zs_excl); - - zs->zs_ops = szs->oldzsops; /* reset to previous handler functions */ - /* - * XXX: revert xsint (usually done via zsopinit() - have still to find - * a way to call that bugger - */ - zs->zs_xsint = zs->zs_ops->zsop_xsint; - - mutex_exit(zs->zs_excl); - - kmem_free((caddr_t)szs, sizeof (struct savedzsops)); - - parseprintf(DD_INSTALL, ("close_zs_linemon: CD monitor deleted\n")); - return; - } -} - -#define ZSRR0_IGNORE (ZSRR0_CD|ZSRR0_SYNC|ZSRR0_CTS) - -#define MAXDEPTH 50 /* maximum allowed stream crawl */ - -/* - * take external status interrupt (only CD interests us) - */ -static void zs_xsisr(struct zscom *zs) -{ - register struct asyncline *za = (struct asyncline *)zs->zs_priv; - register queue_t *q; - register unsigned char zsstatus; - register int loopcheck; - register unsigned char cdstate; - register char *dname; - - /* - * pick up current state - */ - zsstatus = SCC_READ0(); - - if (za->za_rr0 ^ (cdstate = zsstatus & ZSRR0_CD)) - { - timestamp_t cdevent; - register int status; - - /* - * CONDITIONAL external measurement support - */ - SET_LED(cdstate); /* - * inconsistent with upper SET_LED, but this - * is for oscilloscope business anyway and we - * are just interested in edge delays in the - * lower us range - */ - - /* - * time stamp - */ - uniqtime(&cdevent.tv); - - TIMEVAL_USADD(&cdevent.tv, xsdelay); - - q = za->za_ttycommon.t_readq; - - /* - * logical state - */ - status = cd_invert ? cdstate == 0 : cdstate != 0; - - /* - * ok - now the hard part - find ourself - */ - loopcheck = MAXDEPTH; - - while (q) - { - if (q->q_qinfo && q->q_qinfo->qi_minfo) - { - dname = q->q_qinfo->qi_minfo->mi_idname; - - if (!Strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname)) - { - /* - * back home - phew (hopping along stream queues might - * prove dangerous to your health) - */ - - if ((((parsestream_t *)q->q_ptr)->parse_status & PARSE_ENABLE) && - parse_iopps(&((parsestream_t *)q->q_ptr)->parse_io, status ? SYNC_ONE : SYNC_ZERO, &cdevent)) - { - /* - * XXX - currently we do not pass up the message, as - * we should. - * for a correct behaviour wee need to block out - * processing until parse_iodone has been posted via - * a softcall-ed routine which does the message pass-up - * right now PPS information relies on input being - * received - */ - parse_iodone(&((parsestream_t *)q->q_ptr)->parse_io); - } - - if (status) - { - ((parsestream_t *)q->q_ptr)->parse_ppsclockev.tv = cdevent.tv; - ++(((parsestream_t *)q->q_ptr)->parse_ppsclockev.serial); - } - - parseprintf(DD_ISR, ("zs_xsisr: CD event %s has been posted for \"%s\"\n", status ? "ONE" : "ZERO", dname)); - break; - } - } - - q = q->q_next; - - if (!loopcheck--) - { - panic("zs_xsisr: STREAMS Queue corrupted - CD event"); - } - } - - /* - * only pretend that CD and ignored transistion (SYNC,CTS) - * have been handled - */ - za->za_rr0 = (za->za_rr0 & ~ZSRR0_IGNORE) | (zsstatus & ZSRR0_IGNORE); - - if (((za->za_rr0 ^ zsstatus) & ~ZSRR0_IGNORE) == 0) - { - /* - * all done - kill status indication and return - */ - SCC_WRITE0(ZSWR0_RESET_STATUS); /* might kill other conditions here */ - return; - } - } - - parseprintf(DD_ISR, ("zs_xsisr: non CD event 0x%x for \"%s\"\n", - (za->za_rr0 ^ zsstatus) & ~ZSRR0_CD,dname)); - /* - * we are now gathered here to process some unusual external status - * interrupts. - * any CD events have also been handled and shouldn't be processed - * by the original routine (unless we have a VERY busy port pin) - * some initializations are done here, which could have been done before for - * both code paths but have been avioded for minimum path length to - * the uniq_time routine - */ - dname = (char *) 0; - q = za->za_ttycommon.t_readq; - - loopcheck = MAXDEPTH; - - /* - * the real thing for everything else ... - */ - while (q) - { - if (q->q_qinfo && q->q_qinfo->qi_minfo) - { - dname = q->q_qinfo->qi_minfo->mi_idname; - if (!Strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname)) - { - register void (*zsisr)(); - - /* - * back home - phew (hopping along stream queues might - * prove dangerous to your health) - */ - if (zsisr = ((struct savedzsops *)((parsestream_t *)q->q_ptr)->parse_data)->oldzsops->zsop_xsint) - zsisr(zs); - else - panic("zs_xsisr: unable to locate original ISR"); - - parseprintf(DD_ISR, ("zs_xsisr: non CD event was processed for \"%s\"\n", dname)); - /* - * now back to our program ... - */ - return; - } - } - - q = q->q_next; - - if (!loopcheck--) - { - panic("zs_xsisr: STREAMS Queue corrupted - non CD event"); - } - } - - /* - * last resort - shouldn't even come here as it indicates - * corrupted TTY structures - */ - printf("zs_zsisr: looking for \"%s\" - found \"%s\" - taking EMERGENCY path\n", parseinfo.st_rdinit->qi_minfo->mi_idname, dname ? dname : "-NIL-"); - - if (emergencyzs && emergencyzs->zsop_xsint) - emergencyzs->zsop_xsint(zs); - else - panic("zs_xsisr: no emergency ISR handler"); -} -#endif /* sun */ - -/* - * History: - * - * parsesolaris.c,v - * Revision 3.16 1994/05/30 09:57:40 kardel - * kmem_alloc checking - * - * Revision 3.15 1994/02/15 22:20:51 kardel - * rcsid fixed - * - * Revision 3.14 1994/02/15 22:06:04 kardel - * added qprocsx & flags for MT capability - * - * Revision 3.13 1994/02/13 19:16:47 kardel - * updated verbose Copyright message - * - * Revision 3.12 1994/02/02 17:45:35 kardel - * rcs ids fixed - * - * Revision 3.9 1994/01/25 19:05:26 kardel - * 94/01/23 reconcilation - * - * Revision 3.8 1994/01/23 17:22:04 kardel - * 1994 reconcilation - * - * Revision 3.7 1993/12/15 18:24:41 kardel - * Now also ignoring state changes on ZSRR0_{SYNC,CTS} to avoid zs driver bugs (Solaris 2.3) - * - * Revision 3.6 1993/12/15 12:48:53 kardel - * fixed message loss on M_*HANHUP messages - * - * Revision 3.5 1993/12/14 21:05:12 kardel - * PPS working now for SunOS 5.x zs external status hook - * - * Revision 3.4 1993/11/13 11:13:17 kardel - * Solaris 2.3 additional includes - * - * Revision 3.3 1993/11/11 11:20:33 kardel - * declaration fixes - * - * Revision 3.2 1993/11/05 15:40:25 kardel - * shut up nice feature detection - * - * Revision 3.1 1993/11/01 20:00:29 kardel - * parse Solaris support (initial version) - * - */ |