📄 parsestreams.c
字号:
{ 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( register 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; parseprintf(DD_INSTALL, ("init_linemon: driver is \"%s\"\n", dname));#ifdef sun if (dname && !Strcmp(dname, "zs")) { return init_zs_linemon(dq, q); } else#endif { parseprintf(DD_INSTALL, ("init_linemon: driver \"%s\" not suitable for CD monitoring\n", dname)); return 0; } } parseprintf(DD_INSTALL, ("init_linemon: cannot find driver\n")); return 0;}static voidclose_linemon( register queue_t *q, register 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; } parseprintf(DD_INSTALL, ("close_linemon: cannot find driver close routine for \"%s\"\n", dname));#endif } parseprintf(DD_INSTALL, ("close_linemon: cannot find driver name\n"));}#ifdef sun#include <sundev/zsreg.h>#include <sundev/zscom.h>#include <sundev/zsvar.h>static unsigned long cdmask = ZSRR0_CD;struct savedzsops{ struct zsops zsops; struct zsops *oldzsops;};struct zsops *emergencyzs;extern void zsopinit P((struct zscom *, struct zsops *));static int zs_xsisr P((struct zscom *)); /* zs external status interupt handler */static intinit_zs_linemon( register queue_t *q, register queue_t *my_q ){ register struct zscom *zs; register struct savedzsops *szs; register parsestream_t *parsestream = (parsestream_t *)(void *)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 zsaline *)(void *)q->q_ptr)->za_common; if (!zs) { /* * well - not found on startup - just say no (shouldn't happen though) */ return 0; } else { unsigned long s; /* * 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 *)(void *)kmem_alloc(sizeof(struct savedzsops)); if (szs == (struct savedzsops *)0) { parseprintf(DD_INSTALL, ("init_zs_linemon: CD monitor NOT installed - no memory\n")); return 0; } else { parsestream->parse_data = (void *)szs; s = splhigh(); parsestream->parse_dqueue = q; /* remember driver */ szs->zsops = *zs->zs_ops; szs->zsops.zsop_xsint = zs_xsisr; /* place our bastard */ szs->oldzsops = zs->zs_ops; emergencyzs = zs->zs_ops; zsopinit(zs, &szs->zsops); /* hook it up */ (void) splx(s); parseprintf(DD_INSTALL, ("init_zs_linemon: CD monitor installed\n")); return 1; } }}/* * unregister our ISR routine - must call under splhigh() */static voidclose_zs_linemon( register queue_t *q, register queue_t *my_q ){ register struct zscom *zs; register parsestream_t *parsestream = (parsestream_t *)(void *)my_q->q_ptr; zs = ((struct zsaline *)(void *)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; zsopinit(zs, szs->oldzsops); /* reset to previous handler functions */ kmem_free((caddr_t)szs, sizeof (struct savedzsops)); parseprintf(DD_INSTALL, ("close_zs_linemon: CD monitor deleted\n")); return; }}#define MAXDEPTH 50 /* maximum allowed stream crawl */#ifdef PPS_SYNCextern void hardpps P((struct timeval *, long));#ifdef PPS_NEWextern struct timeval timestamp;#elseextern struct timeval pps_time;#endif#endif/* * take external status interrupt (only CD interests us) */static intzs_xsisr( struct zscom *zs ){ register struct zsaline *za = (struct zsaline *)(void *)zs->zs_priv; register struct zscc_device *zsaddr = zs->zs_addr; register queue_t *q; register unsigned char zsstatus; register int loopcheck; register char *dname;#ifdef PPS_SYNC register unsigned int s; register long usec;#endif /* * pick up current state */ zsstatus = zsaddr->zscc_control; if ((za->za_rr0 ^ zsstatus) & (cdmask)) { timestamp_t cdevent; register int status; za->za_rr0 = (za->za_rr0 & ~(cdmask)) | (zsstatus & (cdmask));#ifdef PPS_SYNC s = splclock();#ifdef PPS_NEW usec = timestamp.tv_usec;#else usec = pps_time.tv_usec;#endif#endif /* * time stamp */ uniqtime(&cdevent.tv); #ifdef PPS_SYNC (void)splx(s);#endif /* * logical state */ status = cd_invert ? (zsstatus & cdmask) == 0 : (zsstatus & cdmask) != 0;#ifdef PPS_SYNC if (status) { usec = cdevent.tv.tv_usec - usec; if (usec < 0) usec += 1000000; hardpps(&cdevent.tv, usec); }#endif q = za->za_ttycommon.t_readq; /* * 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 *)(void *)q->q_ptr)->parse_status & PARSE_ENABLE) && parse_iopps(&((parsestream_t *)(void *)q->q_ptr)->parse_io, (int)(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 *)(void *)q->q_ptr)->parse_io); } if (status) { ((parsestream_t *)(void *)q->q_ptr)->parse_ppsclockev.tv = cdevent.tv; ++(((parsestream_t *)(void *)q->q_ptr)->parse_ppsclockev.serial); } parseprintf(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"); } } /* * only pretend that CD has been handled */ ZSDELAY(2); if (!((za->za_rr0 ^ zsstatus) & ~(cdmask))) { /* * all done - kill status indication and return */ zsaddr->zscc_control = ZSWR0_RESET_STATUS; /* might kill other conditions here */ return 0; } } if (zsstatus & cdmask) /* fake CARRIER status */ za->za_flags |= ZAS_CARR_ON; else za->za_flags &= ~ZAS_CARR_ON; /* * 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 avoided 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 int (*zsisr) P((struct zscom *)); /* * back home - phew (hopping along stream queues might * prove dangerous to your health) */ if ((zsisr = ((struct savedzsops *)((parsestream_t *)(void *)q->q_ptr)->parse_data)->oldzsops->zsop_xsint)) return zsisr(zs); else panic("zs_xsisr: unable to locate original ISR"); parseprintf(DD_ISR, ("zs_xsisr: non CD event was processed for \"%s\"\n", dname)); /* * now back to our program ... */ return 0; } } 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"); return 0;}#endif /* sun *//* * History: * * parsestreams.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.7 1999/11/28 09:13:53 kardel * RECON_4_0_98F * * Revision 4.6 1998/12/20 23:45:31 kardel * fix types and warnings * * Revision 4.5 1998/11/15 21:23:38 kardel * ntp_memset() replicated in Sun kernel files * * Revision 4.4 1998/06/13 12:15:59 kardel * superfluous variable removed * * Revision 4.3 1998/06/12 15:23:08 kardel * fix prototypes * adjust for ansi2knr * * Revision 4.2 1998/05/24 18:16:22 kardel * moved copy of shadow status to the beginning * * Revision 4.1 1998/05/24 09:38:47 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.37 log info deleted 1998/04/11 kardel */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -