156830Sralph /* 256830Sralph * Copyright (c) 1992 Regents of the University of California. 356830Sralph * 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*58007Sralph * @(#)rz.c 7.2 (Berkeley) 02/15/93 1156830Sralph */ 1256830Sralph 1356830Sralph #include <stand/stand.h> 1456830Sralph #include <sys/param.h> 1556830Sralph #include <sys/disklabel.h> 1656830Sralph 1756830Sralph struct rz_softc { 18*58007Sralph int sc_fd; /* PROM file id */ 19*58007Sralph int sc_ctlr; /* controller number */ 20*58007Sralph int sc_unit; /* disk unit number */ 21*58007Sralph int sc_part; /* disk partition number */ 2256830Sralph struct disklabel sc_label; /* disk label for this disk */ 2356830Sralph }; 2456830Sralph 2556830Sralph int 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; 38*58007Sralph long offset; 3956830Sralph 40*58007Sralph offset = bn * DEV_BSIZE; 4156830Sralph /* 42*58007Sralph * Partial-block transfers not handled. 4356830Sralph */ 44*58007Sralph if (reqcnt & (DEV_BSIZE - 1)) { 4556830Sralph *cnt = 0; 4656830Sralph return (EINVAL); 4756830Sralph } 4856830Sralph 49*58007Sralph offset += pp->p_offset * DEV_BSIZE; 50*58007Sralph if (prom_lseek(sc->sc_fd, offset, 0) < 0) 51*58007Sralph return (EIO); 52*58007Sralph s = prom_read(sc->sc_fd, addr, reqcnt); 53*58007Sralph if (s < 0) 54*58007Sralph return (EIO); 5556830Sralph 56*58007Sralph *cnt = s; 57*58007Sralph return (0); 5856830Sralph } 5956830Sralph 6056830Sralph int 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; 71*58007Sralph static char device[] = "rz(0,0,0)"; 7256830Sralph 73*58007Sralph if (unit >= 8 || part >= 8) 7456830Sralph return (ENXIO); 75*58007Sralph device[5] = '0' + unit; 76*58007Sralph /* NOTE: only support reads for now */ 77*58007Sralph 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 84*58007Sralph sc->sc_fd = i; 85*58007Sralph sc->sc_ctlr = ctlr; 86*58007Sralph 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; 92*58007Sralph lp->d_secpercyl = 1; 9356830Sralph lp->d_npartitions = MAXPARTITIONS; 9456830Sralph lp->d_partitions[part].p_offset = 0; 95*58007Sralph 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