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