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

##### Functions

    htattach          X
    htclose           X
    htcommand         X
    htinit            X
    htintr            X
    htioctl           X
    htopen            X
    htstart           X
    htstrategy        X

##### Variables

    HTADDR            X
    chtbuf            X
    httab             X
    tu_softc          X

##### Macros

    H_1600BPI         X
    H_NOREWIND        X
    INF               X
    SCOM              X
    SIO               X
    SOK               X
    SRETRY            X
    SSFOR             X
    SSREV             X
    TUUNIT            X

##### struct's

    softc             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:  *	@(#)ht.c	2.2 (2.11BSD GTE) 1/2/93
       7:  */
       8:
       9: /*
      10:  * TJU77/TWU77/TJE16/TWE16 tape driver
      11:  */
      12: #include "ht.h"
      13: #if NHT > 0
      14: #include "param.h"
      15: #include "buf.h"
      16: #include "ioctl.h"
      17: #include "conf.h"
      18: #include "file.h"
      19: #include "user.h"
      20: #include "mtio.h"
      21: #include "fs.h"
      22: #include "htreg.h"
      23: #include "systm.h"
      24:
      25: struct  buf httab, chtbuf;
      26: static  short   rh70;       /* ht.c was ONLY user of B_RH70 and that bit
      27: 				 * was wanted for something else (B_LOCKED)
      28: 				*/
      29: struct  htdevice    *HTADDR;
      30:
      31: #define INF 32760
      32:
      33: struct  softc   {
      34:     char    sc_openf;
      35:     char    sc_lastiow;
      36:     daddr_t sc_blkno;
      37:     daddr_t sc_nxrec;
      38:     u_short sc_erreg;
      39:     u_short sc_fsreg;
      40:     short   sc_resid;
      41:     short   sc_dens;
      42: }   tu_softc[NHT];
      43:
      44:
      45: #define SIO 1
      46: #define SSFOR   2
      47: #define SSREV   3
      48: #define SRETRY  4
      49: #define SCOM    5
      50: #define SOK 6
      51:
      52:
      53: /* bits in minor device */
      54: #define TUUNIT(dev) (minor(dev) & 03)
      55: #define H_NOREWIND  004
      56: #define H_1600BPI   010
      57:
      58: htattach(addr, unit)
      59: register struct htdevice *addr;
      60: {
      61:     /*
      62: 	 * This driver supports only one controller.
      63: 	 */
      64:     if (unit == 0) {
      65:         HTADDR = addr;
      66:         if (fioword(&(addr->htbae)) != -1)
      67:             rh70 = 1;
      68:         return(1);
      69:     }
      70:     return(0);
      71: }
      72:
      73: htopen(dev, flag)
      74: dev_t   dev;
      75: {
      76:     register ds;
      77:     register htunit = TUUNIT(dev);
      78:     register struct softc *sc = &tu_softc[htunit];
      79:     int olddens, dens;
      80:
      81:     httab.b_flags |= B_TAPE;
      82:     if (!HTADDR || htunit >= NHT)
      83:         return(ENXIO);
      84:     if (sc->sc_openf)
      85:         return(EBUSY);
      86:     sc->sc_blkno = (daddr_t) 0;
      87:     sc->sc_nxrec = (daddr_t) INF;
      88:     sc->sc_lastiow = 0;
      89:     olddens = sc->sc_dens;
      90:     dens = sc->sc_dens =
      91:         ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)|
      92:         HTTC_PDP11|htunit;
      93:     ds = htcommand(dev, HT_SENSE, 1);
      94:     sc->sc_dens = olddens;
      95:     if ((ds & HTFS_MOL) == 0) {
      96:         uprintf("tu%d: not online\n", htunit);
      97:         return(EIO);
      98:     }
      99:     if ((flag & FWRITE) && (ds & HTFS_WRL)) {
     100:         uprintf("tu%d: no write ring\n", htunit);
     101:         return(EIO);
     102:     }
     103:     if ((flag & FWRITE) && (ds & HTFS_BOT) == 0 &&
     104:         dens != sc->sc_dens) {
     105:         uprintf("tu%d: can't change density in mid-tape\n", htunit);
     106:         return (EIO);
     107:     }
     108:     sc->sc_openf = 1;
     109:     sc->sc_dens = dens;
     110:     return(0);
     111: }
     112:
     113: htclose(dev, flag)
     114: dev_t   dev;
     115: {
     116:     register struct softc *sc = &tu_softc[TUUNIT(dev)];
     117:
     118:     if (flag == FWRITE || ((flag & FWRITE) && sc->sc_lastiow)) {
     119:         htcommand(dev, HT_WEOF, 1);
     120:         htcommand(dev, HT_WEOF, 1);
     121:         htcommand(dev, HT_SREV, 1);
     122:     }
     123:     if ((minor(dev) & H_NOREWIND) == 0)
     124:         htcommand(dev, HT_REW, 1);
     125:     sc->sc_openf = 0;
     126: }
     127:
     128: /*ARGSUSED*/
     129: htcommand(dev, com, count)
     130: u_short count;
     131: dev_t   dev;
     132: {
     133:     register s;
     134:     register struct buf *bp;
     135:
     136:     bp = &chtbuf;
     137:     s = splbio();
     138:     while(bp->b_flags & B_BUSY) {
     139:         /*
     140: 		 * This special check is because B_BUSY never
     141: 		 * gets cleared in the non-waiting rewind case.
     142: 		 */
     143:         if (bp->b_repcnt == 0 && (bp->b_flags & B_DONE))
     144:             break;
     145:         bp->b_flags |= B_WANTED;
     146:         sleep((caddr_t) bp, PRIBIO);
     147:     }
     148:     bp->b_flags = B_BUSY | B_READ;
     149:     splx(s);
     150:     bp->b_dev = dev;
     151:     if (com == HT_SFORW || com == HT_SREV)
     152:         bp->b_repcnt = count;
     153:     bp->b_command = com;
     154:     bp->b_blkno = (daddr_t) 0;
     155:     htstrategy(bp);
     156:     /*
     157: 	 * In case of rewind from close, don't wait.
     158: 	 * This is the only case where count can be 0.
     159: 	 */
     160:     if (count == 0)
     161:         return(0);
     162:     iowait(bp);
     163:     if(bp->b_flags & B_WANTED)
     164:         wakeup((caddr_t)bp);
     165:     bp->b_flags &= B_ERROR;
     166:     return (bp->b_resid);
     167: }
     168:
     169: htstrategy(bp)
     170: register struct buf *bp;
     171: {
     172:     register int s;
     173:     register struct softc *sc = &tu_softc[TUUNIT(bp->b_dev)];
     174:
     175:     if (rh70 == 0)
     176:         mapalloc(bp);
     177:     if (bp->b_flags & B_PHYS) {
     178:         sc->sc_blkno = sc->sc_nxrec = dbtofsb(bp->b_blkno);
     179:         sc->sc_nxrec++;
     180:     }
     181:     bp->av_forw = NULL;
     182:     s = splbio();
     183:     if (httab.b_actf == NULL)
     184:         httab.b_actf = bp;
     185:     else
     186:         httab.b_actl->av_forw = bp;
     187:     httab.b_actl = bp;
     188:     if (httab.b_active == 0)
     189:         htstart();
     190:     splx(s);
     191: }
     192:
     193: htstart()
     194: {
     195:     register struct buf *bp;
     196:     register den;
     197:     daddr_t blkno;
     198:     register struct softc *sc;
     199:
     200:     loop:
     201:     if ((bp = httab.b_actf) == NULL)
     202:         return;
     203:     sc = &tu_softc[TUUNIT(bp->b_dev)];
     204:     sc->sc_erreg = HTADDR->hter;
     205:     sc->sc_fsreg = HTADDR->htfs;
     206:     sc->sc_resid = HTADDR->htfc;
     207:     HTADDR->htcs2 = 0;  /* controller 0 - do we need this? */
     208:     if ((HTADDR->httc & 03777) != sc->sc_dens)
     209:         HTADDR->httc = sc->sc_dens;
     210:     sc->sc_lastiow = 0;
     211:     if (sc->sc_openf < 0 || HTADDR->htcs2 & HTCS2_NEF || !(HTADDR->htfs & HTFS_MOL))
     212:         goto abort;
     213:     if (bp == &chtbuf) {
     214:         if (bp->b_command == HT_SENSE) {
     215:             bp->b_resid = HTADDR->htfs;
     216:             goto next;
     217:         }
     218:         httab.b_active = SCOM;
     219:         HTADDR->htfc = 0;
     220:         HTADDR->htcs1 = bp->b_command | HT_IE | HT_GO;
     221:         return;
     222:     }
     223:     if (dbtofsb(bp->b_blkno) > sc->sc_nxrec)
     224:         goto abort;
     225:     if (dbtofsb(bp->b_blkno) == sc->sc_nxrec && bp->b_flags & B_READ) {
     226:         /*
     227: 		 * Reading at end of file returns 0 bytes.
     228: 		 * Buffer will be cleared (if written) in rwip.
     229: 		*/
     230:         bp->b_resid = bp->b_bcount;
     231:         goto next;
     232:     }
     233:     if ((bp->b_flags & B_READ) == 0)
     234:         /*
     235: 		 * Writing sets EOF
     236: 		*/
     237:         sc->sc_nxrec = dbtofsb(bp->b_blkno) + 1;
     238:     if ((blkno = sc->sc_blkno) == dbtofsb(bp->b_blkno)) {
     239:         httab.b_active = SIO;
     240:         HTADDR->htba = bp->b_un.b_addr;
     241:         if (rh70)
     242:             HTADDR->htbae = bp->b_xmem;
     243:         HTADDR->htfc = -bp->b_bcount;
     244:         HTADDR->htwc = -(bp->b_bcount >> 1);
     245:         den = ((bp->b_xmem & 3) << 8) | HT_IE | HT_GO;
     246:         if(bp->b_flags & B_READ)
     247:             den |= HT_RCOM;
     248:         else {
     249:             if(HTADDR->htfs & HTFS_EOT) {
     250:                 bp->b_resid = bp->b_bcount;
     251:                 bp->b_error = ENXIO;
     252:                 httab.b_active = 0;
     253:                 goto next;
     254:             }
     255:             den |= HT_WCOM;
     256:         }
     257:         HTADDR->htcs1 = den;
     258:     } else {
     259:         if (blkno < dbtofsb(bp->b_blkno)) {
     260:             httab.b_active = SSFOR;
     261:             HTADDR->htfc = blkno - dbtofsb(bp->b_blkno);
     262:             HTADDR->htcs1 = HT_SFORW | HT_IE | HT_GO;
     263:         } else {
     264:             httab.b_active = SSREV;
     265:             HTADDR->htfc = dbtofsb(bp->b_blkno) - blkno;
     266:             HTADDR->htcs1 = HT_SREV | HT_IE | HT_GO;
     267:         }
     268:     }
     269:     return;
     270:
     271:     abort:
     272:     bp->b_flags |= B_ERROR;
     273:
     274:     next:
     275:     httab.b_actf = bp->av_forw;
     276:     iodone(bp);
     277:     goto loop;
     278: }
     279:
     280: htintr()
     281: {
     282:     register struct buf *bp;
     283:     register state;
     284:     int err, htunit;
     285:     register struct softc *sc;
     286:
     287:     if ((bp = httab.b_actf) == NULL)
     288:         return;
     289:     htunit = TUUNIT(bp->b_dev);
     290:     sc = &tu_softc[htunit];
     291:     sc->sc_erreg = HTADDR->hter;
     292:     sc->sc_fsreg = HTADDR->htfs;
     293:     sc->sc_resid = HTADDR->htfc;
     294:     if ((bp->b_flags & B_READ) == 0)
     295:         sc->sc_lastiow = 1;
     296:     state = httab.b_active;
     297:     httab.b_active = 0;
     298:     if (HTADDR->htcs1 & HT_TRE) {
     299:         err = HTADDR->hter;
     300:         if (HTADDR->htcs2 & HTCS2_ERR || (err & HTER_HARD))
     301:             state = 0;
     302:         if (bp->b_flags & B_PHYS)
     303:             err &= ~HTER_FCE;
     304:         if ((bp->b_flags & B_READ) && (HTADDR->htfs & HTFS_PES))
     305:             err &= ~(HTER_CSITM | HTER_CORCRC);
     306:         if ((HTADDR->htfs & HTFS_MOL) == 0) {
     307:             if(sc->sc_openf)
     308:                 sc->sc_openf = -1;
     309:         }
     310:         else
     311:             if (HTADDR->htfs & HTFS_TM) {
     312:                 HTADDR->htwc = -(bp->b_bcount >> 1);
     313:                 sc->sc_nxrec = dbtofsb(bp->b_blkno);
     314:                 state = SOK;
     315:             }
     316:             else
     317:                 if (state && err == 0)
     318:                     state = SOK;
     319:         if (httab.b_errcnt > 4)
     320:             printf("tu%d: hard error bn %D er=%b ds=%b\n",
     321:                    htunit, bp->b_blkno,
     322:                    sc->sc_erreg, HTER_BITS,
     323:                    sc->sc_fsreg, HTFS_BITS);
     324:         htinit();
     325:         if (state == SIO && ++httab.b_errcnt < 10) {
     326:             httab.b_active = SRETRY;
     327:             sc->sc_blkno++;
     328:             HTADDR->htfc = -1;
     329:             HTADDR->htcs1 = HT_SREV | HT_IE | HT_GO;
     330:             return;
     331:         }
     332:         if (state != SOK) {
     333:             bp->b_flags |= B_ERROR;
     334:             state = SIO;
     335:         }
     336:     } else
     337:         if (HTADDR->htcs1 & HT_SC)
     338:             if(HTADDR->htfs & HTFS_ERR)
     339:                 htinit();
     340:
     341:     switch (state) {
     342:         case SIO:
     343:         case SOK:
     344:             sc->sc_blkno++;
     345:
     346:         case SCOM:
     347:             httab.b_errcnt = 0;
     348:             httab.b_actf = bp->av_forw;
     349:             iodone(bp);
     350:             bp->b_resid = -(HTADDR->htwc << 1);
     351:             break;
     352:
     353:         case SRETRY:
     354:             if((bp->b_flags & B_READ) == 0) {
     355:                 httab.b_active = SSFOR;
     356:                 HTADDR->htcs1 = HT_ERASE | HT_IE | HT_GO;
     357:                 return;
     358:             }
     359:
     360:         case SSFOR:
     361:         case SSREV:
     362:             if(HTADDR->htfs & HTFS_TM) {
     363:                 if(state == SSREV) {
     364:                     sc->sc_nxrec = dbtofsb(bp->b_blkno) - HTADDR->htfc;
     365:                     sc->sc_blkno = sc->sc_nxrec;
     366:                 } else
     367:                     {
     368:                     sc->sc_nxrec = dbtofsb(bp->b_blkno) + HTADDR->htfc - 1;
     369:                     sc->sc_blkno = sc->sc_nxrec + 1;
     370:                 }
     371:             } else
     372:                 sc->sc_blkno = dbtofsb(bp->b_blkno);
     373:             break;
     374:
     375:         default:
     376:             return;
     377:     }
     378:     htstart();
     379: }
     380:
     381: htinit()
     382: {
     383:     register ocs2;
     384:     register omttc;
     385:
     386:     omttc = HTADDR->httc & 03777;   /* preserve old slave select, dens, format */
     387:     ocs2 = HTADDR->htcs2 & 07;  /* preserve old unit */
     388:
     389:     HTADDR->htcs2 = HTCS2_CLR;
     390:     HTADDR->htcs2 = ocs2;
     391:     HTADDR->httc = omttc;
     392:     HTADDR->htcs1 = HT_DCLR | HT_GO;
     393: }
     394:
     395: /*ARGSUSED*/
     396: htioctl(dev, cmd, data, flag)
     397:     dev_t dev;
     398:     u_int cmd;
     399:     caddr_t data;
     400:     int flag;
     401: {
     402:     register struct buf *bp = &chtbuf;
     403:     register struct softc *sc = &tu_softc[minor(dev)&07];
     404:     register callcount;
     405:     int fcount;
     406:     struct  mtop *mtop;
     407:     struct  mtget *mtget;
     408:     /* we depend on the values and order of the MT codes here */
     409:     static  htops[] = {HT_WEOF, HT_SFORW, HT_SREV, HT_SFORW,
     410:         HT_SREV, HT_REW, HT_REWOFFL, HT_SENSE};
     411:
     412:     switch (cmd) {
     413:     case MTIOCTOP:
     414:         mtop = (struct mtop *)data;
     415:         switch (mtop->mt_op) {
     416:         case MTWEOF:
     417:             callcount = mtop->mt_count;
     418:             fcount = 1;
     419:             break;
     420:         case MTFSF: case MTBSF:
     421:             callcount = mtop->mt_count;
     422:             fcount = INF;
     423:             break;
     424:         case MTFSR: case MTBSR:
     425:             callcount = 1;
     426:             fcount = mtop->mt_count;
     427:             break;
     428:         case MTREW: case MTOFFL: case MTNOP:
     429:             callcount = 1;
     430:             fcount = 1;
     431:             break;
     432:         default:
     433:             return (ENXIO);
     434:         }
     435:         if (callcount <= 0 || fcount <= 0)
     436:             return (EINVAL);
     437:         while (--callcount >= 0) {
     438:             htcommand(dev, htops[mtop->mt_op], fcount);
     439:             if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) &&
     440:                 bp->b_resid)
     441:                 return (EIO);
     442:             if ((bp->b_flags&B_ERROR) || sc->sc_fsreg&HTFS_BOT)
     443:                 break;
     444:         }
     445:         return (geterror(bp));
     446:     case MTIOCGET:
     447:         mtget = (struct mtget *)data;
     448:         mtget->mt_dsreg = sc->sc_fsreg;
     449:         mtget->mt_erreg = sc->sc_erreg;
     450:         mtget->mt_resid = sc->sc_resid;
     451:         mtget->mt_type = MT_ISHT;
     452:         break;
     453:     default:
     454:         return (ENXIO);
     455:     }
     456:     return (0);
     457: }
     458: #endif NHT

#### Defined functions

htattach defined in line 58; never used
htclose defined in line 113; never used
htcommand defined in line 129; used 6 times

- in line 93, 119-124(4), 438

htinit defined in line 381; used 2 times

- in line 324, 339

htintr defined in line 280; used 1 times

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

htioctl defined in line 396; never used
htopen defined in line 73; never used
htstart defined in line 193; used 2 times

- in line 189, 378

htstrategy defined in line 169; used 1 times

- in line 155

#### Defined variables

HTADDR defined in line 29; used 48 times

- in line 65, 82, 204-220(11), 240-249(5), 257-266(5), 291-312(10), 328-329(2), 337-338(2), 350, 356, 362-368(3), 386-392(6)

chtbuf defined in line 25; used 3 times

- in line 136, 213, 402

httab defined in line 25; used 22 times

- in line 81, 183-188(5), 201, 218, 239, 252, 260-264(2), 275, 287, 296-297(2), 319, 325-326(2), 347-348(2), 355

rh70 defined in line 26; used 3 times

- in line 67, 175, 241

tu_softc defined in line 42; used 6 times

- in line 78, 116, 173, 203, 290, 403

#### Defined struct's

softc defined in line 33; used 12 times

- in line 78(2), 116(2), 173(2), 198(2), 285(2), 403(2)

#### Defined macros

H_1600BPI defined in line 56; used 1 times

- in line 91

H_NOREWIND defined in line 55; used 1 times

- in line 123

INF defined in line 31; used 2 times

- in line 87, 422

SCOM defined in line 49; used 1 times

- in line 218

SIO defined in line 45; used 3 times

- in line 239, 325, 334

SOK defined in line 50; used 3 times

- in line 314-318(2), 332

SRETRY defined in line 48; used 1 times

- in line 326

SSFOR defined in line 46; used 2 times

- in line 260, 355

SSREV defined in line 47; used 2 times

- in line 264, 363

TUUNIT defined in line 54; used 5 times

- in line 77, 116, 173, 203, 289

Last modified: 1993-01-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1489 |