1 /* $NetBSD: sd.c,v 1.9 2007/03/04 05:59:50 christos 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(int ctlr, int unit) 122 { 123 struct sd_softc *ss = &sd_softc[ctlr][unit]; 124 u_char stat; 125 int capbuf[2]; 126 127 stat = scsi_test_unit_rdy(ctlr, unit); 128 if (stat) { 129 /* drive may be doing RTZ - wait a bit */ 130 if (stat == STS_CHECKCOND) { 131 DELAY(1000000); 132 stat = scsi_test_unit_rdy(ctlr, unit); 133 } 134 if (stat) { 135 printf("sd(%d,%d,0,0): init failed (stat=%x)\n", 136 ctlr, unit, stat); 137 return 0; 138 } 139 } 140 /* 141 * try to get the drive block size. 142 */ 143 capbuf[0] = 0; 144 capbuf[1] = 0; 145 stat = scsi_read_capacity(ctlr, unit, 146 (u_char *)capbuf, sizeof(capbuf)); 147 if (stat == 0) { 148 if (capbuf[1] > DEV_BSIZE) 149 for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1) 150 ++ss->sc_blkshift; 151 } 152 ss->sc_alive = 1; 153 return 1; 154 } 155 156 char io_buf[MAXBSIZE]; 157 158 static int 159 sdgetinfo(struct sd_softc *ss) 160 { 161 struct sdminilabel *pi = &ss->sc_pinfo; 162 struct disklabel *lp = &sdlabel; 163 char *msg; 164 int err, savepart; 165 size_t i; 166 167 memset((void *)lp, 0, sizeof *lp); 168 lp->d_secsize = (DEV_BSIZE << ss->sc_blkshift); 169 170 /* Disklabel is always from RAW_PART. */ 171 savepart = ss->sc_part; 172 ss->sc_part = RAW_PART; 173 err = sdstrategy(ss, F_READ, LABELSECTOR, 174 lp->d_secsize ? lp->d_secsize : DEV_BSIZE, io_buf, &i); 175 ss->sc_part = savepart; 176 177 if (err) { 178 printf("sdgetinfo: sdstrategy error %d\n", err); 179 return 0; 180 } 181 182 msg = getdisklabel(io_buf, lp); 183 if (msg) { 184 printf("sd(%d,%d,%d): WARNING: %s\n", 185 ss->sc_ctlr, ss->sc_unit, ss->sc_part, msg); 186 pi->npart = 3; 187 pi->offset[0] = pi->offset[1] = -1; 188 pi->offset[2] = 0; 189 } else { 190 pi->npart = lp->d_npartitions; 191 for (i = 0; i < pi->npart; i++) 192 pi->offset[i] = lp->d_partitions[i].p_size == 0 ? 193 -1 : lp->d_partitions[i].p_offset; 194 } 195 return 1; 196 } 197 198 int 199 sdopen(struct open_file *f, ...) 200 { 201 va_list ap; 202 int ctlr, unit, part; 203 struct sd_softc *ss; 204 205 va_start(ap, f); 206 ctlr = va_arg(ap, int); 207 unit = va_arg(ap, int); 208 part = va_arg(ap, int); 209 va_end(ap); 210 211 #ifdef SD_DEBUG 212 if (debug) 213 printf("sdopen: ctlr=%d unit=%d part=%d\n", 214 ctlr, unit, part); 215 #endif 216 217 if (ctlr >= NSCSI || scsialive(ctlr) == 0) 218 return EADAPT; 219 if (unit >= NSD) 220 return ECTLR; 221 ss = &sd_softc[ctlr][unit]; 222 ss->sc_part = part; 223 ss->sc_unit = unit; 224 ss->sc_ctlr = ctlr; 225 if (ss->sc_alive == 0) { 226 if (sdinit(ctlr, unit) == 0) 227 return ENXIO; 228 if (sdgetinfo(ss) == 0) 229 return ERDLAB; 230 } 231 if (part != RAW_PART && /* always allow RAW_PART to be opened */ 232 (part >= ss->sc_pinfo.npart || ss->sc_pinfo.offset[part] == -1)) 233 return EPART; 234 f->f_devdata = (void *)ss; 235 return 0; 236 } 237 238 int 239 sdclose(struct open_file *f) 240 { 241 struct sd_softc *ss = f->f_devdata; 242 243 /* 244 * Mark the disk `not alive' so that the disklabel 245 * will be re-loaded at next open. 246 */ 247 memset(ss, 0, sizeof(sd_softc)); 248 f->f_devdata = NULL; 249 250 return 0; 251 } 252 253 int 254 sdstrategy(void *devdata, int func, daddr_t dblk, size_t size, void *v_buf, 255 size_t *rsize) 256 { 257 struct sd_softc *ss = devdata; 258 uint8_t *buf = v_buf; 259 int ctlr = ss->sc_ctlr; 260 int unit = ss->sc_unit; 261 u_int nblk = size >> ss->sc_blkshift; 262 daddr_t blk; 263 int stat; 264 265 if (size == 0) 266 return 0; 267 268 /* 269 * Don't do partition translation on the `raw partition'. 270 */ 271 blk = (dblk + ((ss->sc_part == RAW_PART) ? 0 : 272 ss->sc_pinfo.offset[ss->sc_part])) >> ss->sc_blkshift; 273 274 ss->sc_retry = 0; 275 276 #ifdef SD_DEBUG 277 if (debug) 278 printf("sdstrategy(%d,%d): size=%d blk=%d nblk=%d\n", 279 ctlr, unit, size, blk, nblk); 280 #endif 281 282 retry: 283 if (func == F_READ) 284 stat = scsi_tt_read(ctlr, unit, buf, size, blk, nblk); 285 else 286 stat = scsi_tt_write(ctlr, unit, buf, size, blk, nblk); 287 if (stat) { 288 printf("sd(%d,%d,%d): block=%x, error=0x%x\n", 289 ctlr, unit, ss->sc_part, blk, stat); 290 if (++ss->sc_retry > SDRETRY) 291 return EIO; 292 goto retry; 293 } 294 *rsize = size; 295 296 return 0; 297 } 298