BSD 4_4_Lite2 release
[unix-history] / usr / src / sys / hp300 / dev / sd.c
index 56eebca..95475a9 100644 (file)
@@ -5,9 +5,35 @@
  * 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        8.2 (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
  */
 
 /*
  */
 
 /*
@@ -38,10 +64,7 @@ static char rcsid[] = "$Header: /sys.lite/hp300/dev/RCS/sd.c,v 1.2 1994/01/10 18
 #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();
@@ -246,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)
@@ -282,28 +310,39 @@ sdgetcapacity(sc, hd, dev)
                10,
                CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0
        };
                10,
                CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0
        };
-       u_char capbuf[8];
-       struct buf tbuf;
-       int i;
+       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,
 
        if (dev == NODEV) {
                i = scsi_immed_command(hd->hp_ctlr, hd->hp_slave, sc->sc_punit,
-                                      &cap, capbuf, sizeof(capbuf), B_READ);
+                                      &cap, capbuf, capbufsize, B_READ);
        } else {
        } else {
+               struct buf *bp;
+
                /*
                 * XXX this is horrible
                 */
                /*
                 * XXX this is horrible
                 */
-               if (sc->sc_format_pid)
+               if (sc->sc_format_pid >= 0)
                        panic("sdgetcapacity");
                        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);
                sc->sc_format_pid = curproc->p_pid;
                bcopy((caddr_t)&cap, (caddr_t)&sdcmd[hd->hp_unit], sizeof cap);
-               tbuf.b_dev = dev;
-               tbuf.b_flags = B_READ | B_BUSY;
-               tbuf.b_un.b_addr = (caddr_t)capbuf;
-               tbuf.b_bcount = sizeof capbuf;
-               sdstrategy(&tbuf);
-               i = biowait(&tbuf) ? sdsense[hd->hp_unit].status : 0;
-               sc->sc_format_pid = 0;
+               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) {
        }
        if (i) {
                if (i != STS_CHECKCOND || (sc->sc_flags & SDF_RMEDIA) == 0) {
@@ -312,6 +351,7 @@ sdgetcapacity(sc, hd, dev)
                                printf("sd%d: read_capacity returns %d\n",
                                       hd->hp_unit, i);
 #endif
                                printf("sd%d: read_capacity returns %d\n",
                                       hd->hp_unit, i);
 #endif
+                       free(capbuf, M_DEVBUF);
                        return (-1);
                }
                /*
                        return (-1);
                }
                /*
@@ -325,10 +365,12 @@ sdgetcapacity(sc, hd, dev)
                        printf("sd%d: removable media not present\n",
                               hd->hp_unit);
 #endif
                        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];
                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_bshift = 0;
 
        /* return value of read capacity is last valid block number */
@@ -336,8 +378,8 @@ sdgetcapacity(sc, hd, dev)
 
        if (sc->sc_blksize != DEV_BSIZE) {
                if (sc->sc_blksize < DEV_BSIZE) {
 
        if (sc->sc_blksize != DEV_BSIZE) {
                if (sc->sc_blksize < DEV_BSIZE) {
-                       printf("sd%d: need %d byte blocks - drive ignored\n",
-                               hd->hp_unit, 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)
                        return (-1);
                }
                for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1)
@@ -441,6 +483,9 @@ sdgetinfo(dev)
 #endif
        printf("defining `c' partition as entire disk\n");
        pi[2].p_size = sc->sc_blks;
 #endif
        printf("defining `c' partition as entire disk\n");
        pi[2].p_size = sc->sc_blks;
+       /* XXX reset other info since readdisklabel screws with it */
+       lp->d_npartitions = 3;
+       pi[0].p_size = 0;
        return(0);
 }
 
        return(0);
 }
 
@@ -452,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
@@ -526,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);
 }
 
@@ -639,7 +681,7 @@ sdstrategy(bp)
        register daddr_t bn;
        register int sz, s;
 
        register daddr_t bn;
        register int sz, s;
 
-       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;
                if (sc->sc_format_pid != curproc->p_pid) {      /* XXX */
                        bp->b_error = EPERM;
                        goto bad;
@@ -804,7 +846,7 @@ 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;
 
@@ -840,7 +882,7 @@ sdgo(unit)
        register int pad;
        register struct scsi_fmt_cdb *cmd;
 
        register int pad;
        register struct scsi_fmt_cdb *cmd;
 
-       if (sc->sc_format_pid) {
+       if (sc->sc_format_pid >= 0) {
                cmd = &sdcmd[unit];
                pad = 0;
        } else {
                cmd = &sdcmd[unit];
                pad = 0;
        } else {
@@ -939,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);
                
@@ -955,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);
                
@@ -965,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;
@@ -1026,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:
@@ -1105,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)
@@ -1115,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;