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

📄 parsesolaris.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
			*mp = (*mp)->b_cont;			freeb(mmp);		}	}	return (unsigned long)~0;}/* * convert incoming data */static intparserput(	  queue_t *q,	  mblk_t *imp	  ){	register unsigned char type;	mblk_t *mp = imp;  	switch (type = mp->b_datap->db_type)	{	    default:		/*		 * anything we don't know will be put on queue		 * the service routine will move it to the next one		 */		pprintf(DD_RPUT, "parse: parserput - forward type 0x%x\n", type);		if (canputnext(q) || (mp->b_datap->db_type > QPCTL))		{			putnext(q, mp);		}		else		    putq(q, mp);		break;      	    case M_BREAK:	    case M_DATA:		    {			    register parsestream_t * parse = (parsestream_t *)q->q_ptr;			    register mblk_t *nmp;			    register unsigned long ch;			    timestamp_t ctime;			    timespec_t hres_time;			    /*			     * get time on packet delivery			     */			    gethrestime(&hres_time);			    ctime.tv.tv_sec  = hres_time.tv_sec;			    ctime.tv.tv_usec = hres_time.tv_nsec / 1000;			    if (!(parse->parse_status & PARSE_ENABLE))			    {				    pprintf(DD_RPUT, "parse: parserput - parser disabled - forward type 0x%x\n", type);				    if (canputnext(q) || (mp->b_datap->db_type > QPCTL))				    {					    putnext(q, mp);				    }				    else					putq(q, mp);			    }			    else			    {				    pprintf(DD_RPUT, "parse: parserput - M_%s\n", (type == M_DATA) ? "DATA" : "BREAK");				    if (type == M_DATA)				    {					    /*					     * parse packet looking for start an end characters					     */					    while (mp != (mblk_t *)NULL)					    {						    ch = rdchar(&mp);						    if (ch != ~0 && parse_ioread(&parse->parse_io, (unsigned int)ch, &ctime))						    {							    /*							     * up up and away (hopefully ...)							     * don't press it if resources are tight or nobody wants it							     */							    nmp = (mblk_t *)NULL;							    if (canputnext(parse->parse_queue) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))							    {								    bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));								    nmp->b_wptr += sizeof(parsetime_t);								    putnext(parse->parse_queue, nmp);							    }							    else								if (nmp) freemsg(nmp);							    parse_iodone(&parse->parse_io);						    }					    }					    }				    else				    {					    if (parse_ioread(&parse->parse_io, (unsigned int)0, &ctime))					    {						    /*						     * up up and away (hopefully ...)						     * don't press it if resources are tight or nobody wants it						     */						    nmp = (mblk_t *)NULL;						    if (canputnext(parse->parse_queue) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))						    {							    bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));							    nmp->b_wptr += sizeof(parsetime_t);							    putnext(parse->parse_queue, nmp);						    }						    else							if (nmp) freemsg(nmp);						    parse_iodone(&parse->parse_io);					    }					    freemsg(mp);				    }				    break;			    }		    }		    /*		     * CD PPS support for non direct ISR hack		     */	    case M_HANGUP:	    case M_UNHANGUP:		    {			    register parsestream_t * parse = (parsestream_t *)q->q_ptr;			    timestamp_t ctime;			    timespec_t hres_time;			    register mblk_t *nmp;			    register int status = cd_invert ^ (type == M_UNHANGUP);			    gethrestime(&hres_time);			    ctime.tv.tv_sec  = hres_time.tv_sec;			    ctime.tv.tv_usec = hres_time.tv_nsec / 1000;				    pprintf(DD_RPUT, "parse: parserput - M_%sHANGUP\n", (type == M_HANGUP) ? "" : "UN");			    if ((parse->parse_status & PARSE_ENABLE) &&				parse_iopps(&parse->parse_io, status ? SYNC_ONE : SYNC_ZERO, &ctime))			    {				    nmp = (mblk_t *)NULL;				    if (canputnext(parse->parse_queue) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))				    {					    bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));					    nmp->b_wptr += sizeof(parsetime_t);					    putnext(parse->parse_queue, nmp);				    }				    else					if (nmp) freemsg(nmp);				    parse_iodone(&parse->parse_io);				    freemsg(mp);			    }			    else				if (canputnext(q) || (mp->b_datap->db_type > QPCTL))				{					putnext(q, mp);				}				else				    putq(q, mp);				    if (status)			    {				    parse->parse_ppsclockev.tv = ctime.tv;				    ++(parse->parse_ppsclockev.serial);			    }		    }	}	return 0;}static int  init_zs_linemon  P((queue_t *, queue_t *));	/* handle line monitor for "zs" driver */static void close_zs_linemon P((queue_t *, queue_t *));/*-------------------- CD isr status monitor ---------------*/static intinit_linemon(	     queue_t *q	     ){	register queue_t *dq;  	dq = WR(q);	/*	 * we ARE doing very bad things down here (basically stealing ISR	 * hooks)	 *	 * so we chase down the STREAMS stack searching for the driver	 * and if this is a known driver we insert our ISR routine for	 * status changes in to the ExternalStatus handling hook	 */	while (dq->q_next)	{		dq = dq->q_next;		/* skip down to driver */	}	/*	 * find appropriate driver dependent routine	 */	if (dq->q_qinfo && dq->q_qinfo->qi_minfo)	{		register char *dname = dq->q_qinfo->qi_minfo->mi_idname;		pprintf(DD_INSTALL, "init_linemon: driver is \"%s\"\n", dname);#ifdef sun		if (dname && !strcmp(dname, "zs"))		{			return init_zs_linemon(dq, q);		}		else#endif		{			pprintf(DD_INSTALL, "init_linemon: driver \"%s\" not suitable for CD monitoring\n", dname);			return 0;		}	}	pprintf(DD_INSTALL, "init_linemon: cannot find driver\n");	return 0;}static voidclose_linemon(	      queue_t *q,	      queue_t *my_q	      ){	/*	 * find appropriate driver dependent routine	 */	if (q->q_qinfo && q->q_qinfo->qi_minfo)	{		register char *dname = q->q_qinfo->qi_minfo->mi_idname;#ifdef sun		if (dname && !strcmp(dname, "zs"))		{			close_zs_linemon(q, my_q);			return;		}		pprintf(DD_INSTALL, "close_linemon: cannot find driver close routine for \"%s\"\n", dname);#endif	}	pprintf(DD_INSTALL, "close_linemon: cannot find driver name\n");}#ifdef sun#include <sys/tty.h>#include <sys/zsdev.h>#include <sys/ser_async.h>#include <sys/ser_zscc.h>static void zs_xsisr         P((struct zscom *));	/* zs external status interupt handler *//* * there should be some docs telling how to get to * sz:zs_usec_delay and zs:initzsops() */#define zs_usec_delay 5struct savedzsops{	struct zsops  zsops;	struct zsops *oldzsops;};static struct zsops   *emergencyzs;static intinit_zs_linemon(		queue_t *q,		queue_t *my_q		){	register struct zscom *zs;	register struct savedzsops *szs;	register parsestream_t  *parsestream = (parsestream_t *)my_q->q_ptr;	/*	 * we expect the zsaline pointer in the q_data pointer	 * from there on we insert our on EXTERNAL/STATUS ISR routine	 * into the interrupt path, before the standard handler	 */	zs = ((struct asyncline *)q->q_ptr)->za_common;	if (!zs)	{		/*		 * well - not found on startup - just say no (shouldn't happen though)		 */		return 0;	}	else	{		/*		 * we do a direct replacement, in case others fiddle also		 * if somebody else grabs our hook and we disconnect		 * we are in DEEP trouble - panic is likely to be next, sorry		 */		szs = (struct savedzsops *) kmem_alloc(sizeof(struct savedzsops), KM_SLEEP);		if (szs == (struct savedzsops *)0)		{			pprintf(DD_INSTALL, "init_zs_linemon: CD monitor NOT installed - no memory\n");			return 0;		}		else		{			parsestream->parse_data   = (void *)szs;			mutex_enter(zs->zs_excl);			parsestream->parse_dqueue = q; /* remember driver */			szs->zsops            = *zs->zs_ops;			szs->zsops.zsop_xsint = (void (*) P((struct zscom *)))zs_xsisr; /* place our bastard */			szs->oldzsops         = zs->zs_ops;			emergencyzs           = zs->zs_ops;	  			zs->zs_ops = &szs->zsops; /* hook it up */			/*			 * XXX: this is usually done via zsopinit() 			 * - have yet to find a way to call that routine			 */			zs->zs_xsint          = (void (*) P((struct zscom *)))zs_xsisr;	  			mutex_exit(zs->zs_excl);			pprintf(DD_INSTALL, "init_zs_linemon: CD monitor installed\n");			return 1;		}	}}/* * unregister our ISR routine - must call under splhigh() (or  * whatever block ZS status interrupts) */static voidclose_zs_linemon(		 queue_t *q,		 queue_t *my_q		 ){	register struct zscom *zs;	register parsestream_t  *parsestream = (parsestream_t *)my_q->q_ptr;	zs = ((struct asyncline *)q->q_ptr)->za_common;	if (!zs)	{		/*		 * well - not found on startup - just say no (shouldn't happen though)		 */		return;	}	else	{		register struct savedzsops *szs = (struct savedzsops *)parsestream->parse_data;		mutex_enter(zs->zs_excl);		zs->zs_ops = szs->oldzsops; /* reset to previous handler functions */		/*		 * XXX: revert xsint (usually done via zsopinit() - have still to find		 * a way to call that bugger		 */		zs->zs_xsint = zs->zs_ops->zsop_xsint;		mutex_exit(zs->zs_excl);		kmem_free((caddr_t)szs, sizeof (struct savedzsops));      		pprintf(DD_INSTALL, "close_zs_linemon: CD monitor deleted\n");		return;	}}#define ZSRR0_IGNORE	(ZSRR0_CD|ZSRR0_SYNC|ZSRR0_CTS)#define MAXDEPTH 50		/* maximum allowed stream crawl *//* * take external status interrupt (only CD interests us) */static voidzs_xsisr(	 struct zscom *zs	 ){	register struct asyncline *za = (struct asyncline *)zs->zs_priv;	register queue_t *q;	register unsigned char zsstatus;	register int loopcheck;	register unsigned char cdstate;	register const char *dname = "-UNKNOWN-";	timespec_t hres_time;	/*	 * pick up current state	 */	zsstatus = SCC_READ0();	if (za->za_rr0 ^ (cdstate = zsstatus & ZSRR0_CD))	{		timestamp_t cdevent;		register int status;      		/*		 * time stamp		 */		gethrestime(&hres_time);		cdevent.tv.tv_sec  = hres_time.tv_sec;		cdevent.tv.tv_usec = hres_time.tv_nsec / 1000;		q = za->za_ttycommon.t_readq;		/*		 * logical state		 */		status = cd_invert ? cdstate == 0 : cdstate != 0;		/*		 * ok - now the hard part - find ourself		 */		loopcheck = MAXDEPTH;      		while (q)		{			if (q->q_qinfo && q->q_qinfo->qi_minfo)			{				dname = q->q_qinfo->qi_minfo->mi_idname;				if (!strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname))				{					/*					 * back home - phew (hopping along stream queues might					 * prove dangerous to your health)					 */					if ((((parsestream_t *)q->q_ptr)->parse_status & PARSE_ENABLE) &&					    parse_iopps(&((parsestream_t *)q->q_ptr)->parse_io, status ? SYNC_ONE : SYNC_ZERO, &cdevent))					{						/*						 * XXX - currently we do not pass up the message, as						 * we should.						 * for a correct behaviour wee need to block out						 * processing until parse_iodone has been posted via						 * a softcall-ed routine which does the message pass-up						 * right now PPS information relies on input being						 * received						 */						parse_iodone(&((parsestream_t *)q->q_ptr)->parse_io);					}		  					if (status)					{						((parsestream_t *)q->q_ptr)->parse_ppsclockev.tv = cdevent.tv;						++(((parsestream_t *)q->q_ptr)->parse_ppsclockev.serial);					}					pprintf(DD_ISR, "zs_xsisr: CD event %s has been posted for \"%s\"\n", status ? "ONE" : "ZERO", dname);					break;				}			}			q = q->q_next;			if (!loopcheck--)			{				panic("zs_xsisr: STREAMS Queue corrupted - CD event");			}		}		if (cdstate)	/* fake CARRIER status - XXX currently not coordinated */		  za->za_flags |= ZAS_CARR_ON;		else		  za->za_flags &= ~ZAS_CARR_ON;		/*		 * only pretend that CD and ignored transistion (SYNC,CTS)		 * have been handled		 */		za->za_rr0 = (za->za_rr0 & ~ZSRR0_IGNORE) | (zsstatus & ZSRR0_IGNORE);		if (((za->za_rr0 ^ zsstatus) & ~ZSRR0_IGNORE) == 0)		{			/*			 * all done - kill status indication and return			 */			SCC_WRITE0(ZSWR0_RESET_STATUS); /* might kill other conditions here */			return;		}	}      	pprintf(DD_ISR, "zs_xsisr: non CD event 0x%x for \"%s\"\n", 		(za->za_rr0 ^ zsstatus) & ~ZSRR0_CD,dname);	/*	 * we are now gathered here to process some unusual external status	 * interrupts.	 * any CD events have also been handled and shouldn't be processed	 * by the original routine (unless we have a VERY busy port pin)	 * some initializations are done here, which could have been done before for	 * both code paths but have been avioded for minimum path length to	 * the uniq_time routine	 */	dname = (char *) 0;	q = za->za_ttycommon.t_readq;	loopcheck = MAXDEPTH;      	/*	 * the real thing for everything else ...	 */	while (q)	{		if (q->q_qinfo && q->q_qinfo->qi_minfo)		{			dname = q->q_qinfo->qi_minfo->mi_idname;			if (!strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname))			{				register void (*zsisr) P((struct zscom *));		  				/*				 * back home - phew (hopping along stream queues might				 * prove dangerous to your health)				 */				if ((zsisr = ((struct savedzsops *)((parsestream_t *)q->q_ptr)->parse_data)->oldzsops->zsop_xsint))				    zsisr(zs);				else				    panic("zs_xsisr: unable to locate original ISR");		  				pprintf(DD_ISR, "zs_xsisr: non CD event was processed for \"%s\"\n", dname);				/*				 * now back to our program ...				 */				return;			}		}		q = q->q_next;		if (!loopcheck--)		{			panic("zs_xsisr: STREAMS Queue corrupted - non CD event");		}	}	/*	 * last resort - shouldn't even come here as it indicates	 * corrupted TTY structures	 */	printf("zs_zsisr: looking for \"%s\" - found \"%s\" - taking EMERGENCY path\n", parseinfo.st_rdinit->qi_minfo->mi_idname, dname ? dname : "-NIL-");      	if (emergencyzs && emergencyzs->zsop_xsint)	    emergencyzs->zsop_xsint(zs);	else	    panic("zs_xsisr: no emergency ISR handler");}#endif				/* sun *//* * History: * * parsesolaris.c,v * Revision 4.11  2005/04/16 17:32:10  kardel * update copyright * * Revision 4.10  2004/11/14 16:06:08  kardel * update Id tags * * Revision 4.9  2004/11/14 15:29:41  kardel * support PPSAPI, upgrade Copyright to Berkeley style * * Revision 4.6  1998/11/15 21:56:08  kardel * ntp_memset not necessary * * Revision 4.5  1998/11/15 21:23:37  kardel * ntp_memset() replicated in Sun kernel files * * Revision 4.4  1998/06/14 21:09:40  kardel * Sun acc cleanup * * Revision 4.3  1998/06/13 12:14:59  kardel * more prototypes * fix name clashes * allow for ansi2knr * * Revision 4.2  1998/06/12 15:23:08  kardel * fix prototypes * adjust for ansi2knr * * Revision 4.1  1998/05/24 09:38:46  kardel * streams initiated iopps calls (M_xHANGUP) are now consistent with the * respective calls from zs_xsisr() * simulation of CARRIER status to avoid unecessary M_xHANGUP messages * * Revision 4.0  1998/04/10 19:45:38  kardel * Start 4.0 release version numbering * * from V3 3.28 log info deleted 1998/04/11 kardel */

⌨️ 快捷键说明

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