1*21955Sbloom /* dmf.c 6.6 85/06/04 */ 26940Ssam 36940Ssam #include "dmf.h" 46940Ssam #if NDMF > 0 56940Ssam /* 66940Ssam * DMF32 driver 76940Ssam * 8*21955Sbloom * 96940Ssam * TODO: 106940Ssam * test with modem 116940Ssam * load as much as possible into silo 126940Ssam * use auto XON/XOFF 136940Ssam * test reset code 14*21955Sbloom **************************** 15*21955Sbloom * DMF32 line printer driver 16*21955Sbloom * 17*21955Sbloom * the line printer on dmfx is indicated by a minor device code of 128+x 18*21955Sbloom * 19*21955Sbloom * the flags field of the config file is interpreted like so: 20*21955Sbloom * bits meaning 21*21955Sbloom * ---- ------- 22*21955Sbloom * 0-7 soft carrier bits for ttys part of dmf32 23*21955Sbloom * 8-15 number of cols/line on the line printer 24*21955Sbloom * if 0, 132 will be used. 25*21955Sbloom * 16-23 number of lines/page on the line printer 26*21955Sbloom * if 0, 66 will be used. 27*21955Sbloom * 286940Ssam */ 299772Ssam #include "../machine/pte.h" 309772Ssam 316940Ssam #include "bk.h" 3216063Skarels #include "uba.h" 3317124Sbloom #include "param.h" 3417124Sbloom #include "conf.h" 3517124Sbloom #include "dir.h" 3617124Sbloom #include "user.h" 3717124Sbloom #include "ioctl.h" 3817124Sbloom #include "tty.h" 3917124Sbloom #include "map.h" 4017124Sbloom #include "buf.h" 4117124Sbloom #include "vm.h" 4217124Sbloom #include "bkmac.h" 4317124Sbloom #include "clist.h" 4417124Sbloom #include "file.h" 4517124Sbloom #include "uio.h" 46*21955Sbloom #include "kernel.h" 4718312Sralph #include "syslog.h" 486940Ssam 4917124Sbloom #include "ubareg.h" 5017124Sbloom #include "ubavar.h" 5117124Sbloom #include "dmfreg.h" 528473Sroot 536940Ssam /* 546940Ssam * Definition of the driver for the auto-configuration program. 556940Ssam */ 566940Ssam int dmfprobe(), dmfattach(), dmfrint(), dmfxint(); 57*21955Sbloom int dmflint(); 586940Ssam struct uba_device *dmfinfo[NDMF]; 596940Ssam u_short dmfstd[] = { 0 }; 606940Ssam struct uba_driver dmfdriver = 616940Ssam { dmfprobe, 0, dmfattach, 0, dmfstd, "dmf", dmfinfo }; 626940Ssam 63*21955Sbloom int dmf_timeout = 50; /* silo timeout, in ms */ 64*21955Sbloom int dmf_mindma = 4; /* don't dma below this point */ 65*21955Sbloom 666940Ssam /* 676940Ssam * Local variables for the driver 686940Ssam */ 696940Ssam char dmf_speeds[] = 706940Ssam { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 010, 012, 014, 016, 017, 0 }; 716940Ssam 726940Ssam struct tty dmf_tty[NDMF*8]; 736940Ssam char dmfsoftCAR[NDMF]; 74*21955Sbloom 75*21955Sbloom struct dmfl_softc 76*21955Sbloom { 77*21955Sbloom unsigned dmfl_state; /* soft state bits */ 78*21955Sbloom unsigned dmfl_info; /* uba info */ 79*21955Sbloom unsigned short dmfl_lines; /* lines per page (66 def.) */ 80*21955Sbloom unsigned short dmfl_cols; /* cols per line (132 def.) */ 81*21955Sbloom char dmfl_buf[DMFL_BUFSIZ]; 82*21955Sbloom } dmfl_softc[NDMF]; 83*21955Sbloom 84*21955Sbloom /* 85*21955Sbloom * convert device number into DMF line printer unit number 86*21955Sbloom */ 87*21955Sbloom #define DMFL_UNIT(d) (minor(d)&0xF) /* up to 16 DMFs */ 88*21955Sbloom 89*21955Sbloom #define ASLP 1 /* waiting for interrupt from dmf */ 90*21955Sbloom #define OPEN 2 /* line printer is open */ 91*21955Sbloom #define ERROR 4 /* error while printing, driver 92*21955Sbloom refuses to do anything till closed */ 93*21955Sbloom 948778Sroot #ifndef lint 958778Sroot int ndmf = NDMF*8; /* used by iostat */ 968778Sroot #endif 976940Ssam int dmfact; /* mask of active dmf's */ 986940Ssam int dmfstart(), ttrstrt(); 996940Ssam 1006940Ssam /* 1016940Ssam * The clist space is mapped by the driver onto each UNIBUS. 1026940Ssam * The UBACVT macro converts a clist space address for unibus uban 1036940Ssam * into an i/o space address for the DMA routine. 1046940Ssam */ 10516063Skarels int dmf_ubinfo[NUBA]; /* info about allocated unibus map */ 10616063Skarels static int cbase[NUBA]; /* base address in unibus map */ 1076940Ssam #define UBACVT(x, uban) (cbase[uban] + ((x)-(char *)cfree)) 108*21955Sbloom char dmf_dma[NDMF*8]; 1096940Ssam 1106940Ssam /* 1116940Ssam * Routine for configuration to set dmf interrupt. 1126940Ssam */ 1136940Ssam /*ARGSUSED*/ 1146940Ssam dmfprobe(reg, ctlr) 1156940Ssam caddr_t reg; 116*21955Sbloom struct uba_device *ctlr; 1176940Ssam { 1186940Ssam register int br, cvec; /* these are ``value-result'' */ 1196940Ssam register struct dmfdevice *dmfaddr = (struct dmfdevice *)reg; 120*21955Sbloom register int i; 121*21955Sbloom register unsigned int a; 122*21955Sbloom static char *dmfdevs[]= 123*21955Sbloom {"parallel","printer","synch","asynch"}; 124*21955Sbloom unsigned int dmfoptions; 1256940Ssam 1266940Ssam #ifdef lint 1276940Ssam br = 0; cvec = br; br = cvec; 1288808Sroot dmfxint(0); dmfrint(0); 1298808Sroot dmfsrint(); dmfsxint(); dmfdaint(); dmfdbint(); dmflint(); 1306940Ssam #endif 131*21955Sbloom /* 132*21955Sbloom * Pick the usual size DMF vector here (don't decrement it here). 133*21955Sbloom * grab configuration; note that the DMF32 134*21955Sbloom * doesn't seem to put the right bits in this 135*21955Sbloom * register until AFTER the interrupt vector is set. 136*21955Sbloom */ 1376940Ssam br = 0x15; 138*21955Sbloom cvec = (uba_hd[numuba].uh_lastiv - 4*8); 139*21955Sbloom dmfaddr->dmfccsr0 = (cvec >> 2) ; 140*21955Sbloom dmfoptions = dmfaddr->dmfccsr0 & DMFC_CONFMASK; 141*21955Sbloom 142*21955Sbloom /* catch a couple of special cases: Able vmz/32n and vmz/lp */ 143*21955Sbloom if (dmfoptions == DMFC_ASYNC) { 144*21955Sbloom /* Async portion only - vmz/32n */ 145*21955Sbloom /* device dmf0 csr 0160400 vector dmfrint dmfxint */ 146*21955Sbloom cvec = (uba_hd[numuba].uh_lastiv -= 8); /* only 8 bytes req'd */ 147*21955Sbloom dmfaddr->dmfccsr0 = (cvec - 2*8) >> 2; /* program 020 less */ 148*21955Sbloom printf("dmf%d: Able vmz32/n\n", ctlr->ui_unit); 149*21955Sbloom } 150*21955Sbloom else if (dmfoptions == DMFC_LP) { 151*21955Sbloom /* LP portion only - vmz/lp */ 152*21955Sbloom /* device dmf0 csr 0160400 vector dmflint */ 153*21955Sbloom 154*21955Sbloom cvec = (uba_hd[numuba].uh_lastiv -= 8); /* only 8 bytes req'd */ 155*21955Sbloom dmfaddr->dmfccsr0 = (cvec - 3*8) >> 2; /* program 030 less */ 156*21955Sbloom printf("dmf%d: Able vmz/lp\n", ctlr->ui_unit); 157*21955Sbloom } 158*21955Sbloom else { 159*21955Sbloom /* anything else we program like a dec dmf32 */ 160*21955Sbloom /* device dmf0 vector dmfsrint dmfsxint dmfdaint dmfdbint dmfrint dmfxint dmflint */ 161*21955Sbloom 162*21955Sbloom cvec = (uba_hd[numuba].uh_lastiv -= 4*8); 163*21955Sbloom dmfaddr->dmfccsr0 = (cvec >> 2) ; 164*21955Sbloom a = (dmfaddr->dmfccsr0>>12) & 0xf; 165*21955Sbloom printf("dmf%d:", ctlr->ui_unit); 166*21955Sbloom for(i=0;a != 0;++i,a >>= 1) { 167*21955Sbloom if(a&1) 168*21955Sbloom printf(" %s",dmfdevs[i]); 169*21955Sbloom } 170*21955Sbloom printf(".\n"); 171*21955Sbloom } 172*21955Sbloom 173*21955Sbloom if (dmfoptions & DMFC_LP) 174*21955Sbloom dmfaddr->dmfl[0] = DMFL_RESET; 1756940Ssam /* NEED TO SAVE IT SOMEWHERE FOR OTHER DEVICES */ 1767412Skre return (sizeof (struct dmfdevice)); 1776940Ssam } 1786940Ssam 1796940Ssam /* 1806940Ssam * Routine called to attach a dmf. 1816940Ssam */ 1826940Ssam dmfattach(ui) 1836940Ssam struct uba_device *ui; 1846940Ssam { 185*21955Sbloom register int cols = (ui->ui_flags>>8) & 0xff; 186*21955Sbloom register int lines = (ui->ui_flags>>16) & 0xff; 1876940Ssam 188*21955Sbloom dmfsoftCAR[ui->ui_unit] = ui->ui_flags & 0xff; 189*21955Sbloom dmfl_softc[ui->ui_unit].dmfl_cols = cols==0?DMFL_DEFCOLS:cols; 190*21955Sbloom dmfl_softc[ui->ui_unit].dmfl_lines = lines==0?DMFL_DEFLINES:lines; 1916940Ssam } 1926940Ssam 1936940Ssam 1946940Ssam /* 1956940Ssam * Open a DMF32 line, mapping the clist onto the uba if this 1966940Ssam * is the first dmf on this uba. Turn on this dmf if this is 1976940Ssam * the first use of it. 1986940Ssam */ 1996940Ssam /*ARGSUSED*/ 2006940Ssam dmfopen(dev, flag) 2016940Ssam dev_t dev; 2026940Ssam { 2036940Ssam register struct tty *tp; 2046940Ssam register int unit, dmf; 2056940Ssam register struct dmfdevice *addr; 2066940Ssam register struct uba_device *ui; 2076940Ssam int s; 2086940Ssam 2096940Ssam unit = minor(dev); 210*21955Sbloom if(unit & 0200) 211*21955Sbloom return(dmflopen(dev,flag)); 2126940Ssam dmf = unit >> 3; 2138567Sroot if (unit >= NDMF*8 || (ui = dmfinfo[dmf])== 0 || ui->ui_alive == 0) 2148567Sroot return (ENXIO); 2156940Ssam tp = &dmf_tty[unit]; 2168567Sroot if (tp->t_state&TS_XCLUDE && u.u_uid!=0) 2178567Sroot return (EBUSY); 2186940Ssam addr = (struct dmfdevice *)ui->ui_addr; 2196940Ssam tp->t_addr = (caddr_t)addr; 2206940Ssam tp->t_oproc = dmfstart; 2216971Ssam tp->t_state |= TS_WOPEN; 2226940Ssam /* 2236940Ssam * While setting up state for this uba and this dmf, 2246940Ssam * block uba resets which can clear the state. 2256940Ssam */ 226*21955Sbloom s = spltty(); 2276940Ssam if (dmf_ubinfo[ui->ui_ubanum] == 0) { 2286940Ssam dmf_ubinfo[ui->ui_ubanum] = 2296940Ssam uballoc(ui->ui_ubanum, (caddr_t)cfree, 2306940Ssam nclist*sizeof(struct cblock), 0); 2316940Ssam cbase[ui->ui_ubanum] = dmf_ubinfo[ui->ui_ubanum]&0x3ffff; 2326940Ssam } 2336940Ssam if ((dmfact&(1<<dmf)) == 0) { 2346940Ssam addr->dmfcsr |= DMF_IE; 2356940Ssam dmfact |= (1<<dmf); 236*21955Sbloom addr->dmfrsp = dmf_timeout; 2376940Ssam } 2386940Ssam splx(s); 2396940Ssam /* 2406940Ssam * If this is first open, initialze tty state to default. 2416940Ssam */ 2426971Ssam if ((tp->t_state&TS_ISOPEN) == 0) { 2436940Ssam ttychars(tp); 2446940Ssam if (tp->t_ispeed == 0) { 2456940Ssam tp->t_ispeed = B300; 2466940Ssam tp->t_ospeed = B300; 2476940Ssam tp->t_flags = ODDP|EVENP|ECHO; 2486940Ssam } 2496940Ssam dmfparam(unit); 2506940Ssam } 2516940Ssam /* 2526940Ssam * Wait for carrier, then process line discipline specific open. 2536940Ssam */ 2546940Ssam if ((dmfmctl(dev, DMF_ON, DMSET) & (DMF_CAR<<8)) || 2556940Ssam (dmfsoftCAR[dmf] & (1<<(unit&07)))) 2566971Ssam tp->t_state |= TS_CARR_ON; 257*21955Sbloom s = spltty(); 2586971Ssam while ((tp->t_state & TS_CARR_ON) == 0) { 2596971Ssam tp->t_state |= TS_WOPEN; 2606940Ssam sleep((caddr_t)&tp->t_rawq, TTIPRI); 2616940Ssam } 2626940Ssam splx(s); 2638567Sroot return ((*linesw[tp->t_line].l_open)(dev, tp)); 2646940Ssam } 2656940Ssam 2666940Ssam /* 2676940Ssam * Close a DMF32 line. 2686940Ssam */ 2696940Ssam /*ARGSUSED*/ 2706940Ssam dmfclose(dev, flag) 2716940Ssam dev_t dev; 2726940Ssam int flag; 2736940Ssam { 2746940Ssam register struct tty *tp; 2756940Ssam register unit; 2766940Ssam 2776940Ssam unit = minor(dev); 278*21955Sbloom if(unit & 0200) 279*21955Sbloom return(dmflclose(dev,flag)); 280*21955Sbloom 2816940Ssam tp = &dmf_tty[unit]; 2826940Ssam (*linesw[tp->t_line].l_close)(tp); 2838702Sroot (void) dmfmctl(unit, DMF_BRK, DMBIC); 2846971Ssam if (tp->t_state&TS_HUPCLS || (tp->t_state&TS_ISOPEN)==0) 2858702Sroot (void) dmfmctl(unit, DMF_OFF, DMSET); 2866940Ssam ttyclose(tp); 2876940Ssam } 2886940Ssam 2897726Sroot dmfread(dev, uio) 2906940Ssam dev_t dev; 2917726Sroot struct uio *uio; 2926940Ssam { 2936940Ssam register struct tty *tp; 2946940Ssam 295*21955Sbloom if(minor(dev)&0200) 296*21955Sbloom return(ENXIO); 2976940Ssam tp = &dmf_tty[minor(dev)]; 2987726Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 2996940Ssam } 3006940Ssam 3017832Sroot dmfwrite(dev, uio) 3026940Ssam dev_t dev; 3037832Sroot struct uio *uio; 3046940Ssam { 3056940Ssam register struct tty *tp; 3066940Ssam 307*21955Sbloom if(minor(dev)&0200) 308*21955Sbloom return(dmflwrite(dev,uio)); 3096940Ssam tp = &dmf_tty[minor(dev)]; 3108530Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 3116940Ssam } 3126940Ssam 3136940Ssam /* 3146940Ssam * DMF32 receiver interrupt. 3156940Ssam */ 3166940Ssam dmfrint(dmf) 3176940Ssam int dmf; 3186940Ssam { 3196940Ssam register c; 3206940Ssam register struct dmfdevice *addr; 3216940Ssam register struct tty *tp0; 322*21955Sbloom register dev; 323*21955Sbloom int unit; 32412449Ssam int overrun = 0, s; 3256940Ssam 326*21955Sbloom { 327*21955Sbloom register struct uba_device *ui; 328*21955Sbloom 329*21955Sbloom ui = dmfinfo[dmf]; 330*21955Sbloom if (ui == 0 || ui->ui_alive == 0) 331*21955Sbloom return; 332*21955Sbloom addr = (struct dmfdevice *)ui->ui_addr; 333*21955Sbloom } 334*21955Sbloom tp0 = &dmf_tty[dmf * 8]; 3356940Ssam /* 3366940Ssam * Loop fetching characters from the silo for this 3376940Ssam * dmf until there are no more in the silo. 3386940Ssam */ 3396940Ssam while ((c = addr->dmfrbuf) < 0) { 340*21955Sbloom register struct tty *tp; 341*21955Sbloom 342*21955Sbloom unit = (c >> 8) & 07; 343*21955Sbloom tp = tp0 + unit; 344*21955Sbloom dev = unit + dmf * 8; 3456940Ssam if (c & DMF_DSC) { 346*21955Sbloom s = spltty(); 347*21955Sbloom addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 3486940Ssam if (addr->dmfrms & DMF_CAR) { 3496971Ssam if ((tp->t_state & TS_CARR_ON) == 0) { 3506940Ssam wakeup((caddr_t)&tp->t_rawq); 3516971Ssam tp->t_state |= TS_CARR_ON; 3526940Ssam } 3536940Ssam } else { 3546971Ssam if (tp->t_state & TS_CARR_ON) { 3556940Ssam gsignal(tp->t_pgrp, SIGHUP); 3566940Ssam gsignal(tp->t_pgrp, SIGCONT); 3576940Ssam addr->dmfcsr = DMF_IE | DMFIR_LCR | 358*21955Sbloom unit; 3596940Ssam addr->dmftms = 0; 36012776Ssam ttyflush(tp, FREAD|FWRITE); 3616940Ssam } 3626971Ssam tp->t_state &= ~TS_CARR_ON; 3636940Ssam } 36412449Ssam splx(s); 3656940Ssam continue; 3666940Ssam } 3676971Ssam if ((tp->t_state&TS_ISOPEN)==0) { 3686940Ssam wakeup((caddr_t)tp); 3696940Ssam continue; 3706940Ssam } 371*21955Sbloom if(c & (DMF_PE|DMF_DO|DMF_FE)) { 372*21955Sbloom if (c & DMF_PE) 373*21955Sbloom if ((tp->t_flags&(EVENP|ODDP))==EVENP 374*21955Sbloom || (tp->t_flags&(EVENP|ODDP))==ODDP ) 375*21955Sbloom continue; 376*21955Sbloom if ((c & DMF_DO) && overrun == 0) { 377*21955Sbloom log(KERN_RECOV, "dmf%d: silo overflow\n", dmf); 378*21955Sbloom overrun = 1; 379*21955Sbloom } 380*21955Sbloom if (c & DMF_FE) 381*21955Sbloom /* 382*21955Sbloom * At framing error (break) generate 383*21955Sbloom * a null (in raw mode, for getty), or a 384*21955Sbloom * interrupt (in cooked/cbreak mode). 385*21955Sbloom */ 386*21955Sbloom if (tp->t_flags&RAW) 387*21955Sbloom c = 0; 388*21955Sbloom else 389*21955Sbloom c = tp->t_intrc; 3906940Ssam } 3916940Ssam #if NBK > 0 3926940Ssam if (tp->t_line == NETLDISC) { 3936940Ssam c &= 0177; 3946940Ssam BKINPUT(c, tp); 3956940Ssam } else 3966940Ssam #endif 3976940Ssam (*linesw[tp->t_line].l_rint)(c, tp); 3986940Ssam } 3996940Ssam } 4006940Ssam 4016940Ssam /* 4026940Ssam * Ioctl for DMF32. 4036940Ssam */ 4046940Ssam /*ARGSUSED*/ 4057630Ssam dmfioctl(dev, cmd, data, flag) 4066940Ssam dev_t dev; 4077630Ssam caddr_t data; 4086940Ssam { 4096940Ssam register struct tty *tp; 4106940Ssam register int unit = minor(dev); 4118567Sroot int error; 4126940Ssam 413*21955Sbloom if(unit & 0200) 414*21955Sbloom return (ENOTTY); 4156940Ssam tp = &dmf_tty[unit]; 4168567Sroot error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 4178567Sroot if (error >= 0) 4188567Sroot return (error); 4198567Sroot error = ttioctl(tp, cmd, data, flag); 4208567Sroot if (error >= 0) { 42117562Sbloom if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLBIS || 42217562Sbloom cmd == TIOCLBIC || cmd == TIOCLSET) 4236940Ssam dmfparam(unit); 4248567Sroot return (error); 4258567Sroot } 4268567Sroot switch (cmd) { 4276940Ssam 4286940Ssam case TIOCSBRK: 4298702Sroot (void) dmfmctl(dev, DMF_BRK, DMBIS); 4306940Ssam break; 4317630Ssam 4326940Ssam case TIOCCBRK: 4338702Sroot (void) dmfmctl(dev, DMF_BRK, DMBIC); 4346940Ssam break; 4357630Ssam 4366940Ssam case TIOCSDTR: 4378702Sroot (void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIS); 4386940Ssam break; 4397630Ssam 4406940Ssam case TIOCCDTR: 4418702Sroot (void) dmfmctl(dev, DMF_DTR|DMF_RTS, DMBIC); 4426940Ssam break; 4437630Ssam 4446940Ssam case TIOCMSET: 4458702Sroot (void) dmfmctl(dev, dmtodmf(*(int *)data), DMSET); 4466940Ssam break; 4477630Ssam 4486940Ssam case TIOCMBIS: 4498702Sroot (void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIS); 4506940Ssam break; 4517630Ssam 4526940Ssam case TIOCMBIC: 4538702Sroot (void) dmfmctl(dev, dmtodmf(*(int *)data), DMBIC); 4546940Ssam break; 4557630Ssam 4566940Ssam case TIOCMGET: 4577630Ssam *(int *)data = dmftodm(dmfmctl(dev, 0, DMGET)); 4586940Ssam break; 4597630Ssam 4606940Ssam default: 4618567Sroot return (ENOTTY); 4626940Ssam } 4638567Sroot return (0); 4646940Ssam } 4656940Ssam 4666940Ssam dmtodmf(bits) 4676940Ssam register int bits; 4686940Ssam { 4696940Ssam register int b; 4706940Ssam 4716940Ssam b = bits & 012; 4726940Ssam if (bits & DML_ST) b |= DMF_RATE; 4736940Ssam if (bits & DML_RTS) b |= DMF_RTS; 4746940Ssam if (bits & DML_USR) b |= DMF_USRW; 4756940Ssam return(b); 4766940Ssam } 4776940Ssam 4786940Ssam dmftodm(bits) 4796940Ssam register int bits; 4806940Ssam { 4816940Ssam register int b; 4826940Ssam 4836940Ssam b = (bits & 012) | ((bits >> 7) & 0760) | DML_LE; 4846940Ssam if (bits & DMF_USRR) b |= DML_USR; 4856940Ssam if (bits & DMF_RTS) b |= DML_RTS; 4866940Ssam return(b); 4876940Ssam } 4886940Ssam 4896940Ssam 4906940Ssam /* 4916940Ssam * Set parameters from open or stty into the DMF hardware 4926940Ssam * registers. 4936940Ssam */ 4946940Ssam dmfparam(unit) 4956940Ssam register int unit; 4966940Ssam { 4976940Ssam register struct tty *tp; 4986940Ssam register struct dmfdevice *addr; 4996940Ssam register int lpar, lcr; 5006940Ssam int s; 5016940Ssam 5026940Ssam tp = &dmf_tty[unit]; 5036940Ssam addr = (struct dmfdevice *)tp->t_addr; 5046940Ssam /* 5056940Ssam * Block interrupts so parameters will be set 5066940Ssam * before the line interrupts. 5076940Ssam */ 508*21955Sbloom s = spltty(); 5096940Ssam addr->dmfcsr = (unit&07) | DMFIR_LCR | DMF_IE; 5106940Ssam if ((tp->t_ispeed)==0) { 5116971Ssam tp->t_state |= TS_HUPCLS; 5128702Sroot (void) dmfmctl(unit, DMF_OFF, DMSET); 5136940Ssam return; 5146940Ssam } 5156940Ssam lpar = (dmf_speeds[tp->t_ospeed]<<12) | (dmf_speeds[tp->t_ispeed]<<8); 5166940Ssam lcr = DMFLCR_ENA; 5176940Ssam if ((tp->t_ispeed) == B134) 5186940Ssam lpar |= BITS6|PENABLE; 5199550Ssam else if (tp->t_flags & (RAW|LITOUT)) 5206940Ssam lpar |= BITS8; 5216940Ssam else { 5226940Ssam lpar |= BITS7|PENABLE; 5236940Ssam /* CHECK FOR XON/XOFF AND SET lcr |= DMF_AUTOX; */ 5246940Ssam } 52512450Ssam if (tp->t_flags&EVENP) 52612450Ssam lpar |= EPAR; 5276940Ssam if ((tp->t_ospeed) == B110) 5286940Ssam lpar |= TWOSB; 5296940Ssam lpar |= (unit&07); 5306940Ssam addr->dmflpr = lpar; 53112449Ssam SETLCR(addr, lcr); 5326940Ssam splx(s); 5336940Ssam } 5346940Ssam 5356940Ssam /* 5366940Ssam * DMF32 transmitter interrupt. 5376940Ssam * Restart the idle line. 5386940Ssam */ 5396940Ssam dmfxint(dmf) 5406940Ssam int dmf; 5416940Ssam { 542*21955Sbloom int u = dmf * 8; 543*21955Sbloom struct tty *tp0 = &dmf_tty[u]; 5446940Ssam register struct tty *tp; 5456940Ssam register struct dmfdevice *addr; 5466940Ssam register struct uba_device *ui; 547*21955Sbloom register int t; 5486940Ssam short cntr; 5496940Ssam 5506940Ssam ui = dmfinfo[dmf]; 5516940Ssam addr = (struct dmfdevice *)ui->ui_addr; 5526940Ssam while ((t = addr->dmfcsr) & DMF_TI) { 553*21955Sbloom if (t & DMF_NXM) 554*21955Sbloom /* SHOULD RESTART OR SOMETHING... */ 555*21955Sbloom printf("dmf%d: NXM line %d\n", dmf, t >> 8 & 7); 556*21955Sbloom t = t >> 8 & 7; 557*21955Sbloom tp = tp0 + t; 5586971Ssam tp->t_state &= ~TS_BUSY; 5596971Ssam if (tp->t_state&TS_FLUSH) 5606971Ssam tp->t_state &= ~TS_FLUSH; 561*21955Sbloom else if (dmf_dma[u + t]) { 562*21955Sbloom /* 563*21955Sbloom * Do arithmetic in a short to make up 564*21955Sbloom * for lost 16&17 bits. 565*21955Sbloom */ 566*21955Sbloom addr->dmfcsr = DMFIR_TBA | DMF_IE | t; 567*21955Sbloom cntr = addr->dmftba - 568*21955Sbloom UBACVT(tp->t_outq.c_cf, ui->ui_ubanum); 569*21955Sbloom ndflush(&tp->t_outq, (int)cntr); 5706940Ssam } 5716940Ssam if (tp->t_line) 5726940Ssam (*linesw[tp->t_line].l_start)(tp); 5736940Ssam else 5746940Ssam dmfstart(tp); 5756940Ssam } 5766940Ssam } 5776940Ssam 5786940Ssam /* 5796940Ssam * Start (restart) transmission on the given DMF32 line. 5806940Ssam */ 5816940Ssam dmfstart(tp) 5826940Ssam register struct tty *tp; 5836940Ssam { 5846940Ssam register struct dmfdevice *addr; 5858607Sroot register int unit, nch; 5866940Ssam int s; 587*21955Sbloom register int dmf; 5886940Ssam 5896940Ssam unit = minor(tp->t_dev); 590*21955Sbloom dmf = unit >> 3; 5916940Ssam unit &= 07; 5926940Ssam addr = (struct dmfdevice *)tp->t_addr; 5936940Ssam 5946940Ssam /* 5956940Ssam * Must hold interrupts in following code to prevent 5966940Ssam * state of the tp from changing. 5976940Ssam */ 598*21955Sbloom s = spltty(); 5996940Ssam /* 6006940Ssam * If it's currently active, or delaying, no need to do anything. 6016940Ssam */ 6026971Ssam if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 6036940Ssam goto out; 6046940Ssam /* 6056940Ssam * If there are still characters in the silo, 6066940Ssam * just reenable the transmitter. 6076940Ssam */ 6086940Ssam addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 6096940Ssam if (addr->dmftsc) { 6106940Ssam addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 61112449Ssam SETLCR(addr, addr->dmflcr|DMF_TE); 6126971Ssam tp->t_state |= TS_BUSY; 6136940Ssam goto out; 6146940Ssam } 6156940Ssam /* 6166940Ssam * If there are sleepers, and output has drained below low 6176940Ssam * water mark, wake up the sleepers. 6186940Ssam */ 619*21955Sbloom if (tp->t_outq.c_cc<=TTLOWAT(tp)) { 620*21955Sbloom if (tp->t_state&TS_ASLEEP) { 621*21955Sbloom tp->t_state &= ~TS_ASLEEP; 622*21955Sbloom wakeup((caddr_t)&tp->t_outq); 623*21955Sbloom } 624*21955Sbloom if (tp->t_wsel) { 625*21955Sbloom selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 626*21955Sbloom tp->t_wsel = 0; 627*21955Sbloom tp->t_state &= ~TS_WCOLL; 628*21955Sbloom } 6296940Ssam } 6306940Ssam /* 6316940Ssam * Now restart transmission unless the output queue is 6326940Ssam * empty. 6336940Ssam */ 6346940Ssam if (tp->t_outq.c_cc == 0) 6356940Ssam goto out; 6369550Ssam if (tp->t_flags & (RAW|LITOUT)) 6376940Ssam nch = ndqb(&tp->t_outq, 0); 6386940Ssam else { 639*21955Sbloom if ((nch = ndqb(&tp->t_outq, 0200)) == 0) { 640*21955Sbloom /* 641*21955Sbloom * If first thing on queue is a delay process it. 642*21955Sbloom */ 6436940Ssam nch = getc(&tp->t_outq); 6446940Ssam timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6); 6456971Ssam tp->t_state |= TS_TIMEOUT; 6466940Ssam goto out; 6476940Ssam } 6486940Ssam } 6496940Ssam /* 6506940Ssam * If characters to transmit, restart transmission. 6516940Ssam */ 652*21955Sbloom if (nch >= dmf_mindma) { 653*21955Sbloom register car; 654*21955Sbloom 655*21955Sbloom dmf_dma[minor(tp->t_dev)] = 1; 6566940Ssam addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 65712449Ssam SETLCR(addr, addr->dmflcr|DMF_TE); 6586940Ssam car = UBACVT(tp->t_outq.c_cf, dmfinfo[dmf]->ui_ubanum); 6596940Ssam addr->dmfcsr = DMF_IE | DMFIR_TBA | unit; 6606940Ssam addr->dmftba = car; 661*21955Sbloom addr->dmftcc = ((car >> 2) & 0xc000) | nch; 662*21955Sbloom tp->t_state |= TS_BUSY; 663*21955Sbloom } else if (nch) { 6646940Ssam register char *cp = tp->t_outq.c_cf; 6656940Ssam register int i; 6666940Ssam 667*21955Sbloom dmf_dma[minor(tp->t_dev)] = 0; 6686940Ssam nch = MIN(nch, DMF_SILOCNT); 6696940Ssam addr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 67012449Ssam SETLCR(addr, addr->dmflcr|DMF_TE); 6716940Ssam addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 6726940Ssam for (i = 0; i < nch; i++) 6736940Ssam addr->dmftbuf = *cp++; 6746940Ssam ndflush(&tp->t_outq, nch); 6756971Ssam tp->t_state |= TS_BUSY; 6766940Ssam } 6776940Ssam out: 6786940Ssam splx(s); 6796940Ssam } 6806940Ssam 6816940Ssam /* 6826940Ssam * Stop output on a line, e.g. for ^S/^Q or output flush. 6836940Ssam */ 6846940Ssam /*ARGSUSED*/ 6856940Ssam dmfstop(tp, flag) 6866940Ssam register struct tty *tp; 6876940Ssam { 6886940Ssam register struct dmfdevice *addr; 689*21955Sbloom register unit = minor(tp->t_dev) & 7; 690*21955Sbloom int s; 6916940Ssam 6926940Ssam addr = (struct dmfdevice *)tp->t_addr; 6936940Ssam /* 6946940Ssam * Block input/output interrupts while messing with state. 6956940Ssam */ 696*21955Sbloom s = spltty(); 697*21955Sbloom if (flag) { 698*21955Sbloom addr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 699*21955Sbloom if (addr->dmftsc) { 700*21955Sbloom /* 701*21955Sbloom * Flush regardless of whether we're transmitting 702*21955Sbloom * (TS_BUSY), if the silo contains untransmitted 703*21955Sbloom * characters. 704*21955Sbloom */ 705*21955Sbloom addr->dmfcsr = DMFIR_LCR | unit | DMF_IE; 706*21955Sbloom SETLCR(addr, addr->dmflcr | DMF_TE | DMF_FLUSH); 707*21955Sbloom /* this will interrupt so let dmfxint handle the rest */ 708*21955Sbloom tp->t_state |= TS_FLUSH|TS_BUSY; 709*21955Sbloom } 710*21955Sbloom } else { 711*21955Sbloom if (tp->t_state & TS_BUSY) { 712*21955Sbloom /* 713*21955Sbloom * Stop transmission by disabling 714*21955Sbloom * the transmitter. We'll pick up where we 715*21955Sbloom * left off by reenabling in dmfstart. 716*21955Sbloom */ 717*21955Sbloom addr->dmfcsr = DMFIR_LCR | unit | DMF_IE; 718*21955Sbloom SETLCR(addr, addr->dmflcr &~ DMF_TE); 719*21955Sbloom /* no interrupt here */ 7206971Ssam tp->t_state &= ~TS_BUSY; 721*21955Sbloom } 7226940Ssam } 7236940Ssam splx(s); 7246940Ssam } 7256940Ssam 7266940Ssam /* 7276940Ssam * DMF32 modem control 7286940Ssam */ 7296940Ssam dmfmctl(dev, bits, how) 7306940Ssam dev_t dev; 7316940Ssam int bits, how; 7326940Ssam { 7336940Ssam register struct dmfdevice *dmfaddr; 7346940Ssam register int unit, mbits, lcr; 7356940Ssam int s; 7366940Ssam 7376940Ssam unit = minor(dev); 7386940Ssam dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr); 7396940Ssam unit &= 07; 740*21955Sbloom s = spltty(); 7416940Ssam dmfaddr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; 7426940Ssam mbits = dmfaddr->dmfrms << 8; 7436940Ssam dmfaddr->dmfcsr = DMF_IE | DMFIR_LCR | unit; 7446940Ssam mbits |= dmfaddr->dmftms; 7456940Ssam lcr = dmfaddr->dmflcr; 7466940Ssam switch (how) { 7476940Ssam case DMSET: 74812449Ssam mbits = (mbits &0xff00) | bits; 7496940Ssam break; 7506940Ssam 7516940Ssam case DMBIS: 7526940Ssam mbits |= bits; 7536940Ssam break; 7546940Ssam 7556940Ssam case DMBIC: 7566940Ssam mbits &= ~bits; 7576940Ssam break; 7586940Ssam 7596940Ssam case DMGET: 7606940Ssam (void) splx(s); 7616940Ssam return(mbits); 7626940Ssam } 7636940Ssam if (mbits & DMF_BRK) 7646940Ssam lcr |= DMF_RBRK; 7656940Ssam else 7666940Ssam lcr &= ~DMF_RBRK; 76712449Ssam lcr = ((mbits & 037) << 8) | (lcr & 0xff); 76812449Ssam dmfaddr->dmfun.dmfirw = lcr; 7696940Ssam (void) splx(s); 7706940Ssam return(mbits); 7716940Ssam } 7726940Ssam 7736940Ssam /* 7746940Ssam * Reset state of driver if UBA reset was necessary. 7756940Ssam * Reset the csr, lpr, and lcr registers on open lines, and 7766940Ssam * restart transmitters. 7776940Ssam */ 7786940Ssam dmfreset(uban) 7796940Ssam int uban; 7806940Ssam { 7816940Ssam register int dmf, unit; 7826940Ssam register struct tty *tp; 7836940Ssam register struct uba_device *ui; 7846940Ssam register struct dmfdevice *addr; 7856940Ssam int i; 7866940Ssam 7876940Ssam if (dmf_ubinfo[uban] == 0) 7886940Ssam return; 7896940Ssam dmf_ubinfo[uban] = uballoc(uban, (caddr_t)cfree, 7906940Ssam nclist*sizeof (struct cblock), 0); 7916940Ssam cbase[uban] = dmf_ubinfo[uban]&0x3ffff; 7926940Ssam for (dmf = 0; dmf < NDMF; dmf++) { 7936940Ssam ui = dmfinfo[dmf]; 7946940Ssam if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) 7956940Ssam continue; 7966940Ssam printf(" dmf%d", dmf); 7976940Ssam addr = (struct dmfdevice *)ui->ui_addr; 7986940Ssam addr->dmfcsr = DMF_IE; 799*21955Sbloom addr->dmfrsp = dmf_timeout; 8006940Ssam unit = dmf * 8; 8016940Ssam for (i = 0; i < 8; i++) { 8026940Ssam tp = &dmf_tty[unit]; 8036971Ssam if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 8046940Ssam dmfparam(unit); 8058702Sroot (void) dmfmctl(unit, DMF_ON, DMSET); 8066971Ssam tp->t_state &= ~TS_BUSY; 8076940Ssam dmfstart(tp); 8086940Ssam } 8096940Ssam unit++; 8106940Ssam } 8116940Ssam } 8126940Ssam } 8136940Ssam 814*21955Sbloom /* dmflopen -- open the line printer port on a dmf32 815*21955Sbloom * 816*21955Sbloom */ 817*21955Sbloom dmflopen(dev,flag) 818*21955Sbloom dev_t dev; 819*21955Sbloom int flag; 820*21955Sbloom { 821*21955Sbloom register int dmf; 822*21955Sbloom register struct dmfl_softc *sc; 823*21955Sbloom register struct uba_device *ui; 824*21955Sbloom register struct dmfdevice *addr; 825*21955Sbloom 826*21955Sbloom 827*21955Sbloom dmf = DMFL_UNIT(dev) ; 828*21955Sbloom if(((sc= &dmfl_softc[dmf])->dmfl_state & OPEN) || 829*21955Sbloom ((ui=dmfinfo[dmf]) == 0) || ui->ui_alive == 0) 830*21955Sbloom return(ENXIO); 831*21955Sbloom addr = (struct dmfdevice *)ui->ui_addr; 832*21955Sbloom if((addr->dmfl[0] & DMFL_OFFLINE)) 833*21955Sbloom { 834*21955Sbloom /*printf("dmf: line printer offline/jammed\n");*/ 835*21955Sbloom return(EIO); 836*21955Sbloom } 837*21955Sbloom if((addr->dmfl[0]&DMFL_CONV)) 838*21955Sbloom { 839*21955Sbloom printf("dmf:line printer disconnected\n"); 840*21955Sbloom return(EIO); 841*21955Sbloom } 842*21955Sbloom 843*21955Sbloom addr->dmfl[0] = 0; 844*21955Sbloom sc->dmfl_state |= OPEN; 845*21955Sbloom return 0; 846*21955Sbloom } 847*21955Sbloom 848*21955Sbloom dmflclose(dev,flag) 849*21955Sbloom dev_t dev; 850*21955Sbloom int flag; 851*21955Sbloom { 852*21955Sbloom register int dmf= DMFL_UNIT(dev); 853*21955Sbloom register struct dmfl_softc *sc = &dmfl_softc[dmf]; 854*21955Sbloom 855*21955Sbloom dmflout(dev,"\f",1); 856*21955Sbloom sc->dmfl_state = 0; 857*21955Sbloom if(sc->dmfl_info != 0) 858*21955Sbloom ubarelse((struct dmfdevice *)(dmfinfo[dmf])->ui_ubanum, 859*21955Sbloom &(sc->dmfl_info)); 860*21955Sbloom 861*21955Sbloom ((struct dmfdevice *)(dmfinfo[dmf]->ui_addr))->dmfl[0]=0; 862*21955Sbloom return 0; 863*21955Sbloom } 864*21955Sbloom 865*21955Sbloom dmflwrite(dev,uio) 866*21955Sbloom dev_t dev; 867*21955Sbloom struct uio *uio; 868*21955Sbloom { 869*21955Sbloom register unsigned int n; 870*21955Sbloom register int error; 871*21955Sbloom register struct dmfl_softc *sc; 872*21955Sbloom 873*21955Sbloom sc = &dmfl_softc[DMFL_UNIT(dev)]; 874*21955Sbloom if(sc->dmfl_state&ERROR) return(EIO); 875*21955Sbloom while(n=min(DMFL_BUFSIZ,(unsigned)uio->uio_resid)) 876*21955Sbloom { 877*21955Sbloom if(error=uiomove(&sc->dmfl_buf[0],(int)n, 878*21955Sbloom UIO_WRITE,uio)) 879*21955Sbloom { 880*21955Sbloom printf("uio move error\n"); 881*21955Sbloom return(error); 882*21955Sbloom } 883*21955Sbloom if(error=dmflout(dev,&sc->dmfl_buf[0],n)) 884*21955Sbloom { 885*21955Sbloom return(error); 886*21955Sbloom } 887*21955Sbloom } 888*21955Sbloom return 0; 889*21955Sbloom } 890*21955Sbloom 891*21955Sbloom 892*21955Sbloom /* dmflout -- start io operation to dmf line printer 893*21955Sbloom * cp is addr of buf of n chars to be sent. 894*21955Sbloom * 895*21955Sbloom * -- dmf will be put in formatted output mode, this will 896*21955Sbloom * be selectable from an ioctl if the 897*21955Sbloom * need ever arises. 898*21955Sbloom */ 899*21955Sbloom dmflout(dev,cp,n) 900*21955Sbloom dev_t dev; 901*21955Sbloom char *cp; 902*21955Sbloom int n; 903*21955Sbloom { 904*21955Sbloom register struct dmfl_softc *sc; 905*21955Sbloom register int dmf; 906*21955Sbloom register struct uba_device *ui; 907*21955Sbloom register struct dmfdevice *d; 908*21955Sbloom register unsigned info; 909*21955Sbloom register unsigned i; 910*21955Sbloom 911*21955Sbloom dmf = DMFL_UNIT(dev) ; 912*21955Sbloom sc= &dmfl_softc[dmf]; 913*21955Sbloom if(sc->dmfl_state&ERROR) return(EIO); 914*21955Sbloom ui= dmfinfo[dmf]; 915*21955Sbloom /* allocate unibus resources, will be released when io 916*21955Sbloom * operation is done 917*21955Sbloom */ 918*21955Sbloom sc->dmfl_info= 919*21955Sbloom info= 920*21955Sbloom uballoc(ui->ui_ubanum,cp,n,0); 921*21955Sbloom d= (struct dmfdevice *)ui->ui_addr; 922*21955Sbloom d->dmfl[0] = (2<<8) | DMFL_FORMAT; /* indir reg 2 */ 923*21955Sbloom /* indir reg auto increments on r/w */ 924*21955Sbloom /* SO DON'T CHANGE THE ORDER OF THIS CODE */ 925*21955Sbloom d->dmfl[1] = 0; /* prefix chars & num */ 926*21955Sbloom d->dmfl[1] = 0; /* suffix chars & num */ 927*21955Sbloom d->dmfl[1] = info; /* dma lo 16 bits addr */ 928*21955Sbloom 929*21955Sbloom /* NOT DOCUMENTED !! */ 930*21955Sbloom d->dmfl[1] = -n; /* number of chars */ 931*21955Sbloom /* ----------^-------- */ 932*21955Sbloom 933*21955Sbloom d->dmfl[1] = ((info>>16)&3) /* dma hi 2 bits addr */ 934*21955Sbloom | (1<<8) /* auto cr insert */ 935*21955Sbloom | (1<<9) /* use real ff */ 936*21955Sbloom | (1<<15); /* no u/l conversion */ 937*21955Sbloom d->dmfl[1] = sc->dmfl_lines /* lines per page */ 938*21955Sbloom | (sc->dmfl_cols<<8); /* carriage width */ 939*21955Sbloom sc->dmfl_state |= ASLP; 940*21955Sbloom i=spltty(); 941*21955Sbloom d->dmfl[0] |= DMFL_PEN|DMFL_IE; 942*21955Sbloom while(sc->dmfl_state & ASLP) 943*21955Sbloom { 944*21955Sbloom sleep(&sc->dmfl_buf[0],(PZERO+8)); 945*21955Sbloom while(sc->dmfl_state&ERROR) 946*21955Sbloom { 947*21955Sbloom timeout(dmflint,dmf,10*hz); 948*21955Sbloom sleep(&sc->dmfl_state,(PZERO+8)); 949*21955Sbloom } 950*21955Sbloom /*if(sc->dmfl_state&ERROR) return (EIO);*/ 951*21955Sbloom } 952*21955Sbloom splx(i); 953*21955Sbloom return(0); 954*21955Sbloom } 955*21955Sbloom /* dmflint -- handle an interrupt from the line printer part of the dmf32 956*21955Sbloom * 957*21955Sbloom */ 958*21955Sbloom 959*21955Sbloom dmflint(dmf) 960*21955Sbloom int dmf; 961*21955Sbloom { 962*21955Sbloom 963*21955Sbloom register struct uba_device *ui; 964*21955Sbloom register struct dmfl_softc *sc; 965*21955Sbloom register struct dmfdevice *d; 966*21955Sbloom 967*21955Sbloom ui= dmfinfo[dmf]; 968*21955Sbloom sc= &dmfl_softc[dmf]; 969*21955Sbloom d= (struct dmfdevice *)ui->ui_addr; 970*21955Sbloom 971*21955Sbloom d->dmfl[0] &= ~DMFL_IE; 972*21955Sbloom 973*21955Sbloom if(sc->dmfl_state&ERROR) 974*21955Sbloom { 975*21955Sbloom printf("dmfl: intr while in error state \n"); 976*21955Sbloom if((d->dmfl[0]&DMFL_OFFLINE) == 0) 977*21955Sbloom sc->dmfl_state &= ~ERROR; 978*21955Sbloom wakeup(&sc->dmfl_state); 979*21955Sbloom return; 980*21955Sbloom } 981*21955Sbloom if(d->dmfl[0]&DMFL_DMAERR) 982*21955Sbloom { 983*21955Sbloom printf("dmf:NXM\n"); 984*21955Sbloom } 985*21955Sbloom if(d->dmfl[0]&DMFL_OFFLINE) 986*21955Sbloom { 987*21955Sbloom printf("dmf:printer error\n"); 988*21955Sbloom sc->dmfl_state |= ERROR; 989*21955Sbloom } 990*21955Sbloom if(d->dmfl[0]&DMFL_PDONE) 991*21955Sbloom { 992*21955Sbloom #ifdef notdef 993*21955Sbloom printf("bytes= %d\n",d->dmfl[1]); 994*21955Sbloom printf("lines= %d\n",d->dmfl[1]); 995*21955Sbloom #endif 996*21955Sbloom } 997*21955Sbloom sc->dmfl_state &= ~ASLP; 998*21955Sbloom wakeup(&sc->dmfl_buf[0]); 999*21955Sbloom if(sc->dmfl_info != 0) 1000*21955Sbloom ubarelse(ui->ui_ubanum,&sc->dmfl_info); 1001*21955Sbloom sc->dmfl_info = 0; 1002*21955Sbloom 1003*21955Sbloom } 1004*21955Sbloom 10056940Ssam /* stubs for interrupt routines for devices not yet supported */ 10066940Ssam 10076940Ssam dmfsrint() { printf("dmfsrint\n"); } 10086940Ssam 10096940Ssam dmfsxint() { printf("dmfsxint\n"); } 10106940Ssam 10116940Ssam dmfdaint() { printf("dmfdaint\n"); } 10126940Ssam 10136940Ssam dmfdbint() { printf("dmfdbint\n"); } 10146940Ssam 1015*21955Sbloom 10166940Ssam #endif 1017