diff options
author | njl <njl@FreeBSD.org> | 2004-07-12 20:49:26 +0000 |
---|---|---|
committer | njl <njl@FreeBSD.org> | 2004-07-12 20:49:26 +0000 |
commit | 7b5fb1c0fe7951487bba2244d8e9f2bee0f7c77c (patch) | |
tree | a20b1854c8515a1c3ce89b0e657b0ae22b62080a | |
parent | 91e23d98c534a497b70a4087007fa9d56902f65c (diff) | |
download | FreeBSD-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.
-rw-r--r-- | sys/dev/fdc/fdc.c | 116 | ||||
-rw-r--r-- | sys/dev/fdc/fdc_isa.c | 19 | ||||
-rw-r--r-- | sys/dev/fdc/fdc_pccard.c | 17 | ||||
-rw-r--r-- | sys/dev/fdc/fdcvar.h | 10 |
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); |