|
|
1.1 ! root 1: /* ! 2: * Nautilus console disks ! 3: */ ! 4: ! 5: #include "sys/param.h" ! 6: #include "sys/user.h" ! 7: #include "sys/buf.h" ! 8: #include "sys/conf.h" ! 9: ! 10: /* ! 11: * interface to console driver ! 12: * (on nautilus only) ! 13: * this should really be in a header somewhere ! 14: */ ! 15: ! 16: extern int *cniwrite(), *cniread(); ! 17: extern int cniwait(); ! 18: ! 19: int cbsopen(), cbsstrat(); ! 20: int cbsread(), cbswrite(); ! 21: ! 22: struct bdevsw cbsbdev = bdinit(cbsopen, nulldev, cbsstrat, 0); ! 23: struct cdevsw cbscdev = cdinit(cbsopen, nulldev, cbsread, cbswrite, nodev); ! 24: ! 25: #define NDEVS 3 ! 26: ! 27: static char cbsid[NDEVS] = { ! 28: 1, /* (0) first floppy */ ! 29: 4, /* (1) second floppy */ ! 30: 2, /* (2) winchester -- read only */ ! 31: }; ! 32: ! 33: #define BSCMD 0x9 /* ID to write commands */ ! 34: #define BSSTS 0x8 /* ID to read answers */ ! 35: #define SECTOR 512 ! 36: #define MAXBLK 65535 /* the limit is in the protocol */ ! 37: #define RCOM 0 ! 38: #define WCOM 1 ! 39: #define USHIFT 4 ! 40: #define STSTS(s) ((s)&017) /* status in status */ ! 41: #define STOK 0 ! 42: ! 43: #define UNIT(d) ((d)&077) /* in case of silly 0100 bit */ ! 44: ! 45: static char cbsbusy, cbswant; ! 46: ! 47: #define MAXRAW (8*SECTOR) ! 48: static struct buf cbsbuf; ! 49: static char cbsdat[MAXRAW]; ! 50: struct buf *cbsmkbuf(); ! 51: ! 52: cbsopen(dev) ! 53: dev_t dev; ! 54: { ! 55: if (UNIT(minor(dev)) >= NDEVS) ! 56: u.u_error = ENXIO; ! 57: } ! 58: ! 59: cbsread(dev) ! 60: dev_t dev; ! 61: { ! 62: register struct buf *bp; ! 63: ! 64: if ((bp = cbsmkbuf(dev, B_READ)) == NULL) ! 65: return; ! 66: cbsstrat(bp); ! 67: iowait(bp); ! 68: if (u.u_error == 0) ! 69: iomove(bp->b_un.b_addr, bp->b_bcount-bp->b_resid, B_READ); ! 70: cbsrelse(bp); ! 71: } ! 72: ! 73: cbswrite(dev) ! 74: dev_t dev; ! 75: { ! 76: register struct buf *bp; ! 77: ! 78: if ((bp = cbsmkbuf(dev, B_WRITE)) == NULL) ! 79: return; ! 80: iomove(bp->b_un.b_addr, bp->b_bcount, B_WRITE); ! 81: if (u.u_error) { ! 82: cbsrelse(bp); ! 83: return; ! 84: } ! 85: cbsstrat(bp); ! 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: bp->b_flags &=~ B_DONE; ! 110: splx(s); ! 111: bp->b_bcount = min(u.u_count, MAXRAW); ! 112: bp->b_un.b_addr = cbsdat; ! 113: bp->b_blkno = Ltol(u.u_offset) / SECTOR; ! 114: bp->b_dev = dev; ! 115: return (bp); ! 116: } ! 117: ! 118: cbsrelse(bp) ! 119: register struct buf *bp; ! 120: { ! 121: ! 122: if (bp->b_flags & B_WANTED) ! 123: wakeup((caddr_t)bp); ! 124: bp->b_flags &=~ (B_WANTED|B_BUSY); ! 125: } ! 126: ! 127: cbsstrat(bp) ! 128: struct buf *bp; ! 129: { ! 130: int s; ! 131: ! 132: if (bp->b_blkno >= 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); ! 146: else ! 147: cbswr(bp); ! 148: if (cbswant) { ! 149: cbswant = 0; ! 150: wakeup(&cbsbusy); ! 151: } ! 152: cbsbusy = 0; ! 153: } ! 154: ! 155: cbsrd(bp) ! 156: register struct buf *bp; ! 157: { ! 158: static char cmd[3]; ! 159: static char sts; ! 160: register int unit; ! 161: daddr_t blkno; ! 162: register char *buf; ! 163: register int *pst, *pdt; ! 164: ! 165: unit = UNIT(minor(bp->b_dev)); ! 166: blkno = bp->b_blkno; ! 167: bp->b_resid = bp->b_bcount; ! 168: buf = bp->b_un.b_addr; ! 169: while (bp->b_resid >= SECTOR) { ! 170: cmd[0] = RCOM|(unit<<USHIFT); ! 171: cmd[1] = blkno; ! 172: cmd[2] = blkno>>8; ! 173: pst = cniread(BSSTS, &sts, 1); ! 174: pdt = cniread(cbsid[unit], buf, SECTOR); ! 175: cniwrite(BSCMD, cmd, 3); ! 176: if (cniwait(pst, 5) || STSTS(sts) != STOK) { ! 177: *pdt = 0; ! 178: if (bp->b_resid != bp->b_bcount) ! 179: bp->b_flags |= B_ERROR; ! 180: break; ! 181: } ! 182: if (cniwait(pdt, 5)) { ! 183: if (bp->b_resid != bp->b_bcount) ! 184: bp->b_flags |= B_ERROR; ! 185: break; ! 186: } ! 187: blkno++; ! 188: buf += SECTOR; ! 189: bp->b_resid -= SECTOR; ! 190: } ! 191: iodone(bp); ! 192: } ! 193: ! 194: cbswr(bp) ! 195: register struct buf *bp; ! 196: { ! 197: static char cmd[3]; ! 198: static char sts; ! 199: register int unit; ! 200: daddr_t blkno; ! 201: register char *buf; ! 202: register int *pst, *pdt; ! 203: ! 204: unit = UNIT(minor(bp->b_dev)); ! 205: blkno = bp->b_blkno; ! 206: bp->b_resid = bp->b_bcount; ! 207: buf = bp->b_un.b_addr; ! 208: while (bp->b_resid >= SECTOR) { ! 209: cmd[0] = WCOM|(unit<<USHIFT); ! 210: cmd[1] = blkno; ! 211: cmd[2] = blkno>>8; ! 212: pst = cniread(BSSTS, &sts, 1); ! 213: cniwrite(BSCMD, cmd, 3); ! 214: pdt = cniwrite(cbsid[unit], buf, SECTOR); ! 215: if (cniwait(pst, 5) || STSTS(sts) != STOK) { ! 216: *pdt = 0; ! 217: if (bp->b_resid != bp->b_bcount) ! 218: bp->b_flags |= B_ERROR; ! 219: break; ! 220: } ! 221: if (cniwait(pdt, 1)) { ! 222: if (bp->b_resid != bp->b_bcount) ! 223: bp->b_flags |= B_ERROR; ! 224: break; ! 225: } ! 226: blkno++; ! 227: buf += SECTOR; ! 228: bp->b_resid -= SECTOR; ! 229: } ! 230: iodone(bp); ! 231: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.