summaryrefslogtreecommitdiff
path: root/sys/arch/hp300/stand/common/sd.c
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1997-07-14 08:15:01 +0000
committerJason Downs <downsj@cvs.openbsd.org>1997-07-14 08:15:01 +0000
commit68982ee9315c1d2dfd5ae49889ef59a9a0a2b18e (patch)
tree49722ae0f8e398f3a79268c08a236e5b9bf0c3ad /sys/arch/hp300/stand/common/sd.c
parent5f2612599833ff2e0bc32cb218ce6f42643092b2 (diff)
The grand reorganization, OpenBSD style.
Lossely based on the NetBSD reorg, but much improved upon, simpler, and doesn't scribble needless junk into the bootblocks.
Diffstat (limited to 'sys/arch/hp300/stand/common/sd.c')
-rw-r--r--sys/arch/hp300/stand/common/sd.c258
1 files changed, 258 insertions, 0 deletions
diff --git a/sys/arch/hp300/stand/common/sd.c b/sys/arch/hp300/stand/common/sd.c
new file mode 100644
index 00000000000..e27eb8f1978
--- /dev/null
+++ b/sys/arch/hp300/stand/common/sd.c
@@ -0,0 +1,258 @@
+/* $OpenBSD: sd.c,v 1.1 1997/07/14 08:14:29 downsj Exp $ */
+/* $NetBSD: sd.c,v 1.9 1996/12/21 21:34:41 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson of Lawrence Berkeley Laboratory and the Systems
+ * Programming Group of the University of Utah Computer Science Department.
+ *
+ * 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.
+ *
+ * from: Utah $Hdr: sd.c 1.9 92/12/21$
+ *
+ * @(#)sd.c 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * SCSI CCS disk driver
+ */
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+
+#include <lib/libsa/stand.h>
+
+#include "samachdep.h"
+
+#define _IOCTL_
+#include <hp300/dev/scsireg.h>
+
+struct disklabel sdlabel;
+
+struct sdminilabel {
+ u_short npart;
+ u_long offset[MAXPARTITIONS];
+};
+
+struct sd_softc {
+ int sc_ctlr;
+ int sc_unit;
+ int sc_part;
+ char sc_retry;
+ char sc_alive;
+ short sc_blkshift;
+ struct sdminilabel sc_pinfo;
+} sd_softc[NSCSI][NSD];
+
+#define SDRETRY 2
+
+sdinit(ctlr, unit)
+ int ctlr, unit;
+{
+ register struct sd_softc *ss = &sd_softc[ctlr][unit];
+ u_char stat;
+ int capbuf[2];
+
+ stat = scsi_test_unit_rdy(ctlr, unit);
+ if (stat) {
+ /* drive may be doing RTZ - wait a bit */
+ if (stat == STS_CHECKCOND) {
+ DELAY(1000000);
+ stat = scsi_test_unit_rdy(ctlr, unit);
+ }
+ if (stat) {
+ printf("sd(%d,%d,0,0): init failed (stat=%x)\n",
+ ctlr, unit, stat);
+ return (0);
+ }
+ }
+ /*
+ * try to get the drive block size.
+ */
+ capbuf[0] = 0;
+ capbuf[1] = 0;
+ stat = scsi_read_capacity(ctlr, unit,
+ (u_char *)capbuf, sizeof(capbuf));
+ if (stat == 0) {
+ if (capbuf[1] > DEV_BSIZE)
+ for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1)
+ ++ss->sc_blkshift;
+ }
+ ss->sc_alive = 1;
+ return (1);
+}
+
+sdreset(ctlr, unit)
+ int ctlr, unit;
+{
+}
+
+char io_buf[MAXBSIZE];
+
+sdgetinfo(ss)
+ register struct sd_softc *ss;
+{
+ register struct sdminilabel *pi = &ss->sc_pinfo;
+ register struct disklabel *lp = &sdlabel;
+ char *msg, *getdisklabel();
+ int sdstrategy(), err, savepart;
+ size_t i;
+
+ bzero((caddr_t)lp, sizeof *lp);
+ lp->d_secsize = (DEV_BSIZE << ss->sc_blkshift);
+
+ /* Disklabel is always from RAW_PART. */
+ savepart = ss->sc_part;
+ ss->sc_part = RAW_PART;
+ err = sdstrategy(ss, F_READ, LABELSECTOR,
+ lp->d_secsize ? lp->d_secsize : DEV_BSIZE, io_buf, &i);
+ ss->sc_part = savepart;
+
+ if (err) {
+ printf("sdgetinfo: sdstrategy error %d\n", err);
+ return(0);
+ }
+
+ msg = getdisklabel(io_buf, lp);
+ if (msg) {
+ printf("sd(%d,%d,%d): WARNING: %s, ",
+ ss->sc_ctlr, ss->sc_unit, ss->sc_part, msg);
+ printf("defining `c' partition as entire disk\n");
+ pi->npart = 3;
+ pi->offset[0] = pi->offset[1] = -1;
+ pi->offset[2] = 0;
+ } else {
+ pi->npart = lp->d_npartitions;
+ for (i = 0; i < pi->npart; i++)
+ pi->offset[i] = lp->d_partitions[i].p_size == 0 ?
+ -1 : lp->d_partitions[i].p_offset;
+ }
+ return(1);
+}
+
+sdopen(f, ctlr, unit, part)
+ struct open_file *f;
+ int ctlr, unit, part;
+{
+ register struct sd_softc *ss;
+
+#ifdef SD_DEBUG
+ if (debug)
+ printf("sdopen: ctlr=%d unit=%d part=%d\n",
+ ctlr, unit, part);
+#endif
+
+ if (ctlr >= NSCSI || scsialive(ctlr) == 0)
+ return (EADAPT);
+ if (unit >= NSD)
+ return (ECTLR);
+ ss = &sd_softc[ctlr][unit];
+ ss->sc_part = part;
+ ss->sc_unit = unit;
+ ss->sc_ctlr = ctlr;
+ if (ss->sc_alive == 0) {
+ if (sdinit(ctlr, unit) == 0)
+ return (ENXIO);
+ if (sdgetinfo(ss) == 0)
+ return (ERDLAB);
+ }
+ if (part != RAW_PART && /* always allow RAW_PART to be opened */
+ (part >= ss->sc_pinfo.npart || ss->sc_pinfo.offset[part] == -1))
+ return (EPART);
+ f->f_devdata = (void *)ss;
+ return (0);
+}
+
+sdclose(f)
+ struct open_file *f;
+{
+ struct sd_softc *ss = f->f_devdata;
+
+ /*
+ * Mark the disk `not alive' so that the disklabel
+ * will be re-loaded at next open.
+ */
+ bzero(ss, sizeof(sd_softc));
+ f->f_devdata = NULL;
+
+ return (0);
+}
+
+sdstrategy(ss, func, dblk, size, v_buf, rsize)
+ register struct sd_softc *ss;
+ int func;
+ daddr_t dblk;
+ size_t size;
+ void *v_buf;
+ size_t *rsize;
+{
+ char *buf = v_buf;
+ register int ctlr = ss->sc_ctlr;
+ register int unit = ss->sc_unit;
+ u_int nblk = size >> ss->sc_blkshift;
+ daddr_t blk;
+ char stat;
+
+ if (size == 0)
+ return(0);
+
+ /*
+ * Don't do partition translation on the `raw partition'.
+ */
+ blk = (dblk + ((ss->sc_part == RAW_PART) ? 0 :
+ ss->sc_pinfo.offset[ss->sc_part])) >> ss->sc_blkshift;
+
+ ss->sc_retry = 0;
+
+#ifdef SD_DEBUG
+ if (debug)
+ printf("sdstrategy(%d,%d): size=%d blk=%d nblk=%d\n",
+ ctlr, unit, size, blk, nblk);
+#endif
+
+retry:
+ if (func == F_READ)
+ stat = scsi_tt_read(ctlr, unit, buf, size, blk, nblk);
+ else
+ stat = scsi_tt_write(ctlr, unit, buf, size, blk, nblk);
+ if (stat) {
+ printf("sd(%d,%d,%d): block=%x, error=0x%x\n",
+ ctlr, unit, ss->sc_part, blk, stat);
+ if (++ss->sc_retry > SDRETRY)
+ return(EIO);
+ goto retry;
+ }
+ *rsize = size;
+
+ return(0);
+}