xref: /netbsd-src/sys/arch/sgimips/stand/common/iris_disk.c (revision d02e022db788ed4933c5904d9d6ce3af08f11fee)
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