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

##### Functions

    rxattach          X
    rxintr            X
    rxioctl           X
    rxopen            X
    rxstart           X
    rxstrategy        X

##### Variables

    RXADDR            X
    crxbuf            X
    rxtab             X

##### Macros

    DENSITY           X
    NBPS              X
    NRXBLKS           X
    NSPB              X
    RXGID             X
    SEMPTY            X
    SFILL             X
    SFORMAT           X
    SINIT             X
    SREAD             X
    SWRITE            X
    UNIT              X
    rxwait            X
    seccnt            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:  *	@(#)rx.c	1.4 (2.11BSD GTE) 1995/11/27
       7:  */
       8:
       9: /*
      10:  * RX02 floppy disk device driver
      11:  *
      12:  * sms - November 26, 1995.
      13:  * Actually got it working with a 18 bit controller on a 22 bit Qbus.
      14:  *
      15:  * sms - November 21, 1995.
      16:  * Moved from OTHERS/rx02/#2 into the supported directory: sys/pdpuba.
      17:  * Added conditionalized support for a "software unibus/qbus map" so that
      18:  * 18 bit controllers could be supported in 22 bit Qbus systems.
      19:  *
      20:  * Date: Sun, 8 May 88 18:42:38 CDT
      21:  * uunet!nuchat!steve@rutgers.edu (Steve Nuchia)
      22:  * The rx02 driver as distributed didn't even come close to working
      23:  * on a Q22 machine - probe was wrong and it got worse from there.
      24:  *
      25:  * This driver was written by Bill Shannon and distributed on the
      26:  * DEC v7m UNIX tape.  It has been modified for 2BSD and has been
      27:  * included with the permission of the DEC UNIX Engineering Group.
      28:  *
      29:  * Modified to actually work with 2.9BSD by Gregory Travis, Indiana Univ.
      30:  *
      31:  *	Layout of logical devices:
      32:  *
      33:  *	name	min dev		unit	density
      34:  *	----	-------		----	-------
      35:  *	rx0a	   0		  0	single
      36:  *	rx1a	   1		  1	single
      37:  *	rx0b	   2		  0	double
      38:  *	rx1b	   3		  1	double
      39:  *
      40:  *	ioctl function call may be used to format a disk.
      41:  */
      42:
      43: #include "rx.h"
      44: #if NRX > 0
      45: #include "param.h"
      46: #include "buf.h"
      47: #include "conf.h"
      48: #include "ioctl.h"
      49: #include "tty.h"
      50: #include "rxreg.h"
      51: #include "errno.h"
      52: #include "map.h"
      53: #include "uba.h"
      54:
      55: struct  rxdevice *RXADDR;
      56:
      57: /*
      58:  *	the following defines use some fundamental
      59:  *	constants of the RX02.
      60:  */
      61: #define NSPB    ((minor(bp->b_dev)&2) ? 2 : 4)      /* sectors per block */
      62: #define NRXBLKS ((minor(bp->b_dev)&2) ? 1001 : 500) /* blocks on device */
      63: #define NBPS    ((minor(bp->b_dev)&2) ? 256 : 128)  /* bytes per sector */
      64: #define DENSITY (minor(bp->b_dev)&2)    /* Density: 0 = single, 2 = double */
      65: #define UNIT    (minor(bp->b_dev)&1)    /* Unit Number: 0 = left, 1 = right */
      66: #define RXGID   (RX_GO | RX_IE | (DENSITY << 7))
      67:
      68: #define rxwait()    while (((RXADDR->rxcs) & RX_XREQ) == 0)
      69: #define seccnt(bp)  ((int)((bp)->b_seccnt))
      70:
      71: struct  buf rxtab;
      72: struct  buf crxbuf;     /* buffer header for control functions */
      73:
      74: /*
      75:  * DEC controllers do not do 22 bit DMA but 3rd party (Sigma MXV-22) can.
      76:  * 'rxsoftmap' can be patched (via 'adb') as indicated below to inhibit
      77:  * the probing (checking bit 10 in the CSR) for 22 bit controllers.
      78: */
      79:
      80: static  char    mxv22;      /* MXV22 can do native 22 bit DMA */
      81: static  char    rxsoftmap = -1; /* -1 = OK to check for soft map
      82: 				 *  0 = Never use soft map
      83: 				 *  1 = Always use soft map
      84: 				*/
      85:
      86: /*
      87:  *	states of driver, kept in b_state
      88:  */
      89: #define SREAD   1   /* read started */
      90: #define SEMPTY  2   /* empty started */
      91: #define SFILL   3   /* fill started */
      92: #define SWRITE  4   /* write started */
      93: #define SINIT   5   /* init started */
      94: #define SFORMAT 6   /* format started */
      95:
      96: rxattach(addr, unit)
      97:     struct rxdevice *addr;
      98:     u_int unit;
      99:     {
     100:
     101:     if  (unit != 0)
     102:         return(0);
     103:     RXADDR = addr;
     104:     if  (addr->rxcs & RX_Q22)   /* 22 bit capable? */
     105:         mxv22 = 1;
     106: /*
     107:  * If it is not a 22 bit controller and there is no Unibus map and
     108:  * it is permitted to switch to a soft map then set the "use soft map" flag.
     109: */
     110:     if  (!mxv22 && !ubmap && rxsoftmap == -1)
     111:         rxsoftmap = 1;
     112:     return(1);
     113:     }
     114:
     115: /*ARGSUSED*/
     116: rxopen(dev, flag)
     117:     dev_t dev;
     118: {
     119:     if (minor(dev) >= 4 || !RXADDR)
     120:         return (ENXIO);
     121:     return (0);
     122: }
     123:
     124: rxstrategy(bp)
     125:     register struct buf *bp;
     126: {
     127:     register int s;
     128:
     129:     if (minor(bp->b_dev) >= 4 || !RXADDR)
     130:         goto bad;
     131:     if (bp->b_blkno >= NRXBLKS) {
     132:         if (bp->b_flags&B_READ)
     133:             bp->b_resid = bp->b_bcount;
     134:         else {
     135: bad:            bp->b_flags |= B_ERROR;
     136:             bp->b_error = ENXIO;
     137:         }
     138:         iodone(bp);
     139:         return;
     140:     }
     141:
     142: #ifdef  SOFUB_MAP
     143:     if  (rxsoftmap == 1)
     144:         {
     145:         if  (sofub_alloc(bp) == 0)
     146:             return;
     147:         }
     148:     else
     149: #endif
     150:         mapalloc(bp);
     151:
     152:     bp->av_forw = (struct buf *) NULL;
     153:
     154:     /*
     155: 	 * seccnt is actually the number of floppy sectors transferred,
     156: 	 * incremented by one after each successful transfer of a sector.
     157: 	 */
     158:     seccnt(bp) = 0;
     159:
     160:     /*
     161: 	 * We'll modify b_resid as each piece of the transfer
     162: 	 * successfully completes.  It will also tell us when
     163: 	 * the transfer is complete.
     164: 	 */
     165:     bp->b_resid = bp->b_bcount;
     166:     s = splbio();
     167:     if (rxtab.b_actf == NULL)
     168:         rxtab.b_actf = bp;
     169:     else
     170:         rxtab.b_actl->av_forw = bp;
     171:     rxtab.b_actl = bp;
     172:     if (rxtab.b_state == NULL)
     173:         rxstart();
     174:     splx(s);
     175: }
     176:
     177: rxstart()
     178: {
     179:     register struct buf *bp;
     180:     int addr, xmem, cmd;
     181:     int n, sector, track;
     182:
     183:     if ((bp = rxtab.b_actf) == NULL) {
     184:         rxtab.b_state = NULL;
     185:         return;
     186:     }
     187:
     188:     if (bp == &crxbuf) {        /* is it a control request ? */
     189:         rxtab.b_state = SFORMAT;
     190:         RXADDR->rxcs = RX_SMD | RXGID | (UNIT << 4);
     191:         rxwait();
     192:         RXADDR->rxdb = 0111;
     193:     } else
     194:     if (bp->b_flags & B_READ) {
     195:         rxtab.b_state = SREAD;
     196:         rxfactr((int)bp->b_blkno * NSPB + seccnt(bp), &sector, &track);
     197:         RXADDR->rxcs = RX_RSECT | RXGID | (UNIT << 4);
     198:         rxwait();
     199:         RXADDR->rxsa = sector;
     200:         rxwait();
     201:         RXADDR->rxta = track;
     202:     } else {
     203:         rxtab.b_state = SFILL;
     204:         n = bp->b_resid >= NBPS ? NBPS : bp->b_resid;
     205:         rxaddr ( bp, &addr, &xmem );
     206:         if  (rxsoftmap <= 0)
     207:             cmd = RX_Q22;
     208:         else
     209:             cmd = 0;
     210:         RXADDR->rxcs = RX_FILL | RXGID | ((xmem & 3) << 12) | cmd;
     211:         rxwait();
     212:         RXADDR->rxwc = n >> 1;
     213:         rxwait();
     214:         RXADDR->rxba = addr;
     215:         if  (rxsoftmap <= 0)
     216:             {
     217:             rxwait();
     218:             RXADDR->rxba = xmem;
     219:             }
     220:     }
     221: }
     222:
     223: rxintr()
     224: {
     225:     register struct buf *bp;
     226:     int n, sector, track, cmd;
     227: static  rxerr[4];
     228:     char    *decode;
     229:     int addr, xmem;
     230:
     231:     if (rxtab.b_state == SINIT) {
     232:         rxstart();
     233:         return;
     234:     }
     235:
     236:     if ((bp = rxtab.b_actf) == NULL)
     237:         return;
     238:
     239:     if (RXADDR->rxcs & RX_ERR) {
     240:         if (rxtab.b_errcnt++ > 10 || rxtab.b_state == SFORMAT) {
     241:             bp->b_flags |= B_ERROR;
     242:             harderr(bp, "rx");
     243:             printf("cs=%b er=%b\n", RXADDR->rxcs, RX_BITS,
     244:                 RXADDR->rxes, RXES_BITS);
     245:             RXADDR->rxcs = RX_RDEC | RX_GO;
     246:             rxwait();
     247:             RXADDR->rxba = (short) rxerr;
     248:             while ( ! (RXADDR->rxcs & RX_DONE) );
     249:             switch ( rxerr[0] )
     250:             {
     251:             case 0040: decode = "bad track"; break;
     252:             case 0050: decode = "found home"; break;
     253:             case 0070: decode = "no sch sctr"; break;
     254:             case 0120: decode = "no preamble"; break;
     255:             case 0150: decode = "ozone headers"; break;
     256:             case 0160: decode = "too many IDAM"; break;
     257:             case 0170: decode = "data AM missing"; break;
     258:             case 0200: decode = "CRC error"; break;
     259:             case 0240: decode = "density error"; break;
     260:             case 0250: decode = "bad fmt key"; break;
     261:             case 0260: decode = "bad data AM"; break;
     262:             case 0270: decode = "POK while write"; break;
     263:             case 0300: decode = "drv not ready"; break;
     264:             case 0310: decode = "write protected"; break;
     265:             default: decode = "unknown error"; break;
     266:             }
     267:             printf("rx: err %o=%s\n", rxerr[0], decode );
     268:             rxtab.b_errcnt = 0;
     269:             rxtab.b_actf = bp->av_forw;
     270: #ifdef  SOFUB_MAP
     271:             if  (rxsoftmap == 1)
     272:                 sofub_relse(bp, bp->b_bcount);
     273: #endif
     274:             iodone(bp);
     275:         }
     276:         RXADDR->rxcs = RX_INIT;
     277:         RXADDR->rxcs = RX_IE;
     278:         rxtab.b_state = SINIT;
     279:         return;
     280:     }
     281:     switch (rxtab.b_state) {
     282:
     283:     case SREAD:         /* read done, start empty */
     284:         rxtab.b_state = SEMPTY;
     285:         n = bp->b_resid >= NBPS? NBPS : bp->b_resid;
     286:         rxaddr ( bp, &addr, &xmem );
     287:         if  (rxsoftmap <= 0)
     288:             cmd = RX_Q22;
     289:         else
     290:             cmd = 0;
     291:         RXADDR->rxcs = RX_EMPTY | RXGID | ((xmem & 3) << 12) | cmd;
     292:         rxwait();
     293:         RXADDR->rxwc = n >> 1;
     294:         rxwait();
     295:         RXADDR->rxba = addr;
     296:         if  (rxsoftmap <= 0)
     297:             {
     298:             rxwait();
     299:             RXADDR->rxba = xmem;
     300:             }
     301:         return;
     302:
     303:     case SFILL:         /* fill done, start write */
     304:         rxtab.b_state = SWRITE;
     305:         rxfactr((int)bp->b_blkno * NSPB + seccnt(bp), &sector, &track);
     306:         RXADDR->rxcs = RX_WSECT | RXGID | (UNIT << 4);
     307:         rxwait();
     308:         RXADDR->rxsa = sector;
     309:         rxwait();
     310:         RXADDR->rxta = track;
     311:         return;
     312:
     313:     case SEMPTY:            /* empty done, start next read */
     314:     case SWRITE:            /* write done, start next fill */
     315:         /*
     316: 		 * increment amount remaining to be transferred.
     317: 		 * if it becomes positive, last transfer was a
     318: 		 * partial sector and we're done, so set remaining
     319: 		 * to zero.
     320: 		 */
     321:         if (bp->b_resid <= NBPS) {
     322: done:
     323:             bp->b_resid = 0;
     324:             rxtab.b_errcnt = 0;
     325:             rxtab.b_actf = bp->av_forw;
     326: #ifdef  SOFUB_MAP
     327:             if  (rxsoftmap == 1)
     328:                 sofub_relse(bp, bp->b_bcount);
     329: #endif
     330:             iodone(bp);
     331:             break;
     332:         }
     333:
     334:         bp->b_resid -= NBPS;
     335:         seccnt(bp)++;
     336:         break;
     337:
     338:     case SFORMAT:           /* format done (whew!!!) */
     339:         goto done;      /* driver's getting too big... */
     340:     }
     341:
     342:     /* end up here from states SWRITE and SEMPTY */
     343:     rxstart();
     344: }
     345:
     346: /*
     347:  *	rxfactr -- calculates the physical sector and physical
     348:  *	track on the disk for a given logical sector.
     349:  *	call:
     350:  *		rxfactr(logical_sector,&p_sector,&p_track);
     351:  *	the logical sector number (0 - 2001) is converted
     352:  *	to a physical sector number (1 - 26) and a physical
     353:  *	track number (0 - 76).
     354:  *	the logical sectors specify physical sectors that
     355:  *	are interleaved with a factor of 2. thus the sectors
     356:  *	are read in the following order for increasing
     357:  *	logical sector numbers (1,3, ... 23,25,2,4, ... 24,26)
     358:  *	There is also a 6 sector slew between tracks.
     359:  *	Logical sectors start at track 1, sector 1; go to
     360:  *	track 76 and then to track 0.  Thus, for example, unix block number
     361:  *	498 starts at track 0, sector 25 and runs thru track 0, sector 2
     362:  *	(or 6 depending on density).
     363:  */
     364: static
     365: rxfactr(sectr, psectr, ptrck)
     366:     register int sectr;
     367:     int *psectr, *ptrck;
     368: {
     369:     register int p1, p2;
     370:
     371:     p1 = sectr / 26;
     372:     p2 = sectr % 26;
     373:     /* 2 to 1 interleave */
     374:     p2 = (2 * p2 + (p2 >= 13 ?  1 : 0)) % 26;
     375:     /* 6 sector per track slew */
     376:     *psectr = 1 + (p2 + 6 * p1) % 26;
     377:     if (++p1 >= 77)
     378:         p1 = 0;
     379:     *ptrck = p1;
     380: }
     381:
     382:
     383: /*
     384:  *	rxaddr -- compute core address where next sector
     385:  *	goes to / comes from based on bp->b_un.b_addr, bp->b_xmem,
     386:  *	and seccnt(bp).
     387:  */
     388: static
     389: rxaddr(bp, addr, xmem)
     390:     register struct buf *bp;
     391:     register u_int *addr, *xmem;
     392: {
     393:     *addr = (u_int)bp->b_un.b_addr + (seccnt(bp) * NBPS);
     394:     *xmem = bp->b_xmem;
     395:     if (*addr < (u_int)bp->b_un.b_addr) /* overflow, bump xmem */
     396:         (*xmem)++;
     397: }
     398:
     399: /*
     400:  *	rxioctl -- format RX02 disk, single or double density.
     401:  *	density determined by device opened.
     402:  */
     403: /*ARGSUSED*/
     404: rxioctl(dev, cmd, addr, flag)
     405:     dev_t dev;
     406:     u_int cmd;
     407: {
     408:     register int s;
     409:     register struct buf *bp;
     410:
     411:     if (cmd != RXIOC_FORMAT)
     412:         return (ENXIO);
     413:     bp = &crxbuf;
     414:     while (bp->b_flags & B_BUSY) {
     415:         s = splbio();
     416:         bp->b_flags |= B_WANTED;
     417:         sleep(bp, PRIBIO);
     418:     }
     419:     splx(s);
     420:     bp->b_flags = B_BUSY;
     421:     bp->b_dev = dev;
     422:     bp->b_error = 0;
     423:     rxstrategy(bp);
     424:     iowait(bp);
     425:     bp->b_flags = 0;
     426:     return (0);
     427: }
     428: #endif

#### Defined functions

rxaddr defined in line 388; used 2 times

- in line 205, 286

rxattach defined in line 96; never used
rxfactr defined in line 364; used 2 times

- in line 196, 305

rxintr defined in line 223; used 1 times

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

rxioctl defined in line 404; never used
rxopen defined in line 116; never used
rxstart defined in line 177; used 3 times

- in line 173, 232, 343

rxstrategy defined in line 124; used 1 times

- in line 423

#### Defined variables

RXADDR defined in line 55; used 28 times

- in line 68, 103, 119, 129, 190-201(5), 210-218(4), 239-248(6), 276-277(2), 291-299(4), 306-310(3)

crxbuf defined in line 72; used 2 times

- in line 188, 413

mxv22 defined in line 80; used 2 times

- in line 105-110(2)

rxsoftmap defined in line 81; used 9 times

- in line 110-111(2), 143, 206, 215, 271, 287, 296, 327

rxtab defined in line 71; used 22 times

- in line 167-172(5), 183-189(3), 195, 203, 231-240(4), 268-269(2), 278-284(3), 304, 324-325(2)

#### Defined macros

DENSITY defined in line 64; used 1 times

- in line 66

NBPS defined in line 63; used 7 times

- in line 204(2), 285(2), 321, 334, 393

NRXBLKS defined in line 62; used 1 times

- in line 131

NSPB defined in line 61; used 2 times

- in line 196, 305

RXGID defined in line 66; used 5 times

- in line 190, 197, 210, 291, 306

SEMPTY defined in line 90; used 1 times

- in line 284

SFILL defined in line 91; used 1 times

- in line 203

SFORMAT defined in line 94; used 2 times

- in line 189, 240

SINIT defined in line 93; used 2 times

- in line 231, 278

SREAD defined in line 89; used 1 times

- in line 195

SWRITE defined in line 92; used 1 times

- in line 304

UNIT defined in line 65; used 3 times

- in line 190, 197, 306

rxwait defined in line 68; used 12 times

- in line 191, 198-200(2), 211-217(3), 246, 292-298(3), 307-309(2)

seccnt defined in line 69; used 5 times

- in line 158, 196, 305, 335, 393

Last modified: 1995-11-28 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1132 |