📄 vs.c
字号:
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 + -