1*23324Smckusick /* 2*23324Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23324Smckusick * All rights reserved. The Berkeley software License Agreement 4*23324Smckusick * specifies the terms and conditions for redistribution. 5*23324Smckusick * 6*23324Smckusick * @(#)dmf.c 6.8 (Berkeley) 06/08/85 7*23324Smckusick */ 86940Ssam 96940Ssam #include "dmf.h" 106940Ssam #if NDMF > 0 116940Ssam /* 126940Ssam * DMF32 driver 136940Ssam * 1421955Sbloom * 156940Ssam * TODO: 166940Ssam * test with modem 176940Ssam * load as much as possible into silo 186940Ssam * use auto XON/XOFF 196940Ssam * test reset code 2021955Sbloom **************************** 2121955Sbloom * DMF32 line printer driver 2221955Sbloom * 2321955Sbloom * the line printer on dmfx is indicated by a minor device code of 128+x 2421955Sbloom * 2521955Sbloom * the flags field of the config file is interpreted like so: 2621955Sbloom * bits meaning 2721955Sbloom * ---- ------- 2821955Sbloom * 0-7 soft carrier bits for ttys part of dmf32 2921955Sbloom * 8-15 number of cols/line on the line printer 3021955Sbloom * if 0, 132 will be used. 3121955Sbloom * 16-23 number of lines/page on the line printer 3221955Sbloom * if 0, 66 will be used. 3321955Sbloom * 346940Ssam */ 359772Ssam #include "../machine/pte.h" 369772Ssam 376940Ssam #include "bk.h" 3816063Skarels #include "uba.h" 3917124Sbloom #include "param.h" 4017124Sbloom #include "conf.h" 4117124Sbloom #include "dir.h" 4217124Sbloom #include "user.h" 4317124Sbloom #include "ioctl.h" 4417124Sbloom #include "tty.h" 4517124Sbloom #include "map.h" 4617124Sbloom #include "buf.h" 4717124Sbloom #include "vm.h" 4817124Sbloom #include "bkmac.h" 4917124Sbloom #include "clist.h" 5017124Sbloom #include "file.h" 5117124Sbloom #include "uio.h" 5221955Sbloom #include "kernel.h" 5318312Sralph #include "syslog.h" 546940Ssam 5517124Sbloom #include "ubareg.h" 5617124Sbloom #include "ubavar.h" 5717124Sbloom #include "dmfreg.h" 588473Sroot 596940Ssam /* 606940Ssam * Definition of the driver for the auto-configuration program. 616940Ssam */ 626940Ssam int dmfprobe(), dmfattach(), dmfrint(), dmfxint(); 6321955Sbloom int dmflint(); 646940Ssam struct uba_device *dmfinfo[NDMF]; 656940Ssam u_short dmfstd[] = { 0 }; 666940Ssam struct uba_driver dmfdriver = 676940Ssam { dmfprobe, 0, dmfattach, 0, dmfstd, "dmf", dmfinfo }; 686940Ssam 6921955Sbloom int dmf_timeout = 50; /* silo timeout, in ms */ 7021955Sbloom int dmf_mindma = 4; /* don't dma below this point */ 7121955Sbloom 726940Ssam /* 736940Ssam * Local variables for the driver 746940Ssam */ 756940Ssam char dmf_speeds[] = 766940Ssam { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0 }; 776940Ssam 786940Ssam struct tty dmf_tty[NDMF*8]; 796940Ssam char dmfsoftCAR[NDMF]; 8021955Sbloom 8121955Sbloom struct dmfl_softc 8221955Sbloom { 8321955Sbloom unsigned dmfl_state; /* soft state bits */ 8421955Sbloom unsigned dmfl_info; /* uba info */ 8521955Sbloom unsigned short dmfl_lines; /* lines per page (66 def.) */ 8621955Sbloom unsigned short dmfl_cols; /* cols per line (132 def.) */ 8721955Sbloom char dmfl_buf[DMFL_BUFSIZ]; 8821955Sbloom } dmfl_softc[NDMF]; 8921955Sbloom 9021955Sbloom /* 9121955Sbloom * convert device number into DMF line printer unit number 9221955Sbloom */ 9321955Sbloom #define DMFL_UNIT(d) (minor(d)&0xF) /* up to 16 DMFs */ 9421955Sbloom 9521955Sbloom #define ASLP 1 /* waiting for interrupt from dmf */ 9621955Sbloom #define OPEN 2 /* line printer is open */ 9721955Sbloom #define ERROR 4 /* error while printing, driver 9821955Sbloom refuses to do anything till closed */ 9921955Sbloom 1008778Sroot #ifndef lint 1018778Sroot int ndmf = NDMF*8; /* used by iostat */ 1028778Sroot #endif 1036940Ssam int dmfact; /* mask of active dmf's */ 1046940Ssam int dmfstart(), ttrstrt(); 1056940Ssam 1066940Ssam /* 1076940Ssam * The clist space is mapped by the driver onto each UNIBUS. 1086940Ssam * The UBACVT macro converts a clist space address for unibus uban 1096940Ssam * into an i/o space address for the DMA routine. 1106940Ssam */ 11116063Skarels int dmf_ubinfo[NUBA]; /* info about allocated unibus map */ 11216063Skarels static int cbase[NUBA]; /* base address in unibus map */ 1136940Ssam #define UBACVT(x, uban) (cbase[uban] + ((x)-(char *)cfree)) 11421955Sbloom char dmf_dma[NDMF*8]; 1156940Ssam 1166940Ssam /* 1176940Ssam * Routine for configuration to set dmf interrupt. 1186940Ssam */ 1196940Ssam /*ARGSUSED*/ 1206940Ssam dmfprobe(reg, ctlr) 1216940Ssam caddr_t reg; 12221955Sbloom struct uba_device *ctlr; 1236940Ssam { 1246940Ssam register int br, cvec; /* these are ``value-result'' */ 1256940Ssam register struct dmfdevice *dmfaddr = (struct dmfdevice *)reg; 12621955Sbloom register int i; 12721955Sbloom register unsigned int a; 12821955Sbloom static char *dmfdevs[]= 12921955Sbloom {"parallel","printer","synch","asynch"}; 13021955Sbloom unsigned int dmfoptions; 1316940Ssam 1326940Ssam #ifdef lint 1336940Ssam br = 0; cvec = br; br = cvec; 1348808Sroot dmfxint(0); dmfrint(0); 1358808Sroot dmfsrint(); dmfsxint(); dmfdaint(); dmfdbint(); dmflint(); 1366940Ssam #endif 13721955Sbloom /* 13821955Sbloom * Pick the usual size DMF vector here (don't decrement it here). 13921955Sbloom * grab configuration; note that the DMF32 14021955Sbloom * doesn't seem to put the right bits in this 14121955Sbloom * register until AFTER the interrupt vector is set. 14221955Sbloom */ 1436940Ssam br = 0x15; 14421955Sbloom cvec = (uba_hd[numuba].uh_lastiv - 4*8); 14521955Sbloom dmfaddr->dmfccsr0 = (cvec >> 2) ; 14621955Sbloom dmfoptions = dmfaddr->dmfccsr0 & DMFC_CONFMASK; 14721955Sbloom 14821955Sbloom /* catch a couple of special cases: Able vmz/32n and vmz/lp */ 14921955Sbloom if (dmfoptions == DMFC_ASYNC) { 15021955Sbloom /* Async portion only - vmz/32n */ 15121955Sbloom /* device dmf0 csr 0160400 vector dmfrint dmfxint */ 15221955Sbloom cvec = (uba_hd[numuba].uh_lastiv -= 8); /* only 8 bytes req'd */ 15321955Sbloom dmfaddr->dmfccsr0 = (cvec - 2*8) >> 2; /* program 020 less */ 15421955Sbloom printf("dmf%d: Able vmz32/n\n", ctlr->ui_unit); 15521955Sbloom } 15621955Sbloom else if (dmfoptions == DMFC_LP) { 15721955Sbloom /* LP portion only - vmz/lp */ 15821955Sbloom /* device dmf0 csr 0160400 vector dmflint */ 15921955Sbloom 16021955Sbloom cvec = (uba_hd[numuba].uh_lastiv -= 8); /* only 8 bytes req'd */ 16121955Sbloom dmfaddr->dmfccsr0 = (cvec - 3*8) >> 2; /* program 030 less */ 16221955Sbloom printf("dmf%d: Able vmz/lp\n", ctlr->ui_unit); 16321955Sbloom } 16421955Sbloom else { 16521955Sbloom /* anything else we program like a dec dmf32 */ 16621955Sbloom /* device dmf0 vector dmfsrint dmfsxint dmfdaint dmfdbint dmfrint dmfxint dmflint */ 16721955Sbloom 16821955Sbloom cvec = (uba_hd[numuba].uh_lastiv -= 4*8); 16921955Sbloom dmfaddr->dmfccsr0 = (cvec >> 2) ; 17021955Sbloom a = (dmfaddr->dmfccsr0>>12) & 0xf; 17121955Sbloom printf("dmf%d:", ctlr->ui_unit); 17221955Sbloom for(i=0;a != 0;++i,a >>= 1) { 17321955Sbloom if(a&1) 17421955Sbloom printf(" %s",dmfdevs[i]); 17521955Sbloom } 17621955Sbloom printf(".\n"); 17721955Sbloom } 17821955Sbloom 17921955Sbloom if (dmfoptions & DMFC_LP) 18021955Sbloom dmfaddr->dmfl[0] = DMFL_RESET; 1816940Ssam /* NEED TO SAVE IT SOMEWHERE FOR OTHER DEVICES */ 1827412Skre return (sizeof (struct dmfdevice)); 1836940Ssam } 1846940Ssam 1856940Ssam /* 1866940Ssam * Routine called to attach a dmf. 1876940Ssam */ 1886940Ssam dmfattach(ui) 1896940Ssam struct uba_device *ui; 1906940Ssam { 19121955Sbloom register int cols = (ui->ui_flags>>8) & 0xff; 19221955Sbloom register int lines = (ui->ui_flags>>16) & 0xff; 1936940Ssam 19421955Sbloom dmfsoftCAR[ui->ui_unit] = ui->ui_flags & 0xff; 19521955Sbloom dmfl_softc[ui->ui_unit].dmfl_cols = cols==0?DMFL_DEFCOLS:cols; 19621955Sbloom dmfl_softc[ui->ui_unit].dmfl_lines = lines==0?DMFL_DEFLINES:lines; 1976940Ssam } 1986940Ssam 1996940Ssam 2006940Ssam /* 2016940Ssam * Open a DMF32 line, mapping the clist onto the uba if this 2026940Ssam * is the first dmf on this uba. Turn on this dmf if this is 2036940Ssam * the first use of it. 2046940Ssam */ 2056940Ssam /*ARGSUSED*/ 2066940Ssam dmfopen(dev, flag) 2076940Ssam dev_t dev; 2086940Ssam { 2096940Ssam register struct tty *tp; 2106940Ssam register int unit, dmf; 2116940Ssam register struct dmfdevice *addr; 2126940Ssam register struct uba_device *ui; 2136940Ssam int s; 2146940Ssam 2156940Ssam unit = minor(dev); 21621955Sbloom if(unit & 0200) 21721955Sbloom return(dmflopen(dev,flag)); 2186940Ssam dmf = unit >> 3; 2198567Sroot if (unit >= NDMF*8 || (ui = dmfinfo[dmf])== 0 || ui->ui_alive == 0) 2208567Sroot return (ENXIO); 2216940Ssam tp = &dmf_tty[unit]; 2228567Sroot if (tp->t_state&TS_XCLUDE && u.u_uid!=0) 2238567Sroot return (EBUSY); 2246940Ssam addr = (struct dmfdevice *)ui->ui_addr; 2256940Ssam tp->t_addr = (caddr_t)addr; 2266940Ssam tp->t_oproc = dmfstart; 2276971Ssam tp->t_state |= TS_WOPEN; 2286940Ssam /* 2296940Ssam * While setting up state for this uba and this dmf, 2306940Ssam * block uba resets which can clear the state. 2316940Ssam */ 23221955Sbloom s = spltty(); 2336940Ssam if (dmf_ubinfo[ui->ui_ubanum] == 0) { 2346940Ssam dmf_ubinfo[ui->ui_ubanum] = 2356940Ssam uballoc(ui->ui_ubanum, (caddr_t)cfree, 2366940Ssam nclist*sizeof(struct cblock), 0); 2376940Ssam cbase[ui->ui_ubanum] = dmf_ubinfo[ui->ui_ubanum]&0x3ffff; 2386940Ssam } 2396940Ssam if ((dmfact&(1<<dmf)) == 0) { 2406940Ssam addr->dmfcsr |= DMF_IE; 2416940Ssam dmfact |= (1<<dmf); 24221955Sbloom addr->dmfrsp = dmf_timeout; 2436940Ssam } 2446940Ssam splx(s); 2456940Ssam /* 2466940Ssam * If this is first open, initialze tty state to default. 2476940Ssam */ 2486971Ssam if ((tp->t_state&TS_ISOPEN) == 0) { 2496940Ssam ttychars(tp); 2506940Ssam if (tp->t_ispeed == 0) { 2516940Ssam tp->t_ispeed = B300; 2526940Ssam tp->t_ospeed = B300; 2536940Ssam tp->t_flags = ODDP|EVENP|ECHO; 2546940Ssam } 2556940Ssam dmfparam(unit); 2566940Ssam } 2576940Ssam /* 2586940Ssam * Wait for carrier, then process line discipline specific open. 2596940Ssam */ 2606940Ssam if ((dmfmctl(dev, DMF_ON, DMSET) & (DMF_CAR<<8)) || 2616940Ssam (dmfsoftCAR[dmf] & (1<<(unit&07)))) 2626971Ssam tp->t_state |= TS_CARR_ON; 26321955Sbloom s = spltty(); 2646971Ssam while ((tp->t_state & TS_CARR_ON) == 0) { 2656971Ssam tp->t_state |= TS_WOPEN; 2666940Ssam sleep((caddr_t)&tp->t_rawq, TTIPRI); 2676940Ssam } 2686940Ssam splx(s); 2698567Sroot return ((*linesw[tp->t_line].l_open)(dev, tp)); 2706940Ssam } 2716940Ssam 2726940Ssam /* 2736940Ssam * Close a DMF32 line. 2746940Ssam */ 2756940Ssam /*ARGSUSED*/ 2766940Ssam dmfclose(dev, flag) 2776940Ssam dev_t dev; 2786940Ssam int flag; 2796940Ssam { 2806940Ssam register struct tty *tp; 2816940Ssam register unit; 2826940Ssam 2836940Ssam unit = minor(dev); 28421955Sbloom if(unit & 0200) 28521955Sbloom return(dmflclose(dev,flag)); 28621955Sbloom 2876940Ssam tp = &dmf_tty[unit]; 2886940Ssam (*linesw[tp->t_line].l_close)(tp); 2898702Sroot (void) dmfmctl(unit, DMF_BRK, DMBIC); 2906971Ssam if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0) 2918702Sroot (void) dmfmctl(unit, DMF_OFF, DMSET); 2926940Ssam ttyclose(tp); 2936940Ssam } 2946940Ssam 2957726Sroot dmfread(dev, uio) 2966940Ssam dev_t dev; 2977726Sroot struct uio *uio; 2986940Ssam { 2996940Ssam register struct tty *tp; 3006940Ssam 30121955Sbloom if(minor(dev)&0200) 30221955Sbloom return(ENXIO); 3036940Ssam tp = &dmf_tty[minor(dev)]; 3047726Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 3056940Ssam } 3066940Ssam 3077832Sroot dmfwrite(dev, uio) 3086940Ssam dev_t dev; 3097832Sroot struct uio *uio; 3106940Ssam { 3116940Ssam register struct tty *tp; 3126940Ssam 31321955Sbloom if(minor(dev)&0200) 31421955Sbloom return(dmflwrite(dev,uio)); 3156940Ssam tp = &dmf_tty[minor(dev)]; 3168530Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 3176940Ssam } 3186940Ssam 3196940Ssam /* 3206940Ssam * DMF32 receiver interrupt. 3216940Ssam */ 3226940Ssam dmfrint(dmf) 3236940Ssam int dmf; 3246940Ssam { 3256940Ssam register c; 3266940Ssam register struct dmfdevice *addr; 3276940Ssam register struct tty *tp0; 32821955Sbloom register dev; 32921955Sbloom int unit; 33012449Ssam int overrun = 0, s; 3316940Ssam 33221955Sbloom { 33321955Sbloom register struct uba_device *ui; 33421955Sbloom 33521955Sbloom ui = dmfinfo[dmf]; 33621955Sbloom if (ui == 0 || ui->ui_alive == 0) 33721955Sbloom return; 33821955Sbloom addr = (struct dmfdevice *)ui->ui_addr; 33921955Sbloom } 34021955Sbloom tp0 = &dmf_tty[dmf * 8]; 3416940Ssam /* 3426940Ssam * Loop fetching characters from the silo for this 3436940Ssam * dmf until there are no more in the silo. 3446940Ssam */ 3456940Ssam while ((c = addr->dmfrbuf) < 0) { 34621955Sbloom register struct tty *tp; 34721955Sbloom 34821955Sbloom unit = (c >> 8) & 07; 34921955Sbloom tp = tp0 + unit; 35021955Sbloom dev = unit + dmf * 8; 3516940Ssam if (c & DMF_DSC) { 35221955Sbloom s = spltty(); 35321955Sbloom addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 3546940Ssam if (addr->dmfrms & DMF_CAR) { 3556971Ssam if ((tp->t_state & TS_CARR_ON) == 0) { 3566940Ssam wakeup((caddr_t)&tp->t_rawq); 3576971Ssam tp->t_state |= TS_CARR_ON; 35821956Sbloom } else if ((tp->t_flags & MDMBUF) && 35921956Sbloom (tp->t_state & TS_TTSTOP)) { 36021956Sbloom tp->t_state &= ~TS_TTSTOP; 36121956Sbloom ttstart(tp); 3626940Ssam } 36321956Sbloom } else if ((tp->t_state & TS_WOPEN) == 0 && 36421956Sbloom tp->t_flags & MDMBUF) { 36521956Sbloom if ((tp->t_state & TS_TTSTOP) == 0) { 36621956Sbloom tp->t_state |= TS_TTSTOP; 36721956Sbloom dmfstop(tp, 0); 36821956Sbloom } 36921956Sbloom } else if ((tp->t_state & TS_CARR_ON) && 37021956Sbloom (tp->t_flags & NOHANG) == 0 && 37121956Sbloom (dmfsoftCAR[dmf] & (1<<unit)) == 0) { 37221956Sbloom if (tp->t_state&TS_ISOPEN) { 3736940Ssam gsignal(tp->t_pgrp, SIGHUP); 3746940Ssam gsignal(tp->t_pgrp, SIGCONT); 3756940Ssam addr->dmfcsr = DMF_IE | DMFIR_LCR | 37621955Sbloom unit; 3776940Ssam addr->dmftms = 0; 37812776Ssam ttyflush(tp, FREAD|FWRITE); 3796940Ssam } 3806971Ssam tp->t_state &= ~TS_CARR_ON; 3816940Ssam } 38212449Ssam splx(s); 3836940Ssam continue; 3846940Ssam } 3856971Ssam if ((tp->t_state&TS_ISOPEN)==0) { 3866940Ssam wakeup((caddr_t)tp); 3876940Ssam continue; 3886940Ssam } 38921956Sbloom if (c & (DMF_PE|DMF_DO|DMF_FE)) { 39021955Sbloom if (c & DMF_PE) 39121955Sbloom if ((tp->t_flags&(EVENP|ODDP))==EVENP 39221955Sbloom || (tp->t_flags&(EVENP|ODDP))==ODDP ) 39321955Sbloom continue; 39421955Sbloom if ((c & DMF_DO) && overrun == 0) { 39521955Sbloom log(KERN_RECOV, "dmf%d: silo overflow\n", dmf); 39621955Sbloom overrun = 1; 39721955Sbloom } 39821955Sbloom if (c & DMF_FE) 39921955Sbloom /* 40021955Sbloom * At framing error (break) generate 40121955Sbloom * a null (in raw mode, for getty), or a 40221955Sbloom * interrupt (in cooked/cbreak mode). 40321955Sbloom */ 40421955Sbloom if (tp->t_flags&RAW) 40521955Sbloom c = 0; 40621955Sbloom else 40721955Sbloom c = tp->t_intrc; 4086940Ssam } 4096940Ssam #if NBK > 0 4106940Ssam if (tp->t_line == NETLDISC) { 4116940Ssam c &= 0177; 4126940Ssam BKINPUT(c, tp); 4136940Ssam } else 4146940Ssam #endif 4156940Ssam (*linesw[tp->t_line].l_rint)(c, tp); 4166940Ssam } 4176940Ssam } 4186940Ssam 4196940Ssam /* 4206940Ssam * Ioctl for DMF32. 4216940Ssam */ 4226940Ssam /*ARGSUSED*/ 4237630Ssam dmfioctl(dev, cmd, data, flag) 4246940Ssam dev_t dev; 4257630Ssam caddr_t data; 4266940Ssam { 4276940Ssam register struct tty *tp; 4286940Ssam register int unit = minor(dev); 4298567Sroot int error; 4306940Ssam 43121955Sbloom if(unit & 0200) 43221955Sbloom return (ENOTTY); 4336940Ssam tp = &dmf_tty[unit]; 4348567Sroot error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 4358567Sroot if (error >= 0) 4368567Sroot return (error); 4378567Sroot error = ttioctl(tp, cmd, data, flag); 4388567Sroot if (error >= 0) { 43917562Sbloom if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLBIS || 44017562Sbloom cmd == TIOCLBIC || cmd == TIOCLSET) 4416940Ssam dmfparam(unit); 4428567Sroot return (error); 4438567Sroot } 4448567Sroot switch (cmd) { 4456940Ssam 4466940Ssam case TIOCSBRK: 4478702Sroot (void) dmfmctl(dev, DMF_BRK, DMBIS); 4486940Ssam break; 4497630Ssam 4506940Ssam case TIOCCBRK: 4518702Sroot (void) dmfmctl(dev, DMF_BRK, DMBIC); 4526940Ssam break; 4537630Ssam 4546940Ssam case TIOCSDTR: 4558702Sroot (void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIS); 4566940Ssam break; 4577630Ssam 4586940Ssam case TIOCCDTR: 4598702Sroot (void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIC); 4606940Ssam break; 4617630Ssam 4626940Ssam case TIOCMSET: 4638702Sroot (void) dmfmctl(dev, dmtodmf(*(int *)data), DMSET); 4646940Ssam break; 4657630Ssam 4666940Ssam case TIOCMBIS: 4678702Sroot (void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIS); 4686940Ssam break; 4697630Ssam 4706940Ssam case TIOCMBIC: 4718702Sroot (void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIC); 4726940Ssam break; 4737630Ssam 4746940Ssam case TIOCMGET: 4757630Ssam *(int *)data = dmftodm(dmfmctl(dev, 0, DMGET)); 4766940Ssam break; 4777630Ssam 4786940Ssam default: 4798567Sroot return (ENOTTY); 4806940Ssam } 4818567Sroot return (0); 4826940Ssam } 4836940Ssam 4846940Ssam dmtodmf(bits) 4856940Ssam register int bits; 4866940Ssam { 4876940Ssam register int b; 4886940Ssam 4896940Ssam b = bits & 012; 4906940Ssam if (bits & DML_ST) b |= DMF_RATE; 4916940Ssam if (bits & DML_RTS) b |= DMF_RTS; 4926940Ssam if (bits & DML_USR) b |= DMF_USRW; 4936940Ssam return(b); 4946940Ssam } 4956940Ssam 4966940Ssam dmftodm(bits) 4976940Ssam register int bits; 4986940Ssam { 4996940Ssam register int b; 5006940Ssam 5016940Ssam b = (bits & 012) | ((bits >> 7) & 0760) | DML_LE; 5026940Ssam if (bits & DMF_USRR) b |= DML_USR; 5036940Ssam if (bits & DMF_RTS) b |= DML_RTS; 5046940Ssam return(b); 5056940Ssam } 5066940Ssam 5076940Ssam 5086940Ssam /* 5096940Ssam * Set parameters from open or stty into the DMF hardware 5106940Ssam * registers. 5116940Ssam */ 5126940Ssam dmfparam(unit) 5136940Ssam register int unit; 5146940Ssam { 5156940Ssam register struct tty *tp; 5166940Ssam register struct dmfdevice *addr; 5176940Ssam register int lpar, lcr; 5186940Ssam int s; 5196940Ssam 5206940Ssam tp = &dmf_tty[unit]; 5216940Ssam addr = (struct dmfdevice *)tp->t_addr; 5226940Ssam /* 5236940Ssam * Block interrupts so parameters will be set 5246940Ssam * before the line interrupts. 5256940Ssam */ 52621955Sbloom s = spltty(); 5276940Ssam addr->dmfcsr = (unit&07) | DMFIR_LCR | DMF_IE; 5286940Ssam if ((tp->t_ispeed)==0) { 5296971Ssam tp->t_state |= TS_HUPCLS; 5308702Sroot (void) dmfmctl(unit, DMF_OFF, DMSET); 5316940Ssam return; 5326940Ssam } 5336940Ssam lpar = (dmf_speeds[tp->t_ospeed]<<12) | (dmf_speeds[tp->t_ispeed]<<8); 5346940Ssam lcr = DMFLCR_ENA; 5356940Ssam if ((tp->t_ispeed) == B134) 5366940Ssam lpar |= BITS6|PENABLE; 5379550Ssam else if (tp->t_flags & (RAW|LITOUT)) 5386940Ssam lpar |= BITS8; 5396940Ssam else { 5406940Ssam lpar |= BITS7|PENABLE; 5416940Ssam /* CHECK FOR XON/XOFF AND SET lcr |= DMF_AUTOX; */ 5426940Ssam } 54312450Ssam if (tp->t_flags&EVENP) 54412450Ssam lpar |= EPAR; 5456940Ssam if ((tp->t_ospeed) == B110) 5466940Ssam lpar |= TWOSB; 5476940Ssam lpar |= (unit&07); 5486940Ssam addr->dmflpr = lpar; 54912449Ssam SETLCR(addr, lcr); 5506940Ssam splx(s); 5516940Ssam } 5526940Ssam 5536940Ssam /* 5546940Ssam * DMF32 transmitter interrupt. 5556940Ssam * Restart the idle line. 5566940Ssam */ 5576940Ssam dmfxint(dmf) 5586940Ssam int dmf; 5596940Ssam { 56021955Sbloom int u = dmf * 8; 56121955Sbloom struct tty *tp0 = &dmf_tty[u]; 5626940Ssam register struct tty *tp; 5636940Ssam register struct dmfdevice *addr; 5646940Ssam register struct uba_device *ui; 56521955Sbloom register int t; 5666940Ssam short cntr; 5676940Ssam 5686940Ssam ui = dmfinfo[dmf]; 5696940Ssam addr = (struct dmfdevice *)ui->ui_addr; 5706940Ssam while ((t = addr->dmfcsr) & DMF_TI) { 57121955Sbloom if (t & DMF_NXM) 57221955Sbloom /* SHOULD RESTART OR SOMETHING... */ 57321955Sbloom printf("dmf%d: NXM line %d\n", dmf, t >> 8 & 7); 57421955Sbloom t = t >> 8 & 7; 57521955Sbloom tp = tp0 + t; 5766971Ssam tp->t_state &= ~TS_BUSY; 5776971Ssam if (tp->t_state&TS_FLUSH) 5786971Ssam tp->t_state &= ~TS_FLUSH; 57921955Sbloom else if (dmf_dma[u + t]) { 58021955Sbloom /* 58121955Sbloom * Do arithmetic in a short to make up 58221955Sbloom * for lost 16&17 bits. 58321955Sbloom */ 58421955Sbloom addr->dmfcsr = DMFIR_TBA | DMF_IE | t; 58521955Sbloom cntr = addr->dmftba - 58621955Sbloom UBACVT(tp->t_outq.c_cf, ui->ui_ubanum); 58721955Sbloom ndflush(&tp->t_outq, (int)cntr); 5886940Ssam } 5896940Ssam if (tp->t_line) 5906940Ssam (*linesw[tp->t_line].l_start)(tp); 5916940Ssam else 5926940Ssam dmfstart(tp); 5936940Ssam } 5946940Ssam } 5956940Ssam 5966940Ssam /* 5976940Ssam * Start (restart) transmission on the given DMF32 line. 5986940Ssam */ 5996940Ssam dmfstart(tp) 6006940Ssam register struct tty *tp; 6016940Ssam { 6026940Ssam register struct dmfdevice *addr; 6038607Sroot register int unit, nch; 6046940Ssam int s; 60521955Sbloom register int dmf; 6066940Ssam 6076940Ssam unit = minor(tp->t_dev); 60821955Sbloom dmf = unit >> 3; 6096940Ssam unit &= 07; 6106940Ssam addr = (struct dmfdevice *)tp->t_addr; 6116940Ssam 6126940Ssam /* 6136940Ssam * Must hold interrupts in following code to prevent 6146940Ssam * state of the tp from changing. 6156940Ssam */ 61621955Sbloom s = spltty(); 6176940Ssam /* 6186940Ssam * If it's currently active, or delaying, no need to do anything. 6196940Ssam */ 6206971Ssam if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 6216940Ssam goto out; 6226940Ssam /* 6236940Ssam * If there are still characters in the silo, 6246940Ssam * just reenable the transmitter. 6256940Ssam */ 6266940Ssam addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 6276940Ssam if (addr->dmftsc) { 6286940Ssam addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 62912449Ssam SETLCR(addr, addr->dmflcr|DMF_TE); 6306971Ssam tp->t_state |= TS_BUSY; 6316940Ssam goto out; 6326940Ssam } 6336940Ssam /* 6346940Ssam * If there are sleepers, and output has drained below low 6356940Ssam * water mark, wake up the sleepers. 6366940Ssam */ 63721955Sbloom if (tp->t_outq.c_cc<=TTLOWAT(tp)) { 63821955Sbloom if (tp->t_state&TS_ASLEEP) { 63921955Sbloom tp->t_state &= ~TS_ASLEEP; 64021955Sbloom wakeup((caddr_t)&tp->t_outq); 64121955Sbloom } 64221955Sbloom if (tp->t_wsel) { 64321955Sbloom selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 64421955Sbloom tp->t_wsel = 0; 64521955Sbloom tp->t_state &= ~TS_WCOLL; 64621955Sbloom } 6476940Ssam } 6486940Ssam /* 6496940Ssam * Now restart transmission unless the output queue is 6506940Ssam * empty. 6516940Ssam */ 6526940Ssam if (tp->t_outq.c_cc == 0) 6536940Ssam goto out; 6549550Ssam if (tp->t_flags & (RAW|LITOUT)) 6556940Ssam nch = ndqb(&tp->t_outq, 0); 6566940Ssam else { 65721955Sbloom if ((nch = ndqb(&tp->t_outq, 0200)) == 0) { 65821955Sbloom /* 65921955Sbloom * If first thing on queue is a delay process it. 66021955Sbloom */ 6616940Ssam nch = getc(&tp->t_outq); 6626940Ssam timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6); 6636971Ssam tp->t_state |= TS_TIMEOUT; 6646940Ssam goto out; 6656940Ssam } 6666940Ssam } 6676940Ssam /* 6686940Ssam * If characters to transmit, restart transmission. 6696940Ssam */ 67021955Sbloom if (nch >= dmf_mindma) { 67121955Sbloom register car; 67221955Sbloom 67321955Sbloom dmf_dma[minor(tp->t_dev)] = 1; 6746940Ssam addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 67512449Ssam SETLCR(addr, addr->dmflcr|DMF_TE); 6766940Ssam car = UBACVT(tp->t_outq.c_cf, dmfinfo[dmf]->ui_ubanum); 6776940Ssam addr->dmfcsr = DMF_IE | DMFIR_TBA | unit; 6786940Ssam addr->dmftba = car; 67921955Sbloom addr->dmftcc = ((car >> 2) & 0xc000) | nch; 68021955Sbloom tp->t_state |= TS_BUSY; 68121955Sbloom } else if (nch) { 6826940Ssam register char *cp = tp->t_outq.c_cf; 6836940Ssam register int i; 6846940Ssam 68521955Sbloom dmf_dma[minor(tp->t_dev)] = 0; 6866940Ssam nch = MIN(nch, DMF_SILOCNT); 6876940Ssam addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 68812449Ssam SETLCR(addr, addr->dmflcr|DMF_TE); 6896940Ssam addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 6906940Ssam for (i = 0; i < nch; i++) 6916940Ssam addr->dmftbuf = *cp++; 6926940Ssam ndflush(&tp->t_outq, nch); 6936971Ssam tp->t_state |= TS_BUSY; 6946940Ssam } 6956940Ssam out: 6966940Ssam splx(s); 6976940Ssam } 6986940Ssam 6996940Ssam /* 7006940Ssam * Stop output on a line, e.g. for ^S/^Q or output flush. 7016940Ssam */ 7026940Ssam /*ARGSUSED*/ 7036940Ssam dmfstop(tp, flag) 7046940Ssam register struct tty *tp; 7056940Ssam { 7066940Ssam register struct dmfdevice *addr; 70721955Sbloom register unit = minor(tp->t_dev) & 7; 70821955Sbloom int s; 7096940Ssam 7106940Ssam addr = (struct dmfdevice *)tp->t_addr; 7116940Ssam /* 7126940Ssam * Block input/output interrupts while messing with state. 7136940Ssam */ 71421955Sbloom s = spltty(); 71521955Sbloom if (flag) { 71621955Sbloom addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 71721955Sbloom if (addr->dmftsc) { 71821955Sbloom /* 71921955Sbloom * Flush regardless of whether we're transmitting 72021955Sbloom * (TS_BUSY), if the silo contains untransmitted 72121955Sbloom * characters. 72221955Sbloom */ 72321955Sbloom addr->dmfcsr = DMFIR_LCR | unit | DMF_IE; 72421955Sbloom SETLCR(addr, addr->dmflcr | DMF_TE | DMF_FLUSH); 72521955Sbloom /* this will interrupt so let dmfxint handle the rest */ 72621955Sbloom tp->t_state |= TS_FLUSH|TS_BUSY; 72721955Sbloom } 72821955Sbloom } else { 72921955Sbloom if (tp->t_state & TS_BUSY) { 73021955Sbloom /* 73121955Sbloom * Stop transmission by disabling 73221955Sbloom * the transmitter. We'll pick up where we 73321955Sbloom * left off by reenabling in dmfstart. 73421955Sbloom */ 73521955Sbloom addr->dmfcsr = DMFIR_LCR | unit | DMF_IE; 73621955Sbloom SETLCR(addr, addr->dmflcr &~ DMF_TE); 73721955Sbloom /* no interrupt here */ 7386971Ssam tp->t_state &= ~TS_BUSY; 73921955Sbloom } 7406940Ssam } 7416940Ssam splx(s); 7426940Ssam } 7436940Ssam 7446940Ssam /* 7456940Ssam * DMF32 modem control 7466940Ssam */ 7476940Ssam dmfmctl(dev, bits, how) 7486940Ssam dev_t dev; 7496940Ssam int bits, how; 7506940Ssam { 7516940Ssam register struct dmfdevice *dmfaddr; 7526940Ssam register int unit, mbits, lcr; 7536940Ssam int s; 7546940Ssam 7556940Ssam unit = minor(dev); 7566940Ssam dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr); 7576940Ssam unit &= 07; 75821955Sbloom s = spltty(); 7596940Ssam dmfaddr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 7606940Ssam mbits = dmfaddr->dmfrms << 8; 7616940Ssam dmfaddr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 7626940Ssam mbits |= dmfaddr->dmftms; 7636940Ssam lcr = dmfaddr->dmflcr; 7646940Ssam switch (how) { 7656940Ssam case DMSET: 76612449Ssam mbits = (mbits &0xff00) | bits; 7676940Ssam break; 7686940Ssam 7696940Ssam case DMBIS: 7706940Ssam mbits |= bits; 7716940Ssam break; 7726940Ssam 7736940Ssam case DMBIC: 7746940Ssam mbits &= ~bits; 7756940Ssam break; 7766940Ssam 7776940Ssam case DMGET: 7786940Ssam (void) splx(s); 7796940Ssam return(mbits); 7806940Ssam } 7816940Ssam if (mbits & DMF_BRK) 7826940Ssam lcr |= DMF_RBRK; 7836940Ssam else 7846940Ssam lcr &= ~DMF_RBRK; 78512449Ssam lcr = ((mbits & 037) << 8) | (lcr & 0xff); 78612449Ssam dmfaddr->dmfun.dmfirw = lcr; 7876940Ssam (void) splx(s); 7886940Ssam return(mbits); 7896940Ssam } 7906940Ssam 7916940Ssam /* 7926940Ssam * Reset state of driver if UBA reset was necessary. 7936940Ssam * Reset the csr, lpr, and lcr registers on open lines, and 7946940Ssam * restart transmitters. 7956940Ssam */ 7966940Ssam dmfreset(uban) 7976940Ssam int uban; 7986940Ssam { 7996940Ssam register int dmf, unit; 8006940Ssam register struct tty *tp; 8016940Ssam register struct uba_device *ui; 8026940Ssam register struct dmfdevice *addr; 8036940Ssam int i; 8046940Ssam 8056940Ssam if (dmf_ubinfo[uban] == 0) 8066940Ssam return; 8076940Ssam dmf_ubinfo[uban] = uballoc(uban, (caddr_t)cfree, 8086940Ssam nclist*sizeof (struct cblock), 0); 8096940Ssam cbase[uban] = dmf_ubinfo[uban]&0x3ffff; 8106940Ssam for (dmf = 0; dmf < NDMF; dmf++) { 8116940Ssam ui = dmfinfo[dmf]; 8126940Ssam if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) 8136940Ssam continue; 8146940Ssam printf(" dmf%d", dmf); 8156940Ssam addr = (struct dmfdevice *)ui->ui_addr; 8166940Ssam addr->dmfcsr = DMF_IE; 81721955Sbloom addr->dmfrsp = dmf_timeout; 8186940Ssam unit = dmf * 8; 8196940Ssam for (i = 0; i < 8; i++) { 8206940Ssam tp = &dmf_tty[unit]; 8216971Ssam if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 8226940Ssam dmfparam(unit); 8238702Sroot (void) dmfmctl(unit, DMF_ON, DMSET); 8246971Ssam tp->t_state &= ~TS_BUSY; 8256940Ssam dmfstart(tp); 8266940Ssam } 8276940Ssam unit++; 8286940Ssam } 8296940Ssam } 8306940Ssam } 8316940Ssam 83221955Sbloom /* dmflopen -- open the line printer port on a dmf32 83321955Sbloom * 83421955Sbloom */ 83521955Sbloom dmflopen(dev,flag) 83621955Sbloom dev_t dev; 83721955Sbloom int flag; 83821955Sbloom { 83921955Sbloom register int dmf; 84021955Sbloom register struct dmfl_softc *sc; 84121955Sbloom register struct uba_device *ui; 84221955Sbloom register struct dmfdevice *addr; 84321955Sbloom 84421955Sbloom 84521955Sbloom dmf = DMFL_UNIT(dev) ; 84621955Sbloom if(((sc= &dmfl_softc[dmf])->dmfl_state & OPEN) || 84721955Sbloom ((ui=dmfinfo[dmf]) == 0) || ui->ui_alive == 0) 84821955Sbloom return(ENXIO); 84921955Sbloom addr = (struct dmfdevice *)ui->ui_addr; 85021955Sbloom if((addr->dmfl[0] & DMFL_OFFLINE)) 85121955Sbloom { 85221955Sbloom /*printf("dmf: line printer offline/jammed\n");*/ 85321955Sbloom return(EIO); 85421955Sbloom } 85521955Sbloom if((addr->dmfl[0]&DMFL_CONV)) 85621955Sbloom { 85721955Sbloom printf("dmf:line printer disconnected\n"); 85821955Sbloom return(EIO); 85921955Sbloom } 86021955Sbloom 86121955Sbloom addr->dmfl[0] = 0; 86221955Sbloom sc->dmfl_state |= OPEN; 86321955Sbloom return 0; 86421955Sbloom } 86521955Sbloom 86621955Sbloom dmflclose(dev,flag) 86721955Sbloom dev_t dev; 86821955Sbloom int flag; 86921955Sbloom { 87021955Sbloom register int dmf= DMFL_UNIT(dev); 87121955Sbloom register struct dmfl_softc *sc = &dmfl_softc[dmf]; 87221955Sbloom 87321955Sbloom dmflout(dev,"\f",1); 87421955Sbloom sc->dmfl_state = 0; 87521955Sbloom if(sc->dmfl_info != 0) 87621955Sbloom ubarelse((struct dmfdevice *)(dmfinfo[dmf])->ui_ubanum, 87721955Sbloom &(sc->dmfl_info)); 87821955Sbloom 87921955Sbloom ((struct dmfdevice *)(dmfinfo[dmf]->ui_addr))->dmfl[0]=0; 88021955Sbloom return 0; 88121955Sbloom } 88221955Sbloom 88321955Sbloom dmflwrite(dev,uio) 88421955Sbloom dev_t dev; 88521955Sbloom struct uio *uio; 88621955Sbloom { 88721955Sbloom register unsigned int n; 88821955Sbloom register int error; 88921955Sbloom register struct dmfl_softc *sc; 89021955Sbloom 89121955Sbloom sc = &dmfl_softc[DMFL_UNIT(dev)]; 89221955Sbloom if(sc->dmfl_state&ERROR) return(EIO); 89321955Sbloom while(n=min(DMFL_BUFSIZ,(unsigned)uio->uio_resid)) 89421955Sbloom { 89521955Sbloom if(error=uiomove(&sc->dmfl_buf[0],(int)n, 89621955Sbloom UIO_WRITE,uio)) 89721955Sbloom { 89821955Sbloom printf("uio move error\n"); 89921955Sbloom return(error); 90021955Sbloom } 90121955Sbloom if(error=dmflout(dev,&sc->dmfl_buf[0],n)) 90221955Sbloom { 90321955Sbloom return(error); 90421955Sbloom } 90521955Sbloom } 90621955Sbloom return 0; 90721955Sbloom } 90821955Sbloom 90921955Sbloom 91021955Sbloom /* dmflout -- start io operation to dmf line printer 91121955Sbloom * cp is addr of buf of n chars to be sent. 91221955Sbloom * 91321955Sbloom * -- dmf will be put in formatted output mode, this will 91421955Sbloom * be selectable from an ioctl if the 91521955Sbloom * need ever arises. 91621955Sbloom */ 91721955Sbloom dmflout(dev,cp,n) 91821955Sbloom dev_t dev; 91921955Sbloom char *cp; 92021955Sbloom int n; 92121955Sbloom { 92221955Sbloom register struct dmfl_softc *sc; 92321955Sbloom register int dmf; 92421955Sbloom register struct uba_device *ui; 92521955Sbloom register struct dmfdevice *d; 92621955Sbloom register unsigned info; 92721955Sbloom register unsigned i; 92821955Sbloom 92921955Sbloom dmf = DMFL_UNIT(dev) ; 93021955Sbloom sc= &dmfl_softc[dmf]; 93121955Sbloom if(sc->dmfl_state&ERROR) return(EIO); 93221955Sbloom ui= dmfinfo[dmf]; 93321955Sbloom /* allocate unibus resources, will be released when io 93421955Sbloom * operation is done 93521955Sbloom */ 93621955Sbloom sc->dmfl_info= 93721955Sbloom info= 93821955Sbloom uballoc(ui->ui_ubanum,cp,n,0); 93921955Sbloom d= (struct dmfdevice *)ui->ui_addr; 94021955Sbloom d->dmfl[0] = (2<<8) | DMFL_FORMAT; /* indir reg 2 */ 94121955Sbloom /* indir reg auto increments on r/w */ 94221955Sbloom /* SO DON'T CHANGE THE ORDER OF THIS CODE */ 94321955Sbloom d->dmfl[1] = 0; /* prefix chars & num */ 94421955Sbloom d->dmfl[1] = 0; /* suffix chars & num */ 94521955Sbloom d->dmfl[1] = info; /* dma lo 16 bits addr */ 94621955Sbloom 94721955Sbloom /* NOT DOCUMENTED !! */ 94821955Sbloom d->dmfl[1] = -n; /* number of chars */ 94921955Sbloom /* ----------^-------- */ 95021955Sbloom 95121955Sbloom d->dmfl[1] = ((info>>16)&3) /* dma hi 2 bits addr */ 95221955Sbloom | (1<<8) /* auto cr insert */ 95321955Sbloom | (1<<9) /* use real ff */ 95421955Sbloom | (1<<15); /* no u/l conversion */ 95521955Sbloom d->dmfl[1] = sc->dmfl_lines /* lines per page */ 95621955Sbloom | (sc->dmfl_cols<<8); /* carriage width */ 95721955Sbloom sc->dmfl_state |= ASLP; 95821955Sbloom i=spltty(); 95921955Sbloom d->dmfl[0] |= DMFL_PEN|DMFL_IE; 96021955Sbloom while(sc->dmfl_state & ASLP) 96121955Sbloom { 96221955Sbloom sleep(&sc->dmfl_buf[0],(PZERO+8)); 96321955Sbloom while(sc->dmfl_state&ERROR) 96421955Sbloom { 96521955Sbloom timeout(dmflint,dmf,10*hz); 96621955Sbloom sleep(&sc->dmfl_state,(PZERO+8)); 96721955Sbloom } 96821955Sbloom /*if(sc->dmfl_state&ERROR) return (EIO);*/ 96921955Sbloom } 97021955Sbloom splx(i); 97121955Sbloom return(0); 97221955Sbloom } 97321955Sbloom /* dmflint -- handle an interrupt from the line printer part of the dmf32 97421955Sbloom * 97521955Sbloom */ 97621955Sbloom 97721955Sbloom dmflint(dmf) 97821955Sbloom int dmf; 97921955Sbloom { 98021955Sbloom 98121955Sbloom register struct uba_device *ui; 98221955Sbloom register struct dmfl_softc *sc; 98321955Sbloom register struct dmfdevice *d; 98421955Sbloom 98521955Sbloom ui= dmfinfo[dmf]; 98621955Sbloom sc= &dmfl_softc[dmf]; 98721955Sbloom d= (struct dmfdevice *)ui->ui_addr; 98821955Sbloom 98921955Sbloom d->dmfl[0] &= ~DMFL_IE; 99021955Sbloom 99121955Sbloom if(sc->dmfl_state&ERROR) 99221955Sbloom { 99321955Sbloom printf("dmfl: intr while in error state \n"); 99421955Sbloom if((d->dmfl[0]&DMFL_OFFLINE) == 0) 99521955Sbloom sc->dmfl_state &= ~ERROR; 99621955Sbloom wakeup(&sc->dmfl_state); 99721955Sbloom return; 99821955Sbloom } 99921955Sbloom if(d->dmfl[0]&DMFL_DMAERR) 100021955Sbloom { 100121955Sbloom printf("dmf:NXM\n"); 100221955Sbloom } 100321955Sbloom if(d->dmfl[0]&DMFL_OFFLINE) 100421955Sbloom { 100521955Sbloom printf("dmf:printer error\n"); 100621955Sbloom sc->dmfl_state |= ERROR; 100721955Sbloom } 100821955Sbloom if(d->dmfl[0]&DMFL_PDONE) 100921955Sbloom { 101021955Sbloom #ifdef notdef 101121955Sbloom printf("bytes= %d\n",d->dmfl[1]); 101221955Sbloom printf("lines= %d\n",d->dmfl[1]); 101321955Sbloom #endif 101421955Sbloom } 101521955Sbloom sc->dmfl_state &= ~ASLP; 101621955Sbloom wakeup(&sc->dmfl_buf[0]); 101721955Sbloom if(sc->dmfl_info != 0) 101821955Sbloom ubarelse(ui->ui_ubanum,&sc->dmfl_info); 101921955Sbloom sc->dmfl_info = 0; 102021955Sbloom 102121955Sbloom } 102221955Sbloom 10236940Ssam /* stubs for interrupt routines for devices not yet supported */ 10246940Ssam 10256940Ssam dmfsrint() { printf("dmfsrint\n"); } 10266940Ssam 10276940Ssam dmfsxint() { printf("dmfsxint\n"); } 10286940Ssam 10296940Ssam dmfdaint() { printf("dmfdaint\n"); } 10306940Ssam 10316940Ssam dmfdbint() { printf("dmfdbint\n"); } 10326940Ssam 103321955Sbloom 10346940Ssam #endif 1035