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*39061Smarc * @(#)dmf.c 7.8 (Berkeley) 09/06/89 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 */ 1930537Skarels #include "dmf.h" 2030537Skarels #if NDMF > 0 2130537Skarels 2230537Skarels #ifndef NDMF_LP 2330537Skarels #define NDMF_LP NDMF 2430537Skarels #endif NDMF_LP 2537511Smckusick #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 4630537Skarels #include "dmx.h" 4717124Sbloom #include "ubareg.h" 4817124Sbloom #include "ubavar.h" 4930537Skarels #include "dmxreg.h" 5017124Sbloom #include "dmfreg.h" 5130537Skarels #include "dmreg.h" 528473Sroot 5330537Skarels extern int dmx_timeout; /* silo timeout, in ms */ 5430537Skarels int dmfstart(); 5530537Skarels 566940Ssam /* 5730537Skarels * The clist space is mapped by one terminal driver onto each UNIBUS. 5830537Skarels * The identity of the board which allocated resources is recorded, 5930537Skarels * so the process may be repeated after UNIBUS resets. 6030537Skarels * The UBACVT macro converts a clist space address for unibus uban 6130537Skarels * into an i/o space address for the DMA routine. 626940Ssam */ 6330537Skarels int dmf_uballoc[NUBA]; /* which dmf (if any) allocated unibus map */ 6430537Skarels int cbase[NUBA]; /* base address of clists in unibus map */ 6530537Skarels 6630537Skarels /* 6730537Skarels * Autoconfiguration and variables for DMF32 6830537Skarels */ 696940Ssam int dmfprobe(), dmfattach(), dmfrint(), dmfxint(); 7021955Sbloom int dmflint(); 716940Ssam struct uba_device *dmfinfo[NDMF]; 726940Ssam u_short dmfstd[] = { 0 }; 736940Ssam struct uba_driver dmfdriver = 746940Ssam { dmfprobe, 0, dmfattach, 0, dmfstd, "dmf", dmfinfo }; 756940Ssam 766940Ssam struct tty dmf_tty[NDMF*8]; 7730537Skarels struct dmx_softc dmf_softc[NDMF]; 788778Sroot #ifndef lint 798778Sroot int ndmf = NDMF*8; /* used by iostat */ 808778Sroot #endif 816940Ssam 826940Ssam /* 836940Ssam * Routine for configuration to set dmf interrupt. 846940Ssam */ 856940Ssam /*ARGSUSED*/ 866940Ssam dmfprobe(reg, ctlr) 876940Ssam caddr_t reg; 8821955Sbloom struct uba_device *ctlr; 896940Ssam { 906940Ssam register int br, cvec; /* these are ``value-result'' */ 916940Ssam register struct dmfdevice *dmfaddr = (struct dmfdevice *)reg; 9221955Sbloom register int i; 9321955Sbloom register unsigned int a; 9421955Sbloom static char *dmfdevs[]= 9521955Sbloom {"parallel","printer","synch","asynch"}; 9621955Sbloom unsigned int dmfoptions; 9725449Skarels static int (*intrv[3])() = { (int (*)())0, (int (*)())0, (int (*)())0 }; 986940Ssam 996940Ssam #ifdef lint 1006940Ssam br = 0; cvec = br; br = cvec; 1018808Sroot dmfxint(0); dmfrint(0); 10226366Skarels dmfsrint(); dmfsxint(); dmfdaint(); dmfdbint(); dmflint(0); 1036940Ssam #endif 10421955Sbloom /* 10521955Sbloom * Pick the usual size DMF vector here (don't decrement it here). 10621955Sbloom * grab configuration; note that the DMF32 10721955Sbloom * doesn't seem to put the right bits in this 10821955Sbloom * register until AFTER the interrupt vector is set. 10921955Sbloom */ 1106940Ssam br = 0x15; 11121955Sbloom cvec = (uba_hd[numuba].uh_lastiv - 4*8); 11225449Skarels dmfaddr->dmfccsr0 = (cvec >> 2); 11321955Sbloom dmfoptions = dmfaddr->dmfccsr0 & DMFC_CONFMASK; 11421955Sbloom 11521955Sbloom /* catch a couple of special cases: Able vmz/32n and vmz/lp */ 11621955Sbloom if (dmfoptions == DMFC_ASYNC) { 11725449Skarels /* Async portion only */ 11825449Skarels 11925449Skarels cvec = (uba_hd[numuba].uh_lastiv -= 8); 12025449Skarels dmfaddr->dmfccsr0 = (cvec - 2*8) >> 2; 12125449Skarels intrv[0] = ctlr->ui_intr[4]; 12225449Skarels intrv[1] = ctlr->ui_intr[5]; 12325449Skarels ctlr->ui_intr = intrv; 12426312Skarels } else if (dmfoptions == DMFC_LP) { 12525449Skarels /* LP portion only */ 12621955Sbloom 12725449Skarels cvec = (uba_hd[numuba].uh_lastiv -= 8); 12825449Skarels ctlr->ui_intr = &ctlr->ui_intr[6]; 12926312Skarels } else if (dmfoptions == (DMFC_LP|DMFC_ASYNC)) { 13030537Skarels /* LP and Async portions only */ 13125449Skarels 13225449Skarels cvec = (uba_hd[numuba].uh_lastiv -= 2*8); 13325449Skarels ctlr->ui_intr = &ctlr->ui_intr[4]; 13426312Skarels } else { 13525449Skarels /* All other configurations get everything */ 13621955Sbloom 13721955Sbloom cvec = (uba_hd[numuba].uh_lastiv -= 4*8); 13821955Sbloom } 13925449Skarels a = (dmfoptions >> 12) & 0xf; 14025449Skarels printf("dmf%d:", ctlr->ui_unit); 14126312Skarels for (i = 0; a != 0; ++i, a >>= 1) { 14226312Skarels if (a & 1) 14325449Skarels printf(" %s",dmfdevs[i]); 14425449Skarels } 14525449Skarels printf(".\n"); 14621955Sbloom 14721955Sbloom if (dmfoptions & DMFC_LP) 14827057Skarels dmfaddr->dmfl_ctrl = DMFL_RESET; 1497412Skre return (sizeof (struct dmfdevice)); 1506940Ssam } 1516940Ssam 1526940Ssam /* 1536940Ssam * Routine called to attach a dmf. 1546940Ssam */ 1556940Ssam dmfattach(ui) 15630537Skarels register struct uba_device *ui; 1576940Ssam { 15830537Skarels register struct dmx_softc *sc; 1596940Ssam 16030537Skarels sc = &dmf_softc[ui->ui_unit]; 16130537Skarels sc->dmx_type = 'f'; 16230537Skarels sc->dmx_unit = ui->ui_unit; 16330537Skarels sc->dmx_unit0 = 0; 16430537Skarels sc->dmx_ubanum = ui->ui_ubanum; 16530537Skarels sc->dmx_softCAR = ui->ui_flags & 0xff; 16630537Skarels sc->dmx_tty = &dmf_tty[ui->ui_unit * 8]; 16730537Skarels sc->dmx_octet = 16830537Skarels (struct dmx_octet *)&((struct dmfdevice *)ui->ui_addr)->dmfa; 16930537Skarels 17026221Skarels cbase[ui->ui_ubanum] = -1; 17136610Sbostic dmf_uballoc[ui->ui_ubanum] = -1; 17230537Skarels #if NDMF_LP > 0 17330537Skarels dmflattach(ui); 17430537Skarels #endif NDMF_LP 1756940Ssam } 1766940Ssam 1776940Ssam /* 1786940Ssam * Open a DMF32 line, mapping the clist onto the uba if this 1796940Ssam * is the first dmf on this uba. Turn on this dmf if this is 1806940Ssam * the first use of it. 1816940Ssam */ 1826940Ssam /*ARGSUSED*/ 1836940Ssam dmfopen(dev, flag) 1846940Ssam dev_t dev; 1856940Ssam { 1866940Ssam register struct tty *tp; 18730537Skarels register struct dmx_softc *sc; 18830537Skarels int unit, dmf; 1896940Ssam register struct dmfdevice *addr; 1906940Ssam register struct uba_device *ui; 1916940Ssam int s; 192*39061Smarc int dmxparam(); 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); 20030537Skarels 2016940Ssam tp = &dmf_tty[unit]; 20230537Skarels sc = &dmf_softc[dmf]; 2036940Ssam addr = (struct dmfdevice *)ui->ui_addr; 20430537Skarels tp->t_addr = (caddr_t)(&addr->dmfa); 2056940Ssam tp->t_oproc = dmfstart; 20630537Skarels tp->t_dev = dev; /* needed before dmxopen */ 207*39061Smarc tp->t_param = dmxparam; 20830537Skarels 2096940Ssam /* 21030537Skarels * While setting up state for this uba, 2116940Ssam * block uba resets which can clear the state. 2126940Ssam */ 21330537Skarels s = spl6(); 21426221Skarels if (cbase[ui->ui_ubanum] == -1) { 21530322Skarels dmf_uballoc[ui->ui_ubanum] = dmf; 21630322Skarels cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum, 21730322Skarels (caddr_t)cfree, nclist*sizeof(struct cblock), 0)); 2186940Ssam } 2196940Ssam splx(s); 22030537Skarels 221*39061Smarc return (dmxopen(tp, sc, flag)); 2226940Ssam } 2236940Ssam 2246940Ssam /* 2256940Ssam * Close a DMF32 line. 2266940Ssam */ 2276940Ssam /*ARGSUSED*/ 2286940Ssam dmfclose(dev, flag) 2296940Ssam dev_t dev; 2306940Ssam int flag; 2316940Ssam { 2326940Ssam register unit; 2336940Ssam 2346940Ssam unit = minor(dev); 23526312Skarels if (unit & 0200) { 23630537Skarels dmflclose(dev, flag); 23726312Skarels return; 23826312Skarels } 23930537Skarels dmxclose(&dmf_tty[unit]); 2406940Ssam } 2416940Ssam 242*39061Smarc dmfread(dev, uio, flag) 2436940Ssam dev_t dev; 2447726Sroot struct uio *uio; 2456940Ssam { 2466940Ssam register struct tty *tp; 2476940Ssam 24826312Skarels if (minor(dev) & 0200) 24921955Sbloom return(ENXIO); 2506940Ssam tp = &dmf_tty[minor(dev)]; 251*39061Smarc return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 2526940Ssam } 2536940Ssam 2547832Sroot dmfwrite(dev, uio) 2556940Ssam dev_t dev; 2567832Sroot struct uio *uio; 2576940Ssam { 2586940Ssam register struct tty *tp; 2596940Ssam 26026312Skarels if (minor(dev) & 0200) 26126312Skarels return (dmflwrite(dev,uio)); 2626940Ssam tp = &dmf_tty[minor(dev)]; 2638530Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 2646940Ssam } 2656940Ssam 2666940Ssam /* 2676940Ssam * DMF32 receiver interrupt. 2686940Ssam */ 2696940Ssam dmfrint(dmf) 2706940Ssam int dmf; 2716940Ssam { 27230537Skarels struct uba_device *ui; 2736940Ssam 27426312Skarels ui = dmfinfo[dmf]; 27526312Skarels if (ui == 0 || ui->ui_alive == 0) 27626312Skarels return; 27730537Skarels dmxrint(&dmf_softc[dmf]); 2786940Ssam } 2796940Ssam 2806940Ssam /* 2816940Ssam * Ioctl for DMF32. 2826940Ssam */ 2837630Ssam dmfioctl(dev, cmd, data, flag) 2846940Ssam dev_t dev; 2857630Ssam caddr_t data; 2866940Ssam { 28730537Skarels int unit = minor(dev); 2886940Ssam 28926312Skarels if (unit & 0200) 29021955Sbloom return (ENOTTY); 29130537Skarels return (dmxioctl(&dmf_tty[unit], cmd, data, flag)); 2926940Ssam } 2936940Ssam 2946940Ssam /* 2956940Ssam * DMF32 transmitter interrupt. 2966940Ssam * Restart the idle line. 2976940Ssam */ 2986940Ssam dmfxint(dmf) 2996940Ssam int dmf; 3006940Ssam { 3016940Ssam 30230537Skarels dmxxint(&dmf_softc[dmf]); 3036940Ssam } 3046940Ssam 3056940Ssam /* 30630537Skarels * Start (restart) transmission on the given line. 3076940Ssam */ 3086940Ssam dmfstart(tp) 30930537Skarels struct tty *tp; 3106940Ssam { 3116940Ssam 31230537Skarels dmxstart(tp, &dmf_softc[minor(tp->t_dev) >> 3]); 3136940Ssam } 3146940Ssam 3156940Ssam /* 3166940Ssam * Stop output on a line, e.g. for ^S/^Q or output flush. 3176940Ssam */ 3186940Ssam dmfstop(tp, flag) 31930537Skarels struct tty *tp; 3206940Ssam { 3216940Ssam 32230537Skarels dmxstop(tp, &dmf_softc[minor(tp->t_dev) >> 3], flag); 3236940Ssam } 3246940Ssam 3256940Ssam /* 3266940Ssam * Reset state of driver if UBA reset was necessary. 3276940Ssam * Reset the csr, lpr, and lcr registers on open lines, and 3286940Ssam * restart transmitters. 3296940Ssam */ 3306940Ssam dmfreset(uban) 3316940Ssam int uban; 3326940Ssam { 33330537Skarels register int dmf; 3346940Ssam register struct tty *tp; 3356940Ssam register struct uba_device *ui; 3366940Ssam register struct dmfdevice *addr; 3376940Ssam int i; 3386940Ssam 3396940Ssam for (dmf = 0; dmf < NDMF; dmf++) { 3406940Ssam ui = dmfinfo[dmf]; 3416940Ssam if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) 3426940Ssam continue; 3436940Ssam printf(" dmf%d", dmf); 34430322Skarels if (dmf_uballoc[uban] == dmf) { 34530322Skarels int info; 34630322Skarels 34730322Skarels info = uballoc(uban, (caddr_t)cfree, 34830322Skarels nclist * sizeof(struct cblock), UBA_CANTWAIT); 34930322Skarels if (info) 35030322Skarels cbase[uban] = UBAI_ADDR(info); 35130322Skarels else { 35230322Skarels printf(" [can't get uba map]"); 35330322Skarels cbase[uban] = -1; 35430322Skarels } 35525449Skarels } 3566940Ssam addr = (struct dmfdevice *)ui->ui_addr; 35730537Skarels addr->dmfa.csr = DMF_IE; 35830537Skarels addr->dmfa.rsp = dmx_timeout; 35930537Skarels tp = &dmf_tty[dmf * 8]; 36030537Skarels for (i = 0; i < 8; i++, tp++) { 3616971Ssam if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 362*39061Smarc dmxparam(tp, &tp->t_termios); 36330537Skarels (void) dmxmctl(tp, DMF_ON, DMSET); 3646971Ssam tp->t_state &= ~TS_BUSY; 3656940Ssam dmfstart(tp); 3666940Ssam } 3676940Ssam } 36830537Skarels #if NDMF_LP > 0 36930537Skarels dmflint(dmf); 37030537Skarels #endif 3716940Ssam } 3726940Ssam } 3736940Ssam 37430537Skarels #if NDMF_LP > 0 37526312Skarels /* 37630537Skarels * DMF32 line printer driver 37730537Skarels * 37830537Skarels * the line printer on dmfx is indicated by a minor device code of 128+x 37930537Skarels * 38030537Skarels * the flags field of the config file is interpreted like so: 38130537Skarels * bits meaning 38230537Skarels * ---- ------- 38330537Skarels * 0-7 soft carrier bits for ttys part of dmf32 38430537Skarels * 8-15 number of cols/line on the line printer 38530537Skarels * if 0, 132 will be used. 38630537Skarels * 16-23 number of lines/page on the line printer 38730537Skarels * if 0, 66 will be used. 38830537Skarels * 24 if 1 DO NOT use the auto format mode of the 38930537Skarels * line printer parallel port 39030537Skarels */ 39130537Skarels 39230537Skarels struct dmfl_softc { 39330537Skarels u_int dmfl_state; /* soft state bits */ 39430537Skarels int dmfl_info; /* uba info */ 39530537Skarels u_short dmfl_lines; /* lines per page (66 def.) */ 39630537Skarels u_short dmfl_cols; /* cols per line (132 def.) */ 39730537Skarels u_short dmfl_format; /* fflag for auto form feed */ 39830537Skarels char dmfl_buf[DMFL_BUFSIZ]; 39930537Skarels } dmfl_softc[NDMF]; 40030537Skarels 40130537Skarels /* 40230537Skarels * convert device number into DMF line printer unit number 40330537Skarels */ 40430537Skarels #define DMFL_UNIT(d) (minor(d) & 0xf) /* up to 16 DMFs */ 40530537Skarels 40630537Skarels #define ASLP 1 /* waiting for interrupt from dmf */ 40730537Skarels #define OPEN 2 /* line printer is open */ 40830537Skarels #define ERROR 4 /* error while printing, driver 40930537Skarels refuses to do anything till closed */ 41030537Skarels #define MOREIO 8 /* more data for printer */ 41130537Skarels 41230537Skarels /* 41330537Skarels * Attach printer portion of dmf. 41430537Skarels */ 41530537Skarels dmflattach(ui) 41630537Skarels register struct uba_device *ui; 41730537Skarels { 41830537Skarels register int unit = ui->ui_unit; 41930537Skarels register int cols = (ui->ui_flags>>8) & 0xff; 42030537Skarels register int lines = (ui->ui_flags>>16) & 0xff; 42130537Skarels register struct dmfl_softc *sc; 42230537Skarels 42330537Skarels sc = &dmfl_softc[unit]; 42430537Skarels sc->dmfl_cols = cols == 0 ? DMFL_DEFCOLS : cols; 42530537Skarels sc->dmfl_lines = lines == 0 ? DMFL_DEFLINES : lines; 42630537Skarels if ((ui->ui_flags >> 24) & 0x1) 42730537Skarels sc->dmfl_format = (2 << 8); 42830537Skarels else 42930537Skarels sc->dmfl_format = (2 << 8) | DMFL_FORMAT; 43030537Skarels } 43130537Skarels 43230537Skarels /* 43326312Skarels * dmflopen -- open the line printer port on a dmf32 43421955Sbloom */ 43526312Skarels /* ARGSUSED */ 43626312Skarels dmflopen(dev, flag) 43726312Skarels dev_t dev; 43826312Skarels int flag; 43921955Sbloom { 44021955Sbloom register int dmf; 44121955Sbloom register struct dmfl_softc *sc; 44221955Sbloom register struct uba_device *ui; 44321955Sbloom register struct dmfdevice *addr; 44421955Sbloom 44526312Skarels dmf = DMFL_UNIT(dev); 44626910Skarels if (dmf >= NDMF || (ui = dmfinfo[dmf]) == 0 || ui->ui_alive == 0) 44726910Skarels return (ENXIO); 44826910Skarels sc = &dmfl_softc[dmf]; 44926910Skarels if (sc->dmfl_state & OPEN) 45026910Skarels return (EBUSY); 45121955Sbloom addr = (struct dmfdevice *)ui->ui_addr; 45226910Skarels if (addr->dmfl_ctrl & DMFL_OFFLINE) { 45326910Skarels #ifdef notdef 45426910Skarels log(LOG_WARNING, "dmf%d: line printer offline/jammed\n", 45526910Skarels dmf); 45626910Skarels #endif 45726312Skarels return (EIO); 45821955Sbloom } 45926910Skarels if ((addr->dmfl_ctrl & DMFL_CONV)) { 46026910Skarels log(LOG_WARNING, "dmf%d: line printer disconnected\n", dmf); 46126312Skarels return (EIO); 46221955Sbloom } 46321955Sbloom 46426910Skarels addr->dmfl_ctrl = 0; 46521955Sbloom sc->dmfl_state |= OPEN; 46626312Skarels return (0); 46721955Sbloom } 46821955Sbloom 46926312Skarels /* ARGSUSED */ 47026312Skarels dmflclose(dev, flag) 47126312Skarels dev_t dev; 47226312Skarels int flag; 47321955Sbloom { 47426910Skarels register int dmf = DMFL_UNIT(dev); 47521955Sbloom register struct dmfl_softc *sc = &dmfl_softc[dmf]; 47626910Skarels register struct uba_device *ui = dmfinfo[dmf]; 47721955Sbloom 47821955Sbloom sc->dmfl_state = 0; 47926312Skarels if (sc->dmfl_info != 0) 48026910Skarels ubarelse((int)ui->ui_ubanum, &sc->dmfl_info); 48121955Sbloom 48226910Skarels ((struct dmfdevice *)ui->ui_addr)->dmfl_ctrl = 0; 48321955Sbloom } 48421955Sbloom 48526312Skarels dmflwrite(dev, uio) 48626312Skarels dev_t dev; 48726312Skarels struct uio *uio; 48821955Sbloom { 48926366Skarels register int n; 49021955Sbloom register int error; 49121955Sbloom register struct dmfl_softc *sc; 49221955Sbloom 49321955Sbloom sc = &dmfl_softc[DMFL_UNIT(dev)]; 49426910Skarels if (sc->dmfl_state & ERROR) 49526910Skarels return (EIO); 49626910Skarels while (n = (unsigned)uio->uio_resid) { 49726910Skarels if (n > DMFL_BUFSIZ) { 49826910Skarels n = DMFL_BUFSIZ; 49926910Skarels sc->dmfl_state |= MOREIO; 50026910Skarels } else 50126910Skarels sc->dmfl_state &= ~MOREIO; 50237765Smckusick if (error = uiomove(sc->dmfl_buf, (int)n, uio)) 50326312Skarels return (error); 50426910Skarels if (error = dmflout(dev, sc->dmfl_buf, n)) 50526312Skarels return (error); 50621955Sbloom } 50726312Skarels return (0); 50821955Sbloom } 50921955Sbloom 51021955Sbloom 51126312Skarels /* 51226312Skarels * dmflout -- start io operation to dmf line printer 51321955Sbloom * cp is addr of buf of n chars to be sent. 51421955Sbloom * 51521955Sbloom * -- dmf will be put in formatted output mode, this will 51621955Sbloom * be selectable from an ioctl if the 51721955Sbloom * need ever arises. 51821955Sbloom */ 51926312Skarels dmflout(dev, cp, n) 52026312Skarels dev_t dev; 52126312Skarels char *cp; 52226312Skarels int n; 52321955Sbloom { 52421955Sbloom register struct dmfl_softc *sc; 52521955Sbloom register int dmf; 52621955Sbloom register struct uba_device *ui; 52721955Sbloom register struct dmfdevice *d; 52826910Skarels int s; 52921955Sbloom 53026312Skarels dmf = DMFL_UNIT(dev); 53126312Skarels sc = &dmfl_softc[dmf]; 53226312Skarels if (sc->dmfl_state & ERROR) 53326312Skarels return (EIO); 53426312Skarels ui = dmfinfo[dmf]; 53526312Skarels /* 53626312Skarels * allocate unibus resources, will be released when io 53726312Skarels * operation is done. 53821955Sbloom */ 53926910Skarels if (sc->dmfl_info == 0) 54026910Skarels sc->dmfl_info = uballoc(ui->ui_ubanum, cp, n, 0); 54126312Skarels d = (struct dmfdevice *)ui->ui_addr; 54226910Skarels d->dmfl_ctrl = sc->dmfl_format; /* indir reg 2 */ 54321955Sbloom /* indir reg auto increments on r/w */ 54421955Sbloom /* SO DON'T CHANGE THE ORDER OF THIS CODE */ 54526910Skarels d->dmfl_indrct = 0; /* prefix chars & num */ 54626910Skarels d->dmfl_indrct = 0; /* suffix chars & num */ 54726910Skarels d->dmfl_indrct = sc->dmfl_info; /* dma lo 16 bits addr */ 54826910Skarels d->dmfl_indrct = -n; /* number of chars */ 54921955Sbloom 55026910Skarels d->dmfl_indrct = ((sc->dmfl_info>>16)&3) | DMFL_OPTIONS; 55126910Skarels /* dma hi 2 bits addr */ 55226910Skarels d->dmfl_indrct = sc->dmfl_lines /* lines per page */ 55326910Skarels | (sc->dmfl_cols<<8); /* carriage width */ 55421955Sbloom sc->dmfl_state |= ASLP; 55526910Skarels s = spltty(); 55626910Skarels d->dmfl_ctrl |= DMFL_PEN | DMFL_IE; 55726312Skarels while (sc->dmfl_state & ASLP) { 55826910Skarels sleep(sc->dmfl_buf, PZERO + 8); 55926312Skarels while (sc->dmfl_state & ERROR) { 56026910Skarels timeout(dmflint, (caddr_t)dmf, 10 * hz); 56126910Skarels sleep((caddr_t)&sc->dmfl_state, PZERO + 8); 56221955Sbloom } 56321955Sbloom } 56426910Skarels splx(s); 56526312Skarels return (0); 56621955Sbloom } 56726312Skarels 56826312Skarels /* 56926312Skarels * dmflint -- handle an interrupt from the line printer part of the dmf32 57021955Sbloom */ 57121955Sbloom dmflint(dmf) 57226312Skarels int dmf; 57321955Sbloom { 57421955Sbloom register struct uba_device *ui; 57521955Sbloom register struct dmfl_softc *sc; 57621955Sbloom register struct dmfdevice *d; 57726910Skarels short dmfl_stats; 57821955Sbloom 57926312Skarels ui = dmfinfo[dmf]; 58026312Skarels sc = &dmfl_softc[dmf]; 58126312Skarels d = (struct dmfdevice *)ui->ui_addr; 58221955Sbloom 58326910Skarels d->dmfl_ctrl &= ~DMFL_IE; 58427057Skarels dmfl_stats = d->dmfl_ctrl; 58526312Skarels if (sc->dmfl_state & ERROR) { 58626910Skarels if ((dmfl_stats & DMFL_OFFLINE) == 0) 58721955Sbloom sc->dmfl_state &= ~ERROR; 58826366Skarels wakeup((caddr_t)&sc->dmfl_state); 58921955Sbloom return; 59021955Sbloom } 59126910Skarels if (dmfl_stats & DMFL_DMAERR) 59226910Skarels log(LOG_WARNING, "dmf%d: NXM\n", dmf); 59326910Skarels if (dmfl_stats & DMFL_OFFLINE) { 59426910Skarels log(LOG_WARNING, "dmf%d: printer error\n", dmf); 59521955Sbloom sc->dmfl_state |= ERROR; 59621955Sbloom } 59721955Sbloom #ifdef notdef 59826910Skarels if (dmfl_stats & DMFL_PDONE) { 59926910Skarels printf("bytes= %d\n", d->dmfl_indrct); 60026910Skarels printf("lines= %d\n", d->dmfl_indrct); 60126910Skarels } 60221955Sbloom #endif 60321955Sbloom sc->dmfl_state &= ~ASLP; 60426910Skarels wakeup((caddr_t)sc->dmfl_buf); 60526910Skarels if (sc->dmfl_info && (sc->dmfl_state & MOREIO) == 0) 60626312Skarels ubarelse(ui->ui_ubanum, &sc->dmfl_info); 60721955Sbloom } 60830537Skarels #endif NDMF_LP 60921955Sbloom 6106940Ssam /* stubs for interrupt routines for devices not yet supported */ 6116940Ssam 61226312Skarels dmfsrint() 61326312Skarels { 61426312Skarels printf("dmfsrint\n"); 61526312Skarels } 6166940Ssam 61726312Skarels dmfsxint() 61826312Skarels { 61926312Skarels printf("dmfsxint\n"); 62026312Skarels } 6216940Ssam 62226312Skarels dmfdaint() 62326312Skarels { 62426312Skarels printf("dmfdaint\n"); 62526312Skarels } 6266940Ssam 62726312Skarels dmfdbint() 62826312Skarels { 62926312Skarels printf("dmfdbint\n"); 63026312Skarels } 63126910Skarels #endif NDMF 632