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.9 (Berkeley) 12/16/90 7 */ 8 9 /* 10 * RK611/RK07 11 */ 12 #include "sys/param.h" 13 #include "sys/disklabel.h" 14 15 #include "../include/pte.h" 16 17 #include "../uba/ubareg.h" 18 #include "../uba/rkreg.h" 19 20 #include "stand/saio.h" 21 #include "savax.h" 22 23 #define SECTSIZ 512 /* sector size in bytes */ 24 25 #define MAXCTLR 1 /* all addresses must be specified */ 26 #define MAXUNIT 8 27 u_short rkstd[MAXCTLR] = { 0777440 }; 28 struct disklabel rklabel[MAXNUBA][MAXCTLR][MAXUNIT]; 29 char lbuf[SECTSIZ]; 30 31 rkopen(io) 32 register struct iob *io; 33 { 34 register struct rkdevice *rkaddr; 35 register struct disklabel *lp; 36 struct iob tio; 37 38 if ((u_int)io->i_adapt >= nuba) 39 return (EADAPT); 40 if ((u_int)io->i_ctlr >= MAXCTLR) 41 return (ECTLR); 42 if ((u_int)io->i_unit >= MAXUNIT) 43 return (EUNIT); 44 rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]); 45 if (badaddr((char *)rkaddr, sizeof(short))) 46 return (ENXIO); 47 rkaddr->rkcs2 = RKCS2_SCLR; 48 rkwait(rkaddr); 49 /* 50 * Read in the pack label. 51 */ 52 lp = &rklabel[io->i_adapt][io->i_ctlr][io->i_unit]; 53 lp->d_nsectors = NRKSECT; 54 lp->d_secpercyl = NRKTRK*NRKSECT; 55 tio = *io; 56 tio.i_bn = LABELSECTOR; 57 tio.i_ma = lbuf; 58 tio.i_cc = SECTSIZ; 59 tio.i_flgs |= F_RDDATA; 60 if (rkstrategy(&tio, READ) != SECTSIZ) 61 return (ERDLAB); 62 *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 63 if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) 64 #ifdef COMPAT_42 65 { 66 printf("rk%d: unlabeled\n", io->i_unit); 67 rkmaptype(io, lp); 68 } 69 #else 70 return (EUNLAB); 71 #endif 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