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

📄 mp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
				}				mp_freein(ev);				adjptr(mp->mp_off, MPINSET);				mpstart(tp);				break;			default:				mplog(unit, port, A_INVCMD, (int)ev->ev_cmd);  				mp_freein(ev);				adjptr(mp->mp_off, MPINSET);				break;			}		}	}#undef	nextevent}mp_freein(ev)	register struct mpevent *ev;{	/* re-init all values in this entry */	ev->ev_cmd = 0;	ev->ev_opts = 0;	ev->ev_error = 0;	ev->ev_flags = 0;	ev->ev_count = 0;	/* show this entry is available for use */	ev->ev_status = EVSTATUS_FREE;}/* * Handler for processing received events. */mprintr(unit, list)	u_char *list;{	register struct tty *tp;	register struct mpport *mp;	register struct mpevent *ev;	struct mblok *mb;	register int cc;	register char *cp;	struct mpsoftc *ms;	caddr_t ptr;	char *rcverr;	int port, i;	ms = &mp_softc[unit];	mb = mp_softc[unit].ms_mb;	for (i = 0; i < MPMAXPORT && (port = *list++) != MPPORT_EOL; i++) {		tp = &mp_tty[unit*MPCHUNK + port];		mp = &mb->mb_port[port];		ev = &mp->mp_sendq[mp->mp_nextrcv];		while (ev->ev_status & EVSTATUS_DONE) {			switch(ev->ev_cmd) {			case EVCMD_STATUS:				/*				 * Status change, look for carrier changes.				 */				switch(ev->ev_opts) {				case DCDASRT:					(*linesw[tp->t_line].l_modem)(tp, 1);					wakeup((caddr_t)&tp->t_canq);					break;				case DCDDROP:					(*linesw[tp->t_line].l_modem)(tp, 0);					wakeup((caddr_t)&tp->t_canq);					break;				case NORBUF:				case NOEBUF:					mplog(unit, port,					    "out of receive events", 0);					break;				default:					mplog(unit, port,					    "unexpect status command",					    (int)ev->ev_opts);					break;				}				break;			case EVCMD_READ:				/*			 	 * Process received data.			 	 */				if ((tp->t_state & TS_ISOPEN) == 0) {					wakeup((caddr_t)&tp->t_rawq);					break;				}				if ((cc = ev->ev_count) == 0)					break;				cp = ms->ms_cbuf[port][mp->mp_nextrcv];				mppurge(cp, CBSIZE);				while (cc-- > 0) {					/*				 	 * A null character is inserted,					 * potentially when a break or framing					 * error occurs. If we're not in raw					 * mode, substitute the interrupt					 * character.				 	 */					/*** XXX - FIXUP ***/					if (*cp == 0 &&				            (ev->ev_error == BRKASRT ||				             ev->ev_error == FRAMERR))						if ((tp->t_flags&RAW) == 0)							;							/* XXX was break */					(*linesw[tp->t_line].l_rint)(*cp++, tp);				}				/* setup for next read */				ptr = (caddr_t)&mp_softc[unit].ms_cbuf[port][mp->mp_nextrcv][0];				ev->ev_un.rcvblk = (u_char *)kvtophys(ptr);				ev->ev_params = (caddr_t) kvtophys(ptr);				switch(ev->ev_error) {				case RCVDTA:					/* Normal (good) rcv data do not					 * report the following they are					 * "normal" errors 					 */				case FRAMERR:					/* frame error */				case BRKASRT:					/* Break condition */				case PARERR:					/* parity error */					rcverr = (char *)0;					break;				case OVRNERR:					/* Overrun error */					rcverr = "overrun error";					break;				case OVFERR:					/* Overflow error */					rcverr = "overflow error";					break;				default:					rcverr = "undefined rcv error";					break;				}				if (rcverr != (char *)0)					mplog(unit, port, rcverr,					      (int)ev->ev_error);				break;			default:				mplog(unit, port, "unexpected command",					(int)ev->ev_cmd);				break;			}			ev->ev_cmd = 0;			ev->ev_opts = 0;			ev->ev_error = 0;			ev->ev_flags = 0;			ev->ev_count = 0;			ev->ev_status = EVSTATUS_GO;	/* start next read */			adjptr(mp->mp_nextrcv, MPOUTSET);			ev = &mp->mp_sendq[mp->mp_nextrcv];		}	}}/* * Log an mpcc diagnostic. */mplog(unit, port, cp, flags)	char *cp;{	if (flags)		log(LOG_ERR, "mp%d: port%d, %s (%d)\n",		    unit, port, cp, flags);	else		log(LOG_ERR, "mp%d: port%d, %s\n", unit, port, cp);}int	MPHOSTINT = 1;mptimeint(mb)	register struct mblok *mb;{        mb->mb_mpintcnt = 0;        mb->mb_mpintclk = (caddr_t)0;	*(u_short *)mpinfo[mb->mb_unit]->ui_addr = 2;}/* * Interupt mpcc */mpintmpcc(mb, port)	register struct mblok *mb;{        mb->mb_intr[port] |= MPSEMA_WORK;        if (++mb->mb_mpintcnt == MPHOSTINT) {                mb->mb_mpintcnt = 0;		*(u_short *)mpinfo[mb->mb_unit]->ui_addr = 2;                if (mb->mb_mpintclk) {                        untimeout(mptimeint, (caddr_t)mb);                        mb->mb_mpintclk = 0;                }        } else {                if (mb->mb_mpintclk == 0) {                        timeout(mptimeint, (caddr_t)mb, 4);                        mb->mb_mpintclk = (caddr_t)1;                }        }}static char *mpherrmsg[] = {	"",	"Bus error",				/* MPBUSERR */	"Address error",			/* ADDRERR */	"Undefined ecc interrupt",		/* UNDECC */	"Undefined interrupt",			/* UNDINT */	"Power failure occurred",		/* PWRFL */	"Stray transmit done interrupt",	/* NOXENTRY */	"Two fast timers on one port",		/* TWOFTMRS */	"Interrupt queue full",			/* INTQFULL */	"Interrupt queue ack error",		/* INTQERR */	"Uncorrectable dma parity error",	/* CBPERR */	"32 port ACAP failed power up",		/* ACPDEAD */};#define	NHERRS	(sizeof (mpherrmsg) / sizeof (mpherrmsg[0]))mperror(mb, unit)	register struct mblok *mb;	int unit;{	register char *cp;	register int i;	if (mb->mb_softerr) {		switch (mb->mb_softerr) {		case DMAPERR:   /* dma parity error */			cp = "dma parity error";			break;		case ECCERR:			cp = "local memory ecc error";			break;		default:			cp = "unknown error";			break;		}		log(LOG_ERR, "mp%d: soft error, %s", unit, cp);		mb->mb_softerr = 0;	}	if (mb->mb_harderr) {		if (mb->mb_harderr < NHERRS)			cp = mpherrmsg[mb->mb_harderr];		else			cp = "unknown error";		log(LOG_ERR, "mp%d: hard error, %s", unit, cp);		if (mb->mb_status == MP_OPOPEN) {			for (i = 0; i < MPMAXPORT; i++) {				mpcleanport(mb, i);				mb->mb_proto[i] = MPPROTO_UNUSED;			}		}		mb->mb_harderr = 0;		mb->mb_status = 0;	}}mppurge(addr, cc)	register caddr_t addr;	register int cc;{	for (; cc >= 0; addr += NBPG, cc -= NBPG)		mtpr(P1DC, addr);}/* * MPCC Download Pseudo-device. */char	mpdlbuf[MPDLBUFSIZE];int	mpdlbusy;		/* interlock on download buffer */int	mpdlerr;mpdlopen(dev)	dev_t dev;{	int unit, mpu;	struct vba_device *vi;	unit = minor(dev);	mpu = MPUNIT(unit);	if (mpu >= NMP || (vi = mpinfo[mpu]) == 0 || vi->ui_alive == 0)		return (ENODEV);	return (0);}mpdlwrite(dev, uio)	dev_t dev;	struct uio *uio;{	register struct mpsoftc *ms = &mp_softc[MPUNIT(minor(dev))];	register struct mpdl *dl;	int error;	if (ms->ms_mb == 0 || ms->ms_mb->mb_status != MP_DLOPEN)		return (EFAULT);	dl = &ms->ms_mb->mb_dl;	dl->mpdl_count = uio->uio_iov->iov_len;	dl->mpdl_data = (caddr_t) kvtophys(mpdlbuf);	if (error = uiomove(mpdlbuf, (int)dl->mpdl_count, uio))		return (error);	uio->uio_resid -= dl->mpdl_count;    /* set up return from write */	dl->mpdl_cmd = MPDLCMD_NORMAL;	error = mpdlwait(dl);	return (error);}mpdlclose(dev)	dev_t dev;{	register struct mblok *mb = mp_softc[MPUNIT(minor(dev))].ms_mb;	if (mb == 0 || mb->mb_status != MP_DLDONE) {		mpbogus.status = 0;		if (mpbogus.mb == mpbogus.mbloks[MPUNIT(minor(dev))])			mpdlbusy--;		return (EEXIST);	}	mb->mb_status = MP_OPOPEN;	mpbogus.status = 0;	/* set to dead, for board handshake */	mb->mb_hostint.imok = MPIMOK_DEAD;	return (0);}/* ARGSUSED */mpdlioctl(dev, cmd, data, flag)	dev_t dev;	caddr_t data;{	register struct mblok *mb;	register struct mpdl *dl;	int unit, error = 0, s, i;	mb = mp_softc[unit=MPUNIT(minor(dev))].ms_mb;	if (mb == 0)		 return (EEXIST);	dl = &mb->mb_dl;	error = 0;	switch (cmd) {	case MPIOPORTMAP:		bcopy(data, (caddr_t)mb->mb_proto, sizeof (mb->mb_proto));		break;	case MPIOHILO:		bcopy(data, (caddr_t)&mb->mb_hiport, 2*(sizeof(mb->mb_hiport)));		break;	case MPIOENDDL:		dl->mpdl_count = 0;		dl->mpdl_data = 0;		dl->mpdl_cmd = MPIOENDDL&IOCPARM_MASK;		error = mpdlwait(dl);		mpccinit(unit);		mb->mb_status = MP_DLDONE;		mpdlbusy--;		break;	case MPIOENDCODE:		dl->mpdl_count = 0;		dl->mpdl_data = 0;		dl->mpdl_cmd = MPIOENDCODE&IOCPARM_MASK;		error = mpdlwait(dl);		break;	case MPIOASYNCNF:		bcopy(data, mpdlbuf, sizeof (struct abdcf));		dl->mpdl_data = (caddr_t) kvtophys(mpdlbuf);		dl->mpdl_count = sizeof (struct abdcf);		dl->mpdl_cmd = MPIOASYNCNF&IOCPARM_MASK;		error = mpdlwait(dl);		break;	case MPIOSTARTDL:		s = spl8();		while (mpdlbusy)			if (error = tsleep((caddr_t)&mpdlbusy,			    (PZERO+1) | PCATCH, devioc, 0))				break;		splx(s);		if (error)			break;		mpdlbusy++;		/* initialize the downloading interface */		mpbogus.magic = MPMAGIC;		mpbogus.mb = mpbogus.mbloks[unit];		mpbogus.status = 1;		dl->mpdl_status = EVSTATUS_FREE;		dl->mpdl_count = 0;		dl->mpdl_cmd = 0;		dl->mpdl_data = (char *) 0;		mpdlerr = 0;		mb->mb_magic = MPMAGIC;        	mb->mb_ivec = mp_softc[unit].ms_ivec+1;	/* download vector */		mb->mb_status = MP_DLPEND;		mb->mb_diagswitch[0] = 'A';		mb->mb_diagswitch[1] = 'P';		s = spl8();		*(u_short *)mpinfo[unit]->ui_addr = 2;		error = tsleep((caddr_t)&mb->mb_status, (PZERO+1) | PCATCH,		    devio, 30*hz);		splx(s);		if (error == EWOULDBLOCK)			error = ETIMEDOUT;		if (error)			mpbogus.status = 0;		bzero((caddr_t)mb->mb_port, sizeof (mb->mb_port));		break;	case MPIORESETBOARD:		s = spl8();		if (mb->mb_imokclk)			mb->mb_imokclk = 0;		*(u_short *)mpinfo[unit]->ui_addr = 0x100;		if (mb->mb_status == MP_DLOPEN || mb->mb_status == MP_DLDONE) {			mpdlerr = MP_DLERROR;			dl->mpdl_status = EVSTATUS_FREE;			wakeup((caddr_t)&dl->mpdl_status);			mpbogus.status = 0;		}		for (i = 0; i < MPMAXPORT; i++) {			if (mb->mb_harderr || mb->mb_softerr)				mperror(mb, i);			mpcleanport(mb, i);			mb->mb_proto[i] = MPPROTO_UNUSED;		}		mb->mb_status = 0;		splx(s);		break;	default:		error = EINVAL;		break;	}	return (error);}mpccinit(unit)	int unit;{        register struct mblok *mb = mp_softc[unit].ms_mb;        register struct his *his;        register int i, j;        mb->mb_status = MP_DLDONE;        mb->mb_ivec = mp_softc[unit].ms_ivec;        mb->mb_magic = MPMAGIC;        /* Init host interface structure */        his = &mb->mb_hostint;        his->semaphore = MPSEMA_AVAILABLE;        for (i = 0; i < NMPPROTO; i++)                for (j = 0; j < MPMAXPORT; j++) {                        his->proto[i].inbdone[j] = MPPORT_EOL;                        his->proto[i].outbdone[j] = MPPORT_EOL;                }        mb->mb_unit = unit;}mpdlintr(mpcc)	int mpcc;{	register struct mblok *mb;	register struct mpdl *dl;	mb = mp_softc[mpcc].ms_mb;	if (mb == 0) {		printf("mp%d: stray download interrupt\n", mpcc);		return;	}	dl = &mb->mb_dl;	switch (mb->mb_status) {	case MP_DLOPEN:		if (dl->mpdl_status != EVSTATUS_DONE)			mpdlerr = MP_DLERROR;		dl->mpdl_status = EVSTATUS_FREE;		wakeup((caddr_t)&dl->mpdl_status);		return;	case MP_DLPEND:		mb->mb_status = MP_DLOPEN;		wakeup((caddr_t)&mb->mb_status);		/* fall thru... */	case MP_DLTIME:		return;	case MP_OPOPEN:		if (mb->mb_imokclk)			mb->mb_imokclk = 0;		mb->mb_nointcnt = 0;		/* reset no interrupt count */		mb->mb_hostint.imok = MPIMOK_DEAD;		mb->mb_imokclk = (caddr_t)1;		break;	default:		log(LOG_ERR, "mp%d: mpdlintr, status %x\n",		    mpcc, mb->mb_status);		break;	}}/*  * Wait for a transfer to complete or a timeout to occur. */mpdlwait(dl)	register struct mpdl *dl;{	int s, error = 0;	s = spl8();	dl->mpdl_status = EVSTATUS_GO;	while (dl->mpdl_status != EVSTATUS_FREE) {		error = tsleep((caddr_t)&dl->mpdl_status, (PZERO+1) | PCATCH,		    devout, 0);		if (mpdlerr == MP_DLERROR)			error = EIO;		if (error)			break;	}	splx(s);	return (error);}#endif

⌨️ 快捷键说明

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