summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2004-07-12 20:49:26 +0000
committernjl <njl@FreeBSD.org>2004-07-12 20:49:26 +0000
commit7b5fb1c0fe7951487bba2244d8e9f2bee0f7c77c (patch)
treea20b1854c8515a1c3ce89b0e657b0ae22b62080a /sys/dev
parent91e23d98c534a497b70a4087007fa9d56902f65c (diff)
downloadFreeBSD-src-7b5fb1c0fe7951487bba2244d8e9f2bee0f7c77c.zip
FreeBSD-src-7b5fb1c0fe7951487bba2244d8e9f2bee0f7c77c.tar.gz
Update in preparation for adding the ACPI attachment.
* Add an fdtype ivar. This will be the equivalent of fd->type. * Move enabling the FIFO to the end of attach. * Unify reset code into fdc_initial_reset(). * Add fdc_write_ivar(). * Update isa and pccard attachments accordingly. * Set the flags unconditionally in probe since they may be overridden by other probe routines. Both before and now, we're depending on probe being called a final time on the winning driver so the flags we get are the ones we intended. * Use the bus accessor macros instead of defining our own. * Remove duplicate assigns of fd->type.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/fdc/fdc.c116
-rw-r--r--sys/dev/fdc/fdc_isa.c19
-rw-r--r--sys/dev/fdc/fdc_pccard.c17
-rw-r--r--sys/dev/fdc/fdcvar.h10
4 files changed, 94 insertions, 68 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index e4527a8..9415f5d 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
@@ -81,25 +81,6 @@ __FBSDID("$FreeBSD$");
#define FDBIO_FORMAT BIO_CMD2
-/*
- * fdc maintains a set (1!) of ivars per child of each controller.
- */
-enum fdc_device_ivars {
- FDC_IVAR_FDUNIT,
-};
-
-/*
- * Simple access macros for the ivars.
- */
-#define FDC_ACCESSOR(A, B, T) \
-static __inline T fdc_get_ ## A(device_t dev) \
-{ \
- uintptr_t v; \
- BUS_READ_IVAR(device_get_parent(dev), dev, FDC_IVAR_ ## B, &v); \
- return (T) v; \
-}
-FDC_ACCESSOR(fdunit, FDUNIT, int)
-
/* configuration flags for fdc */
#define FDC_NO_FIFO (1 << 2) /* do not enable FIFO */
@@ -213,7 +194,9 @@ struct fd_data {
struct fdc_ivars {
int fdunit;
+ int fdtype;
};
+
static devclass_t fd_devclass;
/* configuration flags for fd */
@@ -709,10 +692,46 @@ fdc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
case FDC_IVAR_FDUNIT:
*result = ivars->fdunit;
break;
+ case FDC_IVAR_FDTYPE:
+ *result = ivars->fdtype;
+ break;
default:
- return ENOENT;
+ return (ENOENT);
}
- return 0;
+ return (0);
+}
+
+int
+fdc_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+ struct fdc_ivars *ivars = device_get_ivars(child);
+
+ switch (which) {
+ case FDC_IVAR_FDUNIT:
+ ivars->fdunit = value;
+ break;
+ case FDC_IVAR_FDTYPE:
+ ivars->fdtype = value;
+ break;
+ default:
+ return (ENOENT);
+ }
+ return (0);
+}
+
+int
+fdc_initial_reset(struct fdc_data *fdc)
+{
+ /* First, reset the floppy controller. */
+ fdout_wr(fdc, 0);
+ DELAY(100);
+ fdout_wr(fdc, FDO_FRST);
+
+ /* Then, see if it can handle a command. */
+ if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
+ NE7_SPEC_2(2, 0), 0))
+ return (ENXIO);
+ return (0);
}
int
@@ -748,23 +767,25 @@ fdc_detach(device_t dev)
static void
fdc_add_child(device_t dev, const char *name, int unit)
{
- int flags;
+ int fdu, flags;
struct fdc_ivars *ivar;
device_t child;
ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO);
if (ivar == NULL)
return;
- if (resource_int_value(name, unit, "drive", &ivar->fdunit) != 0)
- ivar->fdunit = 0;
child = device_add_child(dev, name, unit);
if (child == NULL) {
free(ivar, M_DEVBUF);
return;
}
device_set_ivars(child, ivar);
+ if (resource_int_value(name, unit, "drive", &fdu) != 0)
+ fdu = 0;
+ fdc_set_fdunit(child, fdu);
+ fdc_set_fdtype(child, FDT_NONE);
if (resource_int_value(name, unit, "flags", &flags) == 0)
- device_set_flags(child, flags);
+ device_set_flags(child, flags);
if (resource_disabled(name, unit))
device_disable(child);
}
@@ -839,21 +860,30 @@ fd_probe(device_t dev)
struct fd_data *fd;
struct fdc_data *fdc;
fdsu_t fdsu;
- int flags;
+ int flags, type;
- fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */
+ fdsu = fdc_get_fdunit(dev);
fd = device_get_softc(dev);
fdc = device_get_softc(device_get_parent(dev));
flags = device_get_flags(dev);
- bzero(fd, sizeof *fd);
fd->dev = dev;
fd->fdc = fdc;
fd->fdsu = fdsu;
fd->fdu = device_get_unit(dev);
- fd->flags = FD_UA; /* make sure fdautoselect() will be called */
- fd->type = FD_DTYPE(flags);
+ type = FD_DTYPE(flags);
+
+ /* Auto-probe if fdinfo is present, but always allow override. */
+ if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) {
+ fd->type = type;
+ goto done;
+ } else {
+ /* make sure fdautoselect() will be called */
+ fd->flags = FD_UA;
+ fd->type = type;
+ }
+
/*
* XXX I think using __i386__ is wrong here since we actually want to probe
* for the machine type, not the CPU type (so non-PC arch's like the PC98 will
@@ -890,15 +920,6 @@ fd_probe(device_t dev)
fdc_reset(fdc); /* XXX reset, then unreset, etc. */
DELAY(1000000); /* 1 sec */
- /* XXX This doesn't work before the first set_motor() */
- if ((fdc->flags & FDC_HAS_FIFO) == 0 &&
- fdc->fdct == FDC_ENHANCED &&
- (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 &&
- enable_fifo(fdc) == 0) {
- device_printf(device_get_parent(dev),
- "FIFO enabled, %d bytes threshold\n", fifo_threshold);
- }
-
if ((flags & FD_NO_PROBE) == 0) {
/* If we're at track 0 first seek inwards. */
if ((fd_sense_drive_status(fdc, &st3) == 0) &&
@@ -938,26 +959,31 @@ fd_probe(device_t dev)
(st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */
return (ENXIO);
+done:
+ /* This doesn't work before the first reset. Or set_motor?? */
+ if ((fdc->flags & FDC_HAS_FIFO) == 0 &&
+ fdc->fdct == FDC_ENHANCED &&
+ (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 &&
+ enable_fifo(fdc) == 0) {
+ device_printf(device_get_parent(dev),
+ "FIFO enabled, %d bytes threshold\n", fifo_threshold);
+ }
+
switch (fd->type) {
case FDT_12M:
device_set_desc(dev, "1200-KB 5.25\" drive");
- fd->type = FDT_12M;
break;
case FDT_144M:
device_set_desc(dev, "1440-KB 3.5\" drive");
- fd->type = FDT_144M;
break;
case FDT_288M:
device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)");
- fd->type = FDT_288M;
break;
case FDT_360K:
device_set_desc(dev, "360-KB 5.25\" drive");
- fd->type = FDT_360K;
break;
case FDT_720K:
device_set_desc(dev, "720-KB 3.5\" drive");
- fd->type = FDT_720K;
break;
default:
return (ENXIO);
diff --git a/sys/dev/fdc/fdc_isa.c b/sys/dev/fdc/fdc_isa.c
index e519bee..748fb95 100644
--- a/sys/dev/fdc/fdc_isa.c
+++ b/sys/dev/fdc/fdc_isa.c
@@ -74,25 +74,21 @@ fdc_isa_probe(device_t dev)
if (error == ENXIO)
return ENXIO;
if (error == 0)
- fdc->flags |= FDC_ISPNP;
+ fdc->flags = FDC_ISPNP;
/* Attempt to allocate our resources for the duration of the probe */
error = fdc_alloc_resources(fdc);
if (error)
goto out;
- /* First - lets reset the floppy controller */
- fdout_wr(fdc, 0);
- DELAY(100);
- fdout_wr(fdc, FDO_FRST);
-
- /* see if it can handle a command */
- if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
- NE7_SPEC_2(2, 0), 0)) {
- error = ENXIO;
- goto out;
+ /* Check that the controller is working. */
+ if ((fdc->flags & FDC_ISPNP) == 0) {
+ error = fdc_initial_reset(fdc);
+ if (error)
+ goto out;
}
+ /* Try to determine a more specific device type. */
if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) {
ic_type = (u_char)ic_type;
switch (ic_type) {
@@ -130,6 +126,7 @@ static device_method_t fdc_methods[] = {
/* Bus interface */
DEVMETHOD(bus_print_child, fdc_print_child),
DEVMETHOD(bus_read_ivar, fdc_read_ivar),
+ DEVMETHOD(bus_write_ivar, fdc_write_ivar),
/* Our children never use any other bus interface methods. */
{ 0, 0 }
diff --git a/sys/dev/fdc/fdc_pccard.c b/sys/dev/fdc/fdc_pccard.c
index d625a23..0732806 100644
--- a/sys/dev/fdc/fdc_pccard.c
+++ b/sys/dev/fdc/fdc_pccard.c
@@ -62,25 +62,17 @@ fdc_pccard_probe(device_t dev)
bzero(fdc, sizeof *fdc);
fdc->fdc_dev = dev;
fdc->fdctl_wr = fdctl_wr_pcmcia;
-
- fdc->flags |= FDC_ISPCMCIA | FDC_NODMA;
+ fdc->flags = FDC_ISPCMCIA | FDC_NODMA;
/* Attempt to allocate our resources for the duration of the probe */
error = fdc_alloc_resources(fdc);
if (error)
goto out;
- /* First - lets reset the floppy controller */
- fdout_wr(fdc, 0);
- DELAY(100);
- fdout_wr(fdc, FDO_FRST);
-
- /* see if it can handle a command */
- if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
- NE7_SPEC_2(2, 0), 0)) {
- error = ENXIO;
+ /* Check that the controller is working. */
+ error = fdc_initial_reset(fdc);
+ if (error)
goto out;
- }
device_set_desc(dev, "Y-E Data PCMCIA floppy");
fdc->fdct = FDC_NE765;
@@ -102,6 +94,7 @@ static device_method_t fdc_pccard_methods[] = {
/* Bus interface */
DEVMETHOD(bus_print_child, fdc_print_child),
DEVMETHOD(bus_read_ivar, fdc_read_ivar),
+ DEVMETHOD(bus_write_ivar, fdc_write_ivar),
/* Our children never use any other bus interface methods. */
{ 0, 0 }
diff --git a/sys/dev/fdc/fdcvar.h b/sys/dev/fdc/fdcvar.h
index 4271b7a..30dd825 100644
--- a/sys/dev/fdc/fdcvar.h
+++ b/sys/dev/fdc/fdcvar.h
@@ -124,11 +124,21 @@ typedef enum fdc_type fdc_t;
extern devclass_t fdc_devclass;
+enum fdc_device_ivars {
+ FDC_IVAR_FDUNIT,
+ FDC_IVAR_FDTYPE,
+};
+
+__BUS_ACCESSOR(fdc, fdunit, FDC, FDUNIT, int);
+__BUS_ACCESSOR(fdc, fdtype, FDC, FDTYPE, int);
+
int fdc_alloc_resources(struct fdc_data *);
void fdout_wr(fdc_p, u_int8_t);
int fd_cmd(struct fdc_data *, int, ...);
void fdc_release_resources(struct fdc_data *);
int fdc_attach(device_t);
int fdc_detach(device_t dev);
+int fdc_initial_reset(struct fdc_data *);
int fdc_print_child(device_t, device_t);
int fdc_read_ivar(device_t, device_t, int, uintptr_t *);
+int fdc_write_ivar(device_t, device_t, int, uintptr_t);
OpenPOWER on IntegriCloud