2 * /src/NTP/ntp-4/libparse/parsestreams.c,v 4.7 1999/11/28 09:13:53 kardel RELEASE_19991128_A
4 * parsestreams.c,v 4.7 1999/11/28 09:13:53 kardel RELEASE_19991128_A
6 * STREAMS module for reference clocks
9 * Copyright (c) 1989-1998 by Frank Kardel
10 * Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 #define KERNEL /* MUST */
19 #define VDDRV /* SHOULD */
26 static char rcsid[] = "parsestreams.c,v 4.7 1999/11/28 09:13:53 kardel RELEASE_19991128_A";
30 #include "Bletch: MUST COMPILE WITH KERNEL DEFINE"
33 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/sysmacros.h>
39 #include <sundev/mbvar.h>
40 #include <sun/autoconf.h>
41 #include <sys/stream.h>
42 #include <sys/stropts.h>
44 #include <sys/signal.h>
45 #include <sys/termios.h>
46 #include <sys/termio.h>
47 #include <sys/ttold.h>
52 #include <sun/vddrv.h>
55 #include "ntp_stdlib.h"
58 * just make checking compilers more silent
60 extern int printf P((const char *, ...));
61 extern int putctl1 P((queue_t *, int, int));
62 extern int canput P((queue_t *));
63 extern void putbq P((queue_t *, mblk_t *));
64 extern void freeb P((mblk_t *));
65 extern void qreply P((queue_t *, mblk_t *));
66 extern void freemsg P((mblk_t *));
67 extern void panic P((const char *, ...));
68 extern void usec_delay P((int));
71 #include "sys/parsestreams.h"
74 * use microtime instead of uniqtime if advised to
77 #define uniqtime microtime
81 static unsigned int parsebusy = 0;
83 /*--------------- loadable driver section -----------------------------*/
85 extern struct streamtab parseinfo;
89 static char mnam[] = "PARSEPPS "; /* name this baby - keep room for revision number */
91 static char mnam[] = "PARSE "; /* name this baby - keep room for revision number */
93 struct vdldrv parsesync_vd =
95 VDMAGIC_PSEUDO, /* nothing like a real driver - a STREAMS module */
100 * strings support usually not in kernel
104 register const char *s
129 while ((c-- > 0) && (*t++ = *s++))
136 register const char *s,
137 register const char *t
142 if (!s || !t || (s == t))
147 while (!(c = *s++ - *t++) && *s && *t)
162 if (!s || !t || (s == t))
167 while (n-- && !(c = *s++ - *t++) && *s && *t)
185 * driver init routine
186 * since no mechanism gets us into and out of the fmodsw, we have to
198 extern struct fmodsw fmodsw[];
201 struct fmodsw *fm = fmodsw;
202 struct fmodsw *fmend = &fmodsw[fmodcnt];
203 struct fmodsw *ifm = (struct fmodsw *)0;
204 char *mname = parseinfo.st_rdinit->qi_minfo->mi_idname;
209 vdp->vdd_vdtab = (struct vdlinkage *)&parsesync_vd;
211 * now, jog along fmodsw scanning for an empty slot
212 * and deposit our name there
216 if (!Strncmp(fm->f_name, mname, FMNAMESZ))
218 printf("vddrinit[%s]: STREAMS module already loaded.\n", mname);
222 if ((ifm == (struct fmodsw *)0) &&
223 (fm->f_name[0] == '\0') &&
224 (fm->f_str == (struct streamtab *)0))
227 * got one - so move in
235 if (ifm == (struct fmodsw *)0)
237 printf("vddrinit[%s]: no slot free for STREAMS module\n", mname);
242 static char revision[] = "4.7";
245 s = rcsid; /* NOOP - keep compilers happy */
247 Strncpy(ifm->f_name, mname, FMNAMESZ);
248 ifm->f_name[FMNAMESZ] = '\0';
249 ifm->f_str = &parseinfo;
251 * copy RCS revision into Drv_name
253 * are we forcing RCS here to do things it was not built for ?
260 * if present. - not necessary on a -kv co (cvs export)
262 while (*s && (*s != ' '))
269 t = parsesync_vd.Drv_name;
270 while (*t && (*t != ' '))
277 while (*S && (((*S >= '0') && (*S <= '9')) || (*S == '.')))
282 if (*s && *t && (S > s))
284 if (Strlen(t) >= (S - s))
286 (void) Strncpy(t, s, S - s);
296 printf("vddrinit[%s]: STREAMS module has still %d instances active.\n", mname, parsebusy);
303 if (!Strncmp(fm->f_name, mname, FMNAMESZ))
306 * got it - kill entry
308 fm->f_name[0] = '\0';
309 fm->f_str = (struct streamtab *)0;
318 printf("vddrinit[%s]: cannot find entry for STREAMS module\n", mname);
338 /*--------------- stream module definition ----------------------------*/
340 static int parseopen P((queue_t *, dev_t, int, int));
341 static int parseclose P((queue_t *, int));
342 static int parsewput P((queue_t *, mblk_t *));
343 static int parserput P((queue_t *, mblk_t *));
344 static int parsersvc P((queue_t *));
346 static char mn[] = "parse";
348 static struct module_info driverinfo =
350 0, /* module ID number */
351 mn, /* module name */
352 0, /* minimum accepted packet size */
353 INFPSZ, /* maximum accepted packet size */
354 1, /* high water mark - flow control */
355 0 /* low water mark - flow control */
358 static struct qinit rinit = /* read queue definition */
360 parserput, /* put procedure */
361 parsersvc, /* service procedure */
362 parseopen, /* open procedure */
363 parseclose, /* close procedure */
364 NULL, /* admin procedure - NOT USED FOR NOW */
365 &driverinfo, /* information structure */
366 NULL /* statistics */
369 static struct qinit winit = /* write queue definition */
371 parsewput, /* put procedure */
372 NULL, /* service procedure */
373 NULL, /* open procedure */
374 NULL, /* close procedure */
375 NULL, /* admin procedure - NOT USED FOR NOW */
376 &driverinfo, /* information structure */
377 NULL /* statistics */
380 struct streamtab parseinfo = /* stream info element for dpr driver */
382 &rinit, /* read queue */
383 &winit, /* write queue */
385 NULL, /* write mux */
386 NULL /* module auto push */
389 /*--------------- driver data structures ----------------------------*/
392 * we usually have an inverted signal - but you
393 * can change this to suit your needs
395 int cd_invert = 1; /* invert status of CD line - PPS support via CD input */
399 extern void uniqtime P((struct timeval *));
401 /*--------------- module implementation -----------------------------*/
403 #define TIMEVAL_USADD(_X_, _US_) {\
404 (_X_)->tv_usec += (_US_);\
405 if ((_X_)->tv_usec >= 1000000)\
408 (_X_)->tv_usec -= 1000000;\
412 static int init_linemon P((queue_t *));
413 static void close_linemon P((queue_t *, queue_t *));
415 #define M_PARSE 0x0001
416 #define M_NOPARSE 0x0002
426 mp = allocb(sizeof(struct stroptions), BPRI_MED);
429 struct stroptions *str = (struct stroptions *)(void *)mp->b_rptr;
431 str->so_flags = SO_READOPT|SO_HIWAT|SO_LOWAT;
432 str->so_readopt = (mode == M_PARSE) ? RMSGD : RNORM;
433 str->so_hiwat = (mode == M_PARSE) ? sizeof(parsetime_t) : 256;
435 mp->b_datap->db_type = M_SETOPTS;
436 mp->b_wptr += sizeof(struct stroptions);
438 return putctl1(WR(q)->q_next, M_CTL, (mode == M_PARSE) ? MC_SERVICEIMM :
443 parseprintf(DD_OPEN,("parse: setup_stream - FAILED - no MEMORY for allocb\n"));
457 register parsestream_t *parse;
458 static int notice = 0;
460 parseprintf(DD_OPEN,("parse: OPEN\n"));
462 if (sflag != MODOPEN)
463 { /* open only for modules */
464 parseprintf(DD_OPEN,("parse: OPEN - FAILED - not MODOPEN\n"));
468 if (q->q_ptr != (caddr_t)NULL)
471 parseprintf(DD_OPEN,("parse: OPEN - FAILED - EXCLUSIVE ONLY\n"));
479 q->q_ptr = (caddr_t)kmem_alloc(sizeof(parsestream_t));
480 if (q->q_ptr == (caddr_t)0)
482 parseprintf(DD_OPEN,("parse: OPEN - FAILED - no memory\n"));
488 WR(q)->q_ptr = q->q_ptr;
490 parse = (parsestream_t *)(void *)q->q_ptr;
491 bzero((caddr_t)parse, sizeof(*parse));
492 parse->parse_queue = q;
493 parse->parse_status = PARSE_ENABLE;
494 parse->parse_ppsclockev.tv.tv_sec = 0;
495 parse->parse_ppsclockev.tv.tv_usec = 0;
496 parse->parse_ppsclockev.serial = 0;
498 if (!parse_ioinit(&parse->parse_io))
503 kmem_free((caddr_t)parse, sizeof(parsestream_t));
510 if (setup_stream(q, M_PARSE))
512 (void) init_linemon(q); /* hook up PPS ISR routines if possible */
514 parseprintf(DD_OPEN,("parse: OPEN - SUCCEEDED\n"));
517 * I know that you know the delete key, but you didn't write this
518 * code, did you ? - So, keep the message in here.
523 printf("%s: Copyright (C) 1991-1998, Frank Kardel\n", parsesync_vd.Drv_name);
525 printf("%s: Copyright (C) 1991-1998, Frank Kardel\n", "parsestreams.c,v 4.7 1999/11/28 09:13:53 kardel RELEASE_19991128_A");
534 kmem_free((caddr_t)parse, sizeof(parsestream_t));
550 register parsestream_t *parse = (parsestream_t *)(void *)q->q_ptr;
551 register unsigned long s;
553 parseprintf(DD_CLOSE,("parse: CLOSE\n"));
557 if (parse->parse_dqueue)
558 close_linemon(parse->parse_dqueue, q);
559 parse->parse_dqueue = (queue_t *)0;
563 parse_ioend(&parse->parse_io);
565 kmem_free((caddr_t)parse, sizeof(parsestream_t));
567 q->q_ptr = (caddr_t)NULL;
568 WR(q)->q_ptr = (caddr_t)NULL;
577 * move unrecognized stuff upward
586 while ((mp = getq(q)))
588 if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
591 parseprintf(DD_RSVC,("parse: RSVC - putnext\n"));
596 parseprintf(DD_RSVC,("parse: RSVC - flow control wait\n"));
605 * send stuff down - dont care about
615 register mblk_t *datap;
616 register struct iocblk *iocp;
617 parsestream_t *parse = (parsestream_t *)(void *)q->q_ptr;
619 parseprintf(DD_WPUT,("parse: parsewput\n"));
621 switch (mp->b_datap->db_type)
628 iocp = (struct iocblk *)(void *)mp->b_rptr;
629 switch (iocp->ioc_cmd)
632 parseprintf(DD_WPUT,("parse: parsewput - forward M_IOCTL\n"));
638 * taken from Craig Leres ppsclock module (and modified)
640 datap = allocb(sizeof(struct ppsclockev), BPRI_MED);
641 if (datap == NULL || mp->b_cont)
643 mp->b_datap->db_type = M_IOCNAK;
644 iocp->ioc_error = (datap == NULL) ? ENOMEM : EINVAL;
652 *(struct ppsclockev *)(void *)datap->b_wptr = parse->parse_ppsclockev;
654 sizeof(struct ppsclockev) / sizeof(*datap->b_wptr);
655 mp->b_datap->db_type = M_IOCACK;
656 iocp->ioc_count = sizeof(struct ppsclockev);
660 case PARSEIOC_ENABLE:
661 case PARSEIOC_DISABLE:
663 parse->parse_status = (parse->parse_status & (unsigned)~PARSE_ENABLE) |
664 (iocp->ioc_cmd == PARSEIOC_ENABLE) ?
666 if (!setup_stream(RD(q), (parse->parse_status & PARSE_ENABLE) ?
667 M_PARSE : M_NOPARSE))
669 mp->b_datap->db_type = M_IOCNAK;
673 mp->b_datap->db_type = M_IOCACK;
679 case PARSEIOC_TIMECODE:
680 case PARSEIOC_SETFMT:
681 case PARSEIOC_GETFMT:
683 if (iocp->ioc_count == sizeof(parsectl_t))
685 parsectl_t *dct = (parsectl_t *)(void *)mp->b_cont->b_rptr;
687 switch (iocp->ioc_cmd)
689 case PARSEIOC_TIMECODE:
690 parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_TIMECODE\n"));
691 ok = parse_timecode(dct, &parse->parse_io);
694 case PARSEIOC_SETFMT:
695 parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETFMT\n"));
696 ok = parse_setfmt(dct, &parse->parse_io);
699 case PARSEIOC_GETFMT:
700 parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_GETFMT\n"));
701 ok = parse_getfmt(dct, &parse->parse_io);
705 parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETCS\n"));
706 ok = parse_setcs(dct, &parse->parse_io);
709 mp->b_datap->db_type = ok ? M_IOCACK : M_IOCNAK;
713 mp->b_datap->db_type = M_IOCNAK;
715 parseprintf(DD_WPUT,("parse: parsewput qreply - %s\n", (mp->b_datap->db_type == M_IOCNAK) ? "M_IOCNAK" : "M_IOCACK"));
724 * read characters from streams buffers
731 while (*mp != (mblk_t *)NULL)
733 if ((*mp)->b_wptr - (*mp)->b_rptr)
735 return (unsigned long)(*(unsigned char *)((*mp)->b_rptr++));
739 register mblk_t *mmp = *mp;
749 * convert incoming data
759 switch (type = mp->b_datap->db_type)
763 * anything we don't know will be put on queue
764 * the service routine will move it to the next one
766 parseprintf(DD_RPUT,("parse: parserput - forward type 0x%x\n", type));
767 if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
778 register parsestream_t * parse = (parsestream_t *)(void *)q->q_ptr;
779 register mblk_t *nmp;
780 register unsigned long ch;
784 * get time on packet delivery
788 if (!(parse->parse_status & PARSE_ENABLE))
790 parseprintf(DD_RPUT,("parse: parserput - parser disabled - forward type 0x%x\n", type));
791 if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
800 parseprintf(DD_RPUT,("parse: parserput - M_%s\n", (type == M_DATA) ? "DATA" : "BREAK"));
805 * parse packet looking for start an end characters
807 while (mp != (mblk_t *)NULL)
810 if (ch != ~0 && parse_ioread(&parse->parse_io, (unsigned int)ch, &ctime))
813 * up up and away (hopefully ...)
814 * don't press it if resources are tight or nobody wants it
816 nmp = (mblk_t *)NULL;
817 if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
819 bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
820 nmp->b_wptr += sizeof(parsetime_t);
821 putnext(parse->parse_queue, nmp);
824 if (nmp) freemsg(nmp);
825 parse_iodone(&parse->parse_io);
831 if (parse_ioread(&parse->parse_io, (unsigned int)0, &ctime))
834 * up up and away (hopefully ...)
835 * don't press it if resources are tight or nobody wants it
837 nmp = (mblk_t *)NULL;
838 if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
840 bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
841 nmp->b_wptr += sizeof(parsetime_t);
842 putnext(parse->parse_queue, nmp);
845 if (nmp) freemsg(nmp);
846 parse_iodone(&parse->parse_io);
855 * CD PPS support for non direct ISR hack
860 register parsestream_t * parse = (parsestream_t *)(void *)q->q_ptr;
862 register mblk_t *nmp;
863 register int status = cd_invert ^ (type == M_UNHANGUP);
867 parseprintf(DD_RPUT,("parse: parserput - M_%sHANGUP\n", (type == M_HANGUP) ? "" : "UN"));
869 if ((parse->parse_status & PARSE_ENABLE) &&
870 parse_iopps(&parse->parse_io, (int)(status ? SYNC_ONE : SYNC_ZERO), &ctime))
872 nmp = (mblk_t *)NULL;
873 if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
875 bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
876 nmp->b_wptr += sizeof(parsetime_t);
877 putnext(parse->parse_queue, nmp);
880 if (nmp) freemsg(nmp);
881 parse_iodone(&parse->parse_io);
885 if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
894 parse->parse_ppsclockev.tv = ctime.tv;
895 ++(parse->parse_ppsclockev.serial);
902 static int init_zs_linemon P((queue_t *, queue_t *)); /* handle line monitor for "zs" driver */
903 static void close_zs_linemon P((queue_t *, queue_t *));
905 /*-------------------- CD isr status monitor ---------------*/
912 register queue_t *dq;
916 * we ARE doing very bad things down here (basically stealing ISR
919 * so we chase down the STREAMS stack searching for the driver
920 * and if this is a known driver we insert our ISR routine for
921 * status changes in to the ExternalStatus handling hook
925 dq = dq->q_next; /* skip down to driver */
929 * find appropriate driver dependent routine
931 if (dq->q_qinfo && dq->q_qinfo->qi_minfo)
933 register char *dname = dq->q_qinfo->qi_minfo->mi_idname;
935 parseprintf(DD_INSTALL, ("init_linemon: driver is \"%s\"\n", dname));
938 if (dname && !Strcmp(dname, "zs"))
940 return init_zs_linemon(dq, q);
945 parseprintf(DD_INSTALL, ("init_linemon: driver \"%s\" not suitable for CD monitoring\n", dname));
949 parseprintf(DD_INSTALL, ("init_linemon: cannot find driver\n"));
956 register queue_t *my_q
960 * find appropriate driver dependent routine
962 if (q->q_qinfo && q->q_qinfo->qi_minfo)
964 register char *dname = q->q_qinfo->qi_minfo->mi_idname;
967 if (dname && !Strcmp(dname, "zs"))
969 close_zs_linemon(q, my_q);
972 parseprintf(DD_INSTALL, ("close_linemon: cannot find driver close routine for \"%s\"\n", dname));
975 parseprintf(DD_INSTALL, ("close_linemon: cannot find driver name\n"));
980 #include <sundev/zsreg.h>
981 #include <sundev/zscom.h>
982 #include <sundev/zsvar.h>
984 static unsigned long cdmask = ZSRR0_CD;
989 struct zsops *oldzsops;
992 struct zsops *emergencyzs;
993 extern void zsopinit P((struct zscom *, struct zsops *));
994 static int zs_xsisr P((struct zscom *)); /* zs external status interupt handler */
999 register queue_t *my_q
1002 register struct zscom *zs;
1003 register struct savedzsops *szs;
1004 register parsestream_t *parsestream = (parsestream_t *)(void *)my_q->q_ptr;
1006 * we expect the zsaline pointer in the q_data pointer
1007 * from there on we insert our on EXTERNAL/STATUS ISR routine
1008 * into the interrupt path, before the standard handler
1010 zs = ((struct zsaline *)(void *)q->q_ptr)->za_common;
1014 * well - not found on startup - just say no (shouldn't happen though)
1023 * we do a direct replacement, in case others fiddle also
1024 * if somebody else grabs our hook and we disconnect
1025 * we are in DEEP trouble - panic is likely to be next, sorry
1027 szs = (struct savedzsops *)(void *)kmem_alloc(sizeof(struct savedzsops));
1029 if (szs == (struct savedzsops *)0)
1031 parseprintf(DD_INSTALL, ("init_zs_linemon: CD monitor NOT installed - no memory\n"));
1037 parsestream->parse_data = (void *)szs;
1041 parsestream->parse_dqueue = q; /* remember driver */
1043 szs->zsops = *zs->zs_ops;
1044 szs->zsops.zsop_xsint = zs_xsisr; /* place our bastard */
1045 szs->oldzsops = zs->zs_ops;
1046 emergencyzs = zs->zs_ops;
1048 zsopinit(zs, &szs->zsops); /* hook it up */
1052 parseprintf(DD_INSTALL, ("init_zs_linemon: CD monitor installed\n"));
1060 * unregister our ISR routine - must call under splhigh()
1064 register queue_t *q,
1065 register queue_t *my_q
1068 register struct zscom *zs;
1069 register parsestream_t *parsestream = (parsestream_t *)(void *)my_q->q_ptr;
1071 zs = ((struct zsaline *)(void *)q->q_ptr)->za_common;
1075 * well - not found on startup - just say no (shouldn't happen though)
1081 register struct savedzsops *szs = (struct savedzsops *)parsestream->parse_data;
1083 zsopinit(zs, szs->oldzsops); /* reset to previous handler functions */
1085 kmem_free((caddr_t)szs, sizeof (struct savedzsops));
1087 parseprintf(DD_INSTALL, ("close_zs_linemon: CD monitor deleted\n"));
1092 #define MAXDEPTH 50 /* maximum allowed stream crawl */
1095 extern void hardpps P((struct timeval *, long));
1097 extern struct timeval timestamp;
1099 extern struct timeval pps_time;
1104 * take external status interrupt (only CD interests us)
1111 register struct zsaline *za = (struct zsaline *)(void *)zs->zs_priv;
1112 register struct zscc_device *zsaddr = zs->zs_addr;
1113 register queue_t *q;
1114 register unsigned char zsstatus;
1115 register int loopcheck;
1116 register char *dname;
1118 register unsigned int s;
1123 * pick up current state
1125 zsstatus = zsaddr->zscc_control;
1127 if ((za->za_rr0 ^ zsstatus) & (cdmask))
1129 timestamp_t cdevent;
1130 register int status;
1132 za->za_rr0 = (za->za_rr0 & ~(cdmask)) | (zsstatus & (cdmask));
1137 usec = timestamp.tv_usec;
1139 usec = pps_time.tv_usec;
1145 uniqtime(&cdevent.tv);
1154 status = cd_invert ? (zsstatus & cdmask) == 0 : (zsstatus & cdmask) != 0;
1159 usec = cdevent.tv.tv_usec - usec;
1163 hardpps(&cdevent.tv, usec);
1167 q = za->za_ttycommon.t_readq;
1170 * ok - now the hard part - find ourself
1172 loopcheck = MAXDEPTH;
1176 if (q->q_qinfo && q->q_qinfo->qi_minfo)
1178 dname = q->q_qinfo->qi_minfo->mi_idname;
1180 if (!Strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname))
1183 * back home - phew (hopping along stream queues might
1184 * prove dangerous to your health)
1187 if ((((parsestream_t *)(void *)q->q_ptr)->parse_status & PARSE_ENABLE) &&
1188 parse_iopps(&((parsestream_t *)(void *)q->q_ptr)->parse_io, (int)(status ? SYNC_ONE : SYNC_ZERO), &cdevent))
1191 * XXX - currently we do not pass up the message, as
1193 * for a correct behaviour wee need to block out
1194 * processing until parse_iodone has been posted via
1195 * a softcall-ed routine which does the message pass-up
1196 * right now PPS information relies on input being
1199 parse_iodone(&((parsestream_t *)(void *)q->q_ptr)->parse_io);
1204 ((parsestream_t *)(void *)q->q_ptr)->parse_ppsclockev.tv = cdevent.tv;
1205 ++(((parsestream_t *)(void *)q->q_ptr)->parse_ppsclockev.serial);
1208 parseprintf(DD_ISR, ("zs_xsisr: CD event %s has been posted for \"%s\"\n", status ? "ONE" : "ZERO", dname));
1217 panic("zs_xsisr: STREAMS Queue corrupted - CD event");
1222 * only pretend that CD has been handled
1226 if (!((za->za_rr0 ^ zsstatus) & ~(cdmask)))
1229 * all done - kill status indication and return
1231 zsaddr->zscc_control = ZSWR0_RESET_STATUS; /* might kill other conditions here */
1236 if (zsstatus & cdmask) /* fake CARRIER status */
1237 za->za_flags |= ZAS_CARR_ON;
1239 za->za_flags &= ~ZAS_CARR_ON;
1242 * we are now gathered here to process some unusual external status
1244 * any CD events have also been handled and shouldn't be processed
1245 * by the original routine (unless we have a VERY busy port pin)
1246 * some initializations are done here, which could have been done before for
1247 * both code paths but have been avoided for minimum path length to
1248 * the uniq_time routine
1251 q = za->za_ttycommon.t_readq;
1253 loopcheck = MAXDEPTH;
1256 * the real thing for everything else ...
1260 if (q->q_qinfo && q->q_qinfo->qi_minfo)
1262 dname = q->q_qinfo->qi_minfo->mi_idname;
1263 if (!Strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname))
1265 register int (*zsisr) P((struct zscom *));
1268 * back home - phew (hopping along stream queues might
1269 * prove dangerous to your health)
1271 if ((zsisr = ((struct savedzsops *)((parsestream_t *)(void *)q->q_ptr)->parse_data)->oldzsops->zsop_xsint))
1274 panic("zs_xsisr: unable to locate original ISR");
1276 parseprintf(DD_ISR, ("zs_xsisr: non CD event was processed for \"%s\"\n", dname));
1278 * now back to our program ...
1288 panic("zs_xsisr: STREAMS Queue corrupted - non CD event");
1293 * last resort - shouldn't even come here as it indicates
1294 * corrupted TTY structures
1296 printf("zs_zsisr: looking for \"%s\" - found \"%s\" - taking EMERGENCY path\n", parseinfo.st_rdinit->qi_minfo->mi_idname, dname ? dname : "-NIL-");
1298 if (emergencyzs && emergencyzs->zsop_xsint)
1299 emergencyzs->zsop_xsint(zs);
1301 panic("zs_xsisr: no emergency ISR handler");
1310 * Revision 4.7 1999/11/28 09:13:53 kardel
1313 * Revision 4.6 1998/12/20 23:45:31 kardel
1314 * fix types and warnings
1316 * Revision 4.5 1998/11/15 21:23:38 kardel
1317 * ntp_memset() replicated in Sun kernel files
1319 * Revision 4.4 1998/06/13 12:15:59 kardel
1320 * superfluous variable removed
1322 * Revision 4.3 1998/06/12 15:23:08 kardel
1324 * adjust for ansi2knr
1326 * Revision 4.2 1998/05/24 18:16:22 kardel
1327 * moved copy of shadow status to the beginning
1329 * Revision 4.1 1998/05/24 09:38:47 kardel
1330 * streams initiated iopps calls (M_xHANGUP) are now consistent with the
1331 * respective calls from zs_xsisr()
1332 * simulation of CARRIER status to avoid unecessary M_xHANGUP messages
1334 * Revision 4.0 1998/04/10 19:45:38 kardel
1335 * Start 4.0 release version numbering
1337 * from V3 3.37 log info deleted 1998/04/11 kardel