📄 va.c
字号:
#ifndef lintstatic char *sccsid = "@(#)va.c 4.1 (ULTRIX) 7/2/90";#endif lint/************************************************************************ * * * Copyright (c) 1985 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* va.c 6.1 83/07/29 */#include "va.h"#if NVA > 0 || defined(BINARY)/* * Varian printer plotter * 18-mar-86 -- jaw br/cvec changed to NOT use registers. * */#include "../data/va_data.c"int vadebug = 0;#define dprintf if(vadebug)printfunsigned minvaph();#define VAPRI (PZERO-1)#define vacsw vacs.Vacsw#define vacsh vacs.vacsr.Vacsh#define vacsl vacs.vacsr.Vacsl/* vacsw bits */#define VA_ERROR 0100000 /* some error has occurred */#define VA_NPRTIMO 0001000 /* DMA timeout error */#define VA_NOTREADY 0000400 /* something besides NPRTIMO */#define VA_DONE 0000200#define VA_IENABLE 0000100 /* interrupt enable */#define VA_DMAGO 0000010 /* DMA go bit */#define VA_DMAGO 0000010 /* DMA go bit */#define VA_SUPPLIESLOW 0000004#define VA_BOTOFFORM 0000002#define VA_BYTEREVERSE 0000001 /* reverse byte order in words *//* vacsh command bytes */#define VAPLOT 0000340#define VAPRINT 0000100#define VAPRINTPLOT 0000160#define VAAUTOSTEP 0000244#define VANOAUTOSTEP 0000045#define VAFORMFEED 0000263#define VASLEW 0000265#define VASTEP 0000064#define VAS_IDLE 0 /* no I/O, free */#define VAS_PIO 1 /* programmed I/O */#define VAS_DMA 2 /* DMA, block pio */#define VAS_WANT 4 /* wakeup when iostate changes */#define VAUNIT(dev) (minor(dev))int vaprobe(), vaslave(), vaattach(), vadgo();u_short vastd[] = { 0764000, 0 };struct uba_driver vadriver = { vaprobe, vaslave, vaattach, vadgo, vastd, "vz", vadinfo, "va", vaminfo };vaprobe(reg) caddr_t reg;{ register struct vadevice *vaaddr = (struct vadevice *)reg;#ifdef lint vaintr(0);#endif#ifndef UCBVAX vaaddr->vacsl = VA_IENABLE; vaaddr->vaba = 0; vaaddr->vacsh = VAPLOT; vaaddr->vacsl = VA_IENABLE|VA_DMAGO; vaaddr->vawc = -1; DELAY(10000); vaaddr->vacsl = 0; vaaddr->vawc = 0;#else br=0x14; cvec=0170;#endif return (sizeof (struct vadevice));}/*ARGSUSED*/vaslave(ui, reg) struct uba_device *ui; caddr_t reg;{ ui->ui_dk = 0; return (ui->ui_unit <= 0);}/*ARGSUSED*/vaattach(ui) struct uba_device *ui;{ ui->ui_mi->um_tab.b_actf = &vabhdr[ui->ui_unit];}vaopen(dev) dev_t dev;{ register struct va_softc *sc; register struct vadevice *vaaddr; register struct uba_device *ui; int error; int unit = VAUNIT(dev); if (unit >= nNVA || (sc = &va_softc[unit])->sc_openf || (ui = vadinfo[unit]) == 0 || ui->ui_alive == 0) return (ENXIO); vaaddr = (struct vadevice *)ui->ui_addr; sc->sc_openf = 1; vaaddr->vawc = 0; sc->sc_state = 0; sc->sc_tocnt = 0; sc->sc_iostate = VAS_IDLE; vaaddr->vacsl = VA_IENABLE; vatimo(dev); error = vacmd(dev, VPRINT); if (error) vaclose(dev); return (error);}vastrategy(bp) register struct buf *bp;{ register struct uba_device *ui; register struct uba_ctlr *um; int s; dprintf("vastrategy(%x)\n", bp); ui = vadinfo[VAUNIT(bp->b_dev)]; if (ui == 0 || ui->ui_alive == 0) { bp->b_flags |= B_ERROR; iodone(bp); return; } s = spl4(); um = ui->ui_mi; bp->b_actf = NULL; if (um->um_tab.b_actf->b_actf == NULL) um->um_tab.b_actf->b_actf = bp; else { printf("bp = 0x%x, um->um_tab.b_actf->b_actf = 0x%x\n", bp, um->um_tab.b_actf->b_actf); panic("vastrategy"); um->um_tab.b_actf->b_actl->b_forw = bp; } um->um_tab.b_actf->b_actl = bp; bp = um->um_tab.b_actf; dprintf("vastrategy: bp=%x actf=%x active=%d\n", bp, bp->b_actf, bp->b_active); if (bp->b_actf && bp->b_active == 0) (void) vastart(um); splx(s);}int vablock = 16384;unsignedminvaph(bp) struct buf *bp;{ if (bp->b_bcount > vablock) bp->b_bcount = vablock;}/*ARGSUSED*/vawrite(dev, uio) dev_t dev; struct uio *uio;{ if (VAUNIT(dev) > nNVA) return (ENXIO); return (physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph, uio));}vastart(um) register struct uba_ctlr *um;{ struct buf *bp; struct vadevice *vaaddr; register struct va_softc *sc; int unit; dprintf("vastart(%x), bp=%x\n", um, um->um_tab.b_actf->b_actf); if ((bp = um->um_tab.b_actf->b_actf) == NULL) return; unit = VAUNIT(bp->b_dev); sc = &va_softc[unit]; sc->sc_tocnt = 0; while (sc->sc_iostate&VAS_PIO) { sc->sc_iostate |= VAS_WANT; sleep((caddr_t)&sc->sc_iostate, VAPRI); } sc->sc_iostate |= VAS_DMA; vaaddr = (struct vadevice *)um->um_addr; vaaddr->vacsl = 0; vaaddr->vawc = -(bp->b_bcount / 2); um->um_cmd = VA_DMAGO | VA_IENABLE; (void) ubago(vadinfo[unit]);}vadgo(um) register struct uba_ctlr *um;{ register struct vadevice *vaaddr = (struct vadevice *)um->um_addr; register struct buf *bp; bp = um->um_tab.b_actf; va_softc[VAUNIT(bp->b_actf->b_dev)].sc_tocnt = 0; bp->b_active++; vaaddr->vaba = um->um_ubinfo; vaaddr->vacsl = ((um->um_ubinfo >> 12) & 0x30) | um->um_cmd;}/*ARGSUSED*/vaioctl(dev, cmd, data, flag) register caddr_t data;{ register struct va_softc *sc = &va_softc[VAUNIT(dev)]; switch (cmd) { case VGETSTATE: *(int *)data = sc->sc_state; break; case VSETSTATE: return (vacmd(dev, *(int *)data)); default: return (ENOTTY); } return (0);}vacmd(dev, vcmd) dev_t dev; int vcmd;{ register struct va_softc *sc = &va_softc[VAUNIT(dev)]; int error = 0; int s, cmd; s = spl4(); while (sc->sc_iostate&VAS_DMA) { sc->sc_iostate |= VAS_WANT; sleep((caddr_t)&sc->sc_iostate, VAPRI); } sc->sc_iostate |= VAS_PIO; sc->sc_tocnt = 0; cmd = 0; switch (vcmd) { case VPLOT: /* Must turn on plot AND autostep modes. */ if (vadopio(dev, VAPLOT)) error = EIO; cmd = VAAUTOSTEP; break; case VPRINT: cmd = VAPRINT; break; case VPRINTPLOT: cmd = VAPRINTPLOT; break; } sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd; if (cmd && vadopio(dev, cmd)) error = EIO; sc->sc_iostate &= ~VAS_PIO; if (sc->sc_iostate&VAS_WANT) { sc->sc_iostate &= ~VAS_WANT; wakeup((caddr_t)&sc->sc_iostate); } splx(s); return (error);}vadopio(dev, cmd) dev_t dev; int cmd;{ register struct vadevice *vaaddr = (struct vadevice *)vaminfo[VAUNIT(dev)]->um_addr; register struct va_softc *sc = &va_softc[VAUNIT(dev)]; sc->sc_info = 0; vaaddr->vacsh = cmd; while ((sc->sc_info&(VA_DONE|VA_ERROR)) == 0) sleep((caddr_t)&sc->sc_info, VAPRI); return (sc->sc_info&VA_ERROR);}vatimo(dev) dev_t dev;{ register struct va_softc *sc = &va_softc[VAUNIT(dev)]; if (sc->sc_openf) timeout(vatimo, (caddr_t)dev, hz/2); if (++sc->sc_tocnt < 2) return; sc->sc_tocnt = 0; dprintf("vatimo: calling vaintr\n"); vaintr(dev);}/*ARGSUSED*/vaintr(dev) dev_t dev;{ register struct uba_ctlr *um; struct vadevice *vaaddr; struct buf *bp; register int unit = VAUNIT(dev), e; register struct va_softc *sc = &va_softc[unit]; um = vaminfo[unit]; vaaddr = (struct vadevice *)um->um_addr; e = vaaddr->vacsw; dprintf("vaintr: um=0x%x, e=0x%x, b_active %d\n", um, e, um->um_tab.b_actf->b_active); if ((e&(VA_DONE|VA_ERROR)) == 0) return; vaaddr->vacsl = 0; if ((e&VA_ERROR) && (e&VA_NPRTIMO)) printf("va%d: npr timeout\n", unit); if (sc->sc_iostate&VAS_PIO) { sc->sc_info = e; wakeup((caddr_t)&sc->sc_info); return; } if (um->um_tab.b_actf->b_active) { bp = um->um_tab.b_actf->b_actf; if (e&VA_ERROR) bp->b_flags |= B_ERROR; if (sc->sc_state&VPRINTPLOT) { sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT; vaaddr->vacsh = VAAUTOSTEP; return; } ubadone(um); um->um_tab.b_actf->b_active = 0; um->um_tab.b_actf->b_actf = bp->b_forw; bp->b_active = 0; bp->b_errcnt = 0; bp->b_resid = 0; iodone(bp); } if (um->um_tab.b_actf->b_actf == 0) { sc->sc_iostate &= ~VAS_DMA; if (sc->sc_iostate&VAS_WANT) { sc->sc_iostate &= ~VAS_WANT; wakeup((caddr_t)&sc->sc_iostate); } return; } if (um->um_tab.b_actf->b_active == 0) vastart(um);}vaclose(dev) dev_t dev;{ register struct va_softc *sc = &va_softc[VAUNIT(dev)]; register struct vadevice *vaaddr = (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; sc->sc_openf = 0; sc->sc_state = 0; if (sc->sc_iostate != VAS_IDLE) wakeup((caddr_t)&sc->sc_iostate); sc->sc_iostate = VAS_IDLE; vaaddr->vacsl = 0; vaaddr->vawc = 0;}vareset(uban) int uban;{ register int va11; register struct uba_ctlr *um; register struct vadevice *vaaddr; register struct va_softc *sc; for (va11 = 0; va11 < nNVA; va11++, sc++) { if ((um = vaminfo[va11]) == 0 || um->um_ubanum != uban || um->um_alive == 0) continue; sc = &va_softc[um->um_ctlr]; if (sc->sc_openf == 0) continue; printf(" va%d", va11); vaaddr = (struct vadevice *)um->um_addr; vaaddr->vacsl = VA_IENABLE; if (sc->sc_state & VPLOT) { vaaddr->vacsh = VAPLOT; DELAY(10000); vaaddr->vacsh = VAAUTOSTEP; } else if (sc->sc_state & VPRINTPLOT) vaaddr->vacsh = VPRINTPLOT; else vaaddr->vacsh = VAPRINTPLOT; DELAY(10000); sc->sc_iostate = VAS_IDLE; um->um_tab.b_actf->b_active = 0; um->um_tab.b_actf->b_actf = um->um_tab.b_actf->b_actl = 0; if (um->um_ubinfo) { printf("<%d>", (um->um_ubinfo >> 28) & 0xf); um->um_ubinfo = 0; } (void) vastart(um); }}vaselect(){ return (1);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -