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