1 /* $NetBSD: sd.c,v 1.5 2004/08/28 17:45:24 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Van Jacobson of Lawrence Berkeley Laboratory and the Systems 9 * Programming Group of the University of Utah Computer Science Department. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * from: Utah $Hdr: sd.c 1.9 92/12/21$ 36 * 37 * @(#)sd.c 8.1 (Berkeley) 6/10/93 38 */ 39 /* 40 * Copyright (c) 1988 University of Utah. 41 * 42 * This code is derived from software contributed to Berkeley by 43 * Van Jacobson of Lawrence Berkeley Laboratory and the Systems 44 * Programming Group of the University of Utah Computer Science Department. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. All advertising materials mentioning features or use of this software 55 * must display the following acknowledgement: 56 * This product includes software developed by the University of 57 * California, Berkeley and its contributors. 58 * 4. Neither the name of the University nor the names of its contributors 59 * may be used to endorse or promote products derived from this software 60 * without specific prior written permission. 61 * 62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 72 * SUCH DAMAGE. 73 * 74 * from: Utah $Hdr: sd.c 1.9 92/12/21$ 75 * 76 * @(#)sd.c 8.1 (Berkeley) 6/10/93 77 */ 78 79 /* 80 * SCSI CCS disk driver 81 */ 82 83 #include <sys/param.h> 84 #include <sys/disklabel.h> 85 86 #include <machine/stdarg.h> 87 88 #include <lib/libsa/stand.h> 89 90 #include <hp300/stand/common/samachdep.h> 91 #include <hp300/stand/common/conf.h> 92 93 #define _IOCTL_ 94 #include <hp300/stand/common/scsireg.h> 95 #include <hp300/stand/common/scsivar.h> 96 97 struct sdminilabel { 98 u_short npart; 99 u_long offset[MAXPARTITIONS]; 100 }; 101 102 struct sd_softc { 103 int sc_ctlr; 104 int sc_unit; 105 int sc_part; 106 char sc_retry; 107 char sc_alive; 108 short sc_blkshift; 109 struct sdminilabel sc_pinfo; 110 }; 111 112 #define SDRETRY 2 113 114 static int sdinit(int ,int); 115 static int sdgetinfo(struct sd_softc *); 116 117 struct disklabel sdlabel; 118 struct sd_softc sd_softc[NSCSI][NSD]; 119 120 static int 121 sdinit(ctlr, unit) 122 int ctlr, unit; 123 { 124 struct sd_softc *ss = &sd_softc[ctlr][unit]; 125 u_char stat; 126 int capbuf[2]; 127 128 stat = scsi_test_unit_rdy(ctlr, unit); 129 if (stat) { 130 /* drive may be doing RTZ - wait a bit */ 131 if (stat == STS_CHECKCOND) { 132 DELAY(1000000); 133 stat = scsi_test_unit_rdy(ctlr, unit); 134 } 135 if (stat) { 136 printf("sd(%d,%d,0,0): init failed (stat=%x)\n", 137 ctlr, unit, stat); 138 return 0; 139 } 140 } 141 /* 142 * try to get the drive block size. 143 */ 144 capbuf[0] = 0; 145 capbuf[1] = 0; 146 stat = scsi_read_capacity(ctlr, unit, 147 (u_char *)capbuf, sizeof(capbuf)); 148 if (stat == 0) { 149 if (capbuf[1] > DEV_BSIZE) 150 for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1) 151 ++ss->sc_blkshift; 152 } 153 ss->sc_alive = 1; 154 return 1; 155 } 156 157 char io_buf[MAXBSIZE]; 158 159 static int 160 sdgetinfo(ss) 161 struct sd_softc *ss; 162 { 163 struct sdminilabel *pi = &ss->sc_pinfo; 164 struct disklabel *lp = &sdlabel; 165 char *msg; 166 int err, savepart; 167 size_t i; 168 169 memset((caddr_t)lp, 0, sizeof *lp); 170 lp->d_secsize = (DEV_BSIZE << ss->sc_blkshift); 171 172 /* Disklabel is always from RAW_PART. */ 173 savepart = ss->sc_part; 174 ss->sc_part = RAW_PART; 175 err = sdstrategy(ss, F_READ, LABELSECTOR, 176 lp->d_secsize ? lp->d_secsize : DEV_BSIZE, io_buf, &i); 177 ss->sc_part = savepart; 178 179 if (err) { 180 printf("sdgetinfo: sdstrategy error %d\n", err); 181 return 0; 182 } 183 184 msg = getdisklabel(io_buf, lp); 185 if (msg) { 186 printf("sd(%d,%d,%d): WARNING: %s\n", 187 ss->sc_ctlr, ss->sc_unit, ss->sc_part, msg); 188 pi->npart = 3; 189 pi->offset[0] = pi->offset[1] = -1; 190 pi->offset[2] = 0; 191 } else { 192 pi->npart = lp->d_npartitions; 193 for (i = 0; i < pi->npart; i++) 194 pi->offset[i] = lp->d_partitions[i].p_size == 0 ? 195 -1 : lp->d_partitions[i].p_offset; 196 } 197 return 1; 198 } 199 200 int 201 sdopen(struct open_file *f, ...) 202 { 203 va_list ap; 204 int ctlr, unit, part; 205 struct sd_softc *ss; 206 207 va_start(ap, f); 208 ctlr = va_arg(ap, int); 209 unit = va_arg(ap, int); 210 part = va_arg(ap, int); 211 va_end(ap); 212 213 #ifdef SD_DEBUG 214 if (debug) 215 printf("sdopen: ctlr=%d unit=%d part=%d\n", 216 ctlr, unit, part); 217 #endif 218 219 if (ctlr >= NSCSI || scsialive(ctlr) == 0) 220 return EADAPT; 221 if (unit >= NSD) 222 return ECTLR; 223 ss = &sd_softc[ctlr][unit]; 224 ss->sc_part = part; 225 ss->sc_unit = unit; 226 ss->sc_ctlr = ctlr; 227 if (ss->sc_alive == 0) { 228 if (sdinit(ctlr, unit) == 0) 229 return ENXIO; 230 if (sdgetinfo(ss) == 0) 231 return ERDLAB; 232 } 233 if (part != RAW_PART && /* always allow RAW_PART to be opened */ 234 (part >= ss->sc_pinfo.npart || ss->sc_pinfo.offset[part] == -1)) 235 return EPART; 236 f->f_devdata = (void *)ss; 237 return 0; 238 } 239 240 int 241 sdclose(f) 242 struct open_file *f; 243 { 244 struct sd_softc *ss = f->f_devdata; 245 246 /* 247 * Mark the disk `not alive' so that the disklabel 248 * will be re-loaded at next open. 249 */ 250 memset(ss, 0, sizeof(sd_softc)); 251 f->f_devdata = NULL; 252 253 return 0; 254 } 255 256 int 257 sdstrategy(devdata, func, dblk, size, v_buf, rsize) 258 void *devdata; 259 int func; 260 daddr_t dblk; 261 size_t size; 262 void *v_buf; 263 size_t *rsize; 264 { 265 struct sd_softc *ss = devdata; 266 char *buf = v_buf; 267 int ctlr = ss->sc_ctlr; 268 int unit = ss->sc_unit; 269 u_int nblk = size >> ss->sc_blkshift; 270 daddr_t blk; 271 char stat; 272 273 if (size == 0) 274 return 0; 275 276 /* 277 * Don't do partition translation on the `raw partition'. 278 */ 279 blk = (dblk + ((ss->sc_part == RAW_PART) ? 0 : 280 ss->sc_pinfo.offset[ss->sc_part])) >> ss->sc_blkshift; 281 282 ss->sc_retry = 0; 283 284 #ifdef SD_DEBUG 285 if (debug) 286 printf("sdstrategy(%d,%d): size=%d blk=%d nblk=%d\n", 287 ctlr, unit, size, blk, nblk); 288 #endif 289 290 retry: 291 if (func == F_READ) 292 stat = scsi_tt_read(ctlr, unit, buf, size, blk, nblk); 293 else 294 stat = scsi_tt_write(ctlr, unit, buf, size, blk, nblk); 295 if (stat) { 296 printf("sd(%d,%d,%d): block=%x, error=0x%x\n", 297 ctlr, unit, ss->sc_part, blk, stat); 298 if (++ss->sc_retry > SDRETRY) 299 return EIO; 300 goto retry; 301 } 302 *rsize = size; 303 304 return 0; 305 } 306