1*0eebeeb2Smiod /* $OpenBSD: disk.c,v 1.1 2023/03/11 20:56:01 miod Exp $ */
2*0eebeeb2Smiod /* $NetBSD: disk.c,v 1.6 1997/04/06 08:40:33 cgd Exp $ */
3*0eebeeb2Smiod
4*0eebeeb2Smiod /*
5*0eebeeb2Smiod * Copyright (c) 1992, 1993
6*0eebeeb2Smiod * The Regents of the University of California. All rights reserved.
7*0eebeeb2Smiod *
8*0eebeeb2Smiod * This code is derived from software contributed to Berkeley by
9*0eebeeb2Smiod * Van Jacobson of Lawrence Berkeley Laboratory and Ralph Campbell.
10*0eebeeb2Smiod *
11*0eebeeb2Smiod * Redistribution and use in source and binary forms, with or without
12*0eebeeb2Smiod * modification, are permitted provided that the following conditions
13*0eebeeb2Smiod * are met:
14*0eebeeb2Smiod * 1. Redistributions of source code must retain the above copyright
15*0eebeeb2Smiod * notice, this list of conditions and the following disclaimer.
16*0eebeeb2Smiod * 2. Redistributions in binary form must reproduce the above copyright
17*0eebeeb2Smiod * notice, this list of conditions and the following disclaimer in the
18*0eebeeb2Smiod * documentation and/or other materials provided with the distribution.
19*0eebeeb2Smiod * 3. Neither the name of the University nor the names of its contributors
20*0eebeeb2Smiod * may be used to endorse or promote products derived from this software
21*0eebeeb2Smiod * without specific prior written permission.
22*0eebeeb2Smiod *
23*0eebeeb2Smiod * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24*0eebeeb2Smiod * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25*0eebeeb2Smiod * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26*0eebeeb2Smiod * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27*0eebeeb2Smiod * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28*0eebeeb2Smiod * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29*0eebeeb2Smiod * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30*0eebeeb2Smiod * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31*0eebeeb2Smiod * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32*0eebeeb2Smiod * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33*0eebeeb2Smiod * SUCH DAMAGE.
34*0eebeeb2Smiod *
35*0eebeeb2Smiod * @(#)rz.c 8.1 (Berkeley) 6/10/93
36*0eebeeb2Smiod */
37*0eebeeb2Smiod
38*0eebeeb2Smiod #include "libsa.h"
39*0eebeeb2Smiod
40*0eebeeb2Smiod #include <sys/param.h>
41*0eebeeb2Smiod #include <sys/disklabel.h>
42*0eebeeb2Smiod
43*0eebeeb2Smiod #include <machine/rpb.h>
44*0eebeeb2Smiod #include <machine/prom.h>
45*0eebeeb2Smiod
46*0eebeeb2Smiod struct disk_softc {
47*0eebeeb2Smiod int sc_fd; /* PROM channel number */
48*0eebeeb2Smiod int sc_part; /* disk partition number */
49*0eebeeb2Smiod struct disklabel sc_label; /* disk label for this disk */
50*0eebeeb2Smiod };
51*0eebeeb2Smiod
52*0eebeeb2Smiod int
diskstrategy(void * devdata,int rw,daddr_t bn,size_t reqcnt,void * addrvoid,size_t * cnt)53*0eebeeb2Smiod diskstrategy(void *devdata, int rw, daddr_t bn, size_t reqcnt, void *addrvoid,
54*0eebeeb2Smiod size_t *cnt)
55*0eebeeb2Smiod {
56*0eebeeb2Smiod char *addr = addrvoid;
57*0eebeeb2Smiod struct disk_softc *sc;
58*0eebeeb2Smiod struct partition *pp;
59*0eebeeb2Smiod prom_return_t ret;
60*0eebeeb2Smiod int s;
61*0eebeeb2Smiod
62*0eebeeb2Smiod #ifdef DEBUG
63*0eebeeb2Smiod if ((reqcnt & 0xffffff) != reqcnt || reqcnt == 0)
64*0eebeeb2Smiod asm("call_pal 0");
65*0eebeeb2Smiod #endif
66*0eebeeb2Smiod
67*0eebeeb2Smiod twiddle();
68*0eebeeb2Smiod
69*0eebeeb2Smiod /* Partial-block transfers not handled. */
70*0eebeeb2Smiod if (reqcnt & (DEV_BSIZE - 1)) {
71*0eebeeb2Smiod *cnt = 0;
72*0eebeeb2Smiod return (EINVAL);
73*0eebeeb2Smiod }
74*0eebeeb2Smiod
75*0eebeeb2Smiod sc = (struct disk_softc *)devdata;
76*0eebeeb2Smiod pp = &sc->sc_label.d_partitions[sc->sc_part];
77*0eebeeb2Smiod bn += DL_GETPOFFSET(pp);
78*0eebeeb2Smiod
79*0eebeeb2Smiod if (rw == F_READ)
80*0eebeeb2Smiod ret.bits = prom_read(sc->sc_fd, reqcnt, addr, bn);
81*0eebeeb2Smiod else
82*0eebeeb2Smiod ret.bits = prom_write(sc->sc_fd, reqcnt, addr, bn);
83*0eebeeb2Smiod if (ret.u.status)
84*0eebeeb2Smiod return (EIO);
85*0eebeeb2Smiod if (cnt)
86*0eebeeb2Smiod *cnt = ret.u.retval;
87*0eebeeb2Smiod return (0);
88*0eebeeb2Smiod }
89*0eebeeb2Smiod
90*0eebeeb2Smiod int
diskopen(struct open_file * f,...)91*0eebeeb2Smiod diskopen(struct open_file *f, ...)
92*0eebeeb2Smiod {
93*0eebeeb2Smiod struct disklabel *lp;
94*0eebeeb2Smiod prom_return_t ret;
95*0eebeeb2Smiod size_t cnt, devlen;
96*0eebeeb2Smiod int i;
97*0eebeeb2Smiod char *msg, buf[DEV_BSIZE];
98*0eebeeb2Smiod struct disk_softc *sc;
99*0eebeeb2Smiod va_list ap;
100*0eebeeb2Smiod unsigned int part = 0;
101*0eebeeb2Smiod char devname[128];
102*0eebeeb2Smiod
103*0eebeeb2Smiod /* See devopen() - we always use the device we're booted off here. */
104*0eebeeb2Smiod ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof(devname));
105*0eebeeb2Smiod devlen = ret.u.retval;
106*0eebeeb2Smiod
107*0eebeeb2Smiod ret.bits = prom_open((u_int64_t)devname, devlen);
108*0eebeeb2Smiod if (ret.u.status == 2)
109*0eebeeb2Smiod return (ENXIO);
110*0eebeeb2Smiod if (ret.u.status == 3)
111*0eebeeb2Smiod return (EIO);
112*0eebeeb2Smiod
113*0eebeeb2Smiod sc = alloc(sizeof(struct disk_softc));
114*0eebeeb2Smiod bzero(sc, sizeof(struct disk_softc));
115*0eebeeb2Smiod f->f_devdata = (void *)sc;
116*0eebeeb2Smiod
117*0eebeeb2Smiod sc->sc_fd = ret.u.retval;
118*0eebeeb2Smiod sc->sc_part = part;
119*0eebeeb2Smiod
120*0eebeeb2Smiod /* Try to read disk label and partition table information. */
121*0eebeeb2Smiod lp = &sc->sc_label;
122*0eebeeb2Smiod lp->d_secsize = DEV_BSIZE;
123*0eebeeb2Smiod lp->d_secpercyl = 1;
124*0eebeeb2Smiod lp->d_npartitions = MAXPARTITIONS;
125*0eebeeb2Smiod DL_SETPOFFSET(&lp->d_partitions[part], 0);
126*0eebeeb2Smiod DL_SETPSIZE(&lp->d_partitions[part], -1LL);
127*0eebeeb2Smiod i = diskstrategy(sc, F_READ, LABELSECTOR, DEV_BSIZE, buf, &cnt);
128*0eebeeb2Smiod if (i || cnt != DEV_BSIZE) {
129*0eebeeb2Smiod printf("%s: error reading disk label\n", __func__);
130*0eebeeb2Smiod goto bad;
131*0eebeeb2Smiod } else if (((struct disklabel *)(buf + LABELOFFSET))->d_magic !=
132*0eebeeb2Smiod DISKMAGIC) {
133*0eebeeb2Smiod /* No label at all. Fake all partitions as whole disk. */
134*0eebeeb2Smiod for (i = 0; i < MAXPARTITIONS; i++) {
135*0eebeeb2Smiod DL_SETPOFFSET(&lp->d_partitions[part], 0);
136*0eebeeb2Smiod DL_SETPSIZE(&lp->d_partitions[part], -1LL);
137*0eebeeb2Smiod }
138*0eebeeb2Smiod } else {
139*0eebeeb2Smiod msg = getdisklabel(buf + LABELOFFSET, lp);
140*0eebeeb2Smiod if (msg) {
141*0eebeeb2Smiod printf("%s: %s\n", __func__, msg);
142*0eebeeb2Smiod goto bad;
143*0eebeeb2Smiod }
144*0eebeeb2Smiod }
145*0eebeeb2Smiod
146*0eebeeb2Smiod if (part >= lp->d_npartitions ||
147*0eebeeb2Smiod DL_GETPSIZE(&lp->d_partitions[part]) == 0) {
148*0eebeeb2Smiod bad:
149*0eebeeb2Smiod free(sc, sizeof(struct disk_softc));
150*0eebeeb2Smiod return (ENXIO);
151*0eebeeb2Smiod }
152*0eebeeb2Smiod return (0);
153*0eebeeb2Smiod }
154*0eebeeb2Smiod
155*0eebeeb2Smiod int
diskclose(struct open_file * f)156*0eebeeb2Smiod diskclose(struct open_file *f)
157*0eebeeb2Smiod {
158*0eebeeb2Smiod struct disk_softc *sc;
159*0eebeeb2Smiod
160*0eebeeb2Smiod sc = f->f_devdata;
161*0eebeeb2Smiod (void)prom_close(sc->sc_fd);
162*0eebeeb2Smiod
163*0eebeeb2Smiod free(sc, sizeof(struct disk_softc));
164*0eebeeb2Smiod f->f_devdata = NULL;
165*0eebeeb2Smiod return (0);
166*0eebeeb2Smiod }
167