BSD 4_4_Lite2 release
[unix-history] / usr / src / sys / hp300 / dev / sd.c
index 98dca14..95475a9 100644 (file)
@@ -1,13 +1,39 @@
 /*
 /*
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
+ * 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.
  *
  *
  * This code is derived from software contributed to Berkeley by
  * Van Jacobson of Lawrence Berkeley Laboratory.
  *
- * %sccs.include.redist.c%
+ * 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.
  *
  *
- *     @(#)sd.c        7.17 (Berkeley) %G%
+ * 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.9 (Berkeley) 5/14/95
  */
 
 /*
  */
 
 /*
@@ -17,7 +43,7 @@
 #if NSD > 0
 
 #ifndef lint
 #if NSD > 0
 
 #ifndef lint
-static char rcsid[] = "$Header: /usr/src/sys/hp300/dev/RCS/sd.c,v 1.4 92/12/26 13:26:40 mike Exp $";
+static char rcsid[] = "$Header: /sys.lite/hp300/dev/RCS/sd.c,v 1.2 1994/01/10 18:29:19 mike Exp mike $";
 #endif
 
 #include <sys/param.h>
 #endif
 
 #include <sys/param.h>
@@ -38,10 +64,7 @@ static char rcsid[] = "$Header: /usr/src/sys/hp300/dev/RCS/sd.c,v 1.4 92/12/26 1
 #include <hp300/hp300/led.h>
 #endif
 
 #include <hp300/hp300/led.h>
 #endif
 
-#include <vm/vm_param.h>
-#include <vm/lock.h>
-#include <vm/vm_prot.h>
-#include <vm/pmap.h>
+#include <vm/vm.h>
 
 extern int scsi_test_unit_rdy();
 extern int scsi_request_sense();
 
 extern int scsi_test_unit_rdy();
 extern int scsi_request_sense();
@@ -71,6 +94,7 @@ struct        driver sddriver = {
 int sddebug = 1;
 #define SDB_ERROR      0x01
 #define SDB_PARTIAL    0x02
 int sddebug = 1;
 #define SDB_ERROR      0x01
 #define SDB_PARTIAL    0x02
+#define SDB_CAPACITY   0x04
 #endif
 
 struct sd_softc sd_softc[NSD];
 #endif
 
 struct sd_softc sd_softc[NSD];
@@ -113,12 +137,6 @@ static struct scsi_fmt_cdb inq = {
        CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0
 };
 
        CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0
 };
 
-static u_char capbuf[8];
-struct scsi_fmt_cdb cap = {
-       10,
-       CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
 static int
 sdident(sc, hd)
        struct sd_softc *sc;
 static int
 sdident(sc, hd)
        struct sd_softc *sc;
@@ -129,7 +147,7 @@ sdident(sc, hd)
        register int i;
        register int tries = 10;
        char idstr[32];
        register int i;
        register int tries = 10;
        char idstr[32];
-       int ismo = 0;
+       int isrm = 0;
 
        ctlr = hd->hp_ctlr;
        slave = hd->hp_slave;
 
        ctlr = hd->hp_ctlr;
        slave = hd->hp_slave;
@@ -141,7 +159,7 @@ sdident(sc, hd)
         */
        while ((i = scsi_test_unit_rdy(ctlr, slave, unit)) != 0) {
                if (i == -1 || --tries < 0) {
         */
        while ((i = scsi_test_unit_rdy(ctlr, slave, unit)) != 0) {
                if (i == -1 || --tries < 0) {
-                       if (ismo)
+                       if (isrm)
                                break;
                        /* doesn't exist or not a CCS device */
                        goto failed;
                                break;
                        /* doesn't exist or not a CCS device */
                        goto failed;
@@ -154,11 +172,14 @@ sdident(sc, hd)
                                           sizeof(sensebuf));
                        if (sp->class == 7)
                                switch (sp->key) {
                                           sizeof(sensebuf));
                        if (sp->class == 7)
                                switch (sp->key) {
-                               /* not ready -- might be MO with no media */
+                               /*
+                                * Not ready -- might be removable media
+                                * device with no media.  Assume as much,
+                                * if it really isn't, the inquiry commmand
+                                * below will fail.
+                                */
                                case 2:
                                case 2:
-                                       if (sp->len == 12 &&
-                                           sensebuf[12] == 10) /* XXX */
-                                               ismo = 1;
+                                       isrm = 1;
                                        break;
                                /* drive doing an RTZ -- give it a while */
                                case 6:
                                        break;
                                /* drive doing an RTZ -- give it a while */
                                case 6:
@@ -209,22 +230,11 @@ sdident(sc, hd)
                bcopy("UNKNOWN", &idstr[0], 8);
                bcopy("DRIVE TYPE", &idstr[8], 11);
        }
                bcopy("UNKNOWN", &idstr[0], 8);
                bcopy("DRIVE TYPE", &idstr[8], 11);
        }
-       i = scsi_immed_command(ctlr, slave, unit, &cap,
-                              (u_char *)&capbuf, sizeof(capbuf), B_READ);
-       if (i) {
-               if (i != STS_CHECKCOND ||
-                   bcmp(&idstr[0], "HP", 3) ||
-                   bcmp(&idstr[8], "S6300.650A", 11))
-                       goto failed;
-               /* XXX unformatted or non-existant MO media; fake it */
-               sc->sc_blks = 318664;
-               sc->sc_blksize = 1024;
-       } else {
-               sc->sc_blks = *(u_int *)&capbuf[0];
-               sc->sc_blksize = *(int *)&capbuf[4];
-       }
-       /* return value of read capacity is last valid block number */
-       sc->sc_blks++;
+       if (inqbuf.qual & 0x80)
+               sc->sc_flags |= SDF_RMEDIA;
+
+       if (sdgetcapacity(sc, hd, NODEV) < 0)
+               goto failed;
 
        switch (inqbuf.version) {
        case 1:
 
        switch (inqbuf.version) {
        case 1:
@@ -239,19 +249,10 @@ sdident(sc, hd)
                       inqbuf.type, inqbuf.qual, inqbuf.version);
                break;
        }
                       inqbuf.type, inqbuf.qual, inqbuf.version);
                break;
        }
-       printf(", %d %d byte blocks\n", sc->sc_blks, sc->sc_blksize);
-       if (inqbuf.qual & 0x80)
-               sc->sc_flags |= SDF_RMEDIA;
-       if (sc->sc_blksize != DEV_BSIZE) {
-               if (sc->sc_blksize < DEV_BSIZE) {
-                       printf("sd%d: need %d byte blocks - drive ignored\n",
-                               unit, DEV_BSIZE);
-                       goto failed;
-               }
-               for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1)
-                       ++sc->sc_bshift;
-               sc->sc_blks <<= sc->sc_bshift;
-       }
+       if (sc->sc_blks)
+               printf(", %d %d byte blocks",
+                      sc->sc_blks >> sc->sc_bshift, sc->sc_blksize);
+       printf("\n");
        sc->sc_wpms = 32 * (60 * DEV_BSIZE / 2);        /* XXX */
        scsi_delay(0);
        return(inqbuf.type);
        sc->sc_wpms = 32 * (60 * DEV_BSIZE / 2);        /* XXX */
        scsi_delay(0);
        return(inqbuf.type);
@@ -268,6 +269,11 @@ sdinit(hd)
 
        sc->sc_hd = hd;
        sc->sc_flags = 0;
 
        sc->sc_hd = hd;
        sc->sc_flags = 0;
+       /*
+        * XXX formerly 0 meant unused but now pid 0 can legitimately
+        * use this interface (sdgetcapacity).
+        */
+       sc->sc_format_pid = -1;
        sc->sc_punit = sdpunit(hd->hp_flags);
        sc->sc_type = sdident(sc, hd);
        if (sc->sc_type < 0)
        sc->sc_punit = sdpunit(hd->hp_flags);
        sc->sc_type = sdident(sc, hd);
        if (sc->sc_type < 0)
@@ -289,6 +295,105 @@ sdreset(sc, hd)
        sdstats[hd->hp_unit].sdresets++;
 }
 
        sdstats[hd->hp_unit].sdresets++;
 }
 
+/*
+ * Determine capacity of a drive.
+ * Returns -1 on a failure, 0 on success, 1 on a failure that is probably
+ * due to missing media.
+ */
+int
+sdgetcapacity(sc, hd, dev)
+       struct sd_softc *sc;
+       struct hp_device *hd;
+       dev_t dev;
+{
+       static struct scsi_fmt_cdb cap = {
+               10,
+               CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0
+       };
+       u_char *capbuf;
+       int i, capbufsize;
+
+       /*
+        * Cannot use stack space for this buffer since stack KVA may not
+        * be valid (i.e. in context of this process) when the operation
+        * actually starts.
+        */
+       capbufsize = 8;
+       capbuf = malloc(capbufsize, M_DEVBUF, M_WAITOK);
+
+       if (dev == NODEV) {
+               i = scsi_immed_command(hd->hp_ctlr, hd->hp_slave, sc->sc_punit,
+                                      &cap, capbuf, capbufsize, B_READ);
+       } else {
+               struct buf *bp;
+
+               /*
+                * XXX this is horrible
+                */
+               if (sc->sc_format_pid >= 0)
+                       panic("sdgetcapacity");
+               bp = malloc(sizeof *bp, M_DEVBUF, M_WAITOK);
+               sc->sc_format_pid = curproc->p_pid;
+               bcopy((caddr_t)&cap, (caddr_t)&sdcmd[hd->hp_unit], sizeof cap);
+               bp->b_dev = dev;
+               bp->b_flags = B_READ | B_BUSY;
+               bp->b_un.b_addr = (caddr_t)capbuf;
+               bp->b_bcount = capbufsize;
+               sdstrategy(bp);
+               i = biowait(bp) ? sdsense[hd->hp_unit].status : 0;
+               free(bp, M_DEVBUF);
+               sc->sc_format_pid = -1;
+       }
+       if (i) {
+               if (i != STS_CHECKCOND || (sc->sc_flags & SDF_RMEDIA) == 0) {
+#ifdef DEBUG
+                       if (sddebug & SDB_CAPACITY)
+                               printf("sd%d: read_capacity returns %d\n",
+                                      hd->hp_unit, i);
+#endif
+                       free(capbuf, M_DEVBUF);
+                       return (-1);
+               }
+               /*
+                * XXX assume unformatted or non-existant media
+                */
+               sc->sc_blks = 0;
+               sc->sc_blksize = DEV_BSIZE;
+               sc->sc_bshift = 0;
+#ifdef DEBUG
+               if (sddebug & SDB_CAPACITY)
+                       printf("sd%d: removable media not present\n",
+                              hd->hp_unit);
+#endif
+               free(capbuf, M_DEVBUF);
+               return (1);
+       }
+       sc->sc_blks = *(u_int *)&capbuf[0];
+       sc->sc_blksize = *(int *)&capbuf[4];
+       free(capbuf, M_DEVBUF);
+       sc->sc_bshift = 0;
+
+       /* return value of read capacity is last valid block number */
+       sc->sc_blks++;
+
+       if (sc->sc_blksize != DEV_BSIZE) {
+               if (sc->sc_blksize < DEV_BSIZE) {
+                       printf("sd%d: need at least %d byte blocks - %s\n",
+                               hd->hp_unit, DEV_BSIZE, "drive ignored");
+                       return (-1);
+               }
+               for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1)
+                       ++sc->sc_bshift;
+               sc->sc_blks <<= sc->sc_bshift;
+       }
+#ifdef DEBUG
+       if (sddebug & SDB_CAPACITY)
+               printf("sd%d: blks=%d, blksize=%d, bshift=%d\n", hd->hp_unit,
+                      sc->sc_blks, sc->sc_blksize, sc->sc_bshift);
+#endif
+       return (0);
+}
+
 /*
  * Read or constuct a disklabel
  */
 /*
  * Read or constuct a disklabel
  */
@@ -301,41 +406,86 @@ sdgetinfo(dev)
        register struct disklabel *lp = &sc->sc_info.si_label;
        register struct partition *pi;
        char *msg, *readdisklabel();
        register struct disklabel *lp = &sc->sc_info.si_label;
        register struct partition *pi;
        char *msg, *readdisklabel();
+#ifdef COMPAT_NOLABEL
+       int usedefault = 1;
 
        /*
 
        /*
-        * Set some default values to use while reading the label
-        * or to use if there isn't a label.
+        * For CD-ROM just define a single partition
         */
         */
+       if (sc->sc_type == 5)
+               usedefault = 0;
+#endif
+
        bzero((caddr_t)lp, sizeof *lp);
        bzero((caddr_t)lp, sizeof *lp);
-       lp->d_type = DTYPE_SCSI;
-       lp->d_secsize = DEV_BSIZE;
-       lp->d_nsectors = 32;
-       lp->d_ntracks = 20;
-       lp->d_secpercyl = 32*20;
-       lp->d_npartitions = 3;
-       lp->d_partitions[2].p_offset = 0;
-       /* XXX ensure size is at least one device block */
-       lp->d_partitions[2].p_size =
-               roundup(LABELSECTOR+1, btodb(sc->sc_blksize));
+       msg = NULL;
 
        /*
 
        /*
-        * Now try to read the disklabel
+        * If removable media or the size unavailable at boot time
+        * (i.e. unformatted hard disk), attempt to set the capacity
+        * now.
         */
         */
-       msg = readdisklabel(sdlabdev(dev), sdstrategy, lp);
-       if (msg == NULL)
-               return(0);
-       if (bcmp(msg, "I/O", 3) == 0) /* XXX */
-               return(EIO);
+       if ((sc->sc_flags & SDF_RMEDIA) || sc->sc_blks == 0) {
+               switch (sdgetcapacity(sc, sc->sc_hd, dev)) {
+               case 0:
+                       break;
+               case -1:
+                       /*
+                        * Hard error, just return (open will fail).
+                        */
+                       return (EIO);
+               case 1:
+                       /*
+                        * XXX return 0 so open can continue just in case
+                        * the media is unformatted and we want to format it.
+                        * We set the error flag so they cannot do much else.
+                        */
+                       sc->sc_flags |= SDF_ERROR;
+                       msg = "unformatted/missing media";
+#ifdef COMPAT_NOLABEL
+                       usedefault = 0;
+#endif
+                       break;
+               }
+       }
+
+       /*
+        * Set some default values to use while reading the label
+        * (or to use if there isn't a label) and try reading it.
+        */
+       if (msg == NULL) {
+               lp->d_type = DTYPE_SCSI;
+               lp->d_secsize = DEV_BSIZE;
+               lp->d_nsectors = 32;
+               lp->d_ntracks = 20;
+               lp->d_ncylinders = 1;
+               lp->d_secpercyl = 32*20;
+               lp->d_npartitions = 3;
+               lp->d_partitions[2].p_offset = 0;
+               /* XXX we can open a device even without SDF_ALIVE */
+               if (sc->sc_blksize == 0)
+                       sc->sc_blksize = DEV_BSIZE;
+               /* XXX ensure size is at least one device block */
+               lp->d_partitions[2].p_size =
+                       roundup(LABELSECTOR+1, btodb(sc->sc_blksize));
+               msg = readdisklabel(sdlabdev(dev), sdstrategy, lp);
+               if (msg == NULL)
+                       return (0);
+       }
 
        pi = lp->d_partitions;
        printf("sd%d: WARNING: %s, ", unit, msg);
 #ifdef COMPAT_NOLABEL
 
        pi = lp->d_partitions;
        printf("sd%d: WARNING: %s, ", unit, msg);
 #ifdef COMPAT_NOLABEL
-       printf("using old default partitioning\n");
-       sdmakedisklabel(unit, lp);
-#else
+       if (usedefault) {
+               printf("using old default partitioning\n");
+               sdmakedisklabel(unit, lp);
+               return(0);
+       }
+#endif
        printf("defining `c' partition as entire disk\n");
        pi[2].p_size = sc->sc_blks;
        printf("defining `c' partition as entire disk\n");
        pi[2].p_size = sc->sc_blks;
-#endif
+       /* XXX reset other info since readdisklabel screws with it */
+       lp->d_npartitions = 3;
+       pi[0].p_size = 0;
        return(0);
 }
 
        return(0);
 }
 
@@ -347,20 +497,17 @@ sdopen(dev, flags, mode, p)
 {
        register int unit = sdunit(dev);
        register struct sd_softc *sc = &sd_softc[unit];
 {
        register int unit = sdunit(dev);
        register struct sd_softc *sc = &sd_softc[unit];
-       int mask, error;
+       int error, mask;
 
 
-       if (unit >= NSD)
-               return(ENXIO);
-       if ((sc->sc_flags & SDF_ALIVE) == 0 && suser(p->p_ucred, &p->p_acflag))
+       if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0)
                return(ENXIO);
                return(ENXIO);
-       if (sc->sc_flags & SDF_ERROR)
-               return(EIO);
 
        /*
         * Wait for any pending opens/closes to complete
         */
        while (sc->sc_flags & (SDF_OPENING|SDF_CLOSING))
                sleep((caddr_t)sc, PRIBIO);
 
        /*
         * Wait for any pending opens/closes to complete
         */
        while (sc->sc_flags & (SDF_OPENING|SDF_CLOSING))
                sleep((caddr_t)sc, PRIBIO);
+
        /*
         * On first open, get label and partition info.
         * We may block reading the label, so be careful
        /*
         * On first open, get label and partition info.
         * We may block reading the label, so be careful
@@ -421,7 +568,7 @@ sdclose(dev, flag, mode, p)
                sc->sc_flags &= ~(SDF_CLOSING|SDF_WLABEL|SDF_ERROR);
                wakeup((caddr_t)sc);
        }
                sc->sc_flags &= ~(SDF_CLOSING|SDF_WLABEL|SDF_ERROR);
                wakeup((caddr_t)sc);
        }
-       sc->sc_format_pid = 0;
+       sc->sc_format_pid = -1;
        return(0);
 }
 
        return(0);
 }
 
@@ -534,17 +681,17 @@ sdstrategy(bp)
        register daddr_t bn;
        register int sz, s;
 
        register daddr_t bn;
        register int sz, s;
 
-       if (sc->sc_flags & SDF_ERROR) {
-               bp->b_error = EIO;
-               goto bad;
-       }
-       if (sc->sc_format_pid) {
+       if (sc->sc_format_pid >= 0) {
                if (sc->sc_format_pid != curproc->p_pid) {      /* XXX */
                        bp->b_error = EPERM;
                        goto bad;
                }
                bp->b_cylin = 0;
        } else {
                if (sc->sc_format_pid != curproc->p_pid) {      /* XXX */
                        bp->b_error = EPERM;
                        goto bad;
                }
                bp->b_cylin = 0;
        } else {
+               if (sc->sc_flags & SDF_ERROR) {
+                       bp->b_error = EIO;
+                       goto bad;
+               }
                bn = bp->b_blkno;
                sz = howmany(bp->b_bcount, DEV_BSIZE);
                pinfo = &sc->sc_info.si_label.d_partitions[sdpart(bp->b_dev)];
                bn = bp->b_blkno;
                sz = howmany(bp->b_bcount, DEV_BSIZE);
                pinfo = &sc->sc_info.si_label.d_partitions[sdpart(bp->b_dev)];
@@ -699,19 +846,25 @@ sdstart(unit)
         * we have the SCSI bus -- in format mode, we may or may not need dma
         * so check now.
         */
         * we have the SCSI bus -- in format mode, we may or may not need dma
         * so check now.
         */
-       if (sc->sc_format_pid && legal_cmds[sdcmd[unit].cdb[0]] > 0) {
+       if (sc->sc_format_pid >= 0 && legal_cmds[sdcmd[unit].cdb[0]] > 0) {
                register struct buf *bp = sdtab[unit].b_actf;
                register int sts;
 
                register struct buf *bp = sdtab[unit].b_actf;
                register int sts;
 
-               sts = scsi_immed_command(hp->hp_ctlr, hp->hp_slave,
-                                        sc->sc_punit, &sdcmd[unit],
-                                        bp->b_un.b_addr, bp->b_bcount,
-                                        bp->b_flags & B_READ);
-               sdsense[unit].status = sts;
-               if (sts & 0xfe) {
-                       (void) sderror(unit, sc, hp, sts);
-                       bp->b_flags |= B_ERROR;
-                       bp->b_error = EIO;
+               sdtab[unit].b_errcnt = 0;
+               while (1) {
+                       sts = scsi_immed_command(hp->hp_ctlr, hp->hp_slave,
+                                                sc->sc_punit, &sdcmd[unit],
+                                                bp->b_un.b_addr, bp->b_bcount,
+                                                bp->b_flags & B_READ);
+                       sdsense[unit].status = sts;
+                       if ((sts & 0xfe) == 0 ||
+                           (sts = sderror(unit, sc, hp, sts)) == 0)
+                               break;
+                       if (sts > 0 || sdtab[unit].b_errcnt++ >= SDRETRY) {
+                               bp->b_flags |= B_ERROR;
+                               bp->b_error = EIO;
+                               break;
+                       }
                }
                sdfinish(unit, sc, bp);
 
                }
                sdfinish(unit, sc, bp);
 
@@ -729,19 +882,19 @@ sdgo(unit)
        register int pad;
        register struct scsi_fmt_cdb *cmd;
 
        register int pad;
        register struct scsi_fmt_cdb *cmd;
 
-       /*
-        * Drive is in an error state, abort all operations
-        */
-       if (sc->sc_flags & SDF_ERROR) {
-               bp->b_flags |= B_ERROR;
-               bp->b_error = EIO;
-               sdfinish(unit, sc, bp);
-               return;
-       }
-       if (sc->sc_format_pid) {
+       if (sc->sc_format_pid >= 0) {
                cmd = &sdcmd[unit];
                pad = 0;
        } else {
                cmd = &sdcmd[unit];
                pad = 0;
        } else {
+               /*
+                * Drive is in an error state, abort all operations
+                */
+               if (sc->sc_flags & SDF_ERROR) {
+                       bp->b_flags |= B_ERROR;
+                       bp->b_error = EIO;
+                       sdfinish(unit, sc, bp);
+                       return;
+               }
                cmd = bp->b_flags & B_READ? &sd_read_cmd : &sd_write_cmd;
                *(int *)(&cmd->cdb[2]) = bp->b_cylin;
                pad = howmany(bp->b_bcount, sc->sc_blksize);
                cmd = bp->b_flags & B_READ? &sd_read_cmd : &sd_write_cmd;
                *(int *)(&cmd->cdb[2]) = bp->b_cylin;
                pad = howmany(bp->b_bcount, sc->sc_blksize);
@@ -828,7 +981,7 @@ sdread(dev, uio, flags)
        register int unit = sdunit(dev);
        register int pid;
 
        register int unit = sdunit(dev);
        register int pid;
 
-       if ((pid = sd_softc[unit].sc_format_pid) &&
+       if ((pid = sd_softc[unit].sc_format_pid) >= 0 &&
            pid != uio->uio_procp->p_pid)
                return (EPERM);
                
            pid != uio->uio_procp->p_pid)
                return (EPERM);
                
@@ -844,7 +997,7 @@ sdwrite(dev, uio, flags)
        register int unit = sdunit(dev);
        register int pid;
 
        register int unit = sdunit(dev);
        register int pid;
 
-       if ((pid = sd_softc[unit].sc_format_pid) &&
+       if ((pid = sd_softc[unit].sc_format_pid) >= 0 &&
            pid != uio->uio_procp->p_pid)
                return (EPERM);
                
            pid != uio->uio_procp->p_pid)
                return (EPERM);
                
@@ -854,7 +1007,7 @@ sdwrite(dev, uio, flags)
 int
 sdioctl(dev, cmd, data, flag, p)
        dev_t dev;
 int
 sdioctl(dev, cmd, data, flag, p)
        dev_t dev;
-       int cmd;
+       u_long cmd;
        caddr_t data;
        int flag;
        struct proc *p;
        caddr_t data;
        int flag;
        struct proc *p;
@@ -915,11 +1068,11 @@ sdioctl(dev, cmd, data, flag, p)
                        return(EPERM);
 
                if (*(int *)data) {
                        return(EPERM);
 
                if (*(int *)data) {
-                       if (sc->sc_format_pid)
+                       if (sc->sc_format_pid >= 0)
                                return (EPERM);
                        sc->sc_format_pid = p->p_pid;
                } else
                                return (EPERM);
                        sc->sc_format_pid = p->p_pid;
                } else
-                       sc->sc_format_pid = 0;
+                       sc->sc_format_pid = -1;
                return (0);
 
        case SDIOCGFORMAT:
                return (0);
 
        case SDIOCGFORMAT:
@@ -994,7 +1147,7 @@ sddump(dev)
        register int maddr;
        register int pages, i;
        int stat;
        register int maddr;
        register int pages, i;
        int stat;
-       extern int lowram;
+       extern int lowram, dumpsize;
 
        /* is drive ok? */
        if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0)
 
        /* is drive ok? */
        if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0)
@@ -1004,7 +1157,7 @@ sddump(dev)
        if (dumplo < 0 || dumplo >= pinfo->p_size ||
            pinfo->p_fstype != FS_SWAP)
                return (EINVAL);
        if (dumplo < 0 || dumplo >= pinfo->p_size ||
            pinfo->p_fstype != FS_SWAP)
                return (EINVAL);
-       pages = physmem;
+       pages = dumpsize;
        if (dumplo + ctod(pages) > pinfo->p_size)
                pages = dtoc(pinfo->p_size - dumplo);
        maddr = lowram;
        if (dumplo + ctod(pages) > pinfo->p_size)
                pages = dtoc(pinfo->p_size - dumplo);
        maddr = lowram;