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

📄 ppsapi.c

📁 内核中关于nano计时的功能
💻 C
字号:
/* *  ppsapi STREAMS module * * This module draws weightily from the ppsclock STREAMS module built by * Craig Leres at LBL. Credit is due. */#include <string.h>#include <sys/errno.h>#include <sys/param.h>#include <sys/stream.h>#include <sys/stropts.h>#include <sys/syslog.h>#include <sys/time.h>#include <sys/timepps.h>#include <sys/ppsclock.h>#include <sys/tty.h>#include <sys/ttycom.h>#include <sys/user.h>/* * SunOS 4.1.3 serial driver */#include <sundev/zsreg.h>#include <sundev/zscom.h>/* * Function prototypes */static int ppsapi_open();	/* STREAMS open */static int ppsapi_close();	/* STREAMS close */static int ppsapi_wput();	/* STREAMS write */static void ppsapi_intr();	/* PPS interrupt processor (SunOS) */extern hardpps();		/* PPS signal processor *//* * STREAMS interface */static struct module_info stm_info = {	0x434c,			/* module id number (??) */	PPSAPISTR,		/* module name */	0,			/* minimum packet size */	INFPSZ,			/* infinite maximum packet size */	STRHIGH,		/* hi-water mark */	STRLOW,			/* lo-water mark */};static struct qinit ppsapi_rinit = {	(int (*)())ppsapi_wput, /* put procedure */	NULL,			/* service procedure */	(int (*)())ppsapi_open,	/* open procedure */	(int (*)())ppsapi_close, /* close procedure */	NULL,			/* administration procedure */	&stm_info,		/* module information structure */	NULL			/* module statistics structure */};static struct qinit ppsapi_winit = {	(int (*)())ppsapi_wput, /* put procedure */	NULL,			/* service procedure */	(int (*)())ppsapi_open,	/* open procedure */	(int (*)())ppsapi_close, /* close procedure */	NULL,			/* administration procedure */	&stm_info,		/* module information structure */	NULL			/* module statistics structure */};struct streamtab ppsapi_info = {	&ppsapi_rinit,		/* qinit for read side */	&ppsapi_winit,		/* qinit for write side */	NULL,			/* mux qinit for read */	NULL			/* mux qinit for write */};/* * SunOS 4.1.3 serial driver */static struct zsops *ppssavedzsops;static struct zsops ppszsops;static struct zscom *ppssavedzscom;#ifdef OPENPROMSextern struct zsaline *zsaline;#elseextern struct zsaline zsaline[];#endif/* * Persistent state variables */static struct ppsclockev ppsclockev; /* PPS time structure */static pps_info_t pps_info;	/* API info structure */static int pps_kpcmode;		/* kernel PPS mode *//* * Open procedure called by I_PUSH */static intppsapi_open(q, dev, flag, sflag)	register queue_t *q;	register dev_t dev;	register int flag;	register int sflag;{	register struct zsaline *za;	register struct zscom *zs;	/*	 * We must be called with MODOPEN	 */	if (sflag != MODOPEN)		return (OPENFAIL);	/*	 * Hook up our external status interrupt handler	 */	if (ppssavedzsops == NULL) {		za = &zsaline[minor(dev) & 0x7f];		if ((zs = za->za_common) == NULL)			return (OPENFAIL);		ppssavedzsops = zs->zs_ops;		ppszsops = *ppssavedzsops;		ppszsops.zsop_xsint = (int (*)())ppsapi_intr;		zsopinit(zs, &ppszsops);		ppssavedzscom = zs;	}	return (0);}/* * Close procedure called by I_POP */static intppsapi_close(q)	register queue_t *q;{	/*	 * Flush outstanding packets	 */	flushq(WR(q), FLUSHALL);	/*	 * Unhook our external status interrupt handler	 */	if (ppssavedzsops) {		zsopinit(ppssavedzscom, ppssavedzsops);		ppssavedzscom = NULL;		ppssavedzsops = NULL;	}	return (0);}/* * Read and write put procedure. Note that we can only get ioctl * messages in the "write" case. */static intppsapi_wput(q, mp)	register queue_t *q;	register mblk_t *mp;{	register struct iocblk *iocp;	register mblk_t *datap;	pps_params_t params;	switch (mp->b_datap->db_type) {	case M_FLUSH:		if (*mp->b_rptr & FLUSHW)			flushq(q, FLUSHDATA);		putnext(q, mp);		break;	case M_IOCTL:		iocp = (struct iocblk *)mp->b_rptr;		switch (iocp->ioc_cmd) {		/*		 * This is the original ppsclock interface built		 * by Van Jacobson and Craig Leres. It is		 * included for legacy purposes.		 */ 		case CIOGETEV:			datap = allocb(sizeof(struct ppsclockev),			    BPRI_HI);			if (datap == NULL) {				iocp->ioc_error = ENOMEM;				mp->b_datap->db_type = M_IOCNAK;				qreply(q, mp);				break;			}			mp->b_cont = datap;			bcopy((char *)&ppsclockev, datap->b_wptr,			    sizeof(struct ppsclockev));			datap->b_wptr += sizeof(struct ppsclockev);			iocp->ioc_count = sizeof(struct ppsclockev);			mp->b_datap->db_type = M_IOCACK;			qreply(q, mp);			break;		/*		 * These have no meaning in this design. Just		 * ignore them.		 */		case PPS_IOC_CREATE:		case PPS_IOC_DESTROY:		case PPS_IOC_SETPARAMS:		case PPS_IOC_GETPARAMS:		case PPS_IOC_GETCAP:			mp->b_datap->db_type = M_IOCACK;			qreply(q, mp);			break;		/*		 * Fetch pps_info structure.		 */		case PPS_IOC_FETCH:			datap = allocb(sizeof(pps_info_t), BPRI_HI);			if (datap == NULL) {				iocp->ioc_error = ENOMEM;				mp->b_datap->db_type = M_IOCNAK;				qreply(q, mp);				break;			}			mp->b_cont = datap;			bcopy((char *)&pps_info, datap->b_wptr,			    sizeof(pps_info_t));			datap->b_wptr += sizeof(pps_info_t);			iocp->ioc_count = sizeof(pps_info_t);			mp->b_datap->db_type = M_IOCACK;			qreply(q, mp);			break;		/*		 * Store pps_kpcmode mode bits.		 */		case PPS_IOC_KPCBIND:			bcopy((char *)mp->b_cont->b_rptr,			    (char *)&pps_kpcmode, sizeof(int));			iocp->ioc_count = 0;			mp->b_datap->db_type = M_IOCACK;			qreply(q, mp);			break;		/*		 * Pass unknown ioctls downstream.		 */		default:			putnext(q, mp);		}		break;	/*	 * Pass unknown messages downstream.	 */	default:		putnext(q, mp);	}	return (0);}/* * Modem control transition procedure (SunOS) */static voidppsapi_intr(zs)	register struct zscom *zs;{	register struct zsaline *za = (struct zsaline *)zs->zs_priv;	register struct zscc_device *zsaddr = zs->zs_addr;	register u_char s0;	long nsec;	/*	 * This code captures an assert/clear timestamp at each	 * assert/clear transition of the PPS signal, regardless of the	 * mode bits. The hardpps() routine is called on the specified	 * edge with a pointer to the timestamp, as well as the hardware	 * nanosecond counter value at the capture.	 */	s0 = zsaddr->zscc_control;	if ((s0 ^ za->za_rr0) & ZSRR0_CD) {		if ((s0 & ZSRR0_CD) != 0) {			ppsclockev.serial++;			uniqtime(&ppsclockev.tv);			pps_info.assert_sequence++;			nsec = nano_time(&pps_info.assert_timestamp);			if (pps_kpcmode & PPS_CAPTUREASSERT)				hardpps(&pps_info.assert_timestamp,				    nsec);		} else {			pps_info.clear_sequence++;			nsec = nano_time(&pps_info.clear_timestamp);			if (pps_kpcmode & PPS_CAPTURECLEAR)				hardpps(&pps_info.clear_timestamp,				    nsec);		}		/*		 * Reset interrupt status (SunOS)		 */		za->za_rr0 = s0;		zsaddr->zscc_control = ZSWR0_RESET_STATUS;		return;	}	/*	 * Call real external status interrupt routine	 */	(void)(*ppssavedzsops->zsop_xsint)(zs);}

⌨️ 快捷键说明

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