123237Smckusick /* 229306Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323237Smckusick * All rights reserved. The Berkeley software License Agreement 423237Smckusick * specifies the terms and conditions for redistribution. 523237Smckusick * 6*30547Skarels * @(#)rk.c 7.2 (Berkeley) 02/21/87 723237Smckusick */ 81915Swnj 91915Swnj /* 103263Swnj * RK611/RK07 111915Swnj */ 129806Ssam #include "../machine/pte.h" 131915Swnj 141915Swnj #include "../h/param.h" 151915Swnj #include "../h/inode.h" 167446Sroot #include "../h/fs.h" 17*30547Skarels #include "../h/disklabel.h" 189186Ssam 199186Ssam #include "../vaxuba/ubareg.h" 209186Ssam #include "../vaxuba/rkreg.h" 219186Ssam 221915Swnj #include "saio.h" 233263Swnj #include "savax.h" 241915Swnj 25*30547Skarels #define SECTSIZ 512 /* sector size in bytes */ 26*30547Skarels 273263Swnj u_short rkstd[] = { 0777440 }; 28*30547Skarels struct disklabel rklabel[MAXNUBA*8]; 29*30547Skarels char lbuf[SECTSIZ]; 301915Swnj 311915Swnj rkopen(io) 323263Swnj register struct iob *io; 331915Swnj { 343349Swnj register struct rkdevice *rkaddr = (struct rkdevice *)ubamem(io->i_unit, rkstd[0]); 35*30547Skarels register struct disklabel *lp = &rklabel[io->i_unit]; 36*30547Skarels struct iob tio; 371915Swnj 38*30547Skarels if (badaddr((char *)rkaddr, sizeof(short))) { 39*30547Skarels printf("nonexistent device"); 40*30547Skarels return (ENXIO); 41*30547Skarels } 423349Swnj rkaddr->rkcs2 = RKCS2_SCLR; 433349Swnj rkwait(rkaddr); 44*30547Skarels /* 45*30547Skarels * Read in the pack label. 46*30547Skarels */ 47*30547Skarels lp->d_nsectors = NRKSECT; 48*30547Skarels lp->d_secpercyl = NRKTRK*NRKSECT; 49*30547Skarels tio = *io; 50*30547Skarels tio.i_bn = LABELSECTOR; 51*30547Skarels tio.i_ma = lbuf; 52*30547Skarels tio.i_cc = SECTSIZ; 53*30547Skarels tio.i_flgs |= F_RDDATA; 54*30547Skarels if (rkstrategy(&tio, READ) != SECTSIZ) { 55*30547Skarels printf("can't read disk label"); 56*30547Skarels return (EIO); 57*30547Skarels } 58*30547Skarels *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 59*30547Skarels if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 60*30547Skarels printf("hk%d: unlabeled\n", io->i_unit); 61*30547Skarels #ifdef COMPAT_42 62*30547Skarels rkmaptype(io, lp); 63*30547Skarels #else 64*30547Skarels return (ENXIO); 65*30547Skarels #endif 66*30547Skarels } 67*30547Skarels if ((unsigned)io->i_boff >= lp->d_npartitions || 68*30547Skarels (io->i_boff = lp->d_partitions[io->i_boff].p_offset) == -1) { 69*30547Skarels printf("rk: bad partition"); 70*30547Skarels return (EUNIT); 71*30547Skarels } 72*30547Skarels return (0); 731915Swnj } 741915Swnj 75*30547Skarels #ifdef COMPAT_42 76*30547Skarels u_long rk_off[] = { 0, 241, 0, -1, -1, -1, 393, -1 }; 77*30547Skarels 78*30547Skarels rkmaptype(io, lp) 79*30547Skarels register struct iob *io; 80*30547Skarels register struct disklabel *lp; 81*30547Skarels { 82*30547Skarels register struct partition *pp; 83*30547Skarels register i; 84*30547Skarels register u_long *off = rk_off; 85*30547Skarels 86*30547Skarels lp->d_npartitions = 8; 87*30547Skarels pp = lp->d_partitions; 88*30547Skarels for (i = 0; i < 8; i++, pp++) 89*30547Skarels pp->p_offset = *off++; 90*30547Skarels } 91*30547Skarels #endif 92*30547Skarels 931915Swnj rkstrategy(io, func) 943263Swnj register struct iob *io; 951915Swnj { 963263Swnj register struct rkdevice *rkaddr = (struct rkdevice *)ubamem(io->i_unit, rkstd[0]); 973263Swnj int com; 981915Swnj daddr_t bn; 991915Swnj short dn, cn, sn, tn; 1003349Swnj int ubinfo, errcnt = 0; 1011915Swnj 1023349Swnj retry: 1031915Swnj ubinfo = ubasetup(io, 1); 1041915Swnj bn = io->i_bn; 105*30547Skarels dn = UNITTODRIVE(io->i_unit); 1063263Swnj cn = bn/(NRKSECT*NRKTRK); 1073263Swnj sn = bn%NRKSECT; 1083263Swnj tn = (bn / NRKSECT) % NRKTRK; 1093263Swnj rkaddr->rkcs2 = dn; 1103263Swnj rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO; 1113263Swnj rkwait(rkaddr); 1123349Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 1133349Swnj rkwait(rkaddr); 1143263Swnj rkaddr->rkda = sn | (tn << 8); 1153263Swnj rkaddr->rkcyl = cn; 1163263Swnj rkaddr->rkba = ubinfo; 1173263Swnj rkaddr->rkwc = -(io->i_cc >> 1); 1184038Swnj com = RK_CDT|((ubinfo>>8)&0x300)|RK_GO; 1193263Swnj if (func == READ) 1203263Swnj com |= RK_READ; 1213263Swnj else 1223263Swnj com |= RK_WRITE; 1233263Swnj rkaddr->rkcs1 = com; 1243263Swnj rkwait(rkaddr); 1253349Swnj while ((rkaddr->rkds & RKDS_SVAL) == 0) 1261915Swnj ; 1273263Swnj ubafree(io, ubinfo); 1283263Swnj if (rkaddr->rkcs1 & RK_CERR) { 1293349Swnj printf("rk error: (cyl,trk,sec)=(%d,%d,%d) cs2=%b er=%b\n", 1303349Swnj cn, tn, sn, rkaddr->rkcs2, RKCS2_BITS, 1313349Swnj rkaddr->rker, RKER_BITS); 1323349Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 1333263Swnj rkwait(rkaddr); 1343349Swnj if (errcnt == 10) { 1353349Swnj printf("rk: unrecovered error\n"); 1363349Swnj return (-1); 1373349Swnj } 1383349Swnj errcnt++; 1393349Swnj goto retry; 1401915Swnj } 1413349Swnj if (errcnt) 1423349Swnj printf("rk: recovered by retry\n"); 1431915Swnj return (io->i_cc); 1441915Swnj } 1453263Swnj 1463263Swnj rkwait(rkaddr) 1473263Swnj register struct rkdevice *rkaddr; 1483263Swnj { 1493263Swnj 1503263Swnj while ((rkaddr->rkcs1 & RK_CRDY) == 0) 1513263Swnj ; 1523263Swnj } 15310024Ssam 15410024Ssam /*ARGSUSED*/ 15510024Ssam rkioctl(io, cmd, arg) 15610024Ssam struct iob *io; 15710024Ssam int cmd; 15810024Ssam caddr_t arg; 15910024Ssam { 16010024Ssam 16110024Ssam return (ECMD); 16210024Ssam } 163