⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parsesolaris.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * /src/NTP/ntp4-dev/libparse/parsesolaris.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A *   * parsesolaris.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A * * STREAMS module for reference clocks * * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org> * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universit鋞 Erlangen-N黵nberg, Germany * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#define _KERNEL			/* it is a _KERNEL module */#ifndef lintstatic char rcsid[] = "parsesolaris.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A";#endif#include <sys/types.h>#include <sys/conf.h>#include <sys/errno.h>#include <sys/time.h>#include <sys/termios.h>#include <sys/stream.h>#include <sys/strtty.h>#include <sys/stropts.h>#include <sys/modctl.h>#include <sys/ddi.h>#include <sys/sunddi.h>#ifdef __GNUC__ /* makes it compile on Solaris 2.6 - acc doesn't like it -- GREAT! */#include <stdarg.h>#endif#include "ntp_fp.h"#include "parse.h"#include <sys/parsestreams.h>/*--------------- loadable driver section -----------------------------*/static struct streamtab parseinfo;static struct fmodsw fmod_templ ={	"parse",			/* module name */	&parseinfo,			/* module information */	D_NEW|D_MP|D_MTQPAIR,		/* exclusive for q pair */	/* lock ptr */};extern struct mod_ops mod_strmodops;static struct modlstrmod modlstrmod = {	&mod_strmodops,		/* a STREAMS module */	"PARSE      - NTP reference",	/* name this baby - keep room for revision number */	&fmod_templ};static struct modlinkage modlinkage ={	MODREV_1,	{		&modlstrmod,		NULL	}};/* * module management routines *//*ARGSUSED*/int_init(     void     ){	static char revision[] = "4.6";	char *s, *S; 	char *t;  #ifndef lint	t = rcsid;#endif		/*	 * copy RCS revision into Drv_name	 *	 * are we forcing RCS here to do things it was not built for ?	 */	s = revision;	if (*s == '$')	{		/*		 * skip "$Revision: "		 * if present. - not necessary on a -kv co (cvs export)		 */		while (*s && (*s != ' '))		{			s++;		}		if (*s == ' ') s++;	}	  	t = modlstrmod.strmod_linkinfo; 	while (*t && (*t != ' '))	{		t++;	}	if (*t == ' ') t++;	  	S = s;	while (*S && (((*S >= '0') && (*S <= '9')) || (*S == '.')))	{		S++;	}	  	if (*s && *t && (S > s))	{		if (strlen(t) >= (S - s))		{			(void) strncpy(t, s, (unsigned)(S - s));		}	}	return (mod_install(&modlinkage));}/*ARGSUSED*/int_info(      struct modinfo *modinfop      ){	return (mod_info(&modlinkage, modinfop));}/*ARGSUSED*/int_fini(      void      ){	if (mod_remove(&modlinkage) != DDI_SUCCESS)	{		return EBUSY;	}	else	    return DDI_SUCCESS;}/*--------------- stream module definition ----------------------------*/static int parseopen  P((queue_t *, dev_t *, int, int, cred_t *));static int parseclose P((queue_t *, int));static int parsewput  P((queue_t *, mblk_t *));static int parserput  P((queue_t *, mblk_t *));static int parsersvc  P((queue_t *));static struct module_info driverinfo ={	0,				/* module ID number */	fmod_templ.f_name,		/* module name - why repeated here ? compat ?*/	0,				/* minimum accepted packet size */	INFPSZ,				/* maximum accepted packet size */	1,				/* high water mark - flow control */	0				/* low water mark - flow control */};static struct qinit rinit =	/* read queue definition */{	parserput,			/* put procedure */	parsersvc,			/* service procedure */	parseopen,			/* open procedure */	parseclose,			/* close procedure */	NULL,				/* admin procedure - NOT USED FOR NOW */	&driverinfo,			/* information structure */	NULL				/* statistics */};static struct qinit winit =	/* write queue definition */{	parsewput,			/* put procedure */	NULL,				/* service procedure */	NULL,				/* open procedure */	NULL,				/* close procedure */	NULL,				/* admin procedure - NOT USED FOR NOW */	&driverinfo,			/* information structure */	NULL				/* statistics */};static struct streamtab parseinfo =	/* stream info element for parse driver */{	&rinit,			/* read queue */	&winit,			/* write queue */	NULL,				/* read mux */	NULL				/* write mux */};/*--------------- driver data structures ----------------------------*//* * we usually have an inverted signal - but you * can change this to suit your needs */int cd_invert = 1;		/* invert status of CD line - PPS support via CD input */#ifdef PARSEDEBUGint parsedebug = ~0;#elseint parsedebug = 0;#endif/*--------------- module implementation -----------------------------*/#define TIMEVAL_USADD(_X_, _US_) do {\	(_X_)->tv_usec += (_US_);\	if ((_X_)->tv_usec >= 1000000)\	{\	    (_X_)->tv_sec++;\	    (_X_)->tv_usec -= 1000000;\	}\     } while (0)static int init_linemon P((queue_t *));static void close_linemon P((queue_t *, queue_t *));#define M_PARSE		0x0001#define M_NOPARSE	0x0002voidntp_memset(	char *a,	int x,	int c	){	while (c-- > 0)	    *a++ = x;}static voidpprintf(	int lev,	const char *form,	...	){	va_list ap;	va_start(ap, form);	if (lev & parsedebug)	    vcmn_err(CE_CONT, (char *)form, ap);	va_end(ap);}static intsetup_stream(	     queue_t *q,	     int mode	     ){	register mblk_t *mp;	pprintf(DD_OPEN,"parse: SETUP_STREAM - setting up stream for q=%x\n", q);	mp = allocb(sizeof(struct stroptions), BPRI_MED);	if (mp)	{		struct stroptions *str = (struct stroptions *)mp->b_wptr;		str->so_flags   = SO_READOPT|SO_HIWAT|SO_LOWAT|SO_ISNTTY;		str->so_readopt = (mode == M_PARSE) ? RMSGD : RNORM;		str->so_hiwat   = (mode == M_PARSE) ? sizeof(parsetime_t) : 256;		str->so_lowat   = 0;		mp->b_datap->db_type = M_SETOPTS;		mp->b_wptr     += sizeof(struct stroptions);		if (!q)		    panic("NULL q - strange");		putnext(q, mp);		return putctl1(WR(q)->q_next, M_CTL, (mode == M_PARSE) ? MC_SERVICEIMM :			       MC_SERVICEDEF);	}	else	{		pprintf(DD_OPEN, "parse: setup_stream - FAILED - no MEMORY for allocb\n"); 		return 0;	}}/*ARGSUSED*/static intparseopen(	  queue_t *q,	  dev_t *dev,	  int flag,	  int sflag,	  cred_t *credp	  ){	register parsestream_t *parse;	static int notice = 0;  	pprintf(DD_OPEN, "parse: OPEN - q=%x\n", q);   	if (sflag != MODOPEN)	{			/* open only for modules */		pprintf(DD_OPEN, "parse: OPEN - FAILED - not MODOPEN\n"); 		return EIO;	}	if (q->q_ptr != (caddr_t)NULL)	{		pprintf(DD_OPEN, "parse: OPEN - FAILED - EXCLUSIVE ONLY\n"); 		return EBUSY;	}	q->q_ptr = (caddr_t)kmem_alloc(sizeof(parsestream_t), KM_SLEEP);	if (q->q_ptr == (caddr_t)0)	{		return ENOMEM;	}	pprintf(DD_OPEN, "parse: OPEN - parse area q=%x, q->q_ptr=%x\n", q, q->q_ptr); 	WR(q)->q_ptr = q->q_ptr;	pprintf(DD_OPEN, "parse: OPEN - WQ parse area q=%x, q->q_ptr=%x\n", WR(q), WR(q)->q_ptr);   	parse = (parsestream_t *) q->q_ptr;	bzero((caddr_t)parse, sizeof(*parse));	parse->parse_queue     = q;	parse->parse_status    = PARSE_ENABLE;	parse->parse_ppsclockev.tv.tv_sec  = 0;	parse->parse_ppsclockev.tv.tv_usec = 0;	parse->parse_ppsclockev.serial     = 0;	qprocson(q);	pprintf(DD_OPEN, "parse: OPEN - initializing io subsystem q=%x\n", q); 	if (!parse_ioinit(&parse->parse_io))	{		/*		 * ok guys - beat it		 */		qprocsoff(q);		kmem_free((caddr_t)parse, sizeof(parsestream_t));		return EIO;	}	pprintf(DD_OPEN, "parse: OPEN - initializing stream q=%x\n", q); 	if (setup_stream(q, M_PARSE))	{		(void) init_linemon(q);	/* hook up PPS ISR routines if possible */		pprintf(DD_OPEN, "parse: OPEN - SUCCEEDED\n"); 		/*		 * I know that you know the delete key, but you didn't write this		 * code, did you ? - So, keep the message in here.		 */		if (!notice)		{		  cmn_err(CE_CONT, "?%s: Copyright (c) 1993-2005, Frank Kardel\n", modlstrmod.strmod_linkinfo);			notice = 1;		}		return 0;	}	else	{		qprocsoff(q);		kmem_free((caddr_t)parse, sizeof(parsestream_t));		return EIO;	}}/*ARGSUSED*/static intparseclose(	   queue_t *q,	   int flags	   ){	register parsestream_t *parse = (parsestream_t *)q->q_ptr;	register unsigned long s;  	pprintf(DD_CLOSE, "parse: CLOSE\n");  	qprocsoff(q);	s = splhigh();  	if (parse->parse_dqueue)	    close_linemon(parse->parse_dqueue, q);	parse->parse_dqueue = (queue_t *)0;	(void) splx(s);      	parse_ioend(&parse->parse_io);	kmem_free((caddr_t)parse, sizeof(parsestream_t));	q->q_ptr = (caddr_t)NULL;	WR(q)->q_ptr = (caddr_t)NULL;	return 0;}/* * move unrecognized stuff upward */static intparsersvc(	  queue_t *q	  ){	mblk_t *mp;  	while ((mp = getq(q)))	{		if (canputnext(q) || (mp->b_datap->db_type > QPCTL))		{			putnext(q, mp);			pprintf(DD_RSVC, "parse: RSVC - putnext\n");		}		else		{			putbq(q, mp);			pprintf(DD_RSVC, "parse: RSVC - flow control wait\n");			break;		}	}	return 0;}/* * do ioctls and * send stuff down - dont care about * flow control */static intparsewput(	  queue_t *q,	  mblk_t *mp	  ){	register int ok = 1;	register mblk_t *datap;	register struct iocblk *iocp;	parsestream_t         *parse = (parsestream_t *)q->q_ptr;  	pprintf(DD_WPUT, "parse: parsewput\n");  	switch (mp->b_datap->db_type)	{	    default:		putnext(q, mp);		break;      	    case M_IOCTL:		iocp = (struct iocblk *)mp->b_rptr;		switch (iocp->ioc_cmd)		{		    default:			pprintf(DD_WPUT, "parse: parsewput - forward M_IOCTL\n");			putnext(q, mp);			break;		    case CIOGETEV:			/*			 * taken from Craig Leres ppsclock module (and modified)			 */			datap = allocb(sizeof(struct ppsclockev), BPRI_MED);			if (datap == NULL || mp->b_cont)			{				mp->b_datap->db_type = M_IOCNAK;				iocp->ioc_error = (datap == NULL) ? ENOMEM : EINVAL;				if (datap != NULL)				    freeb(datap);				qreply(q, mp);				break;			}			mp->b_cont = datap;			*(struct ppsclockev *)datap->b_wptr = parse->parse_ppsclockev;			datap->b_wptr +=				sizeof(struct ppsclockev) / sizeof(*datap->b_wptr);			mp->b_datap->db_type = M_IOCACK;			iocp->ioc_count = sizeof(struct ppsclockev);			qreply(q, mp);			break;	  		    case PARSEIOC_ENABLE:		    case PARSEIOC_DISABLE:			    {				    parse->parse_status = (parse->parse_status & (unsigned)~PARSE_ENABLE) |					    (iocp->ioc_cmd == PARSEIOC_ENABLE) ?					    PARSE_ENABLE : 0;				    if (!setup_stream(RD(q), (parse->parse_status & PARSE_ENABLE) ?						      M_PARSE : M_NOPARSE))				    {					    mp->b_datap->db_type = M_IOCNAK;				    }				    else				    {					    mp->b_datap->db_type = M_IOCACK;				    }				    qreply(q, mp);				    break;			    }	    		    case PARSEIOC_TIMECODE:		    case PARSEIOC_SETFMT:		    case PARSEIOC_GETFMT:		    case PARSEIOC_SETCS:			if (iocp->ioc_count == sizeof(parsectl_t))			{				parsectl_t *dct = (parsectl_t *)mp->b_cont->b_rptr;				switch (iocp->ioc_cmd)				{				    case PARSEIOC_TIMECODE:					pprintf(DD_WPUT, "parse: parsewput - PARSEIOC_TIMECODE\n");					ok = parse_timecode(dct, &parse->parse_io);					break;		  				    case PARSEIOC_SETFMT:					pprintf(DD_WPUT, "parse: parsewput - PARSEIOC_SETFMT\n");					ok = parse_setfmt(dct, &parse->parse_io);					break;				    case PARSEIOC_GETFMT:					pprintf(DD_WPUT, "parse: parsewput - PARSEIOC_GETFMT\n");					ok = parse_getfmt(dct, &parse->parse_io);					break;				    case PARSEIOC_SETCS:					pprintf(DD_WPUT, "parse: parsewput - PARSEIOC_SETCS\n");					ok = parse_setcs(dct, &parse->parse_io);					break;				}				mp->b_datap->db_type = ok ? M_IOCACK : M_IOCNAK;			}			else			{				mp->b_datap->db_type = M_IOCNAK;			}			pprintf(DD_WPUT, "parse: parsewput qreply - %s\n", (mp->b_datap->db_type == M_IOCNAK) ? "M_IOCNAK" : "M_IOCACK");			qreply(q, mp);			break;		}	}	return 0;}/* * read characters from streams buffers */static unsigned longrdchar(       mblk_t **mp       ){	while (*mp != (mblk_t *)NULL)	{		if ((*mp)->b_wptr - (*mp)->b_rptr)		{			return (unsigned long)(*(unsigned char *)((*mp)->b_rptr++));		}		else		{			register mblk_t *mmp = *mp;	  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -