|
|
1.1 ! root 1: /* up.c 4.1 11/9/80 */ ! 2: ! 3: #define OLDUCODE ! 4: ! 5: #include "../h/param.h" ! 6: #include "../h/inode.h" ! 7: #include "../h/pte.h" ! 8: #include "../h/uba.h" ! 9: #include "saio.h" ! 10: ! 11: #define EMULEX ! 12: #ifdef EMULEX ! 13: #define DELAY(N) { register int d; d = N; while (--d > 0); } ! 14: #else ! 15: #define DELAY(N) ! 16: #endif ! 17: ! 18: struct upregs { ! 19: short upcs1; /* Control and Status register 1 */ ! 20: short upwc; /* Word count register */ ! 21: short upba; /* UNIBUS address register */ ! 22: short upda; /* Desired address register */ ! 23: short upcs2; /* Control and Status register 2*/ ! 24: short upds; /* Drive Status */ ! 25: short uper1; /* Error register 1 */ ! 26: short upas; /* Attention Summary */ ! 27: short upla; /* Look ahead */ ! 28: short updb; /* Data buffer */ ! 29: short upmr; /* Maintenance register */ ! 30: short updt; /* Drive type */ ! 31: short upsn; /* Serial number */ ! 32: short upof; /* Offset register */ ! 33: short upca; /* Desired Cylinder address register*/ ! 34: short upcc; /* Current Cylinder */ ! 35: short uper2; /* Error register 2 */ ! 36: short uper3; /* Error register 3 */ ! 37: short uppos; /* Burst error bit position */ ! 38: short uppat; /* Burst error bit pattern */ ! 39: short upbae; /* 11/70 bus extension */ ! 40: }; ! 41: ! 42: #ifdef OLDUCODE ! 43: #define SDELAY 500 ! 44: #else ! 45: #define SDELAY 25 ! 46: #endif ! 47: int sdelay = SDELAY; ! 48: int idelay = 500; ! 49: ! 50: #define UPADDR ((struct upregs *)(PHYSUMEM + 0776700 - UNIBASE)) ! 51: ! 52: /* Drive commands, placed in upcs1 */ ! 53: #define GO 01 /* Go bit, set in all commands */ ! 54: #define PRESET 020 /* Preset drive at init or after errors */ ! 55: #define OFFSET 014 /* Offset heads to try to recover error */ ! 56: #define RTC 016 /* Return to center-line after OFFSET */ ! 57: #define SEARCH 030 /* Search for cylinder+sector */ ! 58: #define SEEK 04 /* Seek to cylinder */ ! 59: #define RECAL 06 /* Recalibrate, needed after seek error */ ! 60: #define DCLR 010 /* Drive clear, after error */ ! 61: #define WCOM 060 /* Write */ ! 62: #define RCOM 070 /* Read */ ! 63: ! 64: /* Other bits of upcs1 */ ! 65: #define IE 0100 /* Controller wide interrupt enable */ ! 66: #define TRE 040000 /* Transfer error */ ! 67: #define RDY 0200 /* Transfer terminated */ ! 68: ! 69: /* Drive status bits of upds */ ! 70: #define PIP 020000 /* Positioning in progress */ ! 71: #define ERR 040000 /* Error has occurred, DCLR necessary */ ! 72: #define VV 0100 /* Volume is valid, set by PRESET */ ! 73: #define DPR 0400 /* Drive has been preset */ ! 74: #define MOL 010000 /* Drive is online, heads loaded, etc */ ! 75: #define DRY 0200 /* Drive ready */ ! 76: ! 77: /* Bits of upcs2 */ ! 78: #define CLR 040 /* Controller clear */ ! 79: /* Bits of uper1 */ ! 80: #define DCK 0100000 /* Ecc error occurred */ ! 81: #define ECH 0100 /* Ecc error was unrecoverable */ ! 82: #define WLE 04000 /* Attempt to write read-only drive */ ! 83: ! 84: /* Bits of upof; the offset bits above are also in this register */ ! 85: #define FMT22 010000 /* 16 bits/word, must be always set */ ! 86: ! 87: struct devsize { ! 88: daddr_t cyloff; ! 89: } up_sizes[] = { ! 90: 0, 27, 68, -1, -1, -1, -1, 82 ! 91: }; ! 92: ! 93: upopen(io) ! 94: register struct iob *io; ! 95: { ! 96: ! 97: if (up_sizes[io->i_boff].cyloff == -1 || ! 98: io->i_boff < 0 || io->i_boff > 7) ! 99: _stop("up bad unit"); ! 100: io->i_boff = up_sizes[io->i_boff].cyloff * 32 * 19; ! 101: } ! 102: ! 103: upstrategy(io, func) ! 104: register struct iob *io; ! 105: { ! 106: int unit, nspc, ns, cn, tn, sn; ! 107: daddr_t bn; ! 108: int info; ! 109: register short *rp; ! 110: int occ = io->i_cc; ! 111: register struct upregs *upaddr = UPADDR; ! 112: ! 113: unit = io->i_unit; ! 114: bn = io->i_bn; ! 115: nspc = 32 * 19; ! 116: ns = 32; ! 117: cn = bn/nspc; ! 118: sn = bn%nspc; ! 119: tn = sn/ns; ! 120: sn = sn%ns; ! 121: upaddr->upcs2 = unit; ! 122: DELAY(sdelay); ! 123: if ((upaddr->upds & VV) == 0) { ! 124: upaddr->upcs1 = DCLR|GO; ! 125: DELAY(idelay); ! 126: upaddr->upcs1 = PRESET|GO; ! 127: DELAY(idelay); ! 128: upaddr->upof = FMT22; ! 129: } ! 130: if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) ! 131: _stop("up !DPR || !MOL"); ! 132: info = ubasetup(io, 1); ! 133: rp = (short *) &upaddr->upda; ! 134: upaddr->upca = cn; ! 135: *rp = (tn << 8) + sn; ! 136: *--rp = info; ! 137: *--rp = -io->i_cc / sizeof (short); ! 138: if (func == READ) ! 139: *--rp = GO|RCOM; ! 140: else ! 141: *--rp = GO|WCOM; ! 142: DELAY(sdelay); ! 143: do { ! 144: DELAY(25); ! 145: } while ((upaddr->upcs1 & RDY) == 0); ! 146: DELAY(200); ! 147: if (upaddr->upcs1&ERR) { ! 148: printf("disk error: cyl=%d track=%d sect=%d cs1=%X, er1=%X\n", ! 149: cn, tn, sn, ! 150: upaddr->upcs1, upaddr->uper1); ! 151: return (-1); ! 152: } ! 153: if (io->i_cc != occ) ! 154: printf("returned %d\n", io->i_cc); ! 155: ubafree(info); ! 156: return (io->i_cc); ! 157: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.