xref: /csrg-svn/sys/pmax/stand/rz.c (revision 63226)
156830Sralph /*
2*63226Sbostic  * Copyright (c) 1992, 1993
3*63226Sbostic  *	The Regents of the University of California.  All rights reserved.
456830Sralph  *
556830Sralph  * This code is derived from software contributed to Berkeley by
656830Sralph  * Van Jacobson of Lawrence Berkeley Laboratory and Ralph Campbell.
756830Sralph  *
856830Sralph  * %sccs.include.redist.c%
956830Sralph  *
10*63226Sbostic  *	@(#)rz.c	8.1 (Berkeley) 06/10/93
1156830Sralph  */
1256830Sralph 
1356830Sralph #include <stand/stand.h>
1456830Sralph #include <sys/param.h>
1556830Sralph #include <sys/disklabel.h>
1656830Sralph 
1756830Sralph struct	rz_softc {
1858007Sralph 	int	sc_fd;			/* PROM file id */
1958007Sralph 	int	sc_ctlr;		/* controller number */
2058007Sralph 	int	sc_unit;		/* disk unit number */
2158007Sralph 	int	sc_part;		/* disk partition number */
2256830Sralph 	struct	disklabel sc_label;	/* disk label for this disk */
2356830Sralph };
2456830Sralph 
2556830Sralph int
rzstrategy(devdata,rw,bn,reqcnt,addr,cnt)2656830Sralph rzstrategy(devdata, rw, bn, reqcnt, addr, cnt)
2756830Sralph 	void *devdata;
2856830Sralph 	int rw;
2956830Sralph 	daddr_t bn;
3056830Sralph 	u_int reqcnt;
3156830Sralph 	char *addr;
3256830Sralph 	u_int *cnt;	/* out: number of bytes transfered */
3356830Sralph {
3456830Sralph 	register struct rz_softc *sc = (struct rz_softc *)devdata;
3556830Sralph 	register int part = sc->sc_part;
3656830Sralph 	register struct partition *pp = &sc->sc_label.d_partitions[part];
3756830Sralph 	register int s;
3858007Sralph 	long offset;
3956830Sralph 
4058007Sralph 	offset = bn * DEV_BSIZE;
4156830Sralph 	/*
4258007Sralph 	 * Partial-block transfers not handled.
4356830Sralph 	 */
4458007Sralph 	if (reqcnt & (DEV_BSIZE - 1)) {
4556830Sralph 		*cnt = 0;
4656830Sralph 		return (EINVAL);
4756830Sralph 	}
4856830Sralph 
4958007Sralph 	offset += pp->p_offset * DEV_BSIZE;
5058007Sralph 	if (prom_lseek(sc->sc_fd, offset, 0) < 0)
5158007Sralph 		return (EIO);
5258007Sralph 	s = prom_read(sc->sc_fd, addr, reqcnt);
5358007Sralph 	if (s < 0)
5458007Sralph 		return (EIO);
5556830Sralph 
5658007Sralph 	*cnt = s;
5758007Sralph 	return (0);
5856830Sralph }
5956830Sralph 
6056830Sralph int
rzopen(f,ctlr,unit,part)6156830Sralph rzopen(f, ctlr, unit, part)
6256830Sralph 	struct open_file *f;
6356830Sralph 	int ctlr, unit, part;
6456830Sralph {
6556830Sralph 	register struct rz_softc *sc;
6656830Sralph 	register struct disklabel *lp;
6756830Sralph 	register int i;
6856830Sralph 	char *msg;
6956830Sralph 	char buf[DEV_BSIZE];
7056830Sralph 	int cnt;
7158007Sralph 	static char device[] = "rz(0,0,0)";
7256830Sralph 
7358007Sralph 	if (unit >= 8 || part >= 8)
7456830Sralph 		return (ENXIO);
7558007Sralph 	device[5] = '0' + unit;
7658007Sralph 	/* NOTE: only support reads for now */
7758007Sralph 	if ((i = prom_open(device, 0)) < 0)
7856830Sralph 		return (ENXIO);
7956830Sralph 
8056830Sralph 	sc = alloc(sizeof(struct rz_softc));
8156830Sralph 	bzero(sc, sizeof(struct rz_softc));
8256830Sralph 	f->f_devdata = (void *)sc;
8356830Sralph 
8458007Sralph 	sc->sc_fd = i;
8558007Sralph 	sc->sc_ctlr = ctlr;
8658007Sralph 	sc->sc_unit = unit;
8756830Sralph 	sc->sc_part = part;
8856830Sralph 
8956830Sralph 	/* try to read disk label and partition table information */
9056830Sralph 	lp = &sc->sc_label;
9156830Sralph 	lp->d_secsize = DEV_BSIZE;
9258007Sralph 	lp->d_secpercyl = 1;
9356830Sralph 	lp->d_npartitions = MAXPARTITIONS;
9456830Sralph 	lp->d_partitions[part].p_offset = 0;
9558007Sralph 	lp->d_partitions[part].p_size = 0x7fffffff;
9656830Sralph 	i = rzstrategy(sc, F_READ, (daddr_t)LABELSECTOR, DEV_BSIZE, buf, &cnt);
9756830Sralph 	if (i || cnt != DEV_BSIZE) {
9856830Sralph 		printf("rz%d: error reading disk label\n", unit);
9956830Sralph 		goto bad;
10056830Sralph 	} else {
10156830Sralph 		msg = getdisklabel(buf, lp);
10256830Sralph 		if (msg) {
10356830Sralph 			printf("rz%d: %s\n", unit, msg);
10456830Sralph 			goto bad;
10556830Sralph 		}
10656830Sralph 	}
10756830Sralph 
10856830Sralph 	if (part >= lp->d_npartitions || lp->d_partitions[part].p_size == 0) {
10956830Sralph 	bad:
11056830Sralph 		free(sc, sizeof(struct rz_softc));
11156830Sralph 		return (ENXIO);
11256830Sralph 	}
11356830Sralph 	return (0);
11456830Sralph }
11556830Sralph 
11656830Sralph rzclose(f)
11756830Sralph 	struct open_file *f;
11856830Sralph {
11956830Sralph 	free(f->f_devdata, sizeof(struct rz_softc));
12056830Sralph 	f->f_devdata = (void *)0;
12156830Sralph 	return (0);
12256830Sralph }
123