123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- /* $OpenBSD: sd.c,v 1.5 2014/07/12 21:03:38 tedu Exp $ */
- /* $NetBSD: sd.c,v 1.5 2013/01/22 15:48:40 tsutsui Exp $ */
- /*
- * Copyright (c) 1992 OMRON Corporation.
- *
- * This code is derived from software contributed to Berkeley by
- * OMRON Corporation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)sd.c 8.1 (Berkeley) 6/10/93
- */
- /*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * OMRON Corporation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)sd.c 8.1 (Berkeley) 6/10/93
- */
- /*
- * sd.c -- SCSI DISK device driver
- * by A.Fujita, FEB-26-1992
- */
- /*
- * SCSI CCS (Command Command Set) disk driver.
- */
- #include <sys/param.h>
- #include <sys/disklabel.h>
- #include <luna88k/stand/boot/samachdep.h>
- #include <luna88k/stand/boot/scsireg.h>
- #include <luna88k/stand/boot/scsivar.h>
- struct sd_softc {
- uint sc_ctlr;
- uint sc_tgt;
- uint sc_part;
- short sc_type; /* drive type */
- short sc_punit; /* physical unit (scsi lun) */
- u_short sc_bshift; /* convert device blocks to DEV_BSIZE blks */
- daddr32_t sc_blks; /* number of blocks on device */
- int sc_blksize; /* device block size in bytes */
- struct disklabel sc_label;
- struct scsi_softc sc_sc;
- };
- struct sd_softc *sdinit(uint, uint);
- static int sdident(struct sd_softc *);
- static struct scsi_inquiry inqbuf;
- static struct scsi_generic_cdb inq = {
- 6,
- { CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 }
- };
- static u_long capbuf[2];
- struct scsi_generic_cdb cap = {
- 10,
- { CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
- };
- int
- sdident(struct sd_softc *sc)
- {
- #ifdef DEBUG
- char idstr[32];
- #endif
- uint ctlr, target, unit;
- int i;
- int tries = 10;
- ctlr = sc->sc_ctlr;
- target = sc->sc_tgt;
- unit = sc->sc_punit;
- if (scinit(&sc->sc_sc, ctlr) == 0)
- return -1;
- /*
- * See if unit exists and is a disk then read block size & nblocks.
- */
- while ((i = scsi_test_unit_rdy(&sc->sc_sc, target, unit)) != 0) {
- if (i < 0 || --tries < 0)
- return (-1);
- if (i == STS_CHECKCOND) {
- u_char sensebuf[8];
- struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf;
- scsi_request_sense(&sc->sc_sc, target, unit, sensebuf,
- sizeof sensebuf);
- if (sp->class == 7 && sp->key == 6)
- /* drive doing an RTZ -- give it a while */
- DELAY(1000000);
- }
- DELAY(1000);
- }
- if (scsi_immed_command(&sc->sc_sc, target, unit, &inq,
- (u_char *)&inqbuf, sizeof(inqbuf)) ||
- scsi_immed_command(&sc->sc_sc, target, unit, &cap,
- (u_char *)&capbuf, sizeof(capbuf)))
- /* doesn't exist or not a CCS device */
- return (-1);
- switch (inqbuf.type) {
- case 0: /* disk */
- case 4: /* WORM */
- case 5: /* CD-ROM */
- case 7: /* Magneto-optical */
- break;
- default: /* not a disk */
- return (-1);
- }
- sc->sc_blks = capbuf[0];
- sc->sc_blksize = capbuf[1];
- #ifdef DEBUG
- memcpy(idstr, &inqbuf.vendor_id, 28);
- for (i = 27; i > 23; --i)
- if (idstr[i] != ' ')
- break;
- idstr[i+1] = 0;
- for (i = 23; i > 7; --i)
- if (idstr[i] != ' ')
- break;
- idstr[i+1] = 0;
- for (i = 7; i >= 0; --i)
- if (idstr[i] != ' ')
- break;
- idstr[i+1] = 0;
- printf("sd(%d,%d): %s %s rev %s", ctlr, target, idstr, &idstr[8],
- &idstr[24]);
- printf(", %d bytes/sect x %d sectors\n", sc->sc_blksize, sc->sc_blks);
- #endif
- if (sc->sc_blksize != DEV_BSIZE) {
- if (sc->sc_blksize < DEV_BSIZE) {
- printf("sd(%d,%d): need %d byte blocks - drive ignored\n",
- ctlr, target, DEV_BSIZE);
- return (-1);
- }
- for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1)
- ++sc->sc_bshift;
- sc->sc_blks <<= sc->sc_bshift;
- }
- return(inqbuf.type);
- }
- struct sd_softc *
- sdinit(uint unit, uint part)
- {
- struct sd_softc *sc;
- struct disklabel *lp;
- char *msg;
- sc = alloc(sizeof *sc);
- if (sc == NULL)
- return NULL;
- memset(sc, 0, sizeof *sc);
- sc->sc_ctlr = unit / 10;
- sc->sc_tgt = unit % 10;
- sc->sc_part = part;
- #ifdef DEBUG
- printf("sdinit: ctlr = %d tgt = %d part = %d\n",
- sc->sc_ctlr, sc->sc_tgt, sc->sc_part);
- #endif
- sc->sc_punit = 0; /* XXX no LUN support yet */
- sc->sc_type = sdident(sc);
- if (sc->sc_type < 0)
- return(NULL);
- /*
- * Use the default sizes until we've read the label,
- * or longer if there isn't one there.
- */
- lp = &sc->sc_label;
- if (lp->d_secpercyl == 0) {
- lp->d_secsize = DEV_BSIZE;
- lp->d_nsectors = 32;
- lp->d_ntracks = 20;
- lp->d_secpercyl = 32*20;
- lp->d_npartitions = 1;
- lp->d_partitions[0].p_offset = 0;
- lp->d_partitions[0].p_size = LABELSECTOR + 1;
- }
- /*
- * read disklabel
- */
- msg = readdisklabel(&sc->sc_sc, sc->sc_tgt, lp);
- if (msg != NULL)
- printf("sd(%d,%d): %s\n", sc->sc_ctlr, sc->sc_tgt, msg);
- return sc;
- }
- int
- sdopen(struct open_file *f, ...)
- {
- va_list ap;
- struct sd_softc *sc;
- int unit, part;
- va_start(ap, f);
- unit = va_arg(ap, int);
- part = va_arg(ap, int);
- va_end(ap);
- if (part < 0 || part >= MAXPARTITIONS)
- return(-1);
- sc = sdinit(unit, part);
- if (sc == NULL)
- return -1;
- f->f_devdata = (void *)sc;
- return 0;
- }
- int
- sdclose(struct open_file *f)
- {
- struct sd_softc *sc = f->f_devdata;
- free(sc, sizeof *sc);
- f->f_devdata = NULL;
- return 0;
- }
- static struct scsi_generic_cdb cdb_read = {
- 10,
- { CMD_READ_EXT, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
- };
- static struct scsi_generic_cdb cdb_write = {
- 6,
- { CMD_WRITE_EXT, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
- };
- int
- sdstrategy(void *devdata, int func, daddr32_t dblk, size_t size, void *v_buf,
- size_t *rsize)
- {
- struct sd_softc *sc = devdata;
- struct disklabel *lp;
- uint8_t *buf = v_buf;
- int target = sc->sc_tgt;
- struct scsi_generic_cdb *cdb;
- daddr32_t blk;
- u_int nblk = size >> sc->sc_bshift;
- int stat;
- #ifdef DEBUG
- int i;
- #endif
- lp = &sc->sc_label;
- blk = dblk + (lp->d_partitions[sc->sc_part].p_offset >> sc->sc_bshift);
- if (func == F_READ)
- cdb = &cdb_read;
- else
- cdb = &cdb_write;
- cdb->cdb[2] = (blk & 0xff000000) >> 24;
- cdb->cdb[3] = (blk & 0x00ff0000) >> 16;
- cdb->cdb[4] = (blk & 0x0000ff00) >> 8;
- cdb->cdb[5] = (blk & 0x000000ff);
- cdb->cdb[7] = ((nblk >> _DEV_BSHIFT) & 0xff00) >> 8;
- cdb->cdb[8] = ((nblk >> _DEV_BSHIFT) & 0x00ff);
- #ifdef DEBUG
- printf("sdstrategy(%d,%d): blk = %lu (0x%lx), nblk = %u (0x%x)\n",
- sc->sc_ctlr, sc->sc_tgt, (u_long)blk, (long)blk, nblk, nblk);
- for (i = 0; i < 10; i++)
- printf("cdb[%d] = 0x%x\n", i, cdb->cdb[i]);
- #endif
- stat = scsi_immed_command(&sc->sc_sc, target, sc->sc_punit, cdb, buf,
- size);
- if (rsize)
- *rsize = size;
- return 0;
- }
|