4.4BSD/usr/src/sys/vax/stand/rk.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 *
 *	@(#)rk.c	7.10 (Berkeley) 5/4/91
 */

/*
 * RK611/RK07
 */
#include "sys/param.h"
#include "sys/disklabel.h"

#include "../include/pte.h"

#include "../uba/ubareg.h"
#include "../uba/rkreg.h"

#include "stand/saio.h"
#include "savax.h"

#define	SECTSIZ		512		/* sector size in bytes */

#define	MAXCTLR		1		/* all addresses must be specified */
#define	MAXUNIT		8
u_short	rkstd[MAXCTLR] = { 0777440 };
struct	disklabel rklabel[MAXNUBA][MAXCTLR][MAXUNIT];
char	lbuf[SECTSIZ];

rkopen(io)
	register struct iob *io;
{
	register struct rkdevice *rkaddr;
	register struct disklabel *lp;
	struct iob tio;

	if ((u_int)io->i_adapt >= nuba)
		return (EADAPT);
	if ((u_int)io->i_ctlr >= MAXCTLR)
		return (ECTLR);
	if ((u_int)io->i_unit >= MAXUNIT)
		return (EUNIT);
	rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]);
	if (badaddr((char *)rkaddr, sizeof(short)))
		return (ENXIO);
	rkaddr->rkcs2 = RKCS2_SCLR;
	rkwait(rkaddr);
	/*
	 * Read in the pack label.
	 */
	lp = &rklabel[io->i_adapt][io->i_ctlr][io->i_unit];
	lp->d_nsectors = NRKSECT;
	lp->d_secpercyl = NRKTRK*NRKSECT;
	tio = *io;
	tio.i_bn = LABELSECTOR;
	tio.i_ma = lbuf;
	tio.i_cc = SECTSIZ;
	tio.i_flgs |= F_RDDATA;
	if (rkstrategy(&tio, F_READ) != SECTSIZ)
		return (ERDLAB);
	*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
	if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC)
#ifdef COMPAT_42
	{
		printf("rk%d: unlabeled\n", io->i_unit);
		rkmaptype(io, lp);
	}
#else
		return (EUNLAB);
#endif
	if ((u_int)io->i_part >= lp->d_npartitions ||
	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
		return (EPART);
	return (0);
}

#ifdef COMPAT_42
u_long	rk_off[] = { 0, 241, 0, -1, -1, -1, 393, -1 };

rkmaptype(io, lp)
	struct iob *io;
	register struct disklabel *lp;
{
	register struct partition *pp;
	register u_long *off = rk_off;
	register int i;

	lp->d_npartitions = 8;
	pp = lp->d_partitions;
	for (i = 0; i < 8; i++, pp++)
		pp->p_offset = *off++;
}
#endif

rkstrategy(io, func)
	register struct iob *io;
{
	register struct rkdevice *rkaddr;
	register daddr_t bn;
	int com, ubinfo, errcnt = 0;
	short cn, sn, tn;

	rkaddr = (struct rkdevice *)ubamem(io->i_adapt, rkstd[io->i_ctlr]);
retry:
	ubinfo = ubasetup(io, 1);
	bn = io->i_bn;
	cn = bn / (NRKSECT*NRKTRK);
	sn = bn % NRKSECT;
	tn = (bn / NRKSECT) % NRKTRK;
	rkaddr->rkcs2 = io->i_unit;
	rkaddr->rkcs1 = RK_CDT|RK_PACK|RK_GO;
	rkwait(rkaddr);
	rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
	rkwait(rkaddr);
	rkaddr->rkda = sn | (tn << 8);
	rkaddr->rkcyl = cn;
	rkaddr->rkba = ubinfo;
	rkaddr->rkwc = -(io->i_cc >> 1);
	com = RK_CDT|((ubinfo>>8)&0x300)|RK_GO;
	if (func == F_READ)
		com |= RK_READ;
	else
		com |= RK_WRITE;
	rkaddr->rkcs1 = com;
	rkwait(rkaddr);
	while ((rkaddr->rkds & RKDS_SVAL) == 0)
		;
	ubafree(io, ubinfo);
	if (rkaddr->rkcs1 & RK_CERR) {
		printf("rk error: (cyl,trk,sec)=(%d,%d,%d) cs2=%b er=%b\n",
		    cn, tn, sn, rkaddr->rkcs2, RKCS2_BITS,
		    rkaddr->rker, RKER_BITS);
		rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
		rkwait(rkaddr);
		if (errcnt++ == 10) {
			printf("rk: unrecovered error\n");
			return (-1);
		}
		goto retry;
	}
	if (errcnt)
		printf("rk: recovered by retry\n");
	return (io->i_cc);
}

rkwait(rkaddr)
	register struct rkdevice *rkaddr;
{
	while ((rkaddr->rkcs1 & RK_CRDY) == 0);
}