xref: /original-bsd/sys/vax/stand/rk.c (revision 31e799e3)
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