1 /* 2 * Copyright (c) 1982, 1986, 1988 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 * @(#)rk.c 7.7 (Berkeley) 07/09/88 7 */ 8 9 /* 10 * RK611/RK07 11 */ 12 #include "param.h" 13 #include "inode.h" 14 #include "fs.h" 15 #include "disklabel.h" 16 17 #include "../vax/pte.h" 18 19 #include "../vaxuba/ubareg.h" 20 #include "../vaxuba/rkreg.h" 21 22 #include "saio.h" 23 #include "savax.h" 24 25 #define SECTSIZ 512 /* sector size in bytes */ 26 27 #define MAXCTLR 1 /* all addresses must be specified */ 28 #define MAXUNIT 8 29 u_short rkstd[MAXCTLR] = { 0777440 }; 30 struct disklabel rklabel[MAXNUBA][MAXCTLR][MAXUNIT]; 31 char lbuf[SECTSIZ]; 32 33 rkopen(io) 34 register struct iob *io; 35 { 36 register struct rkdevice *rkaddr; 37 register struct disklabel *lp; 38 struct iob tio; 39 40 if ((u_int)io->i_adapt >= nuba) 41 return (EADAPT); 42 if ((u_int)io->i_ctlr >= MAXCTLR) 43 return (ECTLR); 44 if ((u_int)io->i_unit >= MAXUNIT) 45 return (EUNIT); 46 rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]); 47 if (badaddr((char *)rkaddr, sizeof(short))) 48 return (ENXIO); 49 rkaddr->rkcs2 = RKCS2_SCLR; 50 rkwait(rkaddr); 51 /* 52 * Read in the pack label. 53 */ 54 lp = &rklabel[io->i_adapt][io->i_ctlr][io->i_unit]; 55 lp->d_nsectors = NRKSECT; 56 lp->d_secpercyl = NRKTRK*NRKSECT; 57 tio = *io; 58 tio.i_bn = LABELSECTOR; 59 tio.i_ma = lbuf; 60 tio.i_cc = SECTSIZ; 61 tio.i_flgs |= F_RDDATA; 62 if (rkstrategy(&tio, READ) != SECTSIZ) 63 return (ERDLAB); 64 *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 65 if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) 66 #ifdef COMPAT_42 67 { 68 printf("rk%d: unlabeled\n", io->i_unit); 69 rkmaptype(io, lp); 70 } 71 #else 72 return (EUNLAB); 73 #endif 74 if ((u_int)io->i_part >= lp->d_npartitions || 75 (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1) 76 return (EPART); 77 return (0); 78 } 79 80 #ifdef COMPAT_42 81 u_long rk_off[] = { 0, 241, 0, -1, -1, -1, 393, -1 }; 82 83 rkmaptype(io, lp) 84 struct iob *io; 85 register struct disklabel *lp; 86 { 87 register struct partition *pp; 88 register u_long *off = rk_off; 89 register int i; 90 91 lp->d_npartitions = 8; 92 pp = lp->d_partitions; 93 for (i = 0; i < 8; i++, pp++) 94 pp->p_offset = *off++; 95 } 96 #endif 97 98 rkstrategy(io, func) 99 register struct iob *io; 100 { 101 register struct rkdevice *rkaddr; 102 register daddr_t bn; 103 int com, ubinfo, errcnt = 0; 104 short cn, sn, tn; 105 106 rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]); 107 retry: 108 ubinfo = ubasetup(io, 1); 109 bn = io->i_bn; 110 cn = bn / (NRKSECT*NRKTRK); 111 sn = bn % NRKSECT; 112 tn = (bn / NRKSECT) % NRKTRK; 113 rkaddr->rkcs2 = io->i_unit; 114 rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO; 115 rkwait(rkaddr); 116 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 117 rkwait(rkaddr); 118 rkaddr->rkda = sn | (tn << 8); 119 rkaddr->rkcyl = cn; 120 rkaddr->rkba = ubinfo; 121 rkaddr->rkwc = -(io->i_cc >> 1); 122 com = RK_CDT|((ubinfo>>8)&0x300)|RK_GO; 123 if (func == READ) 124 com |= RK_READ; 125 else 126 com |= RK_WRITE; 127 rkaddr->rkcs1 = com; 128 rkwait(rkaddr); 129 while ((rkaddr->rkds & RKDS_SVAL) == 0) 130 ; 131 ubafree(io, ubinfo); 132 if (rkaddr->rkcs1 & RK_CERR) { 133 printf("rk error: (cyl,trk,sec)=(%d,%d,%d) cs2=%b er=%b\n", 134 cn, tn, sn, rkaddr->rkcs2, RKCS2_BITS, 135 rkaddr->rker, RKER_BITS); 136 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 137 rkwait(rkaddr); 138 if (errcnt++ == 10) { 139 printf("rk: unrecovered error\n"); 140 return (-1); 141 } 142 goto retry; 143 } 144 if (errcnt) 145 printf("rk: recovered by retry\n"); 146 return (io->i_cc); 147 } 148 149 rkwait(rkaddr) 150 register struct rkdevice *rkaddr; 151 { 152 while ((rkaddr->rkcs1 & RK_CRDY) == 0); 153 } 154