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