Home | History | Annotate | Line # | Download | only in boot
      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