| 1 | /* up.c 4.9 81/04/18 */ |
| 2 | |
| 3 | #include "../h/param.h" |
| 4 | #include "../h/inode.h" |
| 5 | #include "../h/upreg.h" |
| 6 | #include "../h/pte.h" |
| 7 | #include "../h/ubareg.h" |
| 8 | #include "saio.h" |
| 9 | #include "savax.h" |
| 10 | |
| 11 | u_short ubastd[] = { 0776700 }; |
| 12 | char up_gottype[MAXNUBA*8] = { 0 }; |
| 13 | char up_type[MAXNUBA*8] = { 0 }; |
| 14 | short up_off[] = { 0, 27, 68, -1, -1, -1, -1, 82 }; |
| 15 | short fj_off[] = { 0, 50, 0, -1, -1, -1, -1, 155 }; |
| 16 | struct upst { |
| 17 | short nsect; |
| 18 | short ntrak; |
| 19 | short nspc; |
| 20 | short ncyl; |
| 21 | short *off; |
| 22 | } upst[] = { |
| 23 | 32, 19, 32*19, 823, up_off, |
| 24 | 32, 10, 32*10, 823, fj_off, |
| 25 | }; |
| 26 | |
| 27 | upopen(io) |
| 28 | register struct iob *io; |
| 29 | { |
| 30 | register struct updevice *upaddr = |
| 31 | (struct updevice *)ubamem(io->i_unit, ubastd[0]); |
| 32 | register struct upst *st; |
| 33 | |
| 34 | while ((upaddr->upcs1 & UP_DVA) == 0) |
| 35 | ; |
| 36 | if (up_gottype[io->i_unit] == 0) { |
| 37 | upaddr->uphr = UPHR_MAXTRAK; |
| 38 | if (upaddr->uphr == 9) |
| 39 | up_type[io->i_unit] = 1; /* fuji kludge */ |
| 40 | upaddr->upcs2 = UPCS2_CLR; |
| 41 | up_gottype[io->i_unit] = 1; |
| 42 | } |
| 43 | st = &upst[up_type[io->i_unit]]; |
| 44 | if (io->i_boff < 0 || io->i_boff > 7 || st->off[io->i_boff] == -1) |
| 45 | _stop("up bad unit"); |
| 46 | io->i_boff = st->off[io->i_boff] * st->nspc; |
| 47 | } |
| 48 | |
| 49 | upstrategy(io, func) |
| 50 | register struct iob *io; |
| 51 | { |
| 52 | int unit, nspc, ns, cn, tn, sn; |
| 53 | daddr_t bn; |
| 54 | int info; |
| 55 | register short *rp; |
| 56 | register struct updevice *upaddr = |
| 57 | (struct updevice *)ubamem(io->i_unit, ubastd[0]); |
| 58 | register struct upst *st = &upst[up_type[io->i_unit]]; |
| 59 | |
| 60 | unit = io->i_unit; |
| 61 | bn = io->i_bn; |
| 62 | cn = bn/st->nspc; |
| 63 | sn = bn%st->nspc; |
| 64 | tn = sn/st->nsect; |
| 65 | sn = sn%st->nsect; |
| 66 | upaddr->upcs2 = unit; |
| 67 | if ((upaddr->upds & UPDS_VV) == 0) { |
| 68 | upaddr->upcs1 = UP_DCLR|UP_GO; |
| 69 | upaddr->upcs1 = UP_PRESET|UP_GO; |
| 70 | upaddr->upof = UPOF_FMT22; |
| 71 | } |
| 72 | if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) |
| 73 | _stop("up not ready"); |
| 74 | info = ubasetup(io, 1); |
| 75 | rp = (short *) &upaddr->upda; |
| 76 | upaddr->updc = cn; |
| 77 | *rp = (tn << 8) + sn; |
| 78 | *--rp = info; |
| 79 | *--rp = -io->i_cc / sizeof (short); |
| 80 | if (func == READ) |
| 81 | *--rp = UP_RCOM|UP_GO; |
| 82 | else |
| 83 | *--rp = UP_WCOM|UP_GO; |
| 84 | do { |
| 85 | DELAY(25); |
| 86 | } while ((upaddr->upcs1 & UP_RDY) == 0); |
| 87 | if (upaddr->upds & UPDS_ERR) { |
| 88 | printf("up error: (cyl,trk,sec)=(%d,%d,%d) cs2=%b er1=%b er2=%b\n", |
| 89 | cn, tn, sn, |
| 90 | upaddr->upcs2, UPCS2_BITS, upaddr->uper1, UPER1_BITS, |
| 91 | upaddr->uper2, UPER2_BITS); |
| 92 | return (-1); |
| 93 | } |
| 94 | ubafree(io, info); |
| 95 | return (io->i_cc); |
| 96 | } |