1 /* $NetBSD: sd.c,v 1.4 2003/11/14 16:52:40 tsutsui 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 #ifdef COMPAT_NOLABEL 158 struct sdminilabel defaultpinfo = { 159 8, 160 { 1024, 17408, 0, 17408, 115712, 218112, 82944, 115712 } 161 }; 162 #endif 163 164 char io_buf[MAXBSIZE]; 165 166 static int 167 sdgetinfo(ss) 168 struct sd_softc *ss; 169 { 170 struct sdminilabel *pi = &ss->sc_pinfo; 171 struct disklabel *lp = &sdlabel; 172 char *msg; 173 int err, savepart; 174 size_t i; 175 176 memset((caddr_t)lp, 0, sizeof *lp); 177 lp->d_secsize = (DEV_BSIZE << ss->sc_blkshift); 178 179 /* Disklabel is always from RAW_PART. */ 180 savepart = ss->sc_part; 181 ss->sc_part = RAW_PART; 182 err = sdstrategy(ss, F_READ, LABELSECTOR, 183 lp->d_secsize ? lp->d_secsize : DEV_BSIZE, io_buf, &i); 184 ss->sc_part = savepart; 185 186 if (err) { 187 printf("sdgetinfo: sdstrategy error %d\n", err); 188 return 0; 189 } 190 191 msg = getdisklabel(io_buf, lp); 192 if (msg) { 193 printf("sd(%d,%d,%d): WARNING: %s, ", 194 ss->sc_ctlr, ss->sc_unit, ss->sc_part, msg); 195 #ifdef COMPAT_NOLABEL 196 printf("using old default partitioning\n"); 197 *pi = defaultpinfo; 198 #else 199 printf("defining `c' partition as entire disk\n"); 200 pi->npart = 3; 201 pi->offset[0] = pi->offset[1] = -1; 202 pi->offset[2] = 0; 203 #endif 204 } else { 205 pi->npart = lp->d_npartitions; 206 for (i = 0; i < pi->npart; i++) 207 pi->offset[i] = lp->d_partitions[i].p_size == 0 ? 208 -1 : lp->d_partitions[i].p_offset; 209 } 210 return 1; 211 } 212 213 int 214 sdopen(struct open_file *f, ...) 215 { 216 va_list ap; 217 int ctlr, unit, part; 218 struct sd_softc *ss; 219 220 va_start(ap, f); 221 ctlr = va_arg(ap, int); 222 unit = va_arg(ap, int); 223 part = va_arg(ap, int); 224 va_end(ap); 225 226 #ifdef SD_DEBUG 227 if (debug) 228 printf("sdopen: ctlr=%d unit=%d part=%d\n", 229 ctlr, unit, part); 230 #endif 231 232 if (ctlr >= NSCSI || scsialive(ctlr) == 0) 233 return EADAPT; 234 if (unit >= NSD) 235 return ECTLR; 236 ss = &sd_softc[ctlr][unit]; 237 ss->sc_part = part; 238 ss->sc_unit = unit; 239 ss->sc_ctlr = ctlr; 240 if (ss->sc_alive == 0) { 241 if (sdinit(ctlr, unit) == 0) 242 return ENXIO; 243 if (sdgetinfo(ss) == 0) 244 return ERDLAB; 245 } 246 if (part != RAW_PART && /* always allow RAW_PART to be opened */ 247 (part >= ss->sc_pinfo.npart || ss->sc_pinfo.offset[part] == -1)) 248 return EPART; 249 f->f_devdata = (void *)ss; 250 return 0; 251 } 252 253 int 254 sdclose(f) 255 struct open_file *f; 256 { 257 struct sd_softc *ss = f->f_devdata; 258 259 /* 260 * Mark the disk `not alive' so that the disklabel 261 * will be re-loaded at next open. 262 */ 263 memset(ss, 0, sizeof(sd_softc)); 264 f->f_devdata = NULL; 265 266 return 0; 267 } 268 269 int 270 sdstrategy(devdata, func, dblk, size, v_buf, rsize) 271 void *devdata; 272 int func; 273 daddr_t dblk; 274 size_t size; 275 void *v_buf; 276 size_t *rsize; 277 { 278 struct sd_softc *ss = devdata; 279 char *buf = v_buf; 280 int ctlr = ss->sc_ctlr; 281 int unit = ss->sc_unit; 282 u_int nblk = size >> ss->sc_blkshift; 283 daddr_t blk; 284 char stat; 285 286 if (size == 0) 287 return 0; 288 289 /* 290 * Don't do partition translation on the `raw partition'. 291 */ 292 blk = (dblk + ((ss->sc_part == RAW_PART) ? 0 : 293 ss->sc_pinfo.offset[ss->sc_part])) >> ss->sc_blkshift; 294 295 ss->sc_retry = 0; 296 297 #ifdef SD_DEBUG 298 if (debug) 299 printf("sdstrategy(%d,%d): size=%d blk=%d nblk=%d\n", 300 ctlr, unit, size, blk, nblk); 301 #endif 302 303 retry: 304 if (func == F_READ) 305 stat = scsi_tt_read(ctlr, unit, buf, size, blk, nblk); 306 else 307 stat = scsi_tt_write(ctlr, unit, buf, size, blk, nblk); 308 if (stat) { 309 printf("sd(%d,%d,%d): block=%x, error=0x%x\n", 310 ctlr, unit, ss->sc_part, blk, stat); 311 if (++ss->sc_retry > SDRETRY) 312 return EIO; 313 goto retry; 314 } 315 *rsize = size; 316 317 return 0; 318 } 319