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

📄 vs.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	case VSIOBBACTL:		/* enable/disable BBA */		s = spl5();		vsaddr->vs_irr = 0;		vsaddr->vs_csr0 &= ~VS_FCN;		func = *(int *)addr == VSIO_ON ? VS_ENABBA : VS_DISBBA;		vsaddr->vs_csr0 |= (VS_IE | (func << VS_FCSHIFT) | VS_GO);		error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH, devwait, 0);		splx(s);		if (error)			return (error);		return(vsError(vsp));	case VSIOFIBCTL:		/* turn the fiber lamp on/off */		s = spl5();		if (*(int *)addr == VSIO_OFF)			vsaddr->vs_csr0 &= ~VS_XMIT_ON;		else			vsaddr->vs_csr0 |= (VS_IE | VS_XMIT_ON);		error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH, devwait, 0);		splx(s);		if (error)			return (error);		return(vsError(vsp));	case VSIOFIBRETRY:		/* set fiber retries */		s = spl5();		vsaddr->vs_irr = 0;		vsaddr->vs_csr0 &= ~VS_FCN;		func = *(int *)addr == VS_FIB_FINITE ? VS_FINITE : VS_INFINITE;		vsaddr->vs_csr0 |= (VS_IE | (func << VS_FCSHIFT) | VS_GO);		error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH, devwait, 0);		splx(s);		if (error)			return (error);		return(vsError(vsp));	case VSIOSYNC:			/* get synchronized with device */		break;	default:		return(ENOTTY);	}	return(0);}vsintr(dev)dev_t dev;{	register struct vsdevice *vsaddr;	register struct vs_softc *vsp;	register vsEvent *vep;	struct uba_device *uip;	register struct vsBuffArea *vsb;	int i;	vsCursor cur;	if (VSUNIT(dev) >= NVS || (uip = vsdinfo[VSUNIT(dev)]) == 0	    || uip->ui_alive == 0) {		printI("vs%d stray interrupt\n", VSUNIT(dev));		return;	}	vsaddr = (struct vsdevice *) uip->ui_addr;	vsp = &vs_softc[VSUNIT(dev)];	vsb = &vsBuff[VSUNIT(dev)];#ifdef notdef	printM("vsintr csr0=%x, csr1=%x, csr2=%x, csr3=%x, csr4=%x, csr5=%x, csr6=%x, csr7=%x\n",		vsaddr->vs_csr0, vsaddr->vs_csr1, vsaddr->vs_csr2, vsaddr->vs_csr3,		vsaddr->vs_csr4, vsaddr->vs_csr5, vsaddr->vs_csr6, vsaddr->vs_csr7);	printI("vs%dintr ", VSUNIT(dev));#endif	/* 	 * get the information out of the soft registers	 */	vsp->irr.intr_reg = vsaddr->vs_irr;	vsp->krr.kbd_reg = vsaddr->vs_krr;	vsp->pr.fparm_low = vsaddr->vs_pr1;	vsp->pr.fparm_high = vsaddr->vs_pr2;	cur.x = vsaddr->vs_cxr;	cur.y = vsaddr->vs_cyr;	vsp->csr.csr_reg = vsaddr->vs_csr0;	if (vsp->irr.intr_reason)		vsaddr->vs_irr = 0;	/* clear int reason, if any */	vsaddr->vs_csr0 &= ~VS_OWN;	/* clear owner bit */	if (vsp->csr.csr_linkTran) {		vsaddr->vs_csr0 &= ~VS_LNK_TRNS;	/* clear the bit */		printI("link transition: ");		if (vsp->csr.csr_linkErr)			vsp->stats.linkErrors++;		if (vsp->csr.csr_linkAvail == vsp->linkAvail) {	/* flash */			vsp->stats.flashes++;			printI("flash\n");		} else if (!vsp->csr.csr_linkAvail && vsp->linkAvail) { /* on -> off */			vsp->stats.douses++;			printI("douse\n");			vsp->inited = FALSE;			if (vsp->open && vsp->pgrp)				gsignal(vsp->pgrp, SIGHUP);			wakeup((caddr_t) vsp);		} else {						/* off -> on */			vsp->stats.ignites++;			printI("ignite\n");			wakeup((caddr_t) vsp);		}		i = 200;		while ((vsaddr->vs_csr0 & VS_LNK_TRNS) && i)			i--;		if (i == 0) {		/* bit stuck */			printI("vs%d: Link Transition bit stuck\n", VSUNIT(dev));			vsp->inited = FALSE;			if (vsp->open && vsp->pgrp)				gsignal(vsp->pgrp, SIGHUP);			vsaddr->vs_csr0 &= ~VS_XMIT_ON;			vsp->csr.csr_linkAvail = FALSE;		}		vsp->linkAvail = vsp->csr.csr_linkAvail;		return;	}	if (vsp->irr.intr_error) {		printI("error 0x%x\n", vsp->irr.intr_reg&0xffff);		vsp->stats.errors++;		/* set status and wake up user if necessary */		if (vsp->vs_nextgo.fparm_all) {			vsp->vs_status = vsp->irr.intr_reg;			vsaddr->vs_pr1 = vsp->vs_nextgo.fparm_low;			vsaddr->vs_pr2 = vsp->vs_nextgo.fparm_high;			vsp->vs_nextgo.fparm_all = NULL;			vsaddr->vs_csr0 &= ~VS_FCN;	/* clear bits */			vsaddr->vs_csr0 |= (VS_IE | (VS_SEND << VS_FCSHIFT) | VS_GO);		} else			vsb->vsioa.status = vsp->irr.intr_reg;		wakeup((caddr_t) vsp);		return;	}#ifdef notdef	printI("reason is %b\n", vsp->irr.intr_reason, VSIRR_BITS);#endif	switch(vsp->irr.intr_reason) {	case VS_INT_CD:			/* command done */		/* set status and start a new command if necessary */		if (vsp->vs_nextgo.fparm_all) {			vsp->vs_status = vsp->irr.intr_reg;			vsaddr->vs_pr1 = vsp->vs_nextgo.fparm_low;			vsaddr->vs_pr2 = vsp->vs_nextgo.fparm_high;			vsp->vs_nextgo.fparm_all = NULL;			vsaddr->vs_csr0 &= ~VS_FCN;	/* clear bits */			vsaddr->vs_csr0 |= (VS_IE | (VS_SEND << VS_FCSHIFT) | VS_GO);		} else			vsb->vsioa.status = vsp->irr.intr_reg;		break;	case VS_INT_MM:			/* mouse moved */		vsb->vsioa.mouse = cur;                if (!vsp->open)                        return;         /* ignore on closed device */		/* no event if inside box */		if (cur.y < vsb->vsioa.mbox.bottom &&		    cur.y >= vsb->vsioa.mbox.top &&		    cur.x < vsb->vsioa.mbox.right &&		    cur.x >= vsb->vsioa.mbox.left)		    return;		/* trash box */		vsb->vsioa.mbox.bottom = 0;		if (EVROUND(vsb->vsioa.itail+1) == vsb->vsioa.ihead)		    return;		i = EVROUND(vsb->vsioa.itail-1);		if ((vsb->vsioa.itail != vsb->vsioa.ihead) &&		    (i != vsb->vsioa.ihead)) {		    vep = &vsb->ibuff[i];		    if (vep->vse_type == VSE_MMOTION) {			vep->vse_x = cur.x;			vep->vse_y = cur.y;			vep->vse_time = mfpr(TODR);			return;		    }		}		/* put event into queue and do select */		vep = &vsb->ibuff[vsb->vsioa.itail];		vep->vse_type = VSE_MMOTION;		vep->vse_x = cur.x;		vep->vse_y = cur.y;		vep->vse_time = mfpr(TODR);		vsb->vsioa.itail = EVROUND(vsb->vsioa.itail+1);		if (vsp->rsel) {			selwakeup(vsp->rsel, 0);			vsp->rsel = 0;		}		break;	case VS_INT_BE:			/* button event */		if (!vsp->open)			return;		/* ignore on closed device */		if (vsp->krr.kbd_device == VSE_MOUSE) {		    vsb->vsioa.mouse.x = cur.x;		    vsb->vsioa.mouse.y = cur.y;		}		/* check for room in the queue */		if ((i = EVROUND(vsb->vsioa.itail+1)) == vsb->vsioa.ihead)		    return;		/* put event into queue and do select */		vep = &vsb->ibuff[vsb->vsioa.itail];		vep->vse_type = VSE_BUTTON; 		vep->vse_key = vsp->krr.kbd_key;		vep->vse_direction = vsp->krr.kbd_transition;		vep->vse_device = vsp->krr.kbd_device;	        vep->vse_time = mfpr(TODR);		vep->vse_x = vsb->vsioa.mouse.x;		vep->vse_y = vsb->vsioa.mouse.y;		vsb->vsioa.itail = i;		if (vsp->rsel) {			selwakeup(vsp->rsel, 0);			vsp->rsel = 0;		}		break;	case VS_INT_TM:			/* tablet moved */		if (!vsp->open)			return;		/* ignore on closed device */		if (EVROUND(vsb->vsioa.itail+1) == vsb->vsioa.ihead)		    return;		i = EVROUND(vsb->vsioa.itail-1);		if ((vsb->vsioa.itail != vsb->vsioa.ihead) &&		    (i != vsb->vsioa.ihead)) {		    vep = &vsb->ibuff[i];		    if (vep->vse_type == VSE_TMOTION) {			vep->vse_x = cur.x;			vep->vse_y = cur.y;			vep->vse_time = mfpr(TODR);			return;		    }		}		/* put event into queue and do select */		vep = &vsb->ibuff[vsb->vsioa.itail];		vep->vse_type = VSE_TMOTION;		vep->vse_x = cur.x;		vep->vse_y = cur.y;		vep->vse_time = mfpr(TODR);		vsb->vsioa.itail = EVROUND(vsb->vsioa.itail+1);		if (vsp->rsel) {			selwakeup(vsp->rsel, 0);			vsp->rsel = 0;		}		break;	case VS_INT_US:			/* unsolicited */		vsp->stats.unsolIntr++;		return;	case VS_INT_ID:			/* Initialization done */					/* save offset from device */		vsp->offset.fparm_all = vsp->pr.fparm_all;					/* save rom version */		vsp->romVersion = cur.x;		vsp->inited = TRUE;		break;	case VS_INT_SE:			/* ucode started */		break;	case VS_INT_PWR:		/* power up complete */					/* save rom version */		vsp->romVersion = cur.x;		vsp->inited = FALSE;		if (vsp->open && vsp->pgrp)			gsignal(vsp->pgrp, SIGHUP);		break;	default:		printI("vs%d: unknown interrupt %b\n", VSUNIT(dev),			vsp->irr.intr_reason, VSIRR_BITS);		return;	}	wakeup((caddr_t) vsp);}vsreset(uban)int uban;{	register int i;	register struct uba_device *uip;	register struct vs_softc *vsp = vs_softc;	for (i = 0; i < NVS; i++, vsp++) {		if ((uip = vsdinfo[i]) == 0 || uip->ui_alive == 0 ||		    uip->ui_ubanum != uban || vsp->open == 0)			continue;		printf(" vs%d", i);		vsp->inited = FALSE;		if (vsp->open && vsp->pgrp)			gsignal(vsp->pgrp, SIGHUP);	}}vsselect(dev, rw)dev_t dev;{	register struct vsBuffArea *vsb = &vsBuff[VSUNIT(dev)];	int s = spl5();	switch(rw) {	case FREAD:		if (vsb->vsioa.ihead != vsb->vsioa.itail) {		    splx(s);		    return(1);		}		vs_softc[VSUNIT(dev)].rsel = u.u_procp;		splx(s);		return(0);	default:		splx(s);		return(0);	/* can never write */	}}/* * Initialize VS100 or SBO. * Set XMITON.  VS100 will respond with link available.  SBO won't, so * don't wait forever; assume everything is OK and warn user. */vsInitFiber(dev)dev_t dev;{	struct vsdevice *vsaddr = (struct vsdevice *) vsdinfo[VSUNIT(dev)]->ui_addr;	register struct vs_softc *vsp = &vs_softc[VSUNIT(dev)];	int s, error;	s = spl5();	vsaddr->vs_csr0 |= (VS_IE | VS_XMIT_ON);	/* turn link on */	error = tsleep((caddr_t) vsp, VSWAITPRI, SLP_VS_INITF, 2*hz);	splx(s);	if (error == EWOULDBLOCK)	/* timeout */		error = 0;#ifdef VSSBO	if (!vsp->linkAvail) {		uprintf("\007This had better be a vs125!\n");		printf("vs%d must be a vs125\n", VSUNIT(dev));		vsp->linkAvail = TRUE;	}#endif	return (error);}vsInitDev(dev, retry)dev_t dev;int retry;{	register struct vsdevice *vsaddr;	register struct vs_softc *vsp;	int s, error;	vsaddr = (struct vsdevice *) vsdinfo[VSUNIT(dev)]->ui_addr;	vsp = &vs_softc[VSUNIT(dev)];	if (!vsp->linkAvail)		if (error = vsInitFiber(dev))			return (error);	while (1) {		s = spl5();		vsaddr->vs_irr = 0;		vsaddr->vs_csr0 &= ~VS_FCN;		vsaddr->vs_csr0 |= (VS_IE | (VS_INIT << VS_FCSHIFT) | VS_GO);		error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH,		    devwait, retry ? 10*hz : 0);		splx(s);		if (error == EWOULDBLOCK)			error = 0;		if (error)			return (error);		if (vsp->inited)			break;		printM("vs%d: VS_INIT fails\n", VSUNIT(dev));		uprintf("vsInitDev %x %x\n",vsaddr->vs_csr0, vsaddr->vs_csr1);	}	return (0);}vsError(vsp)	register struct vs_softc *vsp;{	if (vsp->irr.intr_error) {		register int ret = vsp->irr.intr_reg;		printD("\treturning 0x%x\n", ret);		vsp->irr.intr_reg = 0;		return(ret+128);	}	return(0);}#endif

⌨️ 快捷键说明

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