summaryrefslogtreecommitdiff
path: root/sys/dev/isa/fd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/isa/fd.c')
-rw-r--r--sys/dev/isa/fd.c114
1 files changed, 80 insertions, 34 deletions
diff --git a/sys/dev/isa/fd.c b/sys/dev/isa/fd.c
index 3834abd5e89..cab382f4a3b 100644
--- a/sys/dev/isa/fd.c
+++ b/sys/dev/isa/fd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fd.c,v 1.68 2007/10/01 15:34:48 krw Exp $ */
+/* $OpenBSD: fd.c,v 1.69 2008/03/20 00:59:37 krw Exp $ */
/* $NetBSD: fd.c,v 1.90 1996/05/12 23:12:03 mycroft Exp $ */
/*-
@@ -58,6 +58,7 @@
#include <sys/proc.h>
#include <sys/syslog.h>
#include <sys/queue.h>
+#include <sys/stat.h>
#include <sys/timeout.h>
#include <machine/cpu.h>
@@ -138,7 +139,7 @@ struct cfdriver fd_cd = {
NULL, "fd", DV_DISK
};
-void fdgetdisklabel(struct fd_softc *);
+void fdgetdisklabel(dev_t, struct fd_softc *, struct disklabel *, int);
int fd_get_parms(struct fd_softc *);
void fdstrategy(struct buf *);
void fdstart(struct fd_softc *);
@@ -155,6 +156,42 @@ static __inline struct fd_type *fd_dev_to_type(struct fd_softc *, dev_t);
void fdretry(struct fd_softc *);
void fdtimeout(void *);
+void
+fdgetdisklabel(dev_t dev, struct fd_softc *fd, struct disklabel *lp,
+ int spoofonly)
+{
+ char *errstring;
+
+ bzero(lp, sizeof(struct disklabel));
+
+ lp->d_type = DTYPE_FLOPPY;
+ lp->d_secsize = FD_BSIZE(fd);
+ lp->d_secpercyl = fd->sc_type->seccyl;
+ lp->d_nsectors = fd->sc_type->sectrac;
+ lp->d_ncylinders = fd->sc_type->tracks;
+ lp->d_ntracks = fd->sc_type->heads; /* Go figure... */
+ DL_SETDSIZE(lp, fd->sc_type->size);
+ lp->d_rpm = 300; /* XXX like it matters... */
+
+ strncpy(lp->d_typename, "floppy disk", sizeof(lp->d_typename));
+ strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
+ lp->d_interleave = 1;
+ lp->d_version = 1;
+
+ lp->d_magic = DISKMAGIC;
+ lp->d_magic2 = DISKMAGIC;
+ lp->d_checksum = dkcksum(lp);
+
+ /*
+ * Call the generic disklabel extraction routine. If there's
+ * not a label there, fake it.
+ */
+ errstring = readdisklabel(DISKLABELDEV(dev), fdstrategy, lp, spoofonly);
+ if (errstring) {
+ /*printf("%s: %s\n", fd->sc_dv.dv_xname, errstring);*/
+ }
+}
+
int
fdprobe(parent, match, aux)
struct device *parent;
@@ -535,13 +572,13 @@ fd_motor_on(arg)
}
int
-fdopen(dev, flags, mode, p)
+fdopen(dev, flags, fmt, p)
dev_t dev;
int flags;
- int mode;
+ int fmt;
struct proc *p;
{
- int unit;
+ int unit, pmask;
struct fd_softc *fd;
struct fd_type *type;
@@ -563,21 +600,55 @@ fdopen(dev, flags, mode, p)
fd->sc_cylin = -1;
fd->sc_flags |= FD_OPEN;
+ /*
+ * Only update the disklabel if we're not open anywhere else.
+ */
+ if (fd->sc_dk.dk_openmask == 0)
+ fdgetdisklabel(dev, fd, fd->sc_dk.dk_label, 0);
+
+ pmask = (1 << FDPART(dev));
+
+ switch (fmt) {
+ case S_IFCHR:
+ fd->sc_dk.dk_copenmask |= pmask;
+ break;
+
+ case S_IFBLK:
+ fd->sc_dk.dk_bopenmask |= pmask;
+ break;
+ }
+ fd->sc_dk.dk_openmask =
+ fd->sc_dk.dk_copenmask | fd->sc_dk.dk_bopenmask;
+
return 0;
}
int
-fdclose(dev, flags, mode, p)
+fdclose(dev, flags, fmt, p)
dev_t dev;
int flags;
- int mode;
+ int fmt;
struct proc *p;
{
struct fd_softc *fd = fd_cd.cd_devs[FDUNIT(dev)];
+ int pmask = (1 << FDPART(dev));
fd->sc_flags &= ~FD_OPEN;
fd->sc_opts &= ~FDOPT_NORETRY;
- return 0;
+
+ switch (fmt) {
+ case S_IFCHR:
+ fd->sc_dk.dk_copenmask &= ~pmask;
+ break;
+
+ case S_IFBLK:
+ fd->sc_dk.dk_bopenmask &= ~pmask;
+ break;
+ }
+ fd->sc_dk.dk_openmask =
+ fd->sc_dk.dk_copenmask | fd->sc_dk.dk_bopenmask;
+
+ return (0);
}
daddr64_t
@@ -960,7 +1031,6 @@ fdioctl(dev, cmd, addr, flag, p)
{
struct fd_softc *fd = fd_cd.cd_devs[FDUNIT(dev)];
struct disklabel dl, *lp = &dl;
- char *errstring;
int error;
switch (cmd) {
@@ -969,31 +1039,7 @@ fdioctl(dev, cmd, addr, flag, p)
return EIO;
return (0);
case DIOCGDINFO:
- bzero(lp, sizeof(*lp));
-
- lp->d_secsize = FD_BSIZE(fd);
- lp->d_secpercyl = fd->sc_type->seccyl;
- lp->d_ntracks = fd->sc_type->heads;
- lp->d_nsectors = fd->sc_type->sectrac;
- lp->d_ncylinders = fd->sc_type->tracks;
-
- strncpy(lp->d_typename, "floppy disk", sizeof lp->d_typename);
- lp->d_type = DTYPE_FLOPPY;
- strncpy(lp->d_packname, "fictitious", sizeof lp->d_packname);
- DL_SETDSIZE(lp, fd->sc_type->size);
- lp->d_rpm = 300;
- lp->d_interleave = 1;
- lp->d_version = 1;
-
- lp->d_magic = DISKMAGIC;
- lp->d_magic2 = DISKMAGIC;
- lp->d_checksum = dkcksum(lp);
-
- errstring = readdisklabel(DISKLABELDEV(dev), fdstrategy, lp, 0);
- if (errstring) {
- /*printf("%s: %s\n", fd->sc_dev.dv_xname, errstring);*/
- }
-
+ fdgetdisklabel(dev, fd, lp, 0);
*(struct disklabel *)addr = *lp;
return 0;