File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / libparse / parsestreams.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 1 month ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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>