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*33548Sbostic * @(#)rk.c 7.5 (Berkeley) 02/24/88 723237Smckusick */ 81915Swnj 91915Swnj /* 103263Swnj * RK611/RK07 111915Swnj */ 1233408Skarels #include "param.h" 1333408Skarels #include "inode.h" 1433408Skarels #include "fs.h" 1533408Skarels #include "disklabel.h" 161915Swnj 1733408Skarels #include "../vax/pte.h" 189186Ssam 199186Ssam #include "../vaxuba/ubareg.h" 209186Ssam #include "../vaxuba/rkreg.h" 219186Ssam 221915Swnj #include "saio.h" 233263Swnj #include "savax.h" 241915Swnj 2533541Sbostic #define SECTSIZ 512 /* sector size in bytes */ 2630547Skarels 2733541Sbostic #define MAXCTLR 1 /* all addresses must be specified */ 2833541Sbostic u_short rkstd[MAXCTLR] = { 0777440 }; 2933541Sbostic struct disklabel rklabel[MAXNUBA][MAXCTLR][8]; 3030547Skarels char lbuf[SECTSIZ]; 311915Swnj 321915Swnj rkopen(io) 333263Swnj register struct iob *io; 341915Swnj { 3533541Sbostic register struct rkdevice *rkaddr; 3633541Sbostic register struct disklabel *lp; 3730547Skarels struct iob tio; 381915Swnj 3933541Sbostic if ((u_int)io->i_ctlr >= MAXCTLR) 4033541Sbostic return (ECTLR); 4133541Sbostic rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]); 42*33548Sbostic if (badaddr((char *)rkaddr, sizeof(short))) 4330547Skarels return (ENXIO); 443349Swnj rkaddr->rkcs2 = RKCS2_SCLR; 453349Swnj rkwait(rkaddr); 4630547Skarels /* 4730547Skarels * Read in the pack label. 4830547Skarels */ 4933541Sbostic lp = &rklabel[io->i_adapt][io->i_ctlr][io->i_unit]; 5030547Skarels lp->d_nsectors = NRKSECT; 5130547Skarels lp->d_secpercyl = NRKTRK*NRKSECT; 5230547Skarels tio = *io; 5330547Skarels tio.i_bn = LABELSECTOR; 5430547Skarels tio.i_ma = lbuf; 5530547Skarels tio.i_cc = SECTSIZ; 5630547Skarels tio.i_flgs |= F_RDDATA; 5730547Skarels if (rkstrategy(&tio, READ) != SECTSIZ) { 5833541Sbostic printf("rk: can't read disk label\n"); 5930547Skarels return (EIO); 6030547Skarels } 6130547Skarels *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 6230547Skarels if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { 6333541Sbostic printf("rk%d: unlabeled\n", io->i_unit); 6430547Skarels #ifdef COMPAT_42 6530547Skarels rkmaptype(io, lp); 6630547Skarels #else 6730547Skarels return (ENXIO); 6830547Skarels #endif 6930547Skarels } 7033541Sbostic if ((u_int)io->i_part >= lp->d_npartitions || 7133541Sbostic (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1) 7233541Sbostic return (EPART); 7330547Skarels return (0); 741915Swnj } 751915Swnj 7630547Skarels #ifdef COMPAT_42 7730547Skarels u_long rk_off[] = { 0, 241, 0, -1, -1, -1, 393, -1 }; 7830547Skarels 7930547Skarels rkmaptype(io, lp) 8033408Skarels struct iob *io; 8130547Skarels register struct disklabel *lp; 8230547Skarels { 8330547Skarels register struct partition *pp; 8430547Skarels register u_long *off = rk_off; 8533541Sbostic register int i; 8630547Skarels 8730547Skarels lp->d_npartitions = 8; 8830547Skarels pp = lp->d_partitions; 8930547Skarels for (i = 0; i < 8; i++, pp++) 9030547Skarels pp->p_offset = *off++; 9130547Skarels } 9230547Skarels #endif 9330547Skarels 941915Swnj rkstrategy(io, func) 953263Swnj register struct iob *io; 961915Swnj { 9733541Sbostic register struct rkdevice *rkaddr; 9833408Skarels register daddr_t bn; 9933541Sbostic int com, ubinfo, errcnt = 0; 10033408Skarels short cn, sn, tn; 1011915Swnj 10233541Sbostic rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]); 1033349Swnj retry: 1041915Swnj ubinfo = ubasetup(io, 1); 1051915Swnj bn = io->i_bn; 10633408Skarels cn = bn / (NRKSECT*NRKTRK); 10733408Skarels sn = bn % NRKSECT; 1083263Swnj tn = (bn / NRKSECT) % NRKTRK; 10933541Sbostic rkaddr->rkcs2 = io->i_unit; 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); 13433541Sbostic if (errcnt++ == 10) { 1353349Swnj printf("rk: unrecovered error\n"); 1363349Swnj return (-1); 1373349Swnj } 1383349Swnj goto retry; 1391915Swnj } 1403349Swnj if (errcnt) 1413349Swnj printf("rk: recovered by retry\n"); 1421915Swnj return (io->i_cc); 1431915Swnj } 1443263Swnj 1453263Swnj rkwait(rkaddr) 1463263Swnj register struct rkdevice *rkaddr; 1473263Swnj { 14833541Sbostic while ((rkaddr->rkcs1 & RK_CRDY) == 0); 1493263Swnj } 150