123324Smckusick /* 229213Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323324Smckusick * All rights reserved. The Berkeley software License Agreement 423324Smckusick * specifies the terms and conditions for redistribution. 523324Smckusick * 6*30537Skarels * @(#)dmf.c 7.4 (Berkeley) 02/19/87 723324Smckusick */ 86940Ssam 96940Ssam /* 106940Ssam * DMF32 driver 116940Ssam * 1221955Sbloom * 136940Ssam * TODO: 146940Ssam * test with modem 156940Ssam * load as much as possible into silo 166940Ssam * use auto XON/XOFF 176940Ssam * test reset code 186940Ssam */ 19*30537Skarels #include "dmf.h" 20*30537Skarels #if NDMF > 0 21*30537Skarels 22*30537Skarels #ifndef NDMF_LP 23*30537Skarels #define NDMF_LP NDMF 24*30537Skarels #endif NDMF_LP 259772Ssam #include "../machine/pte.h" 269772Ssam 276940Ssam #include "bk.h" 2816063Skarels #include "uba.h" 2917124Sbloom #include "param.h" 3017124Sbloom #include "conf.h" 3117124Sbloom #include "dir.h" 3217124Sbloom #include "user.h" 3326836Skarels #include "proc.h" 3417124Sbloom #include "ioctl.h" 3517124Sbloom #include "tty.h" 3617124Sbloom #include "map.h" 3717124Sbloom #include "buf.h" 3817124Sbloom #include "vm.h" 3917124Sbloom #include "bkmac.h" 4017124Sbloom #include "clist.h" 4117124Sbloom #include "file.h" 4217124Sbloom #include "uio.h" 4321955Sbloom #include "kernel.h" 4418312Sralph #include "syslog.h" 456940Ssam 46*30537Skarels #include "dmx.h" 4717124Sbloom #include "ubareg.h" 4817124Sbloom #include "ubavar.h" 49*30537Skarels #include "dmxreg.h" 5017124Sbloom #include "dmfreg.h" 51*30537Skarels #include "dmreg.h" 528473Sroot 53*30537Skarels extern int dmx_timeout; /* silo timeout, in ms */ 54*30537Skarels extern char dmx_speeds[]; 55*30537Skarels int dmfstart(); 56*30537Skarels 576940Ssam /* 58*30537Skarels * The clist space is mapped by one terminal driver onto each UNIBUS. 59*30537Skarels * The identity of the board which allocated resources is recorded, 60*30537Skarels * so the process may be repeated after UNIBUS resets. 61*30537Skarels * The UBACVT macro converts a clist space address for unibus uban 62*30537Skarels * into an i/o space address for the DMA routine. 636940Ssam */ 64*30537Skarels int dmf_uballoc[NUBA]; /* which dmf (if any) allocated unibus map */ 65*30537Skarels int cbase[NUBA]; /* base address of clists in unibus map */ 66*30537Skarels 67*30537Skarels /* 68*30537Skarels * Autoconfiguration and variables for DMF32 69*30537Skarels */ 706940Ssam int dmfprobe(), dmfattach(), dmfrint(), dmfxint(); 7121955Sbloom int dmflint(); 726940Ssam struct uba_device *dmfinfo[NDMF]; 736940Ssam u_short dmfstd[] = { 0 }; 746940Ssam struct uba_driver dmfdriver = 756940Ssam { dmfprobe, 0, dmfattach, 0, dmfstd, "dmf", dmfinfo }; 766940Ssam 776940Ssam struct tty dmf_tty[NDMF*8]; 78*30537Skarels struct dmx_softc dmf_softc[NDMF]; 798778Sroot #ifndef lint 808778Sroot int ndmf = NDMF*8; /* used by iostat */ 818778Sroot #endif 826940Ssam 836940Ssam /* 846940Ssam * Routine for configuration to set dmf interrupt. 856940Ssam */ 866940Ssam /*ARGSUSED*/ 876940Ssam dmfprobe(reg, ctlr) 886940Ssam caddr_t reg; 8921955Sbloom struct uba_device *ctlr; 906940Ssam { 916940Ssam register int br, cvec; /* these are ``value-result'' */ 926940Ssam register struct dmfdevice *dmfaddr = (struct dmfdevice *)reg; 9321955Sbloom register int i; 9421955Sbloom register unsigned int a; 9521955Sbloom static char *dmfdevs[]= 9621955Sbloom {"parallel","printer","synch","asynch"}; 9721955Sbloom unsigned int dmfoptions; 9825449Skarels static int (*intrv[3])() = { (int (*)())0, (int (*)())0, (int (*)())0 }; 996940Ssam 1006940Ssam #ifdef lint 1016940Ssam br = 0; cvec = br; br = cvec; 1028808Sroot dmfxint(0); dmfrint(0); 10326366Skarels dmfsrint(); dmfsxint(); dmfdaint(); dmfdbint(); dmflint(0); 1046940Ssam #endif 10521955Sbloom /* 10621955Sbloom * Pick the usual size DMF vector here (don't decrement it here). 10721955Sbloom * grab configuration; note that the DMF32 10821955Sbloom * doesn't seem to put the right bits in this 10921955Sbloom * register until AFTER the interrupt vector is set. 11021955Sbloom */ 1116940Ssam br = 0x15; 11221955Sbloom cvec = (uba_hd[numuba].uh_lastiv - 4*8); 11325449Skarels dmfaddr->dmfccsr0 = (cvec >> 2); 11421955Sbloom dmfoptions = dmfaddr->dmfccsr0 & DMFC_CONFMASK; 11521955Sbloom 11621955Sbloom /* catch a couple of special cases: Able vmz/32n and vmz/lp */ 11721955Sbloom if (dmfoptions == DMFC_ASYNC) { 11825449Skarels /* Async portion only */ 11925449Skarels 12025449Skarels cvec = (uba_hd[numuba].uh_lastiv -= 8); 12125449Skarels dmfaddr->dmfccsr0 = (cvec - 2*8) >> 2; 12225449Skarels intrv[0] = ctlr->ui_intr[4]; 12325449Skarels intrv[1] = ctlr->ui_intr[5]; 12425449Skarels ctlr->ui_intr = intrv; 12526312Skarels } else if (dmfoptions == DMFC_LP) { 12625449Skarels /* LP portion only */ 12721955Sbloom 12825449Skarels cvec = (uba_hd[numuba].uh_lastiv -= 8); 12925449Skarels ctlr->ui_intr = &ctlr->ui_intr[6]; 13026312Skarels } else if (dmfoptions == (DMFC_LP|DMFC_ASYNC)) { 131*30537Skarels /* LP and Async portions only */ 13225449Skarels 13325449Skarels cvec = (uba_hd[numuba].uh_lastiv -= 2*8); 13425449Skarels ctlr->ui_intr = &ctlr->ui_intr[4]; 13526312Skarels } else { 13625449Skarels /* All other configurations get everything */ 13721955Sbloom 13821955Sbloom cvec = (uba_hd[numuba].uh_lastiv -= 4*8); 13921955Sbloom } 14025449Skarels a = (dmfoptions >> 12) & 0xf; 14125449Skarels printf("dmf%d:", ctlr->ui_unit); 14226312Skarels for (i = 0; a != 0; ++i, a >>= 1) { 14326312Skarels if (a & 1) 14425449Skarels printf(" %s",dmfdevs[i]); 14525449Skarels } 14625449Skarels printf(".\n"); 14721955Sbloom 14821955Sbloom if (dmfoptions & DMFC_LP) 14927057Skarels dmfaddr->dmfl_ctrl = DMFL_RESET; 1507412Skre return (sizeof (struct dmfdevice)); 1516940Ssam } 1526940Ssam 1536940Ssam /* 1546940Ssam * Routine called to attach a dmf. 1556940Ssam */ 1566940Ssam dmfattach(ui) 157*30537Skarels register struct uba_device *ui; 1586940Ssam { 159*30537Skarels register struct dmx_softc *sc; 1606940Ssam 161*30537Skarels sc = &dmf_softc[ui->ui_unit]; 162*30537Skarels sc->dmx_type = 'f'; 163*30537Skarels sc->dmx_unit = ui->ui_unit; 164*30537Skarels sc->dmx_unit0 = 0; 165*30537Skarels sc->dmx_ubanum = ui->ui_ubanum; 166*30537Skarels sc->dmx_softCAR = ui->ui_flags & 0xff; 167*30537Skarels sc->dmx_tty = &dmf_tty[ui->ui_unit * 8]; 168*30537Skarels sc->dmx_octet = 169*30537Skarels (struct dmx_octet *)&((struct dmfdevice *)ui->ui_addr)->dmfa; 170*30537Skarels 17126221Skarels cbase[ui->ui_ubanum] = -1; 17230322Skarels dmf_uballoc[ui->ui_unit] = -1; 173*30537Skarels #if NDMF_LP > 0 174*30537Skarels dmflattach(ui); 175*30537Skarels #endif NDMF_LP 1766940Ssam } 1776940Ssam 1786940Ssam /* 1796940Ssam * Open a DMF32 line, mapping the clist onto the uba if this 1806940Ssam * is the first dmf on this uba. Turn on this dmf if this is 1816940Ssam * the first use of it. 1826940Ssam */ 1836940Ssam /*ARGSUSED*/ 1846940Ssam dmfopen(dev, flag) 1856940Ssam dev_t dev; 1866940Ssam { 1876940Ssam register struct tty *tp; 188*30537Skarels register struct dmx_softc *sc; 189*30537Skarels int unit, dmf; 1906940Ssam register struct dmfdevice *addr; 1916940Ssam register struct uba_device *ui; 1926940Ssam int s; 1936940Ssam 1946940Ssam unit = minor(dev); 19526312Skarels if (unit & 0200) 19626312Skarels return (dmflopen(dev,flag)); 1976940Ssam dmf = unit >> 3; 1988567Sroot if (unit >= NDMF*8 || (ui = dmfinfo[dmf])== 0 || ui->ui_alive == 0) 1998567Sroot return (ENXIO); 200*30537Skarels 2016940Ssam tp = &dmf_tty[unit]; 202*30537Skarels sc = &dmf_softc[dmf]; 2036940Ssam addr = (struct dmfdevice *)ui->ui_addr; 204*30537Skarels tp->t_addr = (caddr_t)(&addr->dmfa); 2056940Ssam tp->t_oproc = dmfstart; 206*30537Skarels tp->t_dev = dev; /* needed before dmxopen */ 207*30537Skarels 2086940Ssam /* 209*30537Skarels * While setting up state for this uba, 2106940Ssam * block uba resets which can clear the state. 2116940Ssam */ 212*30537Skarels s = spl6(); 21326221Skarels if (cbase[ui->ui_ubanum] == -1) { 21430322Skarels dmf_uballoc[ui->ui_ubanum] = dmf; 21530322Skarels cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum, 21630322Skarels (caddr_t)cfree, nclist*sizeof(struct cblock), 0)); 2176940Ssam } 2186940Ssam splx(s); 219*30537Skarels 220*30537Skarels return (dmxopen(tp, sc)); 2216940Ssam } 2226940Ssam 2236940Ssam /* 2246940Ssam * Close a DMF32 line. 2256940Ssam */ 2266940Ssam /*ARGSUSED*/ 2276940Ssam dmfclose(dev, flag) 2286940Ssam dev_t dev; 2296940Ssam int flag; 2306940Ssam { 2316940Ssam register unit; 2326940Ssam 2336940Ssam unit = minor(dev); 23426312Skarels if (unit & 0200) { 235*30537Skarels dmflclose(dev, flag); 23626312Skarels return; 23726312Skarels } 238*30537Skarels dmxclose(&dmf_tty[unit]); 2396940Ssam } 2406940Ssam 2417726Sroot dmfread(dev, uio) 2426940Ssam dev_t dev; 2437726Sroot struct uio *uio; 2446940Ssam { 2456940Ssam register struct tty *tp; 2466940Ssam 24726312Skarels if (minor(dev) & 0200) 24821955Sbloom return(ENXIO); 2496940Ssam tp = &dmf_tty[minor(dev)]; 2507726Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 2516940Ssam } 2526940Ssam 2537832Sroot dmfwrite(dev, uio) 2546940Ssam dev_t dev; 2557832Sroot struct uio *uio; 2566940Ssam { 2576940Ssam register struct tty *tp; 2586940Ssam 25926312Skarels if (minor(dev) & 0200) 26026312Skarels return (dmflwrite(dev,uio)); 2616940Ssam tp = &dmf_tty[minor(dev)]; 2628530Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 2636940Ssam } 2646940Ssam 2656940Ssam /* 2666940Ssam * DMF32 receiver interrupt. 2676940Ssam */ 2686940Ssam dmfrint(dmf) 2696940Ssam int dmf; 2706940Ssam { 271*30537Skarels struct uba_device *ui; 2726940Ssam 27326312Skarels ui = dmfinfo[dmf]; 27426312Skarels if (ui == 0 || ui->ui_alive == 0) 27526312Skarels return; 276*30537Skarels dmxrint(&dmf_softc[dmf]); 2776940Ssam } 2786940Ssam 2796940Ssam /* 2806940Ssam * Ioctl for DMF32. 2816940Ssam */ 2827630Ssam dmfioctl(dev, cmd, data, flag) 2836940Ssam dev_t dev; 2847630Ssam caddr_t data; 2856940Ssam { 286*30537Skarels int unit = minor(dev); 2876940Ssam 28826312Skarels if (unit & 0200) 28921955Sbloom return (ENOTTY); 290*30537Skarels return (dmxioctl(&dmf_tty[unit], cmd, data, flag)); 2916940Ssam } 2926940Ssam 2936940Ssam /* 2946940Ssam * DMF32 transmitter interrupt. 2956940Ssam * Restart the idle line. 2966940Ssam */ 2976940Ssam dmfxint(dmf) 2986940Ssam int dmf; 2996940Ssam { 3006940Ssam 301*30537Skarels dmxxint(&dmf_softc[dmf]); 3026940Ssam } 3036940Ssam 3046940Ssam /* 305*30537Skarels * Start (restart) transmission on the given line. 3066940Ssam */ 3076940Ssam dmfstart(tp) 308*30537Skarels struct tty *tp; 3096940Ssam { 3106940Ssam 311*30537Skarels dmxstart(tp, &dmf_softc[minor(tp->t_dev) >> 3]); 3126940Ssam } 3136940Ssam 3146940Ssam /* 3156940Ssam * Stop output on a line, e.g. for ^S/^Q or output flush. 3166940Ssam */ 3176940Ssam dmfstop(tp, flag) 318*30537Skarels struct tty *tp; 3196940Ssam { 3206940Ssam 321*30537Skarels dmxstop(tp, &dmf_softc[minor(tp->t_dev) >> 3], flag); 3226940Ssam } 3236940Ssam 3246940Ssam /* 3256940Ssam * Reset state of driver if UBA reset was necessary. 3266940Ssam * Reset the csr, lpr, and lcr registers on open lines, and 3276940Ssam * restart transmitters. 3286940Ssam */ 3296940Ssam dmfreset(uban) 3306940Ssam int uban; 3316940Ssam { 332*30537Skarels register int dmf; 3336940Ssam register struct tty *tp; 3346940Ssam register struct uba_device *ui; 3356940Ssam register struct dmfdevice *addr; 3366940Ssam int i; 3376940Ssam 3386940Ssam for (dmf = 0; dmf < NDMF; dmf++) { 3396940Ssam ui = dmfinfo[dmf]; 3406940Ssam if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) 3416940Ssam continue; 3426940Ssam printf(" dmf%d", dmf); 34330322Skarels if (dmf_uballoc[uban] == dmf) { 34430322Skarels int info; 34530322Skarels 34630322Skarels info = uballoc(uban, (caddr_t)cfree, 34730322Skarels nclist * sizeof(struct cblock), UBA_CANTWAIT); 34830322Skarels if (info) 34930322Skarels cbase[uban] = UBAI_ADDR(info); 35030322Skarels else { 35130322Skarels printf(" [can't get uba map]"); 35230322Skarels cbase[uban] = -1; 35330322Skarels } 35425449Skarels } 3556940Ssam addr = (struct dmfdevice *)ui->ui_addr; 356*30537Skarels addr->dmfa.csr = DMF_IE; 357*30537Skarels addr->dmfa.rsp = dmx_timeout; 358*30537Skarels tp = &dmf_tty[dmf * 8]; 359*30537Skarels for (i = 0; i < 8; i++, tp++) { 3606971Ssam if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 361*30537Skarels dmxparam(tp); 362*30537Skarels (void) dmxmctl(tp, DMF_ON, DMSET); 3636971Ssam tp->t_state &= ~TS_BUSY; 3646940Ssam dmfstart(tp); 3656940Ssam } 3666940Ssam } 367*30537Skarels #if NDMF_LP > 0 368*30537Skarels dmflint(dmf); 369*30537Skarels #endif 3706940Ssam } 3716940Ssam } 3726940Ssam 373*30537Skarels #if NDMF_LP > 0 37426312Skarels /* 375*30537Skarels * DMF32 line printer driver 376*30537Skarels * 377*30537Skarels * the line printer on dmfx is indicated by a minor device code of 128+x 378*30537Skarels * 379*30537Skarels * the flags field of the config file is interpreted like so: 380*30537Skarels * bits meaning 381*30537Skarels * ---- ------- 382*30537Skarels * 0-7 soft carrier bits for ttys part of dmf32 383*30537Skarels * 8-15 number of cols/line on the line printer 384*30537Skarels * if 0, 132 will be used. 385*30537Skarels * 16-23 number of lines/page on the line printer 386*30537Skarels * if 0, 66 will be used. 387*30537Skarels * 24 if 1 DO NOT use the auto format mode of the 388*30537Skarels * line printer parallel port 389*30537Skarels */ 390*30537Skarels 391*30537Skarels struct dmfl_softc { 392*30537Skarels u_int dmfl_state; /* soft state bits */ 393*30537Skarels int dmfl_info; /* uba info */ 394*30537Skarels u_short dmfl_lines; /* lines per page (66 def.) */ 395*30537Skarels u_short dmfl_cols; /* cols per line (132 def.) */ 396*30537Skarels u_short dmfl_format; /* fflag for auto form feed */ 397*30537Skarels char dmfl_buf[DMFL_BUFSIZ]; 398*30537Skarels } dmfl_softc[NDMF]; 399*30537Skarels 400*30537Skarels /* 401*30537Skarels * convert device number into DMF line printer unit number 402*30537Skarels */ 403*30537Skarels #define DMFL_UNIT(d) (minor(d) & 0xf) /* up to 16 DMFs */ 404*30537Skarels 405*30537Skarels #define ASLP 1 /* waiting for interrupt from dmf */ 406*30537Skarels #define OPEN 2 /* line printer is open */ 407*30537Skarels #define ERROR 4 /* error while printing, driver 408*30537Skarels refuses to do anything till closed */ 409*30537Skarels #define MOREIO 8 /* more data for printer */ 410*30537Skarels 411*30537Skarels /* 412*30537Skarels * Attach printer portion of dmf. 413*30537Skarels */ 414*30537Skarels dmflattach(ui) 415*30537Skarels register struct uba_device *ui; 416*30537Skarels { 417*30537Skarels register int unit = ui->ui_unit; 418*30537Skarels register int cols = (ui->ui_flags>>8) & 0xff; 419*30537Skarels register int lines = (ui->ui_flags>>16) & 0xff; 420*30537Skarels register struct dmfl_softc *sc; 421*30537Skarels 422*30537Skarels sc = &dmfl_softc[unit]; 423*30537Skarels sc->dmfl_cols = cols == 0 ? DMFL_DEFCOLS : cols; 424*30537Skarels sc->dmfl_lines = lines == 0 ? DMFL_DEFLINES : lines; 425*30537Skarels if ((ui->ui_flags >> 24) & 0x1) 426*30537Skarels sc->dmfl_format = (2 << 8); 427*30537Skarels else 428*30537Skarels sc->dmfl_format = (2 << 8) | DMFL_FORMAT; 429*30537Skarels } 430*30537Skarels 431*30537Skarels /* 43226312Skarels * dmflopen -- open the line printer port on a dmf32 43321955Sbloom */ 43426312Skarels /* ARGSUSED */ 43526312Skarels dmflopen(dev, flag) 43626312Skarels dev_t dev; 43726312Skarels int flag; 43821955Sbloom { 43921955Sbloom register int dmf; 44021955Sbloom register struct dmfl_softc *sc; 44121955Sbloom register struct uba_device *ui; 44221955Sbloom register struct dmfdevice *addr; 44321955Sbloom 44426312Skarels dmf = DMFL_UNIT(dev); 44526910Skarels if (dmf >= NDMF || (ui = dmfinfo[dmf]) == 0 || ui->ui_alive == 0) 44626910Skarels return (ENXIO); 44726910Skarels sc = &dmfl_softc[dmf]; 44826910Skarels if (sc->dmfl_state & OPEN) 44926910Skarels return (EBUSY); 45021955Sbloom addr = (struct dmfdevice *)ui->ui_addr; 45126910Skarels if (addr->dmfl_ctrl & DMFL_OFFLINE) { 45226910Skarels #ifdef notdef 45326910Skarels log(LOG_WARNING, "dmf%d: line printer offline/jammed\n", 45426910Skarels dmf); 45526910Skarels #endif 45626312Skarels return (EIO); 45721955Sbloom } 45826910Skarels if ((addr->dmfl_ctrl & DMFL_CONV)) { 45926910Skarels log(LOG_WARNING, "dmf%d: line printer disconnected\n", dmf); 46026312Skarels return (EIO); 46121955Sbloom } 46221955Sbloom 46326910Skarels addr->dmfl_ctrl = 0; 46421955Sbloom sc->dmfl_state |= OPEN; 46526312Skarels return (0); 46621955Sbloom } 46721955Sbloom 46826312Skarels /* ARGSUSED */ 46926312Skarels dmflclose(dev, flag) 47026312Skarels dev_t dev; 47126312Skarels int flag; 47221955Sbloom { 47326910Skarels register int dmf = DMFL_UNIT(dev); 47421955Sbloom register struct dmfl_softc *sc = &dmfl_softc[dmf]; 47526910Skarels register struct uba_device *ui = dmfinfo[dmf]; 47621955Sbloom 47721955Sbloom sc->dmfl_state = 0; 47826312Skarels if (sc->dmfl_info != 0) 47926910Skarels ubarelse((int)ui->ui_ubanum, &sc->dmfl_info); 48021955Sbloom 48126910Skarels ((struct dmfdevice *)ui->ui_addr)->dmfl_ctrl = 0; 48221955Sbloom } 48321955Sbloom 48426312Skarels dmflwrite(dev, uio) 48526312Skarels dev_t dev; 48626312Skarels struct uio *uio; 48721955Sbloom { 48826366Skarels register int n; 48921955Sbloom register int error; 49021955Sbloom register struct dmfl_softc *sc; 49121955Sbloom 49221955Sbloom sc = &dmfl_softc[DMFL_UNIT(dev)]; 49326910Skarels if (sc->dmfl_state & ERROR) 49426910Skarels return (EIO); 49526910Skarels while (n = (unsigned)uio->uio_resid) { 49626910Skarels if (n > DMFL_BUFSIZ) { 49726910Skarels n = DMFL_BUFSIZ; 49826910Skarels sc->dmfl_state |= MOREIO; 49926910Skarels } else 50026910Skarels sc->dmfl_state &= ~MOREIO; 50126910Skarels if (error = uiomove(sc->dmfl_buf, (int)n, UIO_WRITE, uio)) 50226312Skarels return (error); 50326910Skarels if (error = dmflout(dev, sc->dmfl_buf, n)) 50426312Skarels return (error); 50521955Sbloom } 50626312Skarels return (0); 50721955Sbloom } 50821955Sbloom 50921955Sbloom 51026312Skarels /* 51126312Skarels * dmflout -- start io operation to dmf line printer 51221955Sbloom * cp is addr of buf of n chars to be sent. 51321955Sbloom * 51421955Sbloom * -- dmf will be put in formatted output mode, this will 51521955Sbloom * be selectable from an ioctl if the 51621955Sbloom * need ever arises. 51721955Sbloom */ 51826312Skarels dmflout(dev, cp, n) 51926312Skarels dev_t dev; 52026312Skarels char *cp; 52126312Skarels int n; 52221955Sbloom { 52321955Sbloom register struct dmfl_softc *sc; 52421955Sbloom register int dmf; 52521955Sbloom register struct uba_device *ui; 52621955Sbloom register struct dmfdevice *d; 52726910Skarels int s; 52821955Sbloom 52926312Skarels dmf = DMFL_UNIT(dev); 53026312Skarels sc = &dmfl_softc[dmf]; 53126312Skarels if (sc->dmfl_state & ERROR) 53226312Skarels return (EIO); 53326312Skarels ui = dmfinfo[dmf]; 53426312Skarels /* 53526312Skarels * allocate unibus resources, will be released when io 53626312Skarels * operation is done. 53721955Sbloom */ 53826910Skarels if (sc->dmfl_info == 0) 53926910Skarels sc->dmfl_info = uballoc(ui->ui_ubanum, cp, n, 0); 54026312Skarels d = (struct dmfdevice *)ui->ui_addr; 54126910Skarels d->dmfl_ctrl = sc->dmfl_format; /* indir reg 2 */ 54221955Sbloom /* indir reg auto increments on r/w */ 54321955Sbloom /* SO DON'T CHANGE THE ORDER OF THIS CODE */ 54426910Skarels d->dmfl_indrct = 0; /* prefix chars & num */ 54526910Skarels d->dmfl_indrct = 0; /* suffix chars & num */ 54626910Skarels d->dmfl_indrct = sc->dmfl_info; /* dma lo 16 bits addr */ 54726910Skarels d->dmfl_indrct = -n; /* number of chars */ 54821955Sbloom 54926910Skarels d->dmfl_indrct = ((sc->dmfl_info>>16)&3) | DMFL_OPTIONS; 55026910Skarels /* dma hi 2 bits addr */ 55126910Skarels d->dmfl_indrct = sc->dmfl_lines /* lines per page */ 55226910Skarels | (sc->dmfl_cols<<8); /* carriage width */ 55321955Sbloom sc->dmfl_state |= ASLP; 55426910Skarels s = spltty(); 55526910Skarels d->dmfl_ctrl |= DMFL_PEN | DMFL_IE; 55626312Skarels while (sc->dmfl_state & ASLP) { 55726910Skarels sleep(sc->dmfl_buf, PZERO + 8); 55826312Skarels while (sc->dmfl_state & ERROR) { 55926910Skarels timeout(dmflint, (caddr_t)dmf, 10 * hz); 56026910Skarels sleep((caddr_t)&sc->dmfl_state, PZERO + 8); 56121955Sbloom } 56221955Sbloom } 56326910Skarels splx(s); 56426312Skarels return (0); 56521955Sbloom } 56626312Skarels 56726312Skarels /* 56826312Skarels * dmflint -- handle an interrupt from the line printer part of the dmf32 56921955Sbloom */ 57021955Sbloom dmflint(dmf) 57126312Skarels int dmf; 57221955Sbloom { 57321955Sbloom register struct uba_device *ui; 57421955Sbloom register struct dmfl_softc *sc; 57521955Sbloom register struct dmfdevice *d; 57626910Skarels short dmfl_stats; 57721955Sbloom 57826312Skarels ui = dmfinfo[dmf]; 57926312Skarels sc = &dmfl_softc[dmf]; 58026312Skarels d = (struct dmfdevice *)ui->ui_addr; 58121955Sbloom 58226910Skarels d->dmfl_ctrl &= ~DMFL_IE; 58327057Skarels dmfl_stats = d->dmfl_ctrl; 58426312Skarels if (sc->dmfl_state & ERROR) { 58526910Skarels if ((dmfl_stats & DMFL_OFFLINE) == 0) 58621955Sbloom sc->dmfl_state &= ~ERROR; 58726366Skarels wakeup((caddr_t)&sc->dmfl_state); 58821955Sbloom return; 58921955Sbloom } 59026910Skarels if (dmfl_stats & DMFL_DMAERR) 59126910Skarels log(LOG_WARNING, "dmf%d: NXM\n", dmf); 59226910Skarels if (dmfl_stats & DMFL_OFFLINE) { 59326910Skarels log(LOG_WARNING, "dmf%d: printer error\n", dmf); 59421955Sbloom sc->dmfl_state |= ERROR; 59521955Sbloom } 59621955Sbloom #ifdef notdef 59726910Skarels if (dmfl_stats & DMFL_PDONE) { 59826910Skarels printf("bytes= %d\n", d->dmfl_indrct); 59926910Skarels printf("lines= %d\n", d->dmfl_indrct); 60026910Skarels } 60121955Sbloom #endif 60221955Sbloom sc->dmfl_state &= ~ASLP; 60326910Skarels wakeup((caddr_t)sc->dmfl_buf); 60426910Skarels if (sc->dmfl_info && (sc->dmfl_state & MOREIO) == 0) 60526312Skarels ubarelse(ui->ui_ubanum, &sc->dmfl_info); 60621955Sbloom } 607*30537Skarels #endif NDMF_LP 60821955Sbloom 6096940Ssam /* stubs for interrupt routines for devices not yet supported */ 6106940Ssam 61126312Skarels dmfsrint() 61226312Skarels { 61326312Skarels printf("dmfsrint\n"); 61426312Skarels } 6156940Ssam 61626312Skarels dmfsxint() 61726312Skarels { 61826312Skarels printf("dmfsxint\n"); 61926312Skarels } 6206940Ssam 62126312Skarels dmfdaint() 62226312Skarels { 62326312Skarels printf("dmfdaint\n"); 62426312Skarels } 6256940Ssam 62626312Skarels dmfdbint() 62726312Skarels { 62826312Skarels printf("dmfdbint\n"); 62926312Skarels } 63026910Skarels #endif NDMF 631