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