1*d02e022dStsutsui /* $NetBSD: iris_disk.c,v 1.1 2019/01/12 16:44:47 tsutsui Exp $ */
2*d02e022dStsutsui
3*d02e022dStsutsui /*
4*d02e022dStsutsui * Copyright (c) 2018 Naruaki Etomi
5*d02e022dStsutsui * All rights reserved.
6*d02e022dStsutsui *
7*d02e022dStsutsui * Redistribution and use in source and binary forms, with or without
8*d02e022dStsutsui * modification, are permitted provided that the following conditions
9*d02e022dStsutsui * are met:
10*d02e022dStsutsui * 1. Redistributions of source code must retain the above copyright
11*d02e022dStsutsui * notice, this list of conditions and the following disclaimer.
12*d02e022dStsutsui * 2. Redistributions in binary form must reproduce the above copyright
13*d02e022dStsutsui * notice, this list of conditions and the following disclaimer in the
14*d02e022dStsutsui * documentation and/or other materials provided with the distribution.
15*d02e022dStsutsui *
16*d02e022dStsutsui * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17*d02e022dStsutsui * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*d02e022dStsutsui * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19*d02e022dStsutsui * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20*d02e022dStsutsui * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21*d02e022dStsutsui * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22*d02e022dStsutsui * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23*d02e022dStsutsui * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*d02e022dStsutsui * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25*d02e022dStsutsui * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*d02e022dStsutsui */
27*d02e022dStsutsui
28*d02e022dStsutsui /*
29*d02e022dStsutsui * Copyright (c) 1988 University of Utah.
30*d02e022dStsutsui * Copyright (c) 1990, 1993
31*d02e022dStsutsui * The Regents of the University of California. All rights reserved.
32*d02e022dStsutsui *
33*d02e022dStsutsui * This code is derived from software contributed to Berkeley by
34*d02e022dStsutsui * Van Jacobson of Lawrence Berkeley Laboratory and the Systems
35*d02e022dStsutsui * Programming Group of the University of Utah Computer Science Department.
36*d02e022dStsutsui *
37*d02e022dStsutsui * Redistribution and use in source and binary forms, with or without
38*d02e022dStsutsui * modification, are permitted provided that the following conditions
39*d02e022dStsutsui * are met:
40*d02e022dStsutsui * 1. Redistributions of source code must retain the above copyright
41*d02e022dStsutsui * notice, this list of conditions and the following disclaimer.
42*d02e022dStsutsui * 2. Redistributions in binary form must reproduce the above copyright
43*d02e022dStsutsui * notice, this list of conditions and the following disclaimer in the
44*d02e022dStsutsui * documentation and/or other materials provided with the distribution.
45*d02e022dStsutsui * 3. Neither the name of the University nor the names of its contributors
46*d02e022dStsutsui * may be used to endorse or promote products derived from this software
47*d02e022dStsutsui * without specific prior written permission.
48*d02e022dStsutsui *
49*d02e022dStsutsui * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50*d02e022dStsutsui * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51*d02e022dStsutsui * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52*d02e022dStsutsui * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53*d02e022dStsutsui * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54*d02e022dStsutsui * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55*d02e022dStsutsui * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56*d02e022dStsutsui * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57*d02e022dStsutsui * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58*d02e022dStsutsui * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59*d02e022dStsutsui * SUCH DAMAGE.
60*d02e022dStsutsui *
61*d02e022dStsutsui * from: Utah $Hdr: sd.c 1.9 92/12/21$
62*d02e022dStsutsui *
63*d02e022dStsutsui * @(#)sd.c 8.1 (Berkeley) 6/10/93
64*d02e022dStsutsui */
65*d02e022dStsutsui
66*d02e022dStsutsui /*
67*d02e022dStsutsui * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
68*d02e022dStsutsui * Disk I/O API routine.
69*d02e022dStsutsui * Most of the following was adapted from /sys/arch/hp300/stand/common/sd.c.
70*d02e022dStsutsui * NetBSD: sd.c,v 1.11 2011/07/17 20:54:40 joerg Exp
71*d02e022dStsutsui */
72*d02e022dStsutsui
73*d02e022dStsutsui #include <lib/libsa/stand.h>
74*d02e022dStsutsui
75*d02e022dStsutsui #include <sys/param.h>
76*d02e022dStsutsui #include <sys/disklabel.h>
77*d02e022dStsutsui
78*d02e022dStsutsui #ifndef INDIGO_R3K_MODE
79*d02e022dStsutsui #include <dev/arcbios/arcbios.h>
80*d02e022dStsutsui #endif
81*d02e022dStsutsui
82*d02e022dStsutsui #include "disk.h"
83*d02e022dStsutsui
84*d02e022dStsutsui #include "iris_machdep.h"
85*d02e022dStsutsui #include "iris_scsivar.h"
86*d02e022dStsutsui
87*d02e022dStsutsui struct disk_softc {
88*d02e022dStsutsui int sc_part; /* disk partition number */
89*d02e022dStsutsui char sc_retry;
90*d02e022dStsutsui char sc_alive;
91*d02e022dStsutsui short sc_blkshift;
92*d02e022dStsutsui struct disklabel sc_label; /* disk label for this disk */
93*d02e022dStsutsui };
94*d02e022dStsutsui
95*d02e022dStsutsui static int diskinit(struct disk_softc *);
96*d02e022dStsutsui
97*d02e022dStsutsui #define DISKRETRY 2
98*d02e022dStsutsui
99*d02e022dStsutsui int
diskstrategy(void * devdata,int rw,daddr_t bn,size_t reqcnt,void * addr,size_t * cnt)100*d02e022dStsutsui diskstrategy(void *devdata, int rw, daddr_t bn, size_t reqcnt, void *addr,
101*d02e022dStsutsui size_t *cnt)
102*d02e022dStsutsui {
103*d02e022dStsutsui struct disk_softc *sc;
104*d02e022dStsutsui struct disklabel *lp;
105*d02e022dStsutsui uint8_t *buf;
106*d02e022dStsutsui daddr_t blk;
107*d02e022dStsutsui u_int nblk;
108*d02e022dStsutsui int stat;
109*d02e022dStsutsui
110*d02e022dStsutsui sc = devdata;
111*d02e022dStsutsui
112*d02e022dStsutsui buf = addr;
113*d02e022dStsutsui lp = &sc->sc_label;
114*d02e022dStsutsui blk = bn + (lp->d_partitions[sc->sc_part].p_offset >> sc->sc_blkshift);
115*d02e022dStsutsui nblk = reqcnt >> sc->sc_blkshift;
116*d02e022dStsutsui
117*d02e022dStsutsui sc->sc_retry = 0;
118*d02e022dStsutsui
119*d02e022dStsutsui retry:
120*d02e022dStsutsui stat = scsi_read(buf, reqcnt, blk, nblk);
121*d02e022dStsutsui
122*d02e022dStsutsui if (stat) {
123*d02e022dStsutsui DELAY(1000000);
124*d02e022dStsutsui if (++sc->sc_retry > DISKRETRY) {
125*d02e022dStsutsui return EIO;
126*d02e022dStsutsui }
127*d02e022dStsutsui printf("diskstrategy retry\n");
128*d02e022dStsutsui goto retry;
129*d02e022dStsutsui }
130*d02e022dStsutsui
131*d02e022dStsutsui *cnt = reqcnt;
132*d02e022dStsutsui
133*d02e022dStsutsui return 0;
134*d02e022dStsutsui }
135*d02e022dStsutsui
136*d02e022dStsutsui static int
diskinit(struct disk_softc * sc)137*d02e022dStsutsui diskinit(struct disk_softc *sc)
138*d02e022dStsutsui {
139*d02e022dStsutsui uint8_t capbuf[2];
140*d02e022dStsutsui
141*d02e022dStsutsui uint8_t stat;
142*d02e022dStsutsui
143*d02e022dStsutsui stat = scsi_test_unit_rdy();
144*d02e022dStsutsui
145*d02e022dStsutsui if (stat != 0) {
146*d02e022dStsutsui /* drive may be doing RTZ - wait a bit */
147*d02e022dStsutsui DELAY(1000000);
148*d02e022dStsutsui stat = scsi_test_unit_rdy();
149*d02e022dStsutsui
150*d02e022dStsutsui if (stat != 0) {
151*d02e022dStsutsui printf("diskinit abort!\n");
152*d02e022dStsutsui printf("Boot failed! Halting...\n");
153*d02e022dStsutsui reboot();
154*d02e022dStsutsui }
155*d02e022dStsutsui }
156*d02e022dStsutsui
157*d02e022dStsutsui /*
158*d02e022dStsutsui * try to get the drive block size.
159*d02e022dStsutsui */
160*d02e022dStsutsui capbuf[0] = 0;
161*d02e022dStsutsui capbuf[1] = 0;
162*d02e022dStsutsui
163*d02e022dStsutsui stat = scsi_read_capacity((uint8_t *)capbuf, sizeof(capbuf));
164*d02e022dStsutsui
165*d02e022dStsutsui if (stat == 0) {
166*d02e022dStsutsui if (capbuf[1] > DEV_BSIZE)
167*d02e022dStsutsui for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1)
168*d02e022dStsutsui ++sc->sc_blkshift;
169*d02e022dStsutsui }
170*d02e022dStsutsui
171*d02e022dStsutsui sc->sc_alive = 1;
172*d02e022dStsutsui return 1;
173*d02e022dStsutsui }
174*d02e022dStsutsui
175*d02e022dStsutsui int
diskopen(struct open_file * f,...)176*d02e022dStsutsui diskopen(struct open_file *f, ...)
177*d02e022dStsutsui {
178*d02e022dStsutsui struct disk_softc *sc;
179*d02e022dStsutsui struct disklabel *lp;
180*d02e022dStsutsui size_t cnt;
181*d02e022dStsutsui char *msg, buf[DEV_BSIZE];
182*d02e022dStsutsui int error;
183*d02e022dStsutsui
184*d02e022dStsutsui cnt = 0;
185*d02e022dStsutsui
186*d02e022dStsutsui sc = alloc(sizeof(struct disk_softc));
187*d02e022dStsutsui memset(sc, 0, sizeof(struct disk_softc));
188*d02e022dStsutsui f->f_devdata = (void *)sc;
189*d02e022dStsutsui
190*d02e022dStsutsui sc->sc_part = scsi_part;
191*d02e022dStsutsui
192*d02e022dStsutsui if (sc->sc_alive == 0) {
193*d02e022dStsutsui if (diskinit(sc) == 0)
194*d02e022dStsutsui return ENXIO;
195*d02e022dStsutsui }
196*d02e022dStsutsui
197*d02e022dStsutsui /* try to read disk label and partition table information */
198*d02e022dStsutsui lp = &sc->sc_label;
199*d02e022dStsutsui lp->d_secsize = DEV_BSIZE;
200*d02e022dStsutsui lp->d_secpercyl = 1;
201*d02e022dStsutsui lp->d_npartitions = MAXPARTITIONS;
202*d02e022dStsutsui lp->d_partitions[scsi_part].p_offset = 0;
203*d02e022dStsutsui lp->d_partitions[scsi_part].p_size = 0x7fffffff;
204*d02e022dStsutsui
205*d02e022dStsutsui error = diskstrategy(sc, F_READ, (daddr_t)LABELSECTOR, DEV_BSIZE, buf,
206*d02e022dStsutsui &cnt);
207*d02e022dStsutsui
208*d02e022dStsutsui if (error || cnt != DEV_BSIZE) {
209*d02e022dStsutsui printf("diskstrategy error...\n");
210*d02e022dStsutsui dealloc(sc, sizeof(struct disk_softc));
211*d02e022dStsutsui return ENXIO;
212*d02e022dStsutsui }
213*d02e022dStsutsui
214*d02e022dStsutsui msg = getdisklabel(buf, lp);
215*d02e022dStsutsui
216*d02e022dStsutsui if (msg) {
217*d02e022dStsutsui /* If no label, just assume 0 and return */
218*d02e022dStsutsui printf("No disklabel...\n");
219*d02e022dStsutsui reboot();
220*d02e022dStsutsui }
221*d02e022dStsutsui
222*d02e022dStsutsui return 0;
223*d02e022dStsutsui }
224*d02e022dStsutsui
225*d02e022dStsutsui int
diskclose(struct open_file * f)226*d02e022dStsutsui diskclose(struct open_file *f)
227*d02e022dStsutsui {
228*d02e022dStsutsui struct disk_softc *sc = f->f_devdata;
229*d02e022dStsutsui
230*d02e022dStsutsui dealloc(sc, sizeof *sc);
231*d02e022dStsutsui f->f_devdata = NULL;
232*d02e022dStsutsui
233*d02e022dStsutsui return 0;
234*d02e022dStsutsui }
235