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