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), §or, &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), §or, &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