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