|
|
1.1 ! root 1: /* ! 2: * Star console floppy ! 3: * -- traces of multiple drives; this was derived from Nautilus. ! 4: * It is probably easier to leave the traces in for future need. ! 5: */ ! 6: ! 7: #include "sys/param.h" ! 8: #include "sys/user.h" ! 9: #include "sys/buf.h" ! 10: #include "sys/conf.h" ! 11: ! 12: /* ! 13: * interface to console driver ! 14: * this should really be in a header somewhere ! 15: */ ! 16: ! 17: extern int *cniwrite(), *cniread(); ! 18: extern int cniwait(); ! 19: ! 20: int cbsopen(), cbsread(), cbswrite(); ! 21: ! 22: struct cdevsw cbscdev = cdinit(cbsopen, nulldev, cbsread, cbswrite, nodev); ! 23: ! 24: #define NDEVS 1 ! 25: ! 26: static char cbsid[NDEVS] = { ! 27: 1, /* (0) floppy */ ! 28: }; ! 29: ! 30: #define BSCMD 0x9 /* ID to write commands */ ! 31: #define BSSTS 0x2 /* ID to read answers */ ! 32: #define SECTOR 128 ! 33: #define SECTRK 26 ! 34: #define MAXBLK (77*SECTRK) ! 35: #define RCOM 0 ! 36: #define WCOM 1 ! 37: #define USHIFT 4 ! 38: #define STSTS(s) ((s)&0200) /* status in status */ ! 39: #define STOK 0 ! 40: ! 41: #define UNIT(d) ((d)&077) /* in case of silly 0100 bit */ ! 42: ! 43: static char cbsbusy, cbswant; ! 44: ! 45: #define MAXRAW (4*SECTOR) ! 46: static struct buf cbsbuf; ! 47: static char cbsdat[MAXRAW]; ! 48: struct buf *cbsmkbuf(); ! 49: ! 50: cbsopen(dev) ! 51: dev_t dev; ! 52: { ! 53: if (UNIT(minor(dev)) >= NDEVS) ! 54: u.u_error = ENXIO; ! 55: } ! 56: ! 57: cbsread(dev) ! 58: dev_t dev; ! 59: { ! 60: register struct buf *bp; ! 61: ! 62: if ((bp = cbsmkbuf(dev, B_READ)) == NULL) ! 63: return; ! 64: cbsdoio(bp, (daddr_t)(Ltol(u.u_offset)/SECTOR)); ! 65: iowait(bp); ! 66: if (u.u_error == 0) ! 67: iomove(bp->b_un.b_addr, bp->b_bcount-bp->b_resid, B_READ); ! 68: cbsrelse(bp); ! 69: } ! 70: ! 71: cbswrite(dev) ! 72: dev_t dev; ! 73: { ! 74: register struct buf *bp; ! 75: daddr_t sno; ! 76: ! 77: if ((bp = cbsmkbuf(dev, B_WRITE)) == NULL) ! 78: return; ! 79: sno = Ltol(u.u_offset)/SECTOR; ! 80: iomove(bp->b_un.b_addr, bp->b_bcount, B_WRITE); ! 81: if (u.u_error) { ! 82: cbsrelse(bp); ! 83: return; ! 84: } ! 85: cbsdoio(bp, sno); ! 86: iowait(bp); ! 87: cbsrelse(bp); ! 88: } ! 89: ! 90: struct buf * ! 91: cbsmkbuf(dev, rw) ! 92: dev_t dev; ! 93: int rw; ! 94: { ! 95: register struct buf *bp; ! 96: register int s; ! 97: ! 98: if (u.u_count < SECTOR || (Ltol(u.u_offset) % SECTOR) != 0) { ! 99: u.u_error = ENXIO; ! 100: return (NULL); ! 101: } ! 102: bp = &cbsbuf; ! 103: s = spl6(); ! 104: while (bp->b_flags & B_BUSY) { ! 105: bp->b_flags |= B_WANTED; ! 106: sleep((caddr_t)bp, PRIBIO); ! 107: } ! 108: bp->b_flags = B_BUSY | rw; ! 109: splx(s); ! 110: bp->b_bcount = min(u.u_count, MAXRAW); ! 111: bp->b_un.b_addr = cbsdat; ! 112: bp->b_dev = dev; ! 113: /* b_blkno unused by any code we'll call */ ! 114: return (bp); ! 115: } ! 116: ! 117: cbsrelse(bp) ! 118: register struct buf *bp; ! 119: { ! 120: ! 121: if (bp->b_flags & B_WANTED) ! 122: wakeup((caddr_t)bp); ! 123: bp->b_flags &=~ (B_WANTED|B_BUSY); ! 124: } ! 125: ! 126: cbsdoio(bp, sno) ! 127: struct buf *bp; ! 128: daddr_t sno; ! 129: { ! 130: int s; ! 131: ! 132: if (sno >= MAXBLK) { ! 133: bp->b_flags |= B_ERROR; ! 134: iodone(bp); ! 135: return; ! 136: } ! 137: s = spl6(); ! 138: while (cbsbusy) { ! 139: cbswant++; ! 140: sleep(&cbsbusy); ! 141: } ! 142: cbsbusy++; ! 143: splx(s); ! 144: if (bp->b_flags & B_READ) ! 145: cbsrd(bp, sno); ! 146: else ! 147: cbswr(bp, sno); ! 148: if (cbswant) { ! 149: cbswant = 0; ! 150: wakeup(&cbsbusy); ! 151: } ! 152: cbsbusy = 0; ! 153: } ! 154: ! 155: cbsrd(bp, sno) ! 156: register struct buf *bp; ! 157: daddr_t sno; ! 158: { ! 159: static char cmd[2]; ! 160: static unsigned char sts; ! 161: register int unit; ! 162: register char *buf; ! 163: register int *pst, *pdt; ! 164: ! 165: unit = UNIT(minor(bp->b_dev)); ! 166: bp->b_resid = bp->b_bcount; ! 167: buf = bp->b_un.b_addr; ! 168: while (bp->b_resid >= SECTOR) { ! 169: cmd[0] = RCOM|(unit<<USHIFT); ! 170: pst = cniwrite(BSCMD, cmd, 1); ! 171: if (cniwait(pst, 5)) { ! 172: bp->b_flags |= B_ERROR; ! 173: break; ! 174: } ! 175: cmd[0] = (sno%SECTRK) + 1; ! 176: cmd[1] = sno / SECTRK; ! 177: pst = cniread(BSSTS, &sts, 1); ! 178: pdt = cniread(cbsid[unit], buf, SECTOR); ! 179: cniwrite(cbsid[unit], cmd, 2); ! 180: if (cniwait(pst, 5) || STSTS(sts) != STOK) { ! 181: *pdt = 0; ! 182: if (bp->b_resid != bp->b_bcount) ! 183: bp->b_flags |= B_ERROR; ! 184: break; ! 185: } ! 186: if (cniwait(pdt, 5)) { ! 187: if (bp->b_resid != bp->b_bcount) ! 188: bp->b_flags |= B_ERROR; ! 189: break; ! 190: } ! 191: sno++; ! 192: buf += SECTOR; ! 193: bp->b_resid -= SECTOR; ! 194: } ! 195: iodone(bp); ! 196: } ! 197: ! 198: cbswr(bp, sno) ! 199: register struct buf *bp; ! 200: daddr_t sno; ! 201: { ! 202: static char cmd[2]; ! 203: static unsigned char sts; ! 204: register int unit; ! 205: register char *buf; ! 206: register int *pst, *pdt; ! 207: ! 208: unit = UNIT(minor(bp->b_dev)); ! 209: bp->b_resid = bp->b_bcount; ! 210: buf = bp->b_un.b_addr; ! 211: while (bp->b_resid >= SECTOR) { ! 212: cmd[0] = WCOM|(unit<<USHIFT); ! 213: pst = cniwrite(BSCMD, cmd, 1); ! 214: if (cniwait(pst, 5)) { ! 215: bp->b_flags |= B_ERROR; ! 216: break; ! 217: } ! 218: cmd[0] = (sno%SECTRK) + 1; ! 219: cmd[1] = sno / SECTRK; ! 220: pst = cniread(BSSTS, &sts, 1); ! 221: pdt = cniwrite(cbsid[unit], cmd, 2); ! 222: if (cniwait(pdt, 5)) { ! 223: *pst = 0; ! 224: bp->b_flags |= B_ERROR; ! 225: break; ! 226: } ! 227: pdt = cniwrite(cbsid[unit], buf, SECTOR); ! 228: if (cniwait(pst, 5) || STSTS(sts) != STOK) { ! 229: *pdt = 0; ! 230: if (bp->b_resid != bp->b_bcount) ! 231: bp->b_flags |= B_ERROR; ! 232: break; ! 233: } ! 234: if (cniwait(pdt, 1)) { ! 235: if (bp->b_resid != bp->b_bcount) ! 236: bp->b_flags |= B_ERROR; ! 237: break; ! 238: } ! 239: sno++; ! 240: buf += SECTOR; ! 241: bp->b_resid -= SECTOR; ! 242: } ! 243: iodone(bp); ! 244: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.