123237Smckusick /* 235052Skarels * Copyright (c) 1982, 1986, 1988 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*45803Sbostic * @(#)rk.c 7.9 (Berkeley) 12/16/90 723237Smckusick */ 81915Swnj 91915Swnj /* 103263Swnj * RK611/RK07 111915Swnj */ 12*45803Sbostic #include "sys/param.h" 13*45803Sbostic #include "sys/disklabel.h" 141915Swnj 15*45803Sbostic #include "../include/pte.h" 169186Ssam 17*45803Sbostic #include "../uba/ubareg.h" 18*45803Sbostic #include "../uba/rkreg.h" 199186Ssam 20*45803Sbostic #include "stand/saio.h" 213263Swnj #include "savax.h" 221915Swnj 2333541Sbostic #define SECTSIZ 512 /* sector size in bytes */ 2430547Skarels 2533541Sbostic #define MAXCTLR 1 /* all addresses must be specified */ 2635052Skarels #define MAXUNIT 8 2733541Sbostic u_short rkstd[MAXCTLR] = { 0777440 }; 2835052Skarels struct disklabel rklabel[MAXNUBA][MAXCTLR][MAXUNIT]; 2930547Skarels char lbuf[SECTSIZ]; 301915Swnj 311915Swnj rkopen(io) 323263Swnj register struct iob *io; 331915Swnj { 3433541Sbostic register struct rkdevice *rkaddr; 3533541Sbostic register struct disklabel *lp; 3630547Skarels struct iob tio; 371915Swnj 3835052Skarels if ((u_int)io->i_adapt >= nuba) 3935052Skarels return (EADAPT); 4033541Sbostic if ((u_int)io->i_ctlr >= MAXCTLR) 4133541Sbostic return (ECTLR); 4235052Skarels if ((u_int)io->i_unit >= MAXUNIT) 4335052Skarels return (EUNIT); 4433541Sbostic rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]); 4533548Sbostic if (badaddr((char *)rkaddr, sizeof(short))) 4630547Skarels return (ENXIO); 473349Swnj rkaddr->rkcs2 = RKCS2_SCLR; 483349Swnj rkwait(rkaddr); 4930547Skarels /* 5030547Skarels * Read in the pack label. 5130547Skarels */ 5233541Sbostic lp = &rklabel[io->i_adapt][io->i_ctlr][io->i_unit]; 5330547Skarels lp->d_nsectors = NRKSECT; 5430547Skarels lp->d_secpercyl = NRKTRK*NRKSECT; 5530547Skarels tio = *io; 5630547Skarels tio.i_bn = LABELSECTOR; 5730547Skarels tio.i_ma = lbuf; 5830547Skarels tio.i_cc = SECTSIZ; 5930547Skarels tio.i_flgs |= F_RDDATA; 6033636Sbostic if (rkstrategy(&tio, READ) != SECTSIZ) 6133636Sbostic return (ERDLAB); 6230547Skarels *lp = *(struct disklabel *)(lbuf + LABELOFFSET); 6333636Sbostic if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) 6433636Sbostic #ifdef COMPAT_42 6533636Sbostic { 6633541Sbostic printf("rk%d: unlabeled\n", io->i_unit); 6730547Skarels rkmaptype(io, lp); 6833636Sbostic } 6930547Skarels #else 7033636Sbostic return (EUNLAB); 7130547Skarels #endif 7233541Sbostic if ((u_int)io->i_part >= lp->d_npartitions || 7333541Sbostic (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1) 7433541Sbostic return (EPART); 7530547Skarels return (0); 761915Swnj } 771915Swnj 7830547Skarels #ifdef COMPAT_42 7930547Skarels u_long rk_off[] = { 0, 241, 0, -1, -1, -1, 393, -1 }; 8030547Skarels 8130547Skarels rkmaptype(io, lp) 8233408Skarels struct iob *io; 8330547Skarels register struct disklabel *lp; 8430547Skarels { 8530547Skarels register struct partition *pp; 8630547Skarels register u_long *off = rk_off; 8733541Sbostic register int i; 8830547Skarels 8930547Skarels lp->d_npartitions = 8; 9030547Skarels pp = lp->d_partitions; 9130547Skarels for (i = 0; i < 8; i++, pp++) 9230547Skarels pp->p_offset = *off++; 9330547Skarels } 9430547Skarels #endif 9530547Skarels 961915Swnj rkstrategy(io, func) 973263Swnj register struct iob *io; 981915Swnj { 9933541Sbostic register struct rkdevice *rkaddr; 10033408Skarels register daddr_t bn; 10133541Sbostic int com, ubinfo, errcnt = 0; 10233408Skarels short cn, sn, tn; 1031915Swnj 10433541Sbostic rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]); 1053349Swnj retry: 1061915Swnj ubinfo = ubasetup(io, 1); 1071915Swnj bn = io->i_bn; 10833408Skarels cn = bn / (NRKSECT*NRKTRK); 10933408Skarels sn = bn % NRKSECT; 1103263Swnj tn = (bn / NRKSECT) % NRKTRK; 11133541Sbostic rkaddr->rkcs2 = io->i_unit; 1123263Swnj rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO; 1133263Swnj rkwait(rkaddr); 1143349Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 1153349Swnj rkwait(rkaddr); 1163263Swnj rkaddr->rkda = sn | (tn << 8); 1173263Swnj rkaddr->rkcyl = cn; 1183263Swnj rkaddr->rkba = ubinfo; 1193263Swnj rkaddr->rkwc = -(io->i_cc >> 1); 1204038Swnj com = RK_CDT|((ubinfo>>8)&0x300)|RK_GO; 1213263Swnj if (func == READ) 1223263Swnj com |= RK_READ; 1233263Swnj else 1243263Swnj com |= RK_WRITE; 1253263Swnj rkaddr->rkcs1 = com; 1263263Swnj rkwait(rkaddr); 1273349Swnj while ((rkaddr->rkds & RKDS_SVAL) == 0) 1281915Swnj ; 1293263Swnj ubafree(io, ubinfo); 1303263Swnj if (rkaddr->rkcs1 & RK_CERR) { 1313349Swnj printf("rk error: (cyl,trk,sec)=(%d,%d,%d) cs2=%b er=%b\n", 1323349Swnj cn, tn, sn, rkaddr->rkcs2, RKCS2_BITS, 1333349Swnj rkaddr->rker, RKER_BITS); 1343349Swnj rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 1353263Swnj rkwait(rkaddr); 13633541Sbostic if (errcnt++ == 10) { 1373349Swnj printf("rk: unrecovered error\n"); 1383349Swnj return (-1); 1393349Swnj } 1403349Swnj goto retry; 1411915Swnj } 1423349Swnj if (errcnt) 1433349Swnj printf("rk: recovered by retry\n"); 1441915Swnj return (io->i_cc); 1451915Swnj } 1463263Swnj 1473263Swnj rkwait(rkaddr) 1483263Swnj register struct rkdevice *rkaddr; 1493263Swnj { 15033541Sbostic while ((rkaddr->rkcs1 & RK_CRDY) == 0); 1513263Swnj } 152