1 /* 2 * Copyright (c) 1992 Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Van Jacobson of Lawrence Berkeley Laboratory and Ralph Campbell. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)rz.c 7.2 (Berkeley) 02/15/93 11 */ 12 13 #include <stand/stand.h> 14 #include <sys/param.h> 15 #include <sys/disklabel.h> 16 17 struct rz_softc { 18 int sc_fd; /* PROM file id */ 19 int sc_ctlr; /* controller number */ 20 int sc_unit; /* disk unit number */ 21 int sc_part; /* disk partition number */ 22 struct disklabel sc_label; /* disk label for this disk */ 23 }; 24 25 int 26 rzstrategy(devdata, rw, bn, reqcnt, addr, cnt) 27 void *devdata; 28 int rw; 29 daddr_t bn; 30 u_int reqcnt; 31 char *addr; 32 u_int *cnt; /* out: number of bytes transfered */ 33 { 34 register struct rz_softc *sc = (struct rz_softc *)devdata; 35 register int part = sc->sc_part; 36 register struct partition *pp = &sc->sc_label.d_partitions[part]; 37 register int s; 38 long offset; 39 40 offset = bn * DEV_BSIZE; 41 /* 42 * Partial-block transfers not handled. 43 */ 44 if (reqcnt & (DEV_BSIZE - 1)) { 45 *cnt = 0; 46 return (EINVAL); 47 } 48 49 offset += pp->p_offset * DEV_BSIZE; 50 if (prom_lseek(sc->sc_fd, offset, 0) < 0) 51 return (EIO); 52 s = prom_read(sc->sc_fd, addr, reqcnt); 53 if (s < 0) 54 return (EIO); 55 56 *cnt = s; 57 return (0); 58 } 59 60 int 61 rzopen(f, ctlr, unit, part) 62 struct open_file *f; 63 int ctlr, unit, part; 64 { 65 register struct rz_softc *sc; 66 register struct disklabel *lp; 67 register int i; 68 char *msg; 69 char buf[DEV_BSIZE]; 70 int cnt; 71 static char device[] = "rz(0,0,0)"; 72 73 if (unit >= 8 || part >= 8) 74 return (ENXIO); 75 device[5] = '0' + unit; 76 /* NOTE: only support reads for now */ 77 if ((i = prom_open(device, 0)) < 0) 78 return (ENXIO); 79 80 sc = alloc(sizeof(struct rz_softc)); 81 bzero(sc, sizeof(struct rz_softc)); 82 f->f_devdata = (void *)sc; 83 84 sc->sc_fd = i; 85 sc->sc_ctlr = ctlr; 86 sc->sc_unit = unit; 87 sc->sc_part = part; 88 89 /* try to read disk label and partition table information */ 90 lp = &sc->sc_label; 91 lp->d_secsize = DEV_BSIZE; 92 lp->d_secpercyl = 1; 93 lp->d_npartitions = MAXPARTITIONS; 94 lp->d_partitions[part].p_offset = 0; 95 lp->d_partitions[part].p_size = 0x7fffffff; 96 i = rzstrategy(sc, F_READ, (daddr_t)LABELSECTOR, DEV_BSIZE, buf, &cnt); 97 if (i || cnt != DEV_BSIZE) { 98 printf("rz%d: error reading disk label\n", unit); 99 goto bad; 100 } else { 101 msg = getdisklabel(buf, lp); 102 if (msg) { 103 printf("rz%d: %s\n", unit, msg); 104 goto bad; 105 } 106 } 107 108 if (part >= lp->d_npartitions || lp->d_partitions[part].p_size == 0) { 109 bad: 110 free(sc, sizeof(struct rz_softc)); 111 return (ENXIO); 112 } 113 return (0); 114 } 115 116 rzclose(f) 117 struct open_file *f; 118 { 119 free(f->f_devdata, sizeof(struct rz_softc)); 120 f->f_devdata = (void *)0; 121 return (0); 122 } 123