# 2.11BSD#431 - /usr/src/sys/pdpuba/dr.c

##### Functions

    drabort           X
    drattach          X
    drclose           X
    drintr            X
    drioctl           X
    dropen            X
    drstart           X
    drstrategy        X
    drtimeout         X

##### Variables

    dr11              X

##### struct's

    dr11w             X

       1: /*
       2:  * Copyright (c) 1986 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  *
       6:  *	@(#)dr.c	1.5 (2.11BSD GTE) 1997/2/14
       7:  */
       8:
       9: /*
      10:  *	DR11-W device driver
      11:  */
      12:
      13: #include "dr.h"
      14: #if NDR > 0
      15:
      16: #include "param.h"
      17: #include "../machine/seg.h"
      18:
      19: #include "user.h"
      20: #include "proc.h"
      21: #include "buf.h"
      22: #include "conf.h"
      23: #include "ioctl.h"
      24: #include "drreg.h"
      25: #include <sys/kernel.h>
      26:
      27: struct  dr11w {
      28:     int i_flags;        /* interface flags */
      29:     int i_req;          /* request number (for timeout) */
      30:     int i_unit;         /* unit number of device */
      31:     int i_prev;         /* previous request number (timeout) */
      32:     short   i_fun;          /* function bits */
      33:     struct  proc *i_proc;       /* process pointer of opening process */
      34:     int i_sig;          /* signal to send on ATTN */
      35:     int i_tsig;         /* signal to send on timeout */
      36:     struct  buf i_tab;      /* buffer for device */
      37:     struct  drdevice *i_addr;   /* address of DR11-W interface */
      38: };
      39:
      40: struct dr11w dr11[NDR];
      41:
      42: drattach(addr, unit)
      43: struct drdevice *addr;
      44: int unit;
      45: {
      46:     if(unit > NDR)
      47:         return(0);
      48:     if((addr != (struct drdevice *)NULL) && (fioword(addr) != -1))
      49:     {
      50:         dr11[unit].i_addr = addr;
      51:         dr11[unit].i_flags = DR_ALIVE;  /* mark as active */
      52:         dr11[unit].i_unit = unit;
      53:         return(1);
      54:     }
      55:     return(0);
      56: }
      57:
      58: dropen(dev)
      59: dev_t dev;
      60: {
      61:     register int unit;
      62:     register struct dr11w *drptr;
      63:     extern int drtimeout();
      64:
      65:     unit = minor(dev) & 07;     /* get minor device number */
      66:     drptr = &dr11[unit];
      67:     if((unit > NDR) || !(drptr->i_flags & DR_ALIVE))
      68:         return(ENXIO);      /* not attatched or present */
      69:     drptr->i_flags |= DR_OPEN;
      70:     drptr->i_flags &= ~(DR_IGNORE | DR_TIMEOUT);
      71:     drptr->i_proc = u.u_procp;  /* process pointer of opener */
      72:     drptr->i_sig = 0;       /* clear signals (set by ioctl) */
      73:     drptr->i_tsig = 0;
      74:     drptr->i_fun = 0;       /* clear function */
      75:     timeout(drtimeout, (caddr_t)drptr, hz);
      76:     return(0);
      77: }
      78:
      79: drclose(dev, flag)
      80: dev_t dev;
      81: {
      82:     register int unit;
      83:     register struct drdevice *addr;
      84:
      85:     unit = minor(dev) & 07;
      86:     dr11[unit].i_flags &= ~DR_OPEN;     /* clear opened status */
      87:     addr = dr11[unit].i_addr;       /* get address of DR11-W */
      88:     addr->csr = dr11[unit].i_fun;       /* clear IE and GO bits */
      89: }
      90:
      91: drstrategy(bp)
      92: register struct buf *bp;
      93: {
      94:     register struct buf *dp;
      95:     register struct dr11w *drptr;
      96:     int s;
      97:
      98:     drptr = &dr11[minor(bp->b_dev) & 07];
      99:     if(!(drptr->i_flags & DR_OPEN))
     100:     {
     101:         bp->b_flags |= B_ERROR; /* unit not open */
     102:         iodone(bp);
     103:         return;
     104:     }
     105:     dp = &(drptr->i_tab);       /* point to buffer */
     106:     bp->av_forw = NULL;
     107:     s = splbio();           /* lock out interrupts */
     108:
     109:     mapalloc(bp);
     110:
     111:     if(dp->b_actf == NULL)      /* if nothing in current buffer */
     112:         dp->b_actf = bp;    /* this request is first */
     113:     dp->b_actl = bp;        /* set last request */
     114:     if(dp->b_active == 0)       /* if not active now */
     115:         drstart(drptr);     /* start the DR11-W */
     116:     splx(s);            /* return to normal state */
     117: }
     118:
     119: drstart(drptr)
     120: register struct dr11w *drptr;
     121: {
     122:     register struct buf *bp, *dp;
     123:     register struct drdevice *addr;
     124:     short com;
     125:
     126:     if(!drptr)
     127:         return;
     128:     dp = &(drptr->i_tab);       /* point dp to device buffer */
     129:     if((bp = dp->b_actf) == NULL)   /* if nothing in queue */
     130:         return;         /* return */
     131:
     132:     drptr->i_req++;         /* increment request number */
     133:     if(drptr->i_flags & DR_TIMEOUT) /* do we need timeout checking */
     134:     {
     135:         drptr->i_flags |= DR_TACTIVE;   /* mark active timeout */
     136:     }
     137:     dp->b_active = 1;       /* set active flag */
     138:     addr = drptr->i_addr;       /* get device pointer */
     139:     /*
     140: 	 *	Set up DR11-W for specific operation
     141: 	 */
     142:     addr->bar = (short)bp->b_un.b_addr;
     143:     addr->wcr = -(bp->b_bcount >> 1);   /* DR deals in words */
     144:     com = ((bp->b_xmem & 3) << 4) | drptr->i_fun;
     145:     addr->csr = com;            /* set csr fun and address */
     146:     com |= (DR_IE | DR_GO);         /* set IE and GO bits (also) */
     147:     addr->csr = com;
     148: }
     149:
     150: drintr(unit)
     151: int unit;
     152: {
     153:     register struct buf *bp;
     154:     register struct drdevice *dr;
     155:     register struct dr11w *drptr;
     156:     mapinfo map;
     157:
     158:     drptr = &dr11[unit];        /* point to struct for device */
     159:     dr = drptr->i_addr;     /* get address of device */
     160:     if(drptr->i_tab.b_active == 0)  /* if not active, return */
     161:         return;
     162:     bp = drptr->i_tab.b_actf;   /* point to current buffer */
     163:     if(dr->csr & DR_ERR)        /* if error */
     164:     {
     165:         /*
     166: 		 * The error bit can be set in one of two ways:
     167: 		 * a 'real' error (timing, non-existant memory) or
     168: 		 * by the interface setting ATTN true.  This is
     169: 		 * not considered an 'error' but cause to send
     170: 		 * a signal to the parent process.  He (hopefully)
     171: 		 * will know what to do then.
     172: 		 */
     173:         if(dr->csr & DR_ATTN)
     174:         {
     175:             dr->csr = drptr->i_fun;
     176:             savemap(map);
     177:             if(drptr->i_sig)
     178:                 psignal(drptr->i_proc, drptr->i_sig);
     179:             restormap(map);
     180:         }
     181:         else
     182:         {
     183:             printf("dr%d: error ", unit);
     184:             printf("csr=%b, ", dr->csr, DRCSR_BITS);
     185:             dr->csr = DR_ERR | drptr->i_fun;
     186:             printf("eir=%b\n", dr->csr, DREIR_BITS);
     187:             /* now reset the DR11-W interface */
     188:             dr->csr = DR_MANT | drptr->i_fun;
     189:             dr->csr = drptr->i_fun;
     190:             bp->b_flags |= B_ERROR;
     191:         }
     192:     }
     193:     drptr->i_flags &= ~DR_TACTIVE;      /* we beat the timeout */
     194:     drptr->i_tab.b_active = 0;      /* clear global stuff */
     195:     drptr->i_tab.b_errcnt = 0;
     196:     drptr->i_tab.b_actf = bp->b_forw;   /* link to next request */
     197:     bp->b_resid = -(dr->wcr) << 1;      /* change words to bytes */
     198:     iodone(bp);             /* tell system we are done */
     199:     if(drptr->i_tab.b_actf)         /* start next request */
     200:         drstart(drptr);
     201: }
     202:
     203: drioctl(dev, cmd, data, flag)
     204:     dev_t dev;
     205:     u_int cmd;
     206:     register caddr_t data;
     207:     int flag;
     208: {
     209:     register struct dr11w *drptr;
     210:     register struct drdevice *dr;
     211:     int *sgbuf = (int *)data;
     212:
     213:     drptr = &dr11[minor(dev) & 07];
     214:     dr = drptr->i_addr;
     215:     if(drptr->i_tab.b_active)
     216:         return (EINVAL);
     217:
     218:     switch(cmd) {
     219:         case DRGTTY:
     220:             sgbuf[0] = drptr->i_flags;
     221:             sgbuf[1] = drptr->i_fun >> 1;
     222:             break;
     223:
     224:         case DRSTTY:
     225:             drptr->i_fun = (sgbuf[1] & 07) << 1;
     226:             dr->csr = drptr->i_fun;
     227:             drptr->i_flags &= ~(DR_TIMEOUT | DR_IGNORE);
     228:             drptr->i_flags |= sgbuf[0] & (DR_TIMEOUT | DR_IGNORE);
     229:             break;
     230:
     231:         case DRSFUN:
     232:             drptr->i_fun = (sgbuf[0] & 07) << 1;
     233:             dr->csr = drptr->i_fun;
     234:             break;
     235:
     236:         case DRSFLAG:
     237:             drptr->i_flags &= ~(DR_TIMEOUT | DR_IGNORE);
     238:             drptr->i_flags |= sgbuf[0] & (DR_TIMEOUT | DR_IGNORE);
     239:             break;
     240:
     241:         case DRGCSR:
     242:             sgbuf[0] = dr->csr;
     243:             sgbuf[1] = dr->wcr;
     244:             break;
     245:
     246:         case DRSSIG:
     247:             drptr->i_sig = sgbuf[0];
     248:             if((drptr->i_sig < 0) || (drptr->i_sig > 15)) {
     249:                 drptr->i_sig = 0;
     250:                 return (EINVAL);
     251:             }
     252:             break;
     253:
     254:         case DRESET:
     255:             dr->csr = DR_MANT | drptr->i_fun;
     256:             dr->csr = drptr->i_fun;
     257:             break;
     258:
     259:         case DRSTIME:
     260:             drptr->i_tsig = sgbuf[0];
     261:             if((drptr->i_tsig < 0) || (drptr->i_tsig > 15)) {
     262:                 drptr->i_tsig = 0;
     263:                 return (EINVAL);
     264:             }
     265:             drptr->i_flags |= DR_TIMEOUT;
     266:             drptr->i_flags &= ~DR_IGNORE;
     267:             break;
     268:
     269:         case DRCTIME:
     270:             drptr->i_flags &= ~(DR_TIMEOUT | DR_IGNORE);
     271:             break;
     272:
     273:         case DRITIME:
     274:             drptr->i_flags |= DR_IGNORE;
     275:             break;
     276:
     277:         case DROUTPUT:
     278:             dr->dar = sgbuf[0];
     279:             break;
     280:
     281:         case DRINPUT:
     282:             sgbuf[0] = dr->dar;
     283:             break;
     284:
     285:         default:
     286:             return (EINVAL);
     287:     }
     288:     return (0);
     289: }
     290:
     291: drtimeout(ptr)
     292: caddr_t ptr;
     293: {
     294:     register struct dr11w *drptr;
     295:     mapinfo map;
     296:
     297:     drptr = (struct dr11w *)ptr;
     298:     if((drptr->i_flags & DR_TACTIVE) && (drptr->i_req == drptr->i_prev))
     299:     {
     300:         printf("dr%d: timeout error\n", drptr->i_unit);
     301:         savemap(map);
     302:         if(drptr->i_tsig)
     303:             psignal(drptr->i_proc, drptr->i_tsig);
     304:
     305:         restormap(map);
     306:         drabort(drptr);
     307:         savemap(map);
     308:         if(drptr->i_tab.b_actf)
     309:             drstart(drptr);     /* start next request */
     310:         restormap(map);
     311:     }
     312:     if(drptr->i_flags & (DR_TACTIVE | DR_OPEN))
     313:     {
     314:         drptr->i_prev = drptr->i_req;   /* arm timeout */
     315:         timeout(drtimeout, ptr, hz);
     316:     }
     317: }
     318:
     319: drabort(drptr)
     320: register struct dr11w *drptr;
     321: {
     322:     register struct buf *bp;
     323:     register struct drdevice *dr;
     324:     mapinfo map;
     325:
     326:     savemap(map);
     327:     dr = drptr->i_addr;         /* point to device */
     328:     bp = drptr->i_tab.b_actf;       /* point to current buffer */
     329:     drptr->i_flags &= ~DR_TACTIVE;      /* turn off timeout active */
     330:     drptr->i_tab.b_active = 0;      /* clean up global stuff */
     331:     drptr->i_tab.b_errcnt = 0;
     332:     drptr->i_tab.b_actf = bp->b_forw;   /* link to next request */
     333:     bp->b_resid = -(dr->wcr) << 1;      /* make it bytes */
     334:     if(!(drptr->i_flags & DR_IGNORE))
     335:         bp->b_flags |= B_ERROR;     /* set an error condition */
     336:     dr->csr = DR_MANT | drptr->i_fun;   /* clear IE bit in csr */
     337:     dr->csr = drptr->i_fun;         /* restore function bits */
     338:     restormap(map);
     339:     iodone(bp);             /* done with that request */
     340: }
     341: #endif NDR

#### Defined functions

drabort defined in line 319; used 1 times

- in line 306

drattach defined in line 42; never used
drclose defined in line 79; never used
drintr defined in line 150; used 1 times

- in /usr/src/sys/pdp/scb.s line 328

drioctl defined in line 203; never used
dropen defined in line 58; never used
drstart defined in line 119; used 3 times

- in line 115, 200, 309

drstrategy defined in line 91; never used
drtimeout defined in line 291; used 3 times

- in line 63, 75, 315

#### Defined variables

dr11 defined in line 40; used 10 times

- in line 50-52(3), 66, 86-88(3), 98, 158, 213

#### Defined struct's

dr11w defined in line 27; used 18 times

- in line 40(2), 62(2), 95(2), 120(2), 155(2), 209(2), 294-297(4), 320(2)

Last modified: 1997-02-15 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1069 |