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.2 (Berkeley) 02/21/87 7 */ 8 9 /* 10 * RK611/RK07 11 */ 12 #include "../machine/pte.h" 13 14 #include "../h/param.h" 15 #include "../h/inode.h" 16 #include "../h/fs.h" 17 #include "../h/disklabel.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 u_short rkstd[] = { 0777440 }; 28 struct disklabel rklabel[MAXNUBA*8]; 29 char lbuf[SECTSIZ]; 30 31 rkopen(io) 32 register struct iob *io; 33 { 34 register struct rkdevice *rkaddr = (struct rkdevice *)ubamem(io->i_unit, rkstd[0]); 35 register struct disklabel *lp = &rklabel[io->i_unit]; 36 struct iob tio; 37 38 if (badaddr((char *)rkaddr, sizeof(short))) { 39 printf("nonexistent device"); 40 return (ENXIO); 41 } 42 rkaddr->rkcs2 = RKCS2_SCLR; 43 rkwait(rkaddr); 44 /* 45 * Read in the pack label. 46 */ 47 lp->d_nsectors = NRKSECT; 48 lp->d_secpercyl = NRKTRK*NRKSECT; 49 tio = *io; 50 tio.i_bn = LABELSECTOR; 51 tio.i_ma = lbuf; 52 tio.i_cc = SECTSIZ; 53 tio.i_flgs |= F_RDDATA; 54 if (rkstrategy(&tio, READ) != SECTSIZ) { 55 printf("can't read disk label"); 56 return (EIO); 57 } 58 *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 59 if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 60 printf("hk%d: unlabeled\n", io->i_unit); 61 #ifdef COMPAT_42 62 rkmaptype(io, lp); 63 #else 64 return (ENXIO); 65 #endif 66 } 67 if ((unsigned)io->i_boff >= lp->d_npartitions || 68 (io->i_boff = lp->d_partitions[io->i_boff].p_offset) == -1) { 69 printf("rk: bad partition"); 70 return (EUNIT); 71 } 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 register struct iob *io; 80 register struct disklabel *lp; 81 { 82 register struct partition *pp; 83 register i; 84 register u_long *off = rk_off; 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 = (struct rkdevice *)ubamem(io->i_unit, rkstd[0]); 97 int com; 98 daddr_t bn; 99 short dn, cn, sn, tn; 100 int ubinfo, errcnt = 0; 101 102 retry: 103 ubinfo = ubasetup(io, 1); 104 bn = io->i_bn; 105 dn = UNITTODRIVE(io->i_unit); 106 cn = bn/(NRKSECT*NRKTRK); 107 sn = bn%NRKSECT; 108 tn = (bn / NRKSECT) % NRKTRK; 109 rkaddr->rkcs2 = dn; 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 errcnt++; 139 goto retry; 140 } 141 if (errcnt) 142 printf("rk: recovered by retry\n"); 143 return (io->i_cc); 144 } 145 146 rkwait(rkaddr) 147 register struct rkdevice *rkaddr; 148 { 149 150 while ((rkaddr->rkcs1 & RK_CRDY) == 0) 151 ; 152 } 153 154 /*ARGSUSED*/ 155 rkioctl(io, cmd, arg) 156 struct iob *io; 157 int cmd; 158 caddr_t arg; 159 { 160 161 return (ECMD); 162 } 163