Annotation of embedaddon/ntp/libparse/parsestreams.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * /src/NTP/ntp4-dev/libparse/parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A
        !             3:  *  
        !             4:  * parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A
        !             5:  *
        !             6:  * STREAMS module for reference clocks
        !             7:  * (SunOS4.x)
        !             8:  *
        !             9:  * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
        !            10:  * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
        !            11:  *
        !            12:  * Redistribution and use in source and binary forms, with or without
        !            13:  * modification, are permitted provided that the following conditions
        !            14:  * are met:
        !            15:  * 1. Redistributions of source code must retain the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer.
        !            17:  * 2. Redistributions in binary form must reproduce the above copyright
        !            18:  *    notice, this list of conditions and the following disclaimer in the
        !            19:  *    documentation and/or other materials provided with the distribution.
        !            20:  * 3. Neither the name of the author nor the names of its contributors
        !            21:  *    may be used to endorse or promote products derived from this software
        !            22:  *    without specific prior written permission.
        !            23:  *
        !            24:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !            28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            34:  * SUCH DAMAGE.
        !            35:  *
        !            36:  */
        !            37: 
        !            38: #define KERNEL                 /* MUST */
        !            39: #define VDDRV                  /* SHOULD */
        !            40: 
        !            41: #ifdef HAVE_CONFIG_H
        !            42: # include "config.h"
        !            43: #endif
        !            44: 
        !            45: #ifndef lint
        !            46: static char rcsid[] = "parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A";
        !            47: #endif
        !            48: 
        !            49: #ifndef KERNEL
        !            50: #include "Bletch: MUST COMPILE WITH KERNEL DEFINE"
        !            51: #endif
        !            52: 
        !            53: #include <sys/types.h>
        !            54: #include <sys/conf.h>
        !            55: #include <sys/buf.h>
        !            56: #include <sys/param.h>
        !            57: #include <sys/sysmacros.h>
        !            58: #include <sys/time.h>
        !            59: #include <sundev/mbvar.h>
        !            60: #include <sun/autoconf.h>
        !            61: #include <sys/stream.h>
        !            62: #include <sys/stropts.h>
        !            63: #include <sys/dir.h>
        !            64: #include <sys/signal.h>
        !            65: #include <sys/termios.h>
        !            66: #include <sys/termio.h>
        !            67: #include <sys/ttold.h>
        !            68: #include <sys/user.h>
        !            69: #include <sys/tty.h>
        !            70: 
        !            71: #ifdef VDDRV
        !            72: #include <sun/vddrv.h>
        !            73: #endif
        !            74: 
        !            75: #include "ntp_stdlib.h"
        !            76: #include "ntp_fp.h"
        !            77: /*
        !            78:  * just make checking compilers more silent
        !            79:  */
        !            80: extern int printf      (const char *, ...);
        !            81: extern int putctl1     (queue_t *, int, int);
        !            82: extern int canput      (queue_t *);
        !            83: extern void putbq      (queue_t *, mblk_t *);
        !            84: extern void freeb      (mblk_t *);
        !            85: extern void qreply     (queue_t *, mblk_t *);
        !            86: extern void freemsg    (mblk_t *);
        !            87: extern void panic      (const char *, ...);
        !            88: extern void usec_delay (int);
        !            89: 
        !            90: #include "parse.h"
        !            91: #include "sys/parsestreams.h"
        !            92: 
        !            93: /*
        !            94:  * use microtime instead of uniqtime if advised to
        !            95:  */
        !            96: #ifdef MICROTIME
        !            97: #define uniqtime microtime
        !            98: #endif
        !            99: 
        !           100: #ifdef VDDRV
        !           101: static unsigned int parsebusy = 0;
        !           102: 
        !           103: /*--------------- loadable driver section -----------------------------*/
        !           104: 
        !           105: extern struct streamtab parseinfo;
        !           106: 
        !           107: 
        !           108: #ifdef PPS_SYNC
        !           109: static char mnam[] = "PARSEPPS     ";  /* name this baby - keep room for revision number */
        !           110: #else
        !           111: static char mnam[] = "PARSE        ";  /* name this baby - keep room for revision number */
        !           112: #endif
        !           113: struct vdldrv parsesync_vd = 
        !           114: {
        !           115:        VDMAGIC_PSEUDO,         /* nothing like a real driver - a STREAMS module */
        !           116:        mnam,
        !           117: };
        !           118: 
        !           119: /*
        !           120:  * strings support usually not in kernel
        !           121:  */
        !           122: static int
        !           123: Strlen(
        !           124:        register const char *s
        !           125:        )
        !           126: {
        !           127:        register int c;
        !           128: 
        !           129:        c = 0;
        !           130:        if (s)
        !           131:        {
        !           132:                while (*s++)
        !           133:                {
        !           134:                        c++;
        !           135:                }
        !           136:        }
        !           137:        return c;
        !           138: }
        !           139: 
        !           140: static void
        !           141: Strncpy(
        !           142:        register char *t,
        !           143:        register char *s,
        !           144:        register int   c
        !           145:        )
        !           146: {
        !           147:        if (s && t)
        !           148:        {
        !           149:                while ((c-- > 0) && (*t++ = *s++))
        !           150:                    ;
        !           151:        }
        !           152: }
        !           153: 
        !           154: static int
        !           155: Strcmp(
        !           156:        register const char *s,
        !           157:        register const char *t
        !           158:        )
        !           159: {
        !           160:        register int c = 0;
        !           161: 
        !           162:        if (!s || !t || (s == t))
        !           163:        {
        !           164:                return 0;
        !           165:        }
        !           166: 
        !           167:        while (!(c = *s++ - *t++) && *s && *t)
        !           168:            /* empty loop */;
        !           169:   
        !           170:        return c;
        !           171: }
        !           172: 
        !           173: static int
        !           174: Strncmp(
        !           175:        register char *s,
        !           176:        register char *t,
        !           177:        register int n
        !           178:        )
        !           179: {
        !           180:        register int c = 0;
        !           181: 
        !           182:        if (!s || !t || (s == t))
        !           183:        {
        !           184:                return 0;
        !           185:        }
        !           186: 
        !           187:        while (n-- && !(c = *s++ - *t++) && *s && *t)
        !           188:            /* empty loop */;
        !           189:   
        !           190:        return c;
        !           191: }
        !           192:  
        !           193: void
        !           194: ntp_memset(
        !           195:        char *a,
        !           196:        int x,
        !           197:        int c
        !           198:        )
        !           199: {
        !           200:        while (c-- > 0)
        !           201:            *a++ = x;
        !           202: }
        !           203: 
        !           204: /*
        !           205:  * driver init routine
        !           206:  * since no mechanism gets us into and out of the fmodsw, we have to
        !           207:  * do it ourselves
        !           208:  */
        !           209: /*ARGSUSED*/
        !           210: int
        !           211: xxxinit(
        !           212:        unsigned int fc,
        !           213:        struct vddrv *vdp,
        !           214:        addr_t vdin,
        !           215:        struct vdstat *vds
        !           216:        )
        !           217: {
        !           218:        extern struct fmodsw fmodsw[];
        !           219:        extern int fmodcnt;
        !           220:   
        !           221:        struct fmodsw *fm    = fmodsw;
        !           222:        struct fmodsw *fmend = &fmodsw[fmodcnt];
        !           223:        struct fmodsw *ifm   = (struct fmodsw *)0;
        !           224:        char *mname          = parseinfo.st_rdinit->qi_minfo->mi_idname;
        !           225:   
        !           226:        switch (fc)
        !           227:        {
        !           228:            case VDLOAD:
        !           229:                vdp->vdd_vdtab = (struct vdlinkage *)&parsesync_vd;
        !           230:                /*
        !           231:                 * now, jog along fmodsw scanning for an empty slot
        !           232:                 * and deposit our name there
        !           233:                 */
        !           234:                while (fm <= fmend)
        !           235:                {
        !           236:          if (!Strncmp(fm->f_name, mname, FMNAMESZ))
        !           237:                        {
        !           238:                                printf("vddrinit[%s]: STREAMS module already loaded.\n", mname);
        !           239:                                return(EBUSY);
        !           240:                        }
        !           241:                        else
        !           242:                            if ((ifm == (struct fmodsw *)0) && 
        !           243:                                (fm->f_name[0] == '\0') &&
        !           244:                                (fm->f_str == (struct streamtab *)0))
        !           245:                            {
        !           246:                                    /*
        !           247:                                     * got one - so move in
        !           248:                                     */
        !           249:                                    ifm = fm;
        !           250:                                    break;
        !           251:                            }
        !           252:                        fm++;
        !           253:                }
        !           254: 
        !           255:                if (ifm == (struct fmodsw *)0)
        !           256:                {
        !           257:                        printf("vddrinit[%s]: no slot free for STREAMS module\n", mname);
        !           258:                        return (ENOSPC);
        !           259:                }
        !           260:                else
        !           261:                {
        !           262:                        static char revision[] = "4.7";
        !           263:                        char *s, *S, *t;
        !           264:          
        !           265:                        s = rcsid;              /* NOOP - keep compilers happy */
        !           266: 
        !           267:                        Strncpy(ifm->f_name, mname, FMNAMESZ);
        !           268:                        ifm->f_name[FMNAMESZ] = '\0';
        !           269:                        ifm->f_str = &parseinfo;
        !           270:                        /*
        !           271:                         * copy RCS revision into Drv_name
        !           272:                         *
        !           273:                         * are we forcing RCS here to do things it was not built for ?
        !           274:                         */
        !           275:                        s = revision;
        !           276:                        if (*s == '$')
        !           277:                        {
        !           278:                                /*
        !           279:                                 * skip "$Revision: "
        !           280:                                 * if present. - not necessary on a -kv co (cvs export)
        !           281:                                 */
        !           282:                                while (*s && (*s != ' '))
        !           283:                                {
        !           284:                                        s++;
        !           285:                                }
        !           286:                                if (*s == ' ') s++;
        !           287:                        }
        !           288:          
        !           289:                        t = parsesync_vd.Drv_name; 
        !           290:                        while (*t && (*t != ' '))
        !           291:                        {
        !           292:                                t++;
        !           293:                        }
        !           294:                        if (*t == ' ') t++;
        !           295:          
        !           296:                        S = s;
        !           297:                        while (*S && (((*S >= '0') && (*S <= '9')) || (*S == '.')))
        !           298:                        {
        !           299:                                S++;
        !           300:                        }
        !           301:          
        !           302:                        if (*s && *t && (S > s))
        !           303:                        {
        !           304:                                if (Strlen(t) >= (S - s))
        !           305:                                {
        !           306:                                        (void) Strncpy(t, s, S - s);
        !           307:                                }
        !           308:                        }
        !           309:                        return (0);
        !           310:                } 
        !           311:                break;
        !           312:       
        !           313:            case VDUNLOAD:
        !           314:                if (parsebusy > 0)
        !           315:                {
        !           316:                        printf("vddrinit[%s]: STREAMS module has still %d instances active.\n", mname, parsebusy);
        !           317:                        return (EBUSY);
        !           318:                }
        !           319:                else
        !           320:                {
        !           321:                        while (fm <= fmend)
        !           322:                        {
        !           323:                                if (!Strncmp(fm->f_name, mname, FMNAMESZ))
        !           324:                                {
        !           325:                                        /*
        !           326:                                         * got it - kill entry
        !           327:                                         */
        !           328:                                        fm->f_name[0] = '\0';
        !           329:                                        fm->f_str = (struct streamtab *)0;
        !           330:                                        fm++;
        !           331:                  
        !           332:                                        break;
        !           333:                                }
        !           334:                                fm++;
        !           335:                        }
        !           336:                        if (fm > fmend)
        !           337:                        {
        !           338:                                printf("vddrinit[%s]: cannot find entry for STREAMS module\n", mname);
        !           339:                                return (ENXIO);
        !           340:                        }
        !           341:                        else
        !           342:                            return (0);
        !           343:                }
        !           344:       
        !           345: 
        !           346:            case VDSTAT:
        !           347:                return (0);
        !           348: 
        !           349:            default:
        !           350:                return (EIO);
        !           351:       
        !           352:        }
        !           353:        return EIO;
        !           354: }
        !           355: 
        !           356: #endif
        !           357: 
        !           358: /*--------------- stream module definition ----------------------------*/
        !           359: 
        !           360: static int parseopen  (queue_t *, dev_t, int, int);
        !           361: static int parseclose (queue_t *, int);
        !           362: static int parsewput  (queue_t *, mblk_t *);
        !           363: static int parserput  (queue_t *, mblk_t *);
        !           364: static int parsersvc  (queue_t *);
        !           365: 
        !           366: static char mn[] = "parse";
        !           367: 
        !           368: static struct module_info driverinfo =
        !           369: {
        !           370:        0,                              /* module ID number */
        !           371:        mn,                     /* module name */
        !           372:        0,                              /* minimum accepted packet size */
        !           373:        INFPSZ,                 /* maximum accepted packet size */
        !           374:        1,                              /* high water mark - flow control */
        !           375:        0                               /* low water mark - flow control */
        !           376: };
        !           377: 
        !           378: static struct qinit rinit =    /* read queue definition */
        !           379: {
        !           380:        parserput,                      /* put procedure */
        !           381:        parsersvc,                      /* service procedure */
        !           382:        parseopen,                      /* open procedure */
        !           383:        parseclose,                     /* close procedure */
        !           384:        NULL,                           /* admin procedure - NOT USED FOR NOW */
        !           385:        &driverinfo,                    /* information structure */
        !           386:        NULL                            /* statistics */
        !           387: };
        !           388: 
        !           389: static struct qinit winit =    /* write queue definition */
        !           390: {
        !           391:        parsewput,                      /* put procedure */
        !           392:        NULL,                           /* service procedure */
        !           393:        NULL,                           /* open procedure */
        !           394:        NULL,                           /* close procedure */
        !           395:        NULL,                           /* admin procedure - NOT USED FOR NOW */
        !           396:        &driverinfo,                    /* information structure */
        !           397:        NULL                            /* statistics */
        !           398: };
        !           399: 
        !           400: struct streamtab parseinfo =   /* stream info element for dpr driver */
        !           401: {
        !           402:        &rinit,                 /* read queue */
        !           403:        &winit,                 /* write queue */
        !           404:        NULL,                           /* read mux */
        !           405:        NULL,                           /* write mux */
        !           406:        NULL                            /* module auto push */
        !           407: };
        !           408: 
        !           409: /*--------------- driver data structures ----------------------------*/
        !           410: 
        !           411: /*
        !           412:  * we usually have an inverted signal - but you
        !           413:  * can change this to suit your needs
        !           414:  */
        !           415: int cd_invert = 1;             /* invert status of CD line - PPS support via CD input */
        !           416: 
        !           417: int parsedebug = ~0;
        !           418: 
        !           419: extern void uniqtime (struct timeval *);
        !           420: 
        !           421: /*--------------- module implementation -----------------------------*/
        !           422: 
        !           423: #define TIMEVAL_USADD(_X_, _US_) {\
        !           424:                                    (_X_)->tv_usec += (_US_);\
        !           425:                                   if ((_X_)->tv_usec >= 1000000)\
        !           426:                                      {\
        !           427:                                        (_X_)->tv_sec++;\
        !           428:                                       (_X_)->tv_usec -= 1000000;\
        !           429:                                      }\
        !           430:                                 } while (0)
        !           431: 
        !           432: static int init_linemon (queue_t *);
        !           433: static void close_linemon (queue_t *, queue_t *);
        !           434: 
        !           435: #define M_PARSE                0x0001
        !           436: #define M_NOPARSE      0x0002
        !           437: 
        !           438: static int
        !           439: setup_stream(
        !           440:             queue_t *q,
        !           441:             int mode
        !           442:             )
        !           443: {
        !           444:        mblk_t *mp;
        !           445: 
        !           446:        mp = allocb(sizeof(struct stroptions), BPRI_MED);
        !           447:        if (mp)
        !           448:        {
        !           449:                struct stroptions *str = (struct stroptions *)(void *)mp->b_rptr;
        !           450: 
        !           451:                str->so_flags   = SO_READOPT|SO_HIWAT|SO_LOWAT;
        !           452:                str->so_readopt = (mode == M_PARSE) ? RMSGD : RNORM;
        !           453:                str->so_hiwat   = (mode == M_PARSE) ? sizeof(parsetime_t) : 256;
        !           454:                str->so_lowat   = 0;
        !           455:                mp->b_datap->db_type = M_SETOPTS;
        !           456:                mp->b_wptr += sizeof(struct stroptions);
        !           457:                putnext(q, mp);
        !           458:                return putctl1(WR(q)->q_next, M_CTL, (mode == M_PARSE) ? MC_SERVICEIMM :
        !           459:                               MC_SERVICEDEF);
        !           460:        }
        !           461:        else
        !           462:        {
        !           463:                parseprintf(DD_OPEN,("parse: setup_stream - FAILED - no MEMORY for allocb\n")); 
        !           464:                return 0;
        !           465:        }
        !           466: }
        !           467: 
        !           468: /*ARGSUSED*/
        !           469: static int
        !           470: parseopen(
        !           471:        queue_t *q,
        !           472:        dev_t dev,
        !           473:        int flag,
        !           474:        int sflag
        !           475:        )
        !           476: {
        !           477:        register parsestream_t *parse;
        !           478:        static int notice = 0;
        !           479:   
        !           480:        parseprintf(DD_OPEN,("parse: OPEN\n")); 
        !           481:   
        !           482:        if (sflag != MODOPEN)
        !           483:        {                       /* open only for modules */
        !           484:                parseprintf(DD_OPEN,("parse: OPEN - FAILED - not MODOPEN\n")); 
        !           485:                return OPENFAIL;
        !           486:        }
        !           487: 
        !           488:        if (q->q_ptr != (caddr_t)NULL)
        !           489:        {
        !           490:                u.u_error = EBUSY;
        !           491:                parseprintf(DD_OPEN,("parse: OPEN - FAILED - EXCLUSIVE ONLY\n")); 
        !           492:                return OPENFAIL;
        !           493:        }
        !           494: 
        !           495: #ifdef VDDRV
        !           496:        parsebusy++;
        !           497: #endif
        !           498:   
        !           499:        q->q_ptr = (caddr_t)kmem_alloc(sizeof(parsestream_t));
        !           500:        if (q->q_ptr == (caddr_t)0)
        !           501:        {
        !           502:                parseprintf(DD_OPEN,("parse: OPEN - FAILED - no memory\n")); 
        !           503: #ifdef VDDRV
        !           504:                parsebusy--;
        !           505: #endif
        !           506:                return OPENFAIL;
        !           507:        }
        !           508:        WR(q)->q_ptr = q->q_ptr;
        !           509:   
        !           510:        parse = (parsestream_t *)(void *)q->q_ptr;
        !           511:        bzero((caddr_t)parse, sizeof(*parse));
        !           512:        parse->parse_queue     = q;
        !           513:        parse->parse_status    = PARSE_ENABLE;
        !           514:        parse->parse_ppsclockev.tv.tv_sec  = 0;
        !           515:        parse->parse_ppsclockev.tv.tv_usec = 0;
        !           516:        parse->parse_ppsclockev.serial     = 0;
        !           517: 
        !           518:        if (!parse_ioinit(&parse->parse_io))
        !           519:        {
        !           520:                /*
        !           521:                 * ok guys - beat it
        !           522:                 */
        !           523:                kmem_free((caddr_t)parse, sizeof(parsestream_t));
        !           524: #ifdef VDDRV
        !           525:                parsebusy--;
        !           526: #endif
        !           527:                return OPENFAIL;
        !           528:        }
        !           529: 
        !           530:        if (setup_stream(q, M_PARSE))
        !           531:        {
        !           532:                (void) init_linemon(q); /* hook up PPS ISR routines if possible */
        !           533: 
        !           534:                parseprintf(DD_OPEN,("parse: OPEN - SUCCEEDED\n")); 
        !           535: 
        !           536:                /*
        !           537:                 * I know that you know the delete key, but you didn't write this
        !           538:                 * code, did you ? - So, keep the message in here.
        !           539:                 */
        !           540:                if (!notice)
        !           541:                {
        !           542: #ifdef VDDRV
        !           543:                        printf("%s: Copyright (C) 1991-2005, Frank Kardel\n", parsesync_vd.Drv_name);
        !           544: #else
        !           545:                        printf("%s: Copyright (C) 1991-2005, Frank Kardel\n", "parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A");
        !           546: #endif
        !           547:                        notice = 1;
        !           548:                }
        !           549: 
        !           550:                return MODOPEN;
        !           551:        }
        !           552:        else
        !           553:        {
        !           554:                kmem_free((caddr_t)parse, sizeof(parsestream_t));
        !           555: 
        !           556: #ifdef VDDRV
        !           557:                parsebusy--;
        !           558: #endif
        !           559:                return OPENFAIL;
        !           560:        }
        !           561: }
        !           562: 
        !           563: /*ARGSUSED*/
        !           564: static int
        !           565: parseclose(
        !           566:        queue_t *q,
        !           567:        int flags
        !           568:        )
        !           569: {
        !           570:        register parsestream_t *parse = (parsestream_t *)(void *)q->q_ptr;
        !           571:        register unsigned long s;
        !           572:   
        !           573:        parseprintf(DD_CLOSE,("parse: CLOSE\n"));
        !           574:   
        !           575:        s = splhigh();
        !           576:   
        !           577:        if (parse->parse_dqueue)
        !           578:            close_linemon(parse->parse_dqueue, q);
        !           579:        parse->parse_dqueue = (queue_t *)0;
        !           580: 
        !           581:        (void) splx(s);
        !           582:       
        !           583:        parse_ioend(&parse->parse_io);
        !           584: 
        !           585:        kmem_free((caddr_t)parse, sizeof(parsestream_t));
        !           586: 
        !           587:        q->q_ptr = (caddr_t)NULL;
        !           588:        WR(q)->q_ptr = (caddr_t)NULL;
        !           589: 
        !           590: #ifdef VDDRV
        !           591:        parsebusy--;
        !           592: #endif
        !           593:        return 0;
        !           594: }
        !           595: 
        !           596: /*
        !           597:  * move unrecognized stuff upward
        !           598:  */
        !           599: static int
        !           600: parsersvc(
        !           601:        queue_t *q
        !           602:        )
        !           603: {
        !           604:        mblk_t *mp;
        !           605:   
        !           606:        while ((mp = getq(q)))
        !           607:        {
        !           608:                if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
        !           609:                {
        !           610:                        putnext(q, mp);
        !           611:                        parseprintf(DD_RSVC,("parse: RSVC - putnext\n"));
        !           612:                }
        !           613:                else
        !           614:                {
        !           615:                        putbq(q, mp);
        !           616:                        parseprintf(DD_RSVC,("parse: RSVC - flow control wait\n"));
        !           617:                        break;
        !           618:                }
        !           619:        }
        !           620:        return 0;
        !           621: }
        !           622: 
        !           623: /*
        !           624:  * do ioctls and
        !           625:  * send stuff down - dont care about
        !           626:  * flow control
        !           627:  */
        !           628: static int
        !           629: parsewput(
        !           630:        queue_t *q,
        !           631:        register mblk_t *mp
        !           632:        )
        !           633: {
        !           634:        register int ok = 1;
        !           635:        register mblk_t *datap;
        !           636:        register struct iocblk *iocp;
        !           637:        parsestream_t         *parse = (parsestream_t *)(void *)q->q_ptr;
        !           638:   
        !           639:        parseprintf(DD_WPUT,("parse: parsewput\n"));
        !           640:   
        !           641:        switch (mp->b_datap->db_type)
        !           642:        {
        !           643:            default:
        !           644:                putnext(q, mp);
        !           645:                break;
        !           646:       
        !           647:            case M_IOCTL:
        !           648:                    iocp = (struct iocblk *)(void *)mp->b_rptr;
        !           649:                switch (iocp->ioc_cmd)
        !           650:                {
        !           651:                    default:
        !           652:                        parseprintf(DD_WPUT,("parse: parsewput - forward M_IOCTL\n"));
        !           653:                        putnext(q, mp);
        !           654:                        break;
        !           655: 
        !           656:                    case CIOGETEV:
        !           657:                        /*
        !           658:                         * taken from Craig Leres ppsclock module (and modified)
        !           659:                         */
        !           660:                        datap = allocb(sizeof(struct ppsclockev), BPRI_MED);
        !           661:                        if (datap == NULL || mp->b_cont)
        !           662:                        {
        !           663:                                mp->b_datap->db_type = M_IOCNAK;
        !           664:                                iocp->ioc_error = (datap == NULL) ? ENOMEM : EINVAL;
        !           665:                                if (datap != NULL)
        !           666:                                    freeb(datap);
        !           667:                                qreply(q, mp);
        !           668:                                break;
        !           669:                        }
        !           670: 
        !           671:                        mp->b_cont = datap;
        !           672:                        *(struct ppsclockev *)(void *)datap->b_wptr = parse->parse_ppsclockev;
        !           673:                        datap->b_wptr +=
        !           674:                                sizeof(struct ppsclockev) / sizeof(*datap->b_wptr);
        !           675:                        mp->b_datap->db_type = M_IOCACK;
        !           676:                        iocp->ioc_count = sizeof(struct ppsclockev);
        !           677:                        qreply(q, mp);
        !           678:                        break;
        !           679:          
        !           680:                    case PARSEIOC_ENABLE:
        !           681:                    case PARSEIOC_DISABLE:
        !           682:                            {
        !           683:                                    parse->parse_status = (parse->parse_status & (unsigned)~PARSE_ENABLE) |
        !           684:                                            (iocp->ioc_cmd == PARSEIOC_ENABLE) ?
        !           685:                                            PARSE_ENABLE : 0;
        !           686:                                    if (!setup_stream(RD(q), (parse->parse_status & PARSE_ENABLE) ?
        !           687:                                                      M_PARSE : M_NOPARSE))
        !           688:                                    {
        !           689:                                            mp->b_datap->db_type = M_IOCNAK;
        !           690:                                    }
        !           691:                                    else
        !           692:                                    {
        !           693:                                            mp->b_datap->db_type = M_IOCACK;
        !           694:                                    }
        !           695:                                    qreply(q, mp);
        !           696:                                    break;
        !           697:                            }       
        !           698: 
        !           699:                    case PARSEIOC_TIMECODE:
        !           700:                    case PARSEIOC_SETFMT:
        !           701:                    case PARSEIOC_GETFMT:
        !           702:                    case PARSEIOC_SETCS:
        !           703:                        if (iocp->ioc_count == sizeof(parsectl_t))
        !           704:                        {
        !           705:                                parsectl_t *dct = (parsectl_t *)(void *)mp->b_cont->b_rptr;
        !           706: 
        !           707:                                switch (iocp->ioc_cmd)
        !           708:                                {
        !           709:                                    case PARSEIOC_TIMECODE:
        !           710:                                        parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_TIMECODE\n"));
        !           711:                                        ok = parse_timecode(dct, &parse->parse_io);
        !           712:                                        break;
        !           713:                  
        !           714:                                    case PARSEIOC_SETFMT:
        !           715:                                        parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETFMT\n"));
        !           716:                                        ok = parse_setfmt(dct, &parse->parse_io);
        !           717:                                        break;
        !           718: 
        !           719:                                    case PARSEIOC_GETFMT:
        !           720:                                        parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_GETFMT\n"));
        !           721:                                        ok = parse_getfmt(dct, &parse->parse_io);
        !           722:                                        break;
        !           723: 
        !           724:                                    case PARSEIOC_SETCS:
        !           725:                                        parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETCS\n"));
        !           726:                                        ok = parse_setcs(dct, &parse->parse_io);
        !           727:                                        break;
        !           728:                                }
        !           729:                                mp->b_datap->db_type = ok ? M_IOCACK : M_IOCNAK;
        !           730:                        }
        !           731:                        else
        !           732:                        {
        !           733:                                mp->b_datap->db_type = M_IOCNAK;
        !           734:                        }
        !           735:                        parseprintf(DD_WPUT,("parse: parsewput qreply - %s\n", (mp->b_datap->db_type == M_IOCNAK) ? "M_IOCNAK" : "M_IOCACK"));
        !           736:                        qreply(q, mp);
        !           737:                        break;
        !           738:                }
        !           739:        }
        !           740:        return 0;
        !           741: }
        !           742: 
        !           743: /*
        !           744:  * read characters from streams buffers
        !           745:  */
        !           746: static unsigned long
        !           747: rdchar(
        !           748:        register mblk_t **mp
        !           749:        )
        !           750: {
        !           751:        while (*mp != (mblk_t *)NULL)
        !           752:        {
        !           753:                if ((*mp)->b_wptr - (*mp)->b_rptr)
        !           754:                {
        !           755:                        return (unsigned long)(*(unsigned char *)((*mp)->b_rptr++));
        !           756:                }
        !           757:                else
        !           758:                {
        !           759:                        register mblk_t *mmp = *mp;
        !           760:          
        !           761:                        *mp = (*mp)->b_cont;
        !           762:                        freeb(mmp);
        !           763:                }
        !           764:        }
        !           765:        return (unsigned)~0;
        !           766: }
        !           767: 
        !           768: /*
        !           769:  * convert incoming data
        !           770:  */
        !           771: static int
        !           772: parserput(
        !           773:        queue_t *q,
        !           774:        mblk_t *mp
        !           775:        )
        !           776: {
        !           777:        unsigned char type;
        !           778:   
        !           779:        switch (type = mp->b_datap->db_type)
        !           780:        {
        !           781:            default:
        !           782:                /*
        !           783:                 * anything we don't know will be put on queue
        !           784:                 * the service routine will move it to the next one
        !           785:                 */
        !           786:                parseprintf(DD_RPUT,("parse: parserput - forward type 0x%x\n", type));
        !           787:                if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
        !           788:                {
        !           789:                        putnext(q, mp);
        !           790:                }
        !           791:                else
        !           792:                    putq(q, mp);
        !           793:                break;
        !           794:       
        !           795:            case M_BREAK:
        !           796:            case M_DATA:
        !           797:                    {
        !           798:                            register parsestream_t * parse = (parsestream_t *)(void *)q->q_ptr;
        !           799:                            register mblk_t *nmp;
        !           800:                            register unsigned long ch;
        !           801:                            timestamp_t ctime;
        !           802: 
        !           803:                            /*
        !           804:                             * get time on packet delivery
        !           805:                             */
        !           806:                            uniqtime(&ctime.tv);
        !           807: 
        !           808:                            if (!(parse->parse_status & PARSE_ENABLE))
        !           809:                            {
        !           810:                                    parseprintf(DD_RPUT,("parse: parserput - parser disabled - forward type 0x%x\n", type));
        !           811:                                    if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
        !           812:                                    {
        !           813:                                            putnext(q, mp);
        !           814:                                    }
        !           815:                                    else
        !           816:                                        putq(q, mp);
        !           817:                            }
        !           818:                            else
        !           819:                            {
        !           820:                                    parseprintf(DD_RPUT,("parse: parserput - M_%s\n", (type == M_DATA) ? "DATA" : "BREAK"));
        !           821: 
        !           822:                                    if (type == M_DATA)
        !           823:                                    {
        !           824:                                            /*
        !           825:                                             * parse packet looking for start an end characters
        !           826:                                             */
        !           827:                                            while (mp != (mblk_t *)NULL)
        !           828:                                            {
        !           829:                                                    ch = rdchar(&mp);
        !           830:                                                    if (ch != ~0 && parse_ioread(&parse->parse_io, (unsigned int)ch, &ctime))
        !           831:                                                    {
        !           832:                                                            /*
        !           833:                                                             * up up and away (hopefully ...)
        !           834:                                                             * don't press it if resources are tight or nobody wants it
        !           835:                                                             */
        !           836:                                                            nmp = (mblk_t *)NULL;
        !           837:                                                            if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
        !           838:                                                            {
        !           839:                                                                    bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
        !           840:                                                                    nmp->b_wptr += sizeof(parsetime_t);
        !           841:                                                                    putnext(parse->parse_queue, nmp);
        !           842:                                                            }
        !           843:                                                            else
        !           844:                                                                if (nmp) freemsg(nmp);
        !           845:                                                            parse_iodone(&parse->parse_io);
        !           846:                                                    }
        !           847:                                            }   
        !           848:                                    }
        !           849:                                    else
        !           850:                                    {
        !           851:                                            if (parse_ioread(&parse->parse_io, (unsigned int)0, &ctime))
        !           852:                                            {
        !           853:                                                    /*
        !           854:                                                     * up up and away (hopefully ...)
        !           855:                                                     * don't press it if resources are tight or nobody wants it
        !           856:                                                     */
        !           857:                                                    nmp = (mblk_t *)NULL;
        !           858:                                                    if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
        !           859:                                                    {
        !           860:                                                            bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
        !           861:                                                            nmp->b_wptr += sizeof(parsetime_t);
        !           862:                                                            putnext(parse->parse_queue, nmp);
        !           863:                                                    }
        !           864:                                                    else
        !           865:                                                        if (nmp) freemsg(nmp);
        !           866:                                                    parse_iodone(&parse->parse_io);
        !           867:                                            }
        !           868:                                            freemsg(mp);
        !           869:                                    }
        !           870:                                    break;
        !           871:                            }
        !           872:                    }
        !           873: 
        !           874:                    /*
        !           875:                     * CD PPS support for non direct ISR hack
        !           876:                     */
        !           877:            case M_HANGUP:
        !           878:            case M_UNHANGUP:
        !           879:                    {
        !           880:                            register parsestream_t * parse = (parsestream_t *)(void *)q->q_ptr;
        !           881:                            timestamp_t ctime;
        !           882:                            register mblk_t *nmp;
        !           883:                            register int status = cd_invert ^ (type == M_UNHANGUP);
        !           884: 
        !           885:                            uniqtime(&ctime.tv);
        !           886:        
        !           887:                            parseprintf(DD_RPUT,("parse: parserput - M_%sHANGUP\n", (type == M_HANGUP) ? "" : "UN"));
        !           888: 
        !           889:                            if ((parse->parse_status & PARSE_ENABLE) &&
        !           890:                                parse_iopps(&parse->parse_io, (int)(status ? SYNC_ONE : SYNC_ZERO), &ctime))
        !           891:                            {
        !           892:                                    nmp = (mblk_t *)NULL;
        !           893:                                    if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
        !           894:                                    {
        !           895:                                            bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
        !           896:                                            nmp->b_wptr += sizeof(parsetime_t);
        !           897:                                            putnext(parse->parse_queue, nmp);
        !           898:                                    }
        !           899:                                    else
        !           900:                                        if (nmp) freemsg(nmp);
        !           901:                                    parse_iodone(&parse->parse_io);
        !           902:                                    freemsg(mp);
        !           903:                            }
        !           904:                            else
        !           905:                                if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
        !           906:                                {
        !           907:                                        putnext(q, mp);
        !           908:                                }
        !           909:                                else
        !           910:                                    putq(q, mp);
        !           911:        
        !           912:                            if (status)
        !           913:                            {
        !           914:                                    parse->parse_ppsclockev.tv = ctime.tv;
        !           915:                                    ++(parse->parse_ppsclockev.serial);
        !           916:                            }
        !           917:                    }
        !           918:        }
        !           919:        return 0;
        !           920: }
        !           921: 
        !           922: static int  init_zs_linemon  (queue_t *, queue_t *);   /* handle line monitor for "zs" driver */
        !           923: static void close_zs_linemon (queue_t *, queue_t *);
        !           924: 
        !           925: /*-------------------- CD isr status monitor ---------------*/
        !           926: 
        !           927: static int
        !           928: init_linemon(
        !           929:        register queue_t *q
        !           930:        )
        !           931: {
        !           932:        register queue_t *dq;
        !           933:   
        !           934:        dq = WR(q);
        !           935:        /*
        !           936:         * we ARE doing very bad things down here (basically stealing ISR
        !           937:         * hooks)
        !           938:         *
        !           939:         * so we chase down the STREAMS stack searching for the driver
        !           940:         * and if this is a known driver we insert our ISR routine for
        !           941:         * status changes in to the ExternalStatus handling hook
        !           942:         */
        !           943:        while (dq->q_next)
        !           944:        {
        !           945:                dq = dq->q_next;                /* skip down to driver */
        !           946:        }
        !           947: 
        !           948:        /*
        !           949:         * find appropriate driver dependent routine
        !           950:         */
        !           951:        if (dq->q_qinfo && dq->q_qinfo->qi_minfo)
        !           952:        {
        !           953:                register char *dname = dq->q_qinfo->qi_minfo->mi_idname;
        !           954: 
        !           955:                parseprintf(DD_INSTALL, ("init_linemon: driver is \"%s\"\n", dname));
        !           956: 
        !           957: #ifdef sun
        !           958:                if (dname && !Strcmp(dname, "zs"))
        !           959:                {
        !           960:                        return init_zs_linemon(dq, q);
        !           961:                }
        !           962:                else
        !           963: #endif
        !           964:                {
        !           965:                        parseprintf(DD_INSTALL, ("init_linemon: driver \"%s\" not suitable for CD monitoring\n", dname));
        !           966:                        return 0;
        !           967:                }
        !           968:        }
        !           969:        parseprintf(DD_INSTALL, ("init_linemon: cannot find driver\n"));
        !           970:        return 0;
        !           971: }
        !           972: 
        !           973: static void
        !           974: close_linemon(
        !           975:        register queue_t *q,
        !           976:        register queue_t *my_q
        !           977:        )
        !           978: {
        !           979:        /*
        !           980:         * find appropriate driver dependent routine
        !           981:         */
        !           982:        if (q->q_qinfo && q->q_qinfo->qi_minfo)
        !           983:        {
        !           984:                register char *dname = q->q_qinfo->qi_minfo->mi_idname;
        !           985: 
        !           986: #ifdef sun
        !           987:                if (dname && !Strcmp(dname, "zs"))
        !           988:                {
        !           989:                        close_zs_linemon(q, my_q);
        !           990:                        return;
        !           991:                }
        !           992:                parseprintf(DD_INSTALL, ("close_linemon: cannot find driver close routine for \"%s\"\n", dname));
        !           993: #endif
        !           994:        }
        !           995:        parseprintf(DD_INSTALL, ("close_linemon: cannot find driver name\n"));
        !           996: }
        !           997: 
        !           998: #ifdef sun
        !           999: 
        !          1000: #include <sundev/zsreg.h>
        !          1001: #include <sundev/zscom.h>
        !          1002: #include <sundev/zsvar.h>
        !          1003: 
        !          1004: static unsigned long cdmask  = ZSRR0_CD;
        !          1005: 
        !          1006: struct savedzsops
        !          1007: {
        !          1008:        struct zsops  zsops;
        !          1009:        struct zsops *oldzsops;
        !          1010: };
        !          1011: 
        !          1012: struct zsops   *emergencyzs;
        !          1013: extern void zsopinit   (struct zscom *, struct zsops *);
        !          1014: static int  zs_xsisr   (struct zscom *);       /* zs external status interupt handler */
        !          1015: 
        !          1016: static int
        !          1017: init_zs_linemon(
        !          1018:        register queue_t *q,
        !          1019:        register queue_t *my_q
        !          1020:        )
        !          1021: {
        !          1022:        register struct zscom *zs;
        !          1023:        register struct savedzsops *szs;
        !          1024:        register parsestream_t  *parsestream = (parsestream_t *)(void *)my_q->q_ptr;
        !          1025:        /*
        !          1026:         * we expect the zsaline pointer in the q_data pointer
        !          1027:         * from there on we insert our on EXTERNAL/STATUS ISR routine
        !          1028:         * into the interrupt path, before the standard handler
        !          1029:         */
        !          1030:        zs = ((struct zsaline *)(void *)q->q_ptr)->za_common;
        !          1031:        if (!zs)
        !          1032:        {
        !          1033:                /*
        !          1034:                 * well - not found on startup - just say no (shouldn't happen though)
        !          1035:                 */
        !          1036:                return 0;
        !          1037:        }
        !          1038:        else
        !          1039:        {
        !          1040:                unsigned long s;
        !          1041:       
        !          1042:                /*
        !          1043:                 * we do a direct replacement, in case others fiddle also
        !          1044:                 * if somebody else grabs our hook and we disconnect
        !          1045:                 * we are in DEEP trouble - panic is likely to be next, sorry
        !          1046:                 */
        !          1047:                szs = (struct savedzsops *)(void *)kmem_alloc(sizeof(struct savedzsops));
        !          1048: 
        !          1049:                if (szs == (struct savedzsops *)0)
        !          1050:                {
        !          1051:                        parseprintf(DD_INSTALL, ("init_zs_linemon: CD monitor NOT installed - no memory\n"));
        !          1052: 
        !          1053:                        return 0;
        !          1054:                }
        !          1055:                else
        !          1056:                {
        !          1057:                        parsestream->parse_data   = (void *)szs;
        !          1058: 
        !          1059:                        s = splhigh();
        !          1060: 
        !          1061:                        parsestream->parse_dqueue = q; /* remember driver */
        !          1062: 
        !          1063:                        szs->zsops            = *zs->zs_ops;
        !          1064:                        szs->zsops.zsop_xsint = zs_xsisr; /* place our bastard */
        !          1065:                        szs->oldzsops         = zs->zs_ops;
        !          1066:                        emergencyzs           = zs->zs_ops;
        !          1067:          
        !          1068:                        zsopinit(zs, &szs->zsops); /* hook it up */
        !          1069:          
        !          1070:                        (void) splx(s);
        !          1071: 
        !          1072:                        parseprintf(DD_INSTALL, ("init_zs_linemon: CD monitor installed\n"));
        !          1073: 
        !          1074:                        return 1;
        !          1075:                }
        !          1076:        }
        !          1077: }
        !          1078: 
        !          1079: /*
        !          1080:  * unregister our ISR routine - must call under splhigh()
        !          1081:  */
        !          1082: static void
        !          1083: close_zs_linemon(
        !          1084:        register queue_t *q,
        !          1085:        register queue_t *my_q
        !          1086:        )
        !          1087: {
        !          1088:        register struct zscom *zs;
        !          1089:        register parsestream_t  *parsestream = (parsestream_t *)(void *)my_q->q_ptr;
        !          1090: 
        !          1091:        zs = ((struct zsaline *)(void *)q->q_ptr)->za_common;
        !          1092:        if (!zs)
        !          1093:        {
        !          1094:                /*
        !          1095:                 * well - not found on startup - just say no (shouldn't happen though)
        !          1096:                 */
        !          1097:                return;
        !          1098:        }
        !          1099:        else
        !          1100:        {
        !          1101:                register struct savedzsops *szs = (struct savedzsops *)parsestream->parse_data;
        !          1102:       
        !          1103:                zsopinit(zs, szs->oldzsops); /* reset to previous handler functions */
        !          1104: 
        !          1105:                kmem_free((caddr_t)szs, sizeof (struct savedzsops));
        !          1106:       
        !          1107:                parseprintf(DD_INSTALL, ("close_zs_linemon: CD monitor deleted\n"));
        !          1108:                return;
        !          1109:        }
        !          1110: }
        !          1111: 
        !          1112: #define MAXDEPTH 50            /* maximum allowed stream crawl */
        !          1113: 
        !          1114: #ifdef PPS_SYNC
        !          1115: extern void hardpps (struct timeval *, long);
        !          1116: #ifdef PPS_NEW
        !          1117: extern struct timeval timestamp;
        !          1118: #else
        !          1119: extern struct timeval pps_time;
        !          1120: #endif
        !          1121: #endif
        !          1122: 
        !          1123: /*
        !          1124:  * take external status interrupt (only CD interests us)
        !          1125:  */
        !          1126: static int
        !          1127: zs_xsisr(
        !          1128:         struct zscom *zs
        !          1129:        )
        !          1130: {
        !          1131:        register struct zsaline *za = (struct zsaline *)(void *)zs->zs_priv;
        !          1132:        register struct zscc_device *zsaddr = zs->zs_addr;
        !          1133:        register queue_t *q;
        !          1134:        register unsigned char zsstatus;
        !          1135:        register int loopcheck;
        !          1136:        register char *dname;
        !          1137: #ifdef PPS_SYNC
        !          1138:        register unsigned int s;
        !          1139:        register long usec;
        !          1140: #endif
        !          1141: 
        !          1142:        /*
        !          1143:         * pick up current state
        !          1144:         */
        !          1145:        zsstatus = zsaddr->zscc_control;
        !          1146: 
        !          1147:        if ((za->za_rr0 ^ zsstatus) & (cdmask))
        !          1148:        {
        !          1149:                timestamp_t cdevent;
        !          1150:                register int status;
        !          1151:       
        !          1152:                za->za_rr0 = (za->za_rr0 & ~(cdmask)) | (zsstatus & (cdmask));
        !          1153: 
        !          1154: #ifdef PPS_SYNC
        !          1155:                s = splclock();
        !          1156: #ifdef PPS_NEW
        !          1157:                usec = timestamp.tv_usec;
        !          1158: #else
        !          1159:                usec = pps_time.tv_usec;
        !          1160: #endif
        !          1161: #endif
        !          1162:                /*
        !          1163:                 * time stamp
        !          1164:                 */
        !          1165:                uniqtime(&cdevent.tv);
        !          1166:       
        !          1167: #ifdef PPS_SYNC
        !          1168:                (void)splx(s);
        !          1169: #endif
        !          1170: 
        !          1171:                /*
        !          1172:                 * logical state
        !          1173:                 */
        !          1174:                status = cd_invert ? (zsstatus & cdmask) == 0 : (zsstatus & cdmask) != 0;
        !          1175: 
        !          1176: #ifdef PPS_SYNC
        !          1177:                if (status)
        !          1178:                {
        !          1179:                        usec = cdevent.tv.tv_usec - usec;
        !          1180:                        if (usec < 0)
        !          1181:                            usec += 1000000;
        !          1182: 
        !          1183:                        hardpps(&cdevent.tv, usec);
        !          1184:                }
        !          1185: #endif
        !          1186: 
        !          1187:                q = za->za_ttycommon.t_readq;
        !          1188: 
        !          1189:                /*
        !          1190:                 * ok - now the hard part - find ourself
        !          1191:                 */
        !          1192:                loopcheck = MAXDEPTH;
        !          1193:       
        !          1194:                while (q)
        !          1195:                {
        !          1196:                        if (q->q_qinfo && q->q_qinfo->qi_minfo)
        !          1197:                        {
        !          1198:                                dname = q->q_qinfo->qi_minfo->mi_idname;
        !          1199: 
        !          1200:                                if (!Strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname))
        !          1201:                                {
        !          1202:                                        /*
        !          1203:                                         * back home - phew (hopping along stream queues might
        !          1204:                                         * prove dangerous to your health)
        !          1205:                                         */
        !          1206: 
        !          1207:                                        if ((((parsestream_t *)(void *)q->q_ptr)->parse_status & PARSE_ENABLE) &&
        !          1208:                                            parse_iopps(&((parsestream_t *)(void *)q->q_ptr)->parse_io, (int)(status ? SYNC_ONE : SYNC_ZERO), &cdevent))
        !          1209:                                        {
        !          1210:                                                /*
        !          1211:                                                 * XXX - currently we do not pass up the message, as
        !          1212:                                                 * we should.
        !          1213:                                                 * for a correct behaviour wee need to block out
        !          1214:                                                 * processing until parse_iodone has been posted via
        !          1215:                                                 * a softcall-ed routine which does the message pass-up
        !          1216:                                                 * right now PPS information relies on input being
        !          1217:                                                 * received
        !          1218:                                                 */
        !          1219:                                                parse_iodone(&((parsestream_t *)(void *)q->q_ptr)->parse_io);
        !          1220:                                        }
        !          1221:                  
        !          1222:                                        if (status)
        !          1223:                                        {
        !          1224:                                                ((parsestream_t *)(void *)q->q_ptr)->parse_ppsclockev.tv = cdevent.tv;
        !          1225:                                                ++(((parsestream_t *)(void *)q->q_ptr)->parse_ppsclockev.serial);
        !          1226:                                        }
        !          1227: 
        !          1228:                                        parseprintf(DD_ISR, ("zs_xsisr: CD event %s has been posted for \"%s\"\n", status ? "ONE" : "ZERO", dname));
        !          1229:                                        break;
        !          1230:                                }
        !          1231:                        }
        !          1232: 
        !          1233:                        q = q->q_next;
        !          1234: 
        !          1235:                        if (!loopcheck--)
        !          1236:                        {
        !          1237:                                panic("zs_xsisr: STREAMS Queue corrupted - CD event");
        !          1238:                        }
        !          1239:                }
        !          1240: 
        !          1241:                /*
        !          1242:                 * only pretend that CD has been handled
        !          1243:                 */
        !          1244:                ZSDELAY(2);
        !          1245: 
        !          1246:                if (!((za->za_rr0 ^ zsstatus) & ~(cdmask)))
        !          1247:                {
        !          1248:                        /*
        !          1249:                         * all done - kill status indication and return
        !          1250:                         */
        !          1251:                        zsaddr->zscc_control = ZSWR0_RESET_STATUS; /* might kill other conditions here */
        !          1252:                        return 0;
        !          1253:                }
        !          1254:        }      
        !          1255: 
        !          1256:        if (zsstatus & cdmask)  /* fake CARRIER status */
        !          1257:                za->za_flags |= ZAS_CARR_ON;
        !          1258:        else
        !          1259:                za->za_flags &= ~ZAS_CARR_ON;
        !          1260:        
        !          1261:        /*
        !          1262:         * we are now gathered here to process some unusual external status
        !          1263:         * interrupts.
        !          1264:         * any CD events have also been handled and shouldn't be processed
        !          1265:         * by the original routine (unless we have a VERY busy port pin)
        !          1266:         * some initializations are done here, which could have been done before for
        !          1267:         * both code paths but have been avoided for minimum path length to
        !          1268:         * the uniq_time routine
        !          1269:         */
        !          1270:        dname = (char *) 0;
        !          1271:        q = za->za_ttycommon.t_readq;
        !          1272: 
        !          1273:        loopcheck = MAXDEPTH;
        !          1274:       
        !          1275:        /*
        !          1276:         * the real thing for everything else ...
        !          1277:         */
        !          1278:        while (q)
        !          1279:        {
        !          1280:                if (q->q_qinfo && q->q_qinfo->qi_minfo)
        !          1281:                {
        !          1282:                        dname = q->q_qinfo->qi_minfo->mi_idname;
        !          1283:                        if (!Strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname))
        !          1284:                        {
        !          1285:                                register int (*zsisr) (struct zscom *);
        !          1286:                  
        !          1287:                                /*
        !          1288:                                 * back home - phew (hopping along stream queues might
        !          1289:                                 * prove dangerous to your health)
        !          1290:                                 */
        !          1291:                                if ((zsisr = ((struct savedzsops *)((parsestream_t *)(void *)q->q_ptr)->parse_data)->oldzsops->zsop_xsint))
        !          1292:                                        return zsisr(zs);
        !          1293:                                else
        !          1294:                                    panic("zs_xsisr: unable to locate original ISR");
        !          1295:                  
        !          1296:                                parseprintf(DD_ISR, ("zs_xsisr: non CD event was processed for \"%s\"\n", dname));
        !          1297:                                /*
        !          1298:                                 * now back to our program ...
        !          1299:                                 */
        !          1300:                                return 0;
        !          1301:                        }
        !          1302:                }
        !          1303: 
        !          1304:                q = q->q_next;
        !          1305: 
        !          1306:                if (!loopcheck--)
        !          1307:                {
        !          1308:                        panic("zs_xsisr: STREAMS Queue corrupted - non CD event");
        !          1309:                }
        !          1310:        }
        !          1311: 
        !          1312:        /*
        !          1313:         * last resort - shouldn't even come here as it indicates
        !          1314:         * corrupted TTY structures
        !          1315:         */
        !          1316:        printf("zs_zsisr: looking for \"%s\" - found \"%s\" - taking EMERGENCY path\n", parseinfo.st_rdinit->qi_minfo->mi_idname, dname ? dname : "-NIL-");
        !          1317:       
        !          1318:        if (emergencyzs && emergencyzs->zsop_xsint)
        !          1319:            emergencyzs->zsop_xsint(zs);
        !          1320:        else
        !          1321:            panic("zs_xsisr: no emergency ISR handler");
        !          1322:        return 0;
        !          1323: }
        !          1324: #endif                         /* sun */
        !          1325: 
        !          1326: /*
        !          1327:  * History:
        !          1328:  *
        !          1329:  * parsestreams.c,v
        !          1330:  * Revision 4.11  2005/04/16 17:32:10  kardel
        !          1331:  * update copyright
        !          1332:  *
        !          1333:  * Revision 4.10  2004/11/14 16:06:08  kardel
        !          1334:  * update Id tags
        !          1335:  *
        !          1336:  * Revision 4.9  2004/11/14 15:29:41  kardel
        !          1337:  * support PPSAPI, upgrade Copyright to Berkeley style
        !          1338:  *
        !          1339:  * Revision 4.7  1999/11/28 09:13:53  kardel
        !          1340:  * RECON_4_0_98F
        !          1341:  *
        !          1342:  * Revision 4.6  1998/12/20 23:45:31  kardel
        !          1343:  * fix types and warnings
        !          1344:  *
        !          1345:  * Revision 4.5  1998/11/15 21:23:38  kardel
        !          1346:  * ntp_memset() replicated in Sun kernel files
        !          1347:  *
        !          1348:  * Revision 4.4  1998/06/13 12:15:59  kardel
        !          1349:  * superfluous variable removed
        !          1350:  *
        !          1351:  * Revision 4.3  1998/06/12 15:23:08  kardel
        !          1352:  * fix prototypes
        !          1353:  * adjust for ansi2knr
        !          1354:  *
        !          1355:  * Revision 4.2  1998/05/24 18:16:22  kardel
        !          1356:  * moved copy of shadow status to the beginning
        !          1357:  *
        !          1358:  * Revision 4.1  1998/05/24 09:38:47  kardel
        !          1359:  * streams initiated iopps calls (M_xHANGUP) are now consistent with the
        !          1360:  * respective calls from zs_xsisr()
        !          1361:  * simulation of CARRIER status to avoid unecessary M_xHANGUP messages
        !          1362:  *
        !          1363:  * Revision 4.0  1998/04/10 19:45:38  kardel
        !          1364:  * Start 4.0 release version numbering
        !          1365:  *
        !          1366:  * from V3 3.37 log info deleted 1998/04/11 kardel
        !          1367:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>