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
rxattach defined in line 96; never used
rxfactr defined in line 364; used 2 times
rxintr defined in line 223; used 1 times
rxioctl defined in line 404; never used
rxopen defined in line 116; never used
rxstart defined in line 177; used 3 times
rxstrategy defined in line 124; used 1 times

Defined variables

RXADDR defined in line 55; used 28 times
crxbuf defined in line 72; used 2 times
mxv22 defined in line 80; used 2 times
rxsoftmap defined in line 81; used 9 times
rxtab defined in line 71; used 22 times

Defined macros

DENSITY defined in line 64; used 1 times
  • in line 66
NBPS defined in line 63; used 7 times
NRXBLKS defined in line 62; used 1 times
NSPB defined in line 61; used 2 times
RXGID defined in line 66; used 5 times
SEMPTY defined in line 90; used 1 times
SFILL defined in line 91; used 1 times
SFORMAT defined in line 94; used 2 times
SINIT defined in line 93; used 2 times
SREAD defined in line 89; used 1 times
SWRITE defined in line 92; used 1 times
UNIT defined in line 65; used 3 times
rxwait defined in line 68; used 12 times
seccnt defined in line 69; used 5 times
Last modified: 1995-11-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3681
Valid CSS Valid XHTML 1.0 Strict