diff options
author | imp <imp@FreeBSD.org> | 2004-07-07 22:35:27 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2004-07-07 22:35:27 +0000 |
commit | 78dfca395175fd86f8c8faaf75b1e5b0337884c0 (patch) | |
tree | 2f085542ee70d0dfcf96a610d0590fce001f2a6f | |
parent | f84c290dac19b5128b113c287907f5dd7b520538 (diff) | |
download | FreeBSD-src-78dfca395175fd86f8c8faaf75b1e5b0337884c0.zip FreeBSD-src-78dfca395175fd86f8c8faaf75b1e5b0337884c0.tar.gz |
Break out the isa and pccard front ends from fdc. This is the first
step in making this driver more attachment neutral. Others plan on
adding acpi front ends.
Still need to cleanup the MI part of the driver because it isn't as
bus independent as it could be.
-rw-r--r-- | sys/dev/fdc/fdc.c | 316 | ||||
-rw-r--r-- | sys/dev/fdc/fdc_isa.c | 145 | ||||
-rw-r--r-- | sys/dev/fdc/fdc_pccard.c | 114 | ||||
-rw-r--r-- | sys/dev/fdc/fdcvar.h | 134 | ||||
-rw-r--r-- | sys/modules/fdc/Makefile | 16 |
5 files changed, 407 insertions, 318 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index 70e9835..e4527a8 100644 --- a/sys/dev/fdc/fdc.c +++ b/sys/dev/fdc/fdc.c @@ -52,13 +52,10 @@ __FBSDID("$FreeBSD$"); #include "opt_fdc.h" -#include "card.h" #include <sys/param.h> -#include <sys/systm.h> #include <sys/bio.h> #include <sys/bus.h> -#include <sys/conf.h> #include <sys/devicestat.h> #include <sys/disk.h> #include <sys/fcntl.h> @@ -70,109 +67,20 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/mutex.h> #include <sys/proc.h> -#include <sys/syslog.h> - -#include <machine/bus.h> #include <sys/rman.h> +#include <sys/systm.h> #include <machine/clock.h> -#include <machine/resource.h> #include <machine/stdarg.h> #include <isa/isavar.h> #include <isa/isareg.h> #include <dev/fdc/fdcreg.h> +#include <dev/fdc/fdcvar.h> #include <isa/rtc.h> -enum fdc_type -{ - FDC_NE765, FDC_ENHANCED, FDC_UNKNOWN = -1 -}; - -enum fdc_states { - DEVIDLE, - FINDWORK, - DOSEEK, - SEEKCOMPLETE , - IOCOMPLETE, - RECALCOMPLETE, - STARTRECAL, - RESETCTLR, - SEEKWAIT, - RECALWAIT, - MOTORWAIT, - IOTIMEDOUT, - RESETCOMPLETE, - PIOREAD -}; - -#ifdef FDC_DEBUG -static char const * const fdstates[] = { - "DEVIDLE", - "FINDWORK", - "DOSEEK", - "SEEKCOMPLETE", - "IOCOMPLETE", - "RECALCOMPLETE", - "STARTRECAL", - "RESETCTLR", - "SEEKWAIT", - "RECALWAIT", - "MOTORWAIT", - "IOTIMEDOUT", - "RESETCOMPLETE", - "PIOREAD" -}; -#endif - -/* - * Per controller structure (softc). - */ -struct fdc_data -{ - int fdcu; /* our unit number */ - int dmachan; - int dmacnt; - int flags; -#define FDC_ATTACHED 0x01 -#define FDC_STAT_VALID 0x08 -#define FDC_HAS_FIFO 0x10 -#define FDC_NEEDS_RESET 0x20 -#define FDC_NODMA 0x40 -#define FDC_ISPNP 0x80 -#define FDC_ISPCMCIA 0x100 - struct fd_data *fd; - int fdu; /* the active drive */ - enum fdc_states state; - int retry; - int fdout; /* mirror of the w/o digital output reg */ - u_int status[7]; /* copy of the registers */ - enum fdc_type fdct; /* chip version of FDC */ - int fdc_errs; /* number of logged errors */ - int dma_overruns; /* number of DMA overruns */ - struct bio_queue_head head; - struct bio *bp; /* active buffer */ - struct resource *res_ioport, *res_ctl, *res_irq, *res_drq; - int rid_ioport, rid_ctl, rid_irq, rid_drq; - int port_off; - bus_space_tag_t portt; - bus_space_handle_t porth; - bus_space_tag_t ctlt; - bus_space_handle_t ctlh; - void *fdc_intr; - struct device *fdc_dev; - void (*fdctl_wr)(struct fdc_data *fdc, u_int8_t v); -}; - #define FDBIO_FORMAT BIO_CMD2 -typedef int fdu_t; -typedef int fdcu_t; -typedef int fdsu_t; -typedef struct fd_data *fd_p; -typedef struct fdc_data *fdc_p; -typedef enum fdc_type fdc_t; - /* * fdc maintains a set (1!) of ivars per child of each controller. */ @@ -195,10 +103,6 @@ FDC_ACCESSOR(fdunit, FDUNIT, int) /* configuration flags for fdc */ #define FDC_NO_FIFO (1 << 2) /* do not enable FIFO */ -/* error returns for fd_cmd() */ -#define FD_FAILED -1 -#define FD_NOT_VALID -2 -#define FDC_ERRMAX 100 /* do not log more */ /* * Stop retrying after this many DMA overruns. Since each retry takes * one revolution, with 300 rpm., 25 retries take approximately 5 @@ -276,7 +180,7 @@ static struct fd_type fd_searchlist_288m[] = { * up to cyl 82 */ #define MAX_HEAD 1 -static devclass_t fdc_devclass; +devclass_t fdc_devclass; /* * Per drive structure (softc). @@ -342,34 +246,18 @@ static devclass_t fd_devclass; * as below -- makes locating a particular function in the body much * easier. */ -static void fdout_wr(fdc_p, u_int8_t); static u_int8_t fdsts_rd(fdc_p); static void fddata_wr(fdc_p, u_int8_t); static u_int8_t fddata_rd(fdc_p); -static void fdctl_wr_isa(fdc_p, u_int8_t); -#if NCARD > 0 -static void fdctl_wr_pcmcia(fdc_p, u_int8_t); -#endif #if 0 static u_int8_t fdin_rd(fdc_p); #endif static int fdc_err(struct fdc_data *, const char *); -static int fd_cmd(struct fdc_data *, int, ...); static int enable_fifo(fdc_p fdc); static int fd_sense_drive_status(fdc_p, int *); static int fd_sense_int(fdc_p, int *, int *); static int fd_read_status(fdc_p); -static int fdc_alloc_resources(struct fdc_data *); -static void fdc_release_resources(struct fdc_data *); -static int fdc_read_ivar(device_t, device_t, int, uintptr_t *); -static int fdc_probe(device_t); -#if NCARD > 0 -static int fdc_pccard_probe(device_t); -#endif -static int fdc_detach(device_t dev); static void fdc_add_child(device_t, const char *, int); -static int fdc_attach(device_t); -static int fdc_print_child(device_t, device_t); static int fd_probe(device_t); static int fd_attach(device_t); static int fd_detach(device_t); @@ -416,7 +304,7 @@ static int volatile fd_debug = 0; /* * Bus space handling (access to low-level IO). */ -static void +void fdout_wr(fdc_p fdc, u_int8_t v) { bus_space_write_1(fdc->portt, fdc->porth, FDOUT+fdc->port_off, v); @@ -440,20 +328,6 @@ fddata_rd(fdc_p fdc) return bus_space_read_1(fdc->portt, fdc->porth, FDDATA+fdc->port_off); } -static void -fdctl_wr_isa(fdc_p fdc, u_int8_t v) -{ - bus_space_write_1(fdc->ctlt, fdc->ctlh, 0, v); -} - -#if NCARD > 0 -static void -fdctl_wr_pcmcia(fdc_p fdc, u_int8_t v) -{ - bus_space_write_1(fdc->portt, fdc->porth, FDCTL+fdc->port_off, v); -} -#endif - static u_int8_t fdin_rd(fdc_p fdc) { @@ -497,7 +371,7 @@ fdc_err(struct fdc_data *fdc, const char *s) * # of output bytes, output bytes as ints ..., * # of input bytes, input bytes as ints ... */ -static int +int fd_cmd(struct fdc_data *fdc, int n_out, ...) { u_char cmd; @@ -653,7 +527,7 @@ fd_read_status(fdc_p fdc) return ret; } -static int +int fdc_alloc_resources(struct fdc_data *fdc) { device_t dev; @@ -770,8 +644,7 @@ fdc_alloc_resources(struct fdc_data *fdc) fdc->ctlh = rman_get_bushandle(fdc->res_ctl); } - fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, - &fdc->rid_irq, + fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq, RF_ACTIVE | RF_SHAREABLE); if (fdc->res_irq == 0) { device_printf(dev, "cannot reserve interrupt line\n"); @@ -791,7 +664,7 @@ fdc_alloc_resources(struct fdc_data *fdc) return 0; } -static void +void fdc_release_resources(struct fdc_data *fdc) { device_t dev; @@ -827,13 +700,7 @@ fdc_release_resources(struct fdc_data *fdc) * Configuration/initialization stuff, per controller. */ -static struct isa_pnp_id fdc_ids[] = { - {0x0007d041, "PC standard floppy disk controller"}, /* PNP0700 */ - {0x0107d041, "Standard floppy controller supporting MS Device Bay Spec"}, /* PNP0701 */ - {0} -}; - -static int +int fdc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { struct fdc_ivars *ivars = device_get_ivars(child); @@ -848,109 +715,7 @@ fdc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) return 0; } -static int -fdc_probe(device_t dev) -{ - int error, ic_type; - struct fdc_data *fdc; - - fdc = device_get_softc(dev); - bzero(fdc, sizeof *fdc); - fdc->fdc_dev = dev; - fdc->fdctl_wr = fdctl_wr_isa; - - /* Check pnp ids */ - error = ISA_PNP_PROBE(device_get_parent(dev), dev, fdc_ids); - if (error == ENXIO) - return ENXIO; - if (error == 0) - 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; - } - - if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) { - ic_type = (u_char)ic_type; - switch (ic_type) { - case 0x80: - device_set_desc(dev, "NEC 765 or clone"); - fdc->fdct = FDC_NE765; - break; - case 0x81: /* not mentioned in any hardware doc */ - case 0x90: - device_set_desc(dev, - "Enhanced floppy controller (i82077, NE72065 or clone)"); - fdc->fdct = FDC_ENHANCED; - break; - default: - device_set_desc(dev, "Generic floppy controller"); - fdc->fdct = FDC_UNKNOWN; - break; - } - } - -out: - fdc_release_resources(fdc); - return (error); -} - -#if NCARD > 0 - -static int -fdc_pccard_probe(device_t dev) -{ - int error; - struct fdc_data *fdc; - - fdc = device_get_softc(dev); - bzero(fdc, sizeof *fdc); - fdc->fdc_dev = dev; - fdc->fdctl_wr = fdctl_wr_pcmcia; - - 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; - goto out; - } - - device_set_desc(dev, "Y-E Data PCMCIA floppy"); - fdc->fdct = FDC_NE765; - -out: - fdc_release_resources(fdc); - return (error); -} - -#endif /* NCARD > 0 */ - -static int +int fdc_detach(device_t dev) { struct fdc_data *fdc; @@ -974,7 +739,6 @@ fdc_detach(device_t dev) BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, fdc->fdc_intr); fdc_release_resources(fdc); - device_printf(dev, "unload\n"); return (0); } @@ -1005,7 +769,7 @@ fdc_add_child(device_t dev, const char *name, int unit) device_disable(child); } -static int +int fdc_attach(device_t dev) { struct fdc_data *fdc; @@ -1049,7 +813,7 @@ fdc_attach(device_t dev) return (0); } -static int +int fdc_print_child(device_t me, device_t child) { int retval = 0, flags; @@ -1064,62 +828,6 @@ fdc_print_child(device_t me, device_t child) return (retval); } -static device_method_t fdc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, fdc_probe), - DEVMETHOD(device_attach, fdc_attach), - DEVMETHOD(device_detach, fdc_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_print_child, fdc_print_child), - DEVMETHOD(bus_read_ivar, fdc_read_ivar), - /* Our children never use any other bus interface methods. */ - - { 0, 0 } -}; - -static driver_t fdc_driver = { - "fdc", - fdc_methods, - sizeof(struct fdc_data) -}; - -DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0); -DRIVER_MODULE(fdc, acpi, fdc_driver, fdc_devclass, 0, 0); - -#if NCARD > 0 - -static device_method_t fdc_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, fdc_pccard_probe), - DEVMETHOD(device_attach, fdc_attach), - DEVMETHOD(device_detach, fdc_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_print_child, fdc_print_child), - DEVMETHOD(bus_read_ivar, fdc_read_ivar), - /* Our children never use any other bus interface methods. */ - - { 0, 0 } -}; - -static driver_t fdc_pccard_driver = { - "fdc", - fdc_pccard_methods, - sizeof(struct fdc_data) -}; - -DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, 0, 0); - -#endif /* NCARD > 0 */ - - /* * Configuration/initialization, per drive. */ diff --git a/sys/dev/fdc/fdc_isa.c b/sys/dev/fdc/fdc_isa.c new file mode 100644 index 0000000..e519bee --- /dev/null +++ b/sys/dev/fdc/fdc_isa.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2004 M. Warner Losh. + * All rights reserved. + * + * 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, + * without modification, immediately at the beginning of the file. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/bio.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/rman.h> +#include <sys/systm.h> + +#include <dev/fdc/fdcvar.h> +#include <dev/fdc/fdcreg.h> + +#include <isa/isavar.h> +#include <isa/isareg.h> + +static int fdc_isa_probe(device_t); +static void fdctl_wr_isa(fdc_p, u_int8_t); + +static struct isa_pnp_id fdc_ids[] = { + {0x0007d041, "PC standard floppy disk controller"}, /* PNP0700 */ + {0x0107d041, "Standard floppy controller supporting MS Device Bay Spec"}, /* PNP0701 */ + {0} +}; + +static void +fdctl_wr_isa(fdc_p fdc, u_int8_t v) +{ + bus_space_write_1(fdc->ctlt, fdc->ctlh, 0, v); +} + +static int +fdc_isa_probe(device_t dev) +{ + int error, ic_type; + struct fdc_data *fdc; + + fdc = device_get_softc(dev); + bzero(fdc, sizeof *fdc); + fdc->fdc_dev = dev; + fdc->fdctl_wr = fdctl_wr_isa; + + /* Check pnp ids */ + error = ISA_PNP_PROBE(device_get_parent(dev), dev, fdc_ids); + if (error == ENXIO) + return ENXIO; + if (error == 0) + 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; + } + + if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) { + ic_type = (u_char)ic_type; + switch (ic_type) { + case 0x80: + device_set_desc(dev, "NEC 765 or clone"); + fdc->fdct = FDC_NE765; + break; + case 0x81: /* not mentioned in any hardware doc */ + case 0x90: + device_set_desc(dev, + "Enhanced floppy controller (i82077, NE72065 or clone)"); + fdc->fdct = FDC_ENHANCED; + break; + default: + device_set_desc(dev, "Generic floppy controller"); + fdc->fdct = FDC_UNKNOWN; + break; + } + } + +out: + fdc_release_resources(fdc); + return (error); +} + +static device_method_t fdc_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, fdc_isa_probe), + DEVMETHOD(device_attach, fdc_attach), + DEVMETHOD(device_detach, fdc_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_print_child, fdc_print_child), + DEVMETHOD(bus_read_ivar, fdc_read_ivar), + /* Our children never use any other bus interface methods. */ + + { 0, 0 } +}; + +static driver_t fdc_driver = { + "fdc", + fdc_methods, + sizeof(struct fdc_data) +}; + +DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0); +DRIVER_MODULE(fdc, acpi, fdc_driver, fdc_devclass, 0, 0); diff --git a/sys/dev/fdc/fdc_pccard.c b/sys/dev/fdc/fdc_pccard.c new file mode 100644 index 0000000..bf66f4b --- /dev/null +++ b/sys/dev/fdc/fdc_pccard.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2004 M. Warner Losh. + * All rights reserved. + * + * 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, + * without modification, immediately at the beginning of the file. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/bio.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/rman.h> +#include <sys/systm.h> + +#include <dev/fdc/fdcvar.h> +#include <dev/fdc/fdcreg.h> + +static void fdctl_wr_pcmcia(fdc_p, u_int8_t); +static int fdc_pccard_probe(device_t); + +static void +fdctl_wr_pcmcia(fdc_p fdc, u_int8_t v) +{ + bus_space_write_1(fdc->portt, fdc->porth, FDCTL+fdc->port_off, v); +} + +/* XXX this is really an attach routine */ +static int +fdc_pccard_probe(device_t dev) +{ + int error; + struct fdc_data *fdc; + + fdc = device_get_softc(dev); + bzero(fdc, sizeof *fdc); + fdc->fdc_dev = dev; + fdc->fdctl_wr = fdctl_wr_pcmcia; + + 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; + goto out; + } + + device_set_desc(dev, "Y-E Data PCMCIA floppy"); + fdc->fdct = FDC_NE765; + +out: + fdc_release_resources(fdc); + return (error); +} + +static device_method_t fdc_pccard_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, fdc_pccard_probe), + DEVMETHOD(device_attach, fdc_attach), + DEVMETHOD(device_detach, fdc_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_print_child, fdc_print_child), + DEVMETHOD(bus_read_ivar, fdc_read_ivar), + /* Our children never use any other bus interface methods. */ + + { 0, 0 } +}; + +static driver_t fdc_pccard_driver = { + "fdc", + fdc_pccard_methods, + sizeof(struct fdc_data) +}; + +DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, 0, 0); diff --git a/sys/dev/fdc/fdcvar.h b/sys/dev/fdc/fdcvar.h new file mode 100644 index 0000000..4271b7a --- /dev/null +++ b/sys/dev/fdc/fdcvar.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2004 M. Warner Losh. + * All rights reserved. + * + * 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, + * without modification, immediately at the beginning of the file. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +/* XXX should audit this file to see if additional copyrights needed */ + +enum fdc_type +{ + FDC_NE765, FDC_ENHANCED, FDC_UNKNOWN = -1 +}; + +enum fdc_states { + DEVIDLE, + FINDWORK, + DOSEEK, + SEEKCOMPLETE , + IOCOMPLETE, + RECALCOMPLETE, + STARTRECAL, + RESETCTLR, + SEEKWAIT, + RECALWAIT, + MOTORWAIT, + IOTIMEDOUT, + RESETCOMPLETE, + PIOREAD +}; + +#ifdef FDC_DEBUG +static char const * const fdstates[] = { + "DEVIDLE", + "FINDWORK", + "DOSEEK", + "SEEKCOMPLETE", + "IOCOMPLETE", + "RECALCOMPLETE", + "STARTRECAL", + "RESETCTLR", + "SEEKWAIT", + "RECALWAIT", + "MOTORWAIT", + "IOTIMEDOUT", + "RESETCOMPLETE", + "PIOREAD" +}; +#endif + +/* + * Per controller structure (softc). + */ +struct fdc_data +{ + int fdcu; /* our unit number */ + int dmacnt; + int dmachan; + int flags; +#define FDC_ATTACHED 0x01 +#define FDC_STAT_VALID 0x08 +#define FDC_HAS_FIFO 0x10 +#define FDC_NEEDS_RESET 0x20 +#define FDC_NODMA 0x40 +#define FDC_ISPNP 0x80 +#define FDC_ISPCMCIA 0x100 + struct fd_data *fd; + int fdu; /* the active drive */ + enum fdc_states state; + int retry; + int fdout; /* mirror of the w/o digital output reg */ + u_int status[7]; /* copy of the registers */ + enum fdc_type fdct; /* chip version of FDC */ + int fdc_errs; /* number of logged errors */ + int dma_overruns; /* number of DMA overruns */ + struct bio_queue_head head; + struct bio *bp; /* active buffer */ + struct resource *res_ioport, *res_ctl, *res_irq, *res_drq; + int rid_ioport, rid_ctl, rid_irq, rid_drq; + int port_off; + bus_space_tag_t portt; + bus_space_handle_t porth; + bus_space_tag_t ctlt; + bus_space_handle_t ctlh; + void *fdc_intr; + struct device *fdc_dev; + void (*fdctl_wr)(struct fdc_data *fdc, u_int8_t v); +}; + +typedef int fdu_t; +typedef int fdcu_t; +typedef int fdsu_t; +typedef struct fd_data *fd_p; +typedef struct fdc_data *fdc_p; +typedef enum fdc_type fdc_t; + +/* error returns for fd_cmd() */ +#define FD_FAILED -1 +#define FD_NOT_VALID -2 +#define FDC_ERRMAX 100 /* do not log more */ + +extern devclass_t fdc_devclass; + +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_print_child(device_t, device_t); +int fdc_read_ivar(device_t, device_t, int, uintptr_t *); diff --git a/sys/modules/fdc/Makefile b/sys/modules/fdc/Makefile index 2635148..959a93c 100644 --- a/sys/modules/fdc/Makefile +++ b/sys/modules/fdc/Makefile @@ -5,21 +5,15 @@ .else .PATH: ${.CURDIR}/../../dev/fdc .endif - KMOD= fdc .if ${MACHINE} == "pc98" SRCS= fd.c .else -SRCS= fdc.c +SRCS= fdc.c fdc_isa.c fdc_pccard.c .endif -SRCS+= opt_fdc.h card.h \ - bus_if.h card_if.h device_if.h isa_if.h pccarddevs.h +SRCS+= opt_fdc.h bus_if.h card_if.h device_if.h isa_if.h pccarddevs.h FDC_DEBUG?= 0 # 0/1 -FDC_PCCARD?= 1 # 0/1 whether pccard support (i. e. Y-E DATA PCMCIA -# # fdc) is desired - -CLEANFILES= card.h opt_fdc.h: touch ${.TARGET} @@ -27,10 +21,4 @@ opt_fdc.h: echo "#define FDC_DEBUG 1" >> ${.TARGET} .endif -card.h: - touch ${.TARGET} -.if ${FDC_PCCARD} > 0 - echo "#define NCARD 1" >> ${.TARGET} -.endif - .include <bsd.kmod.mk> |