Changes to ramdisk driver to support disklabels. Work done by Theo.
authorrahnds <rahnds@openbsd.org>
Thu, 6 Feb 1997 04:30:35 +0000 (04:30 +0000)
committerrahnds <rahnds@openbsd.org>
Thu, 6 Feb 1997 04:30:35 +0000 (04:30 +0000)
This will require changes for each machine type.
changes to MAKEDEV, suggest treating rd like sd
---
sd*|vnd*|ccd*|rd*)
...
rd*)  name=rd;  blk=17; chr=17;;
---
Make certain that majors and minors are correct
conf.c
add a entry in cdevsw for rd (previously was only in bdev)
---
cdev_decl(rd);
...
struct cdevsw cdevsw[] = {
...
cdev_disk_init(NRD,rd),         /* 17 ram disk driver*/
---

other changes to how rdconfig is called may be appropriate,
it must now be configured using the "raw" parition typically 'c'.

sys/dev/ramdisk.c

index a3e3310..9ed1110 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ramdisk.c,v 1.5 1996/04/21 22:19:53 deraadt Exp $     */
+/*     $OpenBSD: ramdisk.c,v 1.6 1997/02/06 04:30:35 rahnds Exp $      */
 /*     $NetBSD: ramdisk.c,v 1.8 1996/04/12 08:30:09 leo Exp $  */
 
 /*
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/device.h>
+#include <sys/file.h>
 #include <sys/disk.h>
 #include <sys/proc.h>
 #include <sys/conf.h>
+#include <sys/disklabel.h>
+#include <sys/dkio.h>
 
 #include <vm/vm.h>
 #include <vm/vm_kern.h>
@@ -80,8 +83,12 @@ extern vm_offset_t    kmem_alloc __P((vm_map_t, vm_size_t));
  * XXX Assumption: 16 RAM-disks are enough!
  */
 #define RD_MAX_UNITS   0x10
-#define RD_IS_CTRL(unit) (unit & 0x10)
-#define RD_UNIT(unit)    (unit &  0xF)
+#define RD_UNIT(unit)    (unit / MAXPARTITIONS)
+#define RD_PART(unit)    (unit % MAXPARTITIONS)
+#define RD_IS_CTRL(unit) (RD_PART(unit) == RAW_PART)
+#define        MAKERDDEV(maj, unit, part)      MAKEDISKDEV(maj, unit, part)
+
+#define        RDLABELDEV(dev) (MAKERDDEV(major(dev), RD_UNIT(dev), RAW_PART))
 
 /* autoconfig stuff... */
 
@@ -102,6 +109,7 @@ struct rd_softc {
 
 void rdattach __P((int));
 static void rd_attach __P((struct device *, struct device *, void *));
+struct disklabel *rdgetdisklabel __P((dev_t dev, struct rd_softc *sc));
 
 /*
  * Some ports (like i386) use a swapgeneric that wants to
@@ -393,25 +401,68 @@ rdioctl(dev, cmd, data, flag, proc)
        int md, unit;
        struct rd_softc *sc;
        struct rd_conf *urd;
+       struct cpu_disklabel clp;
+       struct disklabel lp, *lpp;
+       int error;
 
        md = minor(dev);
        unit = RD_UNIT(md);
        sc = ramdisk_devs[unit];
 
-       /* If this is not the control device, punt! */
-       if (RD_IS_CTRL(md) == 0)
-               return ENOTTY;
-
        urd = (struct rd_conf *)data;
        switch (cmd) {
+       case DIOCGDINFO:
+               if (sc->sc_type == RD_UNCONFIGURED) {
+                       break;
+               }
+               lpp = rdgetdisklabel(dev, sc);
+               if (lpp)
+                       *(struct disklabel *)data = *lpp;
+               return 0;
+
+       case DIOCWDINFO:
+       case DIOCSDINFO:
+               if (sc->sc_type == RD_UNCONFIGURED) {
+                       break;
+               }
+               if ((flag & FWRITE) == 0)
+                       return EBADF;
+
+               error = setdisklabel(&lp, (struct disklabel *)data,
+                   /*sd->sc_dk.dk_openmask : */0, &clp);
+               if (error == 0) {
+                       if (cmd == DIOCWDINFO)
+                               error = writedisklabel(RDLABELDEV(dev),
+                                   rdstrategy, &lp, &clp);
+               }
+
+               return error;
+
+       case DIOCWLABEL:
+               if (sc->sc_type == RD_UNCONFIGURED) {
+                       break;
+               }
+               if ((flag & FWRITE) == 0)
+                       return EBADF;
+               return 0;
+
        case RD_GETCONF:
+               /* If this is not the control device, punt! */
+               if (RD_IS_CTRL(md) == 0) {
+                       break;
+               }
                *urd = sc->sc_rd;
                return 0;
 
        case RD_SETCONF:
+               /* If this is not the control device, punt! */
+               if (RD_IS_CTRL(md) == 0) {
+                       break;
+               }
                /* Can only set it once. */
-               if (sc->sc_type != RD_UNCONFIGURED)
+               if (sc->sc_type != RD_UNCONFIGURED) {
                        break;
+               }
                switch (urd->rd_type) {
                case RD_KMEM_ALLOCATED:
                        return rd_ioctl_kalloc(sc, urd, proc);
@@ -427,6 +478,57 @@ rdioctl(dev, cmd, data, flag, proc)
        return EINVAL;
 }
 
+struct disklabel *
+rdgetdisklabel(dev, sc)
+       dev_t dev;
+       struct rd_softc *sc;
+{
+       static struct disklabel lp;
+       struct cpu_disklabel clp;
+       char *errstring;
+
+       bzero(&lp, sizeof(struct disklabel));
+       bzero(&clp, sizeof(struct cpu_disklabel));
+
+       lp.d_secsize = 1 << DEV_BSHIFT;
+       lp.d_ntracks = 1;
+       lp.d_nsectors = sc->sc_size >> DEV_BSHIFT;
+       lp.d_ncylinders = 1;
+       lp.d_secpercyl = lp.d_nsectors;
+       if (lp.d_secpercyl == 0) {
+               lp.d_secpercyl = 100;
+               /* as long as it's not 0 - readdisklabel divides by it (?) */
+       }
+
+       strncpy(lp.d_typename, "RAM disk", 16);
+       lp.d_type = DTYPE_SCSI;
+       strncpy(lp.d_packname, "fictitious", 16);
+       lp.d_secperunit = lp.d_nsectors;
+       lp.d_rpm = 3600;
+       lp.d_interleave = 1;
+       lp.d_flags = 0;
+
+       lp.d_partitions[RAW_PART].p_offset = 0;
+       lp.d_partitions[RAW_PART].p_size =
+           lp.d_secperunit * (lp.d_secsize / DEV_BSIZE);
+       lp.d_partitions[RAW_PART].p_fstype = FS_UNUSED;
+       lp.d_npartitions = RAW_PART + 1;
+
+       lp.d_magic = DISKMAGIC;
+       lp.d_magic2 = DISKMAGIC;
+       lp.d_checksum = dkcksum(&lp);
+
+       /*
+        * Call the generic disklabel extraction routine
+        */
+       errstring = readdisklabel(RDLABELDEV(dev), rdstrategy, &lp, &clp);
+       if (errstring) {
+               printf("%s: %s\n", sc->sc_dev.dv_xname, errstring);
+               return NULL;
+       }
+       return &lp;
+}
+
 /*
  * Handle ioctl RD_SETCONF for (sc_type == RD_KMEM_ALLOCATED)
  * Just allocate some kernel memory and return.