Home | History | Annotate | Line # | Download | only in boot
sd.c revision 1.11.4.1
      1  1.11.4.1    skrll /*	$NetBSD: sd.c,v 1.11.4.1 2015/04/06 15:17:58 skrll 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.9  tsutsui static int sdident(struct sd_softc *);
    100  1.11.4.1    skrll static struct sd_softc *sdinit(uint);
    101       1.1  tsutsui 
    102  1.11.4.1    skrll 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.11.4.1    skrll 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.1  tsutsui 	6,
    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