1 /* $NetBSD: sd.c,v 1.13 2023/06/24 07:02:11 tsutsui Exp $ */ 2 3 /* 4 * Copyright (c) 1992 OMRON Corporation. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * OMRON Corporation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)sd.c 8.1 (Berkeley) 6/10/93 38 */ 39 /* 40 * Copyright (c) 1992, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This code is derived from software contributed to Berkeley by 44 * OMRON Corporation. 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. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 * 70 * @(#)sd.c 8.1 (Berkeley) 6/10/93 71 */ 72 73 /* 74 * sd.c -- SCSI DISK device driver 75 * by A.Fujita, FEB-26-1992 76 */ 77 78 79 /* 80 * SCSI CCS (Command Command Set) disk driver. 81 */ 82 #include <sys/param.h> 83 #include <sys/disklabel.h> 84 #include <luna68k/stand/boot/samachdep.h> 85 #include <luna68k/stand/boot/scsireg.h> 86 87 struct sd_softc { 88 int sc_unit; 89 uint sc_ctlr; 90 uint sc_tgt; 91 uint sc_lun; 92 int sc_part; 93 uint sc_bshift; /* convert device blocks to DEV_BSIZE blks */ 94 uint sc_blks; /* number of blocks on device */ 95 int sc_blksize; /* device block size in bytes */ 96 struct disklabel sc_label; 97 }; 98 99 static int sdident(struct sd_softc *); 100 static struct sd_softc *sdinit(uint); 101 102 static int 103 sdident(struct sd_softc *sc) 104 { 105 struct scsi_inquiry inqbuf; 106 uint32_t capbuf[2]; 107 int i; 108 109 if (!scident(sc->sc_ctlr, sc->sc_tgt, sc->sc_lun, &inqbuf, capbuf)) 110 return -1; 111 112 sc->sc_blks = capbuf[0]; 113 sc->sc_blksize = capbuf[1]; 114 115 if (sc->sc_blksize != DEV_BSIZE) { 116 if (sc->sc_blksize < DEV_BSIZE) { 117 return -1; 118 } 119 for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1) 120 ++sc->sc_bshift; 121 sc->sc_blks <<= sc->sc_bshift; 122 } 123 return inqbuf.type; 124 } 125 126 static struct sd_softc * 127 sdinit(uint unit) 128 { 129 struct sd_softc *sc; 130 struct disklabel *lp; 131 char *msg; 132 int type; 133 134 #ifdef DEBUG 135 printf("sdinit: unit = %d\n", unit); 136 #endif 137 sc = alloc(sizeof *sc); 138 memset(sc, 0, sizeof *sc); 139 140 sc->sc_unit = unit; 141 sc->sc_ctlr = CTLR(unit); 142 sc->sc_tgt = TARGET(unit); 143 sc->sc_lun = 0; /* XXX no LUN support yet */ 144 type = sdident(sc); 145 if (type < 0) 146 return NULL; 147 148 /* 149 * Use the default sizes until we've read the label, 150 * or longer if there isn't one there. 151 */ 152 lp = &sc->sc_label; 153 154 if (lp->d_secpercyl == 0) { 155 lp->d_secsize = DEV_BSIZE; 156 lp->d_nsectors = 32; 157 lp->d_ntracks = 20; 158 lp->d_secpercyl = 32*20; 159 lp->d_npartitions = 1; 160 lp->d_partitions[0].p_offset = 0; 161 lp->d_partitions[0].p_size = LABELSECTOR + 1; 162 } 163 164 /* 165 * read disklabel 166 */ 167 msg = readdisklabel(sc->sc_ctlr, sc->sc_tgt, lp); 168 if (msg != NULL) 169 printf("sd(%d): %s\n", unit, msg); 170 171 return sc; 172 } 173 174 int 175 sdopen(struct open_file *f, ...) 176 { 177 va_list ap; 178 struct sd_softc *sc; 179 int unit, part; 180 181 va_start(ap, f); 182 unit = va_arg(ap, int); 183 part = va_arg(ap, int); 184 va_end(ap); 185 186 if (unit < 0 || CTLR(unit) >= 2 || TARGET(unit) >= 7) 187 return -1; 188 if (part < 0 || part >= MAXPARTITIONS) 189 return -1; 190 191 sc = sdinit(unit); 192 if (sc == NULL) 193 return -1; 194 195 sc->sc_part = part; 196 f->f_devdata = (void *)sc; 197 198 return 0; 199 } 200 201 int 202 sdclose(struct open_file *f) 203 { 204 struct sd_softc *sc = f->f_devdata; 205 206 dealloc(sc, sizeof *sc); 207 f->f_devdata = NULL; 208 209 return 0; 210 } 211 212 static struct scsi_generic_cdb cdb_read = { 213 10, 214 { CMD_READ_EXT, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 215 }; 216 217 static struct scsi_generic_cdb cdb_write = { 218 10, 219 { CMD_WRITE_EXT, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 220 }; 221 222 int 223 sdstrategy(void *devdata, int func, daddr_t dblk, size_t size, void *v_buf, 224 size_t *rsize) 225 { 226 struct sd_softc *sc; 227 struct disklabel *lp; 228 uint8_t *buf; 229 struct scsi_generic_cdb *cdb; 230 daddr_t blk; 231 u_int nblk; 232 int stat; 233 #ifdef DEBUG 234 int i; 235 #endif 236 237 sc = devdata; 238 if (sc == NULL) 239 return -1; 240 241 buf = v_buf; 242 lp = &sc->sc_label; 243 blk = dblk + (lp->d_partitions[sc->sc_part].p_offset >> sc->sc_bshift); 244 nblk = size >> sc->sc_bshift; 245 246 if (func == F_READ) 247 cdb = &cdb_read; 248 else 249 cdb = &cdb_write; 250 251 cdb->cdb[2] = (blk & 0xff000000) >> 24; 252 cdb->cdb[3] = (blk & 0x00ff0000) >> 16; 253 cdb->cdb[4] = (blk & 0x0000ff00) >> 8; 254 cdb->cdb[5] = (blk & 0x000000ff); 255 256 cdb->cdb[7] = ((nblk >> DEV_BSHIFT) & 0xff00) >> 8; 257 cdb->cdb[8] = ((nblk >> DEV_BSHIFT) & 0x00ff); 258 259 #ifdef DEBUG 260 printf("sdstrategy: unit = %d\n", sc->sc_unit); 261 printf("sdstrategy: blk = %lu (0x%lx), nblk = %u (0x%x)\n", 262 (u_long)blk, (long)blk, nblk, nblk); 263 for (i = 0; i < 10; i++) 264 printf("sdstrategy: cdb[%d] = 0x%x\n", i, cdb->cdb[i]); 265 printf("sdstrategy: ctlr = %d, target = %d\n", sc->sc_ctlr, sc->sc_tgt); 266 #endif 267 stat = scsi_immed_command(sc->sc_ctlr, sc->sc_tgt, sc->sc_lun, 268 cdb, buf, size); 269 if (stat != 0) 270 return EIO; 271 272 if (rsize) 273 *rsize = size; 274 275 return 0; 276 } 277