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
drattach defined in line 42; never used
drclose defined in line 79; never used
drintr defined in line 150; used 1 times
drioctl defined in line 203; never used
dropen defined in line 58; never used
drstart defined in line 119; used 3 times
drstrategy defined in line 91; never used
drtimeout defined in line 291; used 3 times

Defined variables

dr11 defined in line 40; used 10 times

Defined struct's

dr11w defined in line 27; used 18 times
Last modified: 1997-02-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3745
Valid CSS Valid XHTML 1.0 Strict