diff options
| author | Doug Rabson <dfr@FreeBSD.org> | 1999-05-31 18:36:14 +0000 |
|---|---|---|
| committer | Doug Rabson <dfr@FreeBSD.org> | 1999-05-31 18:36:14 +0000 |
| commit | 3bfc7e59282b61d142c0a1c2170c0f892a3ad90f (patch) | |
| tree | f8c61c9826112c233276ec8073d3ce5c1cf6cfbb | |
| parent | c77dda34aebb95e74d334721ad753a89352c2bdb (diff) | |
Notes
| -rw-r--r-- | sys/amd64/amd64/machdep.c | 4 | ||||
| -rw-r--r-- | sys/amd64/amd64/tsc.c | 4 | ||||
| -rw-r--r-- | sys/amd64/isa/clock.c | 4 | ||||
| -rw-r--r-- | sys/i386/i386/machdep.c | 4 | ||||
| -rw-r--r-- | sys/i386/i386/tsc.c | 4 | ||||
| -rw-r--r-- | sys/i386/isa/clock.c | 4 | ||||
| -rw-r--r-- | sys/i386/isa/fd.c | 2398 | ||||
| -rw-r--r-- | sys/i386/isa/fdc.h | 95 | ||||
| -rw-r--r-- | sys/i386/isa/fdreg.h | 69 | ||||
| -rw-r--r-- | sys/i386/isa/ic/nec765.h | 142 | ||||
| -rw-r--r-- | sys/i386/isa/rtc.h | 117 | ||||
| -rw-r--r-- | sys/isa/atrtc.c | 4 |
12 files changed, 14 insertions, 2835 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 2dd2ad4230df2..006f3fdecbf6d 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.334 1999/05/06 00:54:44 luoqi Exp $ + * $Id: machdep.c,v 1.335 1999/05/12 21:38:42 luoqi Exp $ */ #include "apm.h" @@ -125,7 +125,7 @@ #endif #include <i386/isa/intr_machdep.h> #ifndef VM86 -#include <i386/isa/rtc.h> +#include <isa/rtc.h> #endif #include <machine/random.h> #include <sys/ptrace.h> diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c index 64ef3b21c17ac..6b787b80b80b7 100644 --- a/sys/amd64/amd64/tsc.c +++ b/sys/amd64/amd64/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.134 1999/05/28 14:08:59 bde Exp $ + * $Id: clock.c,v 1.135 1999/05/29 06:57:55 phk Exp $ */ /* @@ -84,7 +84,7 @@ #include <i386/isa/icu.h> #include <i386/isa/isa.h> -#include <i386/isa/rtc.h> +#include <isa/rtc.h> #include <i386/isa/timerreg.h> #include <i386/isa/intr_machdep.h> diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index 64ef3b21c17ac..6b787b80b80b7 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.134 1999/05/28 14:08:59 bde Exp $ + * $Id: clock.c,v 1.135 1999/05/29 06:57:55 phk Exp $ */ /* @@ -84,7 +84,7 @@ #include <i386/isa/icu.h> #include <i386/isa/isa.h> -#include <i386/isa/rtc.h> +#include <isa/rtc.h> #include <i386/isa/timerreg.h> #include <i386/isa/intr_machdep.h> diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 2dd2ad4230df2..006f3fdecbf6d 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.334 1999/05/06 00:54:44 luoqi Exp $ + * $Id: machdep.c,v 1.335 1999/05/12 21:38:42 luoqi Exp $ */ #include "apm.h" @@ -125,7 +125,7 @@ #endif #include <i386/isa/intr_machdep.h> #ifndef VM86 -#include <i386/isa/rtc.h> +#include <isa/rtc.h> #endif #include <machine/random.h> #include <sys/ptrace.h> diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c index 64ef3b21c17ac..6b787b80b80b7 100644 --- a/sys/i386/i386/tsc.c +++ b/sys/i386/i386/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.134 1999/05/28 14:08:59 bde Exp $ + * $Id: clock.c,v 1.135 1999/05/29 06:57:55 phk Exp $ */ /* @@ -84,7 +84,7 @@ #include <i386/isa/icu.h> #include <i386/isa/isa.h> -#include <i386/isa/rtc.h> +#include <isa/rtc.h> #include <i386/isa/timerreg.h> #include <i386/isa/intr_machdep.h> diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index 64ef3b21c17ac..6b787b80b80b7 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.134 1999/05/28 14:08:59 bde Exp $ + * $Id: clock.c,v 1.135 1999/05/29 06:57:55 phk Exp $ */ /* @@ -84,7 +84,7 @@ #include <i386/isa/icu.h> #include <i386/isa/isa.h> -#include <i386/isa/rtc.h> +#include <isa/rtc.h> #include <i386/isa/timerreg.h> #include <i386/isa/intr_machdep.h> diff --git a/sys/i386/isa/fd.c b/sys/i386/isa/fd.c deleted file mode 100644 index cd7001be81516..0000000000000 --- a/sys/i386/isa/fd.c +++ /dev/null @@ -1,2398 +0,0 @@ -/* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Don Ahn. - * - * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu) - * aided by the Linux floppy driver modifications from David Bateman - * (dbateman@eng.uts.edu.au). - * - * Copyright (c) 1993, 1994 by - * jc@irbs.UUCP (John Capo) - * vak@zebub.msk.su (Serge Vakulenko) - * ache@astral.msk.su (Andrew A. Chernov) - * - * Copyright (c) 1993, 1994, 1995 by - * joerg_wunsch@uriah.sax.de (Joerg Wunsch) - * dufault@hda.com (Peter Dufault) - * - * 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. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id: fd.c,v 1.144 1999/05/30 11:10:54 dfr Exp $ - * - */ - -#include "fd.h" -#include "opt_devfs.h" -#include "opt_fdc.h" - -#if NFDC > 0 - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/buf.h> -#include <sys/bus.h> -#include <sys/conf.h> -#include <sys/disklabel.h> -#include <sys/devicestat.h> -#include <sys/fcntl.h> -#include <sys/malloc.h> -#include <sys/module.h> -#include <sys/proc.h> -#include <sys/syslog.h> - -#include <sys/bus.h> -#include <machine/bus.h> -#include <sys/rman.h> - -#include <machine/clock.h> -#include <machine/ioctl_fd.h> -#include <machine/resource.h> -#include <machine/stdarg.h> - -#ifdef DEVFS -#include <sys/devfsext.h> -#endif /* DEVFS */ - -#include <isa/isavar.h> -#include <i386/isa/isa.h> -#include <i386/isa/fdreg.h> -#include <i386/isa/fdc.h> -#include <i386/isa/rtc.h> - -#ifdef FDC_YE -#undef FDC_YE -#warning "fix FDC_YE! - newbus casualty" -#endif - -/* misuse a flag to identify format operation */ -#define B_FORMAT B_XXX - -/* configuration flags */ -#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */ -#ifdef FDC_YE -#define FDC_IS_PCMCIA (1 << 1) /* if successful probe, then it's - a PCMCIA device */ -#endif - -/* internally used only, not really from CMOS: */ -#define RTCFDT_144M_PRETENDED 0x1000 - -/* error returns for fd_cmd() */ -#define FD_FAILED -1 -#define FD_NOT_VALID -2 -#define FDC_ERRMAX 100 /* do not log more */ - -#define NUMTYPES 14 -#define NUMDENS (NUMTYPES - 6) - -/* These defines (-1) must match index for fd_types */ -#define F_TAPE_TYPE 0x020 /* bit for fd_types to indicate tape */ -#define NO_TYPE 0 /* must match NO_TYPE in ft.c */ -#define FD_1720 1 -#define FD_1480 2 -#define FD_1440 3 -#define FD_1200 4 -#define FD_820 5 -#define FD_800 6 -#define FD_720 7 -#define FD_360 8 - -#define FD_1480in5_25 9 -#define FD_1440in5_25 10 -#define FD_820in5_25 11 -#define FD_800in5_25 12 -#define FD_720in5_25 13 -#define FD_360in5_25 14 - - -static struct fd_type fd_types[NUMTYPES] = -{ -{ 21,2,0xFF,0x04,82,3444,1,FDC_500KBPS,2,0x0C,2 }, /* 1.72M in HD 3.5in */ -{ 18,2,0xFF,0x1B,82,2952,1,FDC_500KBPS,2,0x6C,1 }, /* 1.48M in HD 3.5in */ -{ 18,2,0xFF,0x1B,80,2880,1,FDC_500KBPS,2,0x6C,1 }, /* 1.44M in HD 3.5in */ -{ 15,2,0xFF,0x1B,80,2400,1,FDC_500KBPS,2,0x54,1 }, /* 1.2M in HD 5.25/3.5 */ -{ 10,2,0xFF,0x10,82,1640,1,FDC_250KBPS,2,0x2E,1 }, /* 820K in HD 3.5in */ -{ 10,2,0xFF,0x10,80,1600,1,FDC_250KBPS,2,0x2E,1 }, /* 800K in HD 3.5in */ -{ 9,2,0xFF,0x20,80,1440,1,FDC_250KBPS,2,0x50,1 }, /* 720K in HD 3.5in */ -{ 9,2,0xFF,0x2A,40, 720,1,FDC_250KBPS,2,0x50,1 }, /* 360K in DD 5.25in */ - -{ 18,2,0xFF,0x02,82,2952,1,FDC_500KBPS,2,0x02,2 }, /* 1.48M in HD 5.25in */ -{ 18,2,0xFF,0x02,80,2880,1,FDC_500KBPS,2,0x02,2 }, /* 1.44M in HD 5.25in */ -{ 10,2,0xFF,0x10,82,1640,1,FDC_300KBPS,2,0x2E,1 }, /* 820K in HD 5.25in */ -{ 10,2,0xFF,0x10,80,1600,1,FDC_300KBPS,2,0x2E,1 }, /* 800K in HD 5.25in */ -{ 9,2,0xFF,0x20,80,1440,1,FDC_300KBPS,2,0x50,1 }, /* 720K in HD 5.25in */ -{ 9,2,0xFF,0x23,40, 720,2,FDC_300KBPS,2,0x50,1 }, /* 360K in HD 5.25in */ -}; - -#define DRVS_PER_CTLR 2 /* 2 floppies */ - -/***********************************************************************\ -* Per controller structure. * -\***********************************************************************/ -static devclass_t fdc_devclass; - -/***********************************************************************\ -* Per drive structure. * -* N per controller (DRVS_PER_CTLR) * -\***********************************************************************/ -struct fd_data { - struct fdc_data *fdc; /* pointer to controller structure */ - int fdsu; /* this units number on this controller */ - int type; /* Drive type (FD_1440...) */ - struct fd_type *ft; /* pointer to the type descriptor */ - int flags; -#define FD_OPEN 0x01 /* it's open */ -#define FD_ACTIVE 0x02 /* it's active */ -#define FD_MOTOR 0x04 /* motor should be on */ -#define FD_MOTOR_WAIT 0x08 /* motor coming up */ - int skip; - int hddrv; -#define FD_NO_TRACK -2 - int track; /* where we think the head is */ - int options; /* user configurable options, see ioctl_fd.h */ - struct callout_handle toffhandle; - struct callout_handle tohandle; - struct devstat device_stats; -#ifdef DEVFS - void *bdevs[1 + NUMDENS + MAXPARTITIONS]; - void *cdevs[1 + NUMDENS + MAXPARTITIONS]; -#endif - device_t dev; - fdu_t fdu; -}; -static devclass_t fd_devclass; - -/***********************************************************************\ -* Throughout this file the following conventions will be used: * -* fd is a pointer to the fd_data struct for the drive in question * -* fdc is a pointer to the fdc_data struct for the controller * -* fdu is the floppy drive unit number * -* fdcu is the floppy controller unit number * -* fdsu is the floppy drive unit number on that controller. (sub-unit) * -\***********************************************************************/ - -#ifdef FDC_YE -#include "card.h" -static int yeattach(struct isa_device *); -#endif - -/* needed for ft driver, thus exported */ -int in_fdc(struct fdc_data *); -int out_fdc(struct fdc_data *, int); - -/* internal functions */ -static void fdc_add_device(device_t, const char *, int); -static void fdc_intr(void *); -static void set_motor(struct fdc_data *, int, int); -# define TURNON 1 -# define TURNOFF 0 -static timeout_t fd_turnoff; -static timeout_t fd_motor_on; -static void fd_turnon(struct fd_data *); -static void fdc_reset(fdc_p); -static int fd_in(struct fdc_data *, int *); -static void fdstart(struct fdc_data *); -static timeout_t fd_iotimeout; -static timeout_t fd_pseudointr; -static int fdstate(struct fdc_data *); -static int retrier(struct fdc_data *); -static int fdformat(dev_t, struct fd_formb *, struct proc *); - -static int enable_fifo(fdc_p fdc); - -static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */ - - -#define DEVIDLE 0 -#define FINDWORK 1 -#define DOSEEK 2 -#define SEEKCOMPLETE 3 -#define IOCOMPLETE 4 -#define RECALCOMPLETE 5 -#define STARTRECAL 6 -#define RESETCTLR 7 -#define SEEKWAIT 8 -#define RECALWAIT 9 -#define MOTORWAIT 10 -#define IOTIMEDOUT 11 -#define RESETCOMPLETE 12 -#ifdef FDC_YE -#define PIOREAD 13 -#endif - -#ifdef FDC_DEBUG -static char const * const fdstates[] = -{ -"DEVIDLE", -"FINDWORK", -"DOSEEK", -"SEEKCOMPLETE", -"IOCOMPLETE", -"RECALCOMPLETE", -"STARTRECAL", -"RESETCTLR", -"SEEKWAIT", -"RECALWAIT", -"MOTORWAIT", -"IOTIMEDOUT", -"RESETCOMPLETE", -#ifdef FDC_YE -"PIOREAD", -#endif -}; - -/* CAUTION: fd_debug causes huge amounts of logging output */ -static int volatile fd_debug = 0; -#define TRACE0(arg) if(fd_debug) printf(arg) -#define TRACE1(arg1, arg2) if(fd_debug) printf(arg1, arg2) -#else /* FDC_DEBUG */ -#define TRACE0(arg) -#define TRACE1(arg1, arg2) -#endif /* FDC_DEBUG */ - -#ifdef FDC_YE -#if NCARD > 0 -#include <sys/select.h> -#include <sys/module.h> -#include <pccard/cardinfo.h> -#include <pccard/driver.h> -#include <pccard/slot.h> - -/* - * PC-Card (PCMCIA) specific code. - */ -static int yeinit(struct pccard_devinfo *); /* init device */ -static void yeunload(struct pccard_devinfo *); /* Disable driver */ -static int yeintr(struct pccard_devinfo *); /* Interrupt handler */ - -PCCARD_MODULE(fdc, yeinit, yeunload, yeintr, 0, bio_imask); - -/* - * this is the secret PIO data port (offset from base) - */ -#define FDC_YE_DATAPORT 6 - -/* - * Initialize the device - called from Slot manager. - */ -static int yeinit(struct pccard_devinfo *devi) -{ - fdc_p fdc = &fdc_data[devi->isahd.id_unit]; - - /* validate unit number. */ - if (devi->isahd.id_unit >= NFDC) - return(ENODEV); - fdc->baseport = devi->isahd.id_iobase; - /* - * reset controller - */ - outb(fdc->baseport+FDOUT, 0); - DELAY(100); - outb(fdc->baseport+FDOUT, FDO_FRST); - - /* - * wire into system - */ - if (yeattach(&devi->isahd) == 0) - return(ENXIO); - - return(0); -} - -/* - * yeunload - unload the driver and clear the table. - * XXX TODO: - * This is usually called when the card is ejected, but - * can be caused by a modunload of a controller driver. - * The idea is to reset the driver's view of the device - * and ensure that any driver entry points such as - * read and write do not hang. - */ -static void yeunload(struct pccard_devinfo *devi) -{ - if (fd_data[devi->isahd.id_unit].type == NO_TYPE) - return; - - /* - * this prevents Fdopen() and fdstrategy() from attempting - * to access unloaded controller - */ - fd_data[devi->isahd.id_unit].type = NO_TYPE; - - printf("fdc%d: unload\n", devi->isahd.id_unit); -} - -/* - * yeintr - Shared interrupt called from - * front end of PC-Card handler. - */ -static int yeintr(struct pccard_devinfo *devi) -{ - fdintr((fdcu_t)devi->isahd.id_unit); - return(1); -} -#endif /* NCARD > 0 */ -#endif /* FDC_YE */ - -static d_open_t Fdopen; /* NOTE, not fdopen */ -static d_close_t fdclose; -static d_ioctl_t fdioctl; -static d_strategy_t fdstrategy; - -#define CDEV_MAJOR 9 -#define BDEV_MAJOR 2 - -static struct cdevsw fd_cdevsw = { - /* open */ Fdopen, - /* close */ fdclose, - /* read */ physread, - /* write */ physwrite, - /* ioctl */ fdioctl, - /* stop */ nostop, - /* reset */ noreset, - /* devtotty */ nodevtotty, - /* poll */ nopoll, - /* mmap */ nommap, - /* strategy */ fdstrategy, - /* name */ "fd", - /* parms */ noparms, - /* maj */ CDEV_MAJOR, - /* dump */ nodump, - /* psize */ nopsize, - /* flags */ D_DISK, - /* maxio */ 0, - /* bmaj */ BDEV_MAJOR -}; - -static int -fdc_err(struct fdc_data *fdc, const char *s) -{ - fdc->fdc_errs++; - if (s) { - if (fdc->fdc_errs < FDC_ERRMAX) { - device_print_prettyname(fdc->fdc_dev); - printf("%s", s); - } else if (fdc->fdc_errs == FDC_ERRMAX) { - device_print_prettyname(fdc->fdc_dev); - printf("too many errors, not logging any more\n"); - } - } - - return FD_FAILED; -} - -/* - * fd_cmd: Send a command to the chip. Takes a varargs with this structure: - * Unit number, - * # of output bytes, output bytes as ints ..., - * # of input bytes, input bytes as ints ... - */ -static int -fd_cmd(struct fdc_data *fdc, int n_out, ...) -{ - u_char cmd; - int n_in; - int n; - va_list ap; - - va_start(ap, n_out); - cmd = (u_char)(va_arg(ap, int)); - va_end(ap); - va_start(ap, n_out); - for (n = 0; n < n_out; n++) - { - if (out_fdc(fdc, va_arg(ap, int)) < 0) - { - char msg[50]; - snprintf(msg, sizeof(msg), - "cmd %x failed at out byte %d of %d\n", - cmd, n + 1, n_out); - return fdc_err(fdc, msg); - } - } - n_in = va_arg(ap, int); - for (n = 0; n < n_in; n++) - { - int *ptr = va_arg(ap, int *); - if (fd_in(fdc, ptr) < 0) - { - char msg[50]; - snprintf(msg, sizeof(msg), - "cmd %02x failed at in byte %d of %d\n", - cmd, n + 1, n_in); - return fdc_err(fdc, msg); - } - } - - return 0; -} - -static int -enable_fifo(fdc_p fdc) -{ - int i, j; - - if ((fdc->flags & FDC_HAS_FIFO) == 0) { - - /* - * XXX: - * Cannot use fd_cmd the normal way here, since - * this might be an invalid command. Thus we send the - * first byte, and check for an early turn of data directon. - */ - - if (out_fdc(fdc, I8207X_CONFIGURE) < 0) - return fdc_err(fdc, "Enable FIFO failed\n"); - - /* If command is invalid, return */ - j = 100000; - while ((i = inb(fdc->baseport + FDSTS) & (NE7_DIO | NE7_RQM)) - != NE7_RQM && j-- > 0) - if (i == (NE7_DIO | NE7_RQM)) { - fdc_reset(fdc); - return FD_FAILED; - } - if (j<0 || - fd_cmd(fdc, 3, - 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { - fdc_reset(fdc); - return fdc_err(fdc, "Enable FIFO failed\n"); - } - fdc->flags |= FDC_HAS_FIFO; - return 0; - } - if (fd_cmd(fdc, 4, - I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) - return fdc_err(fdc, "Re-enable FIFO failed\n"); - return 0; -} - -static int -fd_sense_drive_status(fdc_p fdc, int *st3p) -{ - int st3; - - if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3)) - { - return fdc_err(fdc, "Sense Drive Status failed\n"); - } - if (st3p) - *st3p = st3; - - return 0; -} - -static int -fd_sense_int(fdc_p fdc, int *st0p, int *cylp) -{ - int cyl, st0, ret; - - ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0); - if (ret) { - (void)fdc_err(fdc, - "sense intr err reading stat reg 0\n"); - return ret; - } - - if (st0p) - *st0p = st0; - - if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) { - /* - * There doesn't seem to have been an interrupt. - */ - return FD_NOT_VALID; - } - - if (fd_in(fdc, &cyl) < 0) { - return fdc_err(fdc, "can't get cyl num\n"); - } - - if (cylp) - *cylp = cyl; - - return 0; -} - - -static int -fd_read_status(fdc_p fdc, int fdsu) -{ - int i, ret; - - for (i = 0; i < 7; i++) { - /* - * XXX types are poorly chosen. Only bytes can by read - * from the hardware, but fdc->status[] wants u_ints and - * fd_in() gives ints. - */ - int status; - - ret = fd_in(fdc, &status); - fdc->status[i] = status; - if (ret != 0) - break; - } - - if (ret == 0) - fdc->flags |= FDC_STAT_VALID; - else - fdc->flags &= ~FDC_STAT_VALID; - - return ret; -} - -/****************************************************************************/ -/* autoconfiguration stuff */ -/****************************************************************************/ - -static int -fdc_probe(device_t dev) -{ - int error, i, ic_type; - struct fdc_data *fdc; - char myname[8]; /* better be long enough */ - - fdc = device_get_softc(dev); - bzero(fdc, sizeof *fdc); - fdc->fdc_dev = dev; - fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0; - fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0; - - fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, - &fdc->rid_ioport, 0ul, ~0ul, - IO_FDCSIZE, RF_ACTIVE); - if (fdc->res_ioport == 0) { - device_print_prettyname(dev); - printf("cannot reserve I/O port range\n"); - error = ENXIO; - goto out; - } - fdc->baseport = fdc->res_ioport->r_start; - - fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, - &fdc->rid_irq, 0ul, ~0ul, 1, - RF_ACTIVE); - if (fdc->res_irq == 0) { - device_print_prettyname(dev); - printf("cannot reserve interrupt line\n"); - error = ENXIO; - goto out; - } - fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ, - &fdc->rid_drq, 0ul, ~0ul, 1, - RF_ACTIVE); - if (fdc->res_drq == 0) { - device_print_prettyname(dev); - printf("cannot reserve DMA request line\n"); - error = ENXIO; - goto out; - } - fdc->dmachan = fdc->res_drq->r_start; - error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq, - INTR_TYPE_BIO, fdc_intr, fdc, &fdc->fdc_intr); - - /* First - lets reset the floppy controller */ - outb(fdc->baseport + FDOUT, 0); - DELAY(100); - outb(fdc->baseport + FDOUT, 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: - device_set_desc(dev, "Intel 82077 or clone"); - fdc->fdct = FDC_I82077; - break; - case 0x90: - device_set_desc(dev, "NEC 72065B or clone"); - fdc->fdct = FDC_NE72065; - break; - default: - device_set_desc(dev, "generic floppy controller"); - fdc->fdct = FDC_UNKNOWN; - break; - } - } - - snprintf(myname, sizeof(myname), "%s%d", device_get_name(dev), - device_get_unit(dev)); - for (i = resource_query_string(-1, "at", myname); i != -1; - i = resource_query_string(i, "at", myname)) - fdc_add_device(dev, resource_query_name(i), - resource_query_unit(i)); -#ifdef FDC_YE - /* - * don't succeed on probe; wait - * for PCCARD subsystem to do it - */ - if (dev->id_flags & FDC_IS_PCMCIA) - return(0); -#endif - return (0); - -out: - if (fdc->fdc_intr) - BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, - fdc->fdc_intr); - if (fdc->res_irq != 0) { - bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq, - fdc->res_irq); - bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, - fdc->res_irq); - } - if (fdc->res_ioport != 0) { - bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, - fdc->res_ioport); - bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, - fdc->res_ioport); - } - if (fdc->res_drq != 0) { - bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, - fdc->res_drq); - bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, - fdc->res_drq); - } - return (error); -} - -/* - * Aped dfr@freebsd.org's isa_add_device(). - */ -static void -fdc_add_device(device_t dev, const char *name, int unit) -{ - int disabled, *ivar; - device_t child; - - ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT); - if (ivar == 0) - return; - if (resource_int_value(name, unit, "drive", ivar) == 0) - *ivar = 0; - child = device_add_child(dev, name, unit, ivar); - if (child == 0) - return; - if (resource_int_value(name, unit, "disabled", &disabled) == 0) - device_disable(child); -} - -static int -fdc_attach(device_t dev) -{ - struct fdc_data *fdc = device_get_softc(dev); - fdcu_t fdcu = device_get_unit(dev); - - fdc->fdcu = fdcu; - fdc->flags |= FDC_ATTACHED; - - /* Acquire the DMA channel forever, The driver will do the rest */ - /* XXX should integrate with rman */ - isa_dma_acquire(fdc->dmachan); - isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */); - fdc->state = DEVIDLE; - - /* reset controller, turn motor off, clear fdout mirror reg */ - outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); - bufq_init(&fdc->head); - -#ifdef FIFO_BEFORE_MOTORON - /* Hmm, this doesn't work here - is set_motor() magic? -Peter */ - if (fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN - && enable_fifo(fdc) == 0) { - device_print_prettyname(dev); - printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); - } -#endif - /* - * Probe and attach any children as were configured above. - */ - return (bus_generic_attach(dev)); -} - -static void -fdc_print_child(device_t me, device_t child) -{ - printf(" at %s%d drive %d", device_get_name(me), device_get_unit(me), - *(int *)device_get_ivars(child)); -} - -static int -fd_probe(device_t dev) -{ - int i; - u_int fdt, st0, st3; - struct fd_data *fd; - struct fdc_data *fdc; - fdsu_t fdsu; -#ifndef FIFO_BEFORE_MOTORON - static int fd_fifo = 0; -#endif - - /* No pnp support */ - if (isa_get_vendorid(dev)) - return (ENXIO); - - fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */ - fd = device_get_softc(dev); - fdc = device_get_softc(device_get_parent(dev)); - - bzero(fd, sizeof *fd); - fd->dev = dev; - fd->fdc = fdc; - fd->fdsu = fdsu; - fd->fdu = device_get_unit(dev); - - /* look up what bios thinks we have */ - switch (fd->fdu) { - case 0: - if (isa_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0) - fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED; - else - fdt = (rtcin(RTC_FDISKETTE) & 0xf0); - break; - case 1: - fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0); - break; - default: - fdt = RTCFDT_NONE; - break; - } - - /* is there a unit? */ - if (fdt == RTCFDT_NONE) - return (ENXIO); - - /* select it */ - set_motor(fdc, fdsu, TURNON); - DELAY(1000000); /* 1 sec */ - -#ifndef FIFO_BEFORE_MOTORON - if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN - && enable_fifo(fdc) == 0) { - device_print_prettyname(device_get_parent(dev)); - printf("FIFO enabled, %d bytes threshold\n", fifo_threshold); - } - fd_fifo = 1; -#endif - - if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) - && (st3 & NE7_ST3_T0)) { - /* if at track 0, first seek inwards */ - /* seek some steps: */ - fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0); - DELAY(300000); /* ...wait a moment... */ - fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ - } - - /* If we're at track 0 first seek inwards. */ - if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) { - /* Seek some steps... */ - if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { - /* ...wait a moment... */ - DELAY(300000); - /* make ctrlr happy: */ - fd_sense_int(fdc, 0, 0); - } - } - - for (i = 0; i < 2; i++) { - /* - * we must recalibrate twice, just in case the - * heads have been beyond cylinder 76, since most - * FDCs still barf when attempting to recalibrate - * more than 77 steps - */ - /* go back to 0: */ - if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) { - /* a second being enough for full stroke seek*/ - DELAY(i == 0 ? 1000000 : 300000); - - /* anything responding? */ - if (fd_sense_int(fdc, &st0, 0) == 0 && - (st0 & NE7_ST0_EC) == 0) - break; /* already probed succesfully */ - } - } - - set_motor(fdc, fdsu, TURNOFF); - - if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ - return (ENXIO); - - fd->track = FD_NO_TRACK; - fd->fdc = fdc; - fd->fdsu = fdsu; - fd->options = 0; - callout_handle_init(&fd->toffhandle); - callout_handle_init(&fd->tohandle); - - switch (fdt) { - case RTCFDT_12M: - device_set_desc(dev, "1200-KB 5.25\" drive"); - fd->type = FD_1200; - break; - case RTCFDT_144M | RTCFDT_144M_PRETENDED: - device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive"); - fdt = RTCFDT_144M; - fd->type = FD_1440; - case RTCFDT_144M: - device_set_desc(dev, "1440-KB 3.5\" drive"); - fd->type = FD_1440; - break; - case RTCFDT_288M: - case RTCFDT_288M_1: - device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)"); - fd->type = FD_1440; - break; - case RTCFDT_360K: - device_set_desc(dev, "360-KB 5.25\" drive"); - fd->type = FD_360; - break; - case RTCFDT_720K: - printf("720-KB 3.5\" drive"); - fd->type = FD_720; - break; - default: - return (ENXIO); - } - return (0); -} - -static int -fd_attach(device_t dev) -{ - struct fd_data *fd; -#ifdef DEVFS - int i; - int mynor; - int typemynor; - int typesize; -#endif - - fd = device_get_softc(dev); - -#ifdef DEVFS /* XXX bitrot */ - mynor = fd->fdu << 6; - fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, - UID_ROOT, GID_OPERATOR, 0640, - "fd%d", fd->fdu); - fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, - UID_ROOT, GID_OPERATOR, 0640, - "rfd%d", fd->fdu); - for (i = 1; i < 1 + NUMDENS; i++) { - /* - * XXX this and the lookup in Fdopen() should be - * data driven. - */ - switch (fd->type) { - case FD_360: - if (i != FD_360) - continue; - break; - case FD_720: - if (i != FD_720 && i != FD_800 && i != FD_820) - continue; - break; - case FD_1200: - if (i != FD_360 && i != FD_720 && i != FD_800 - && i != FD_820 && i != FD_1200 - && i != FD_1440 && i != FD_1480) - continue; - break; - case FD_1440: - if (i != FD_720 && i != FD_800 && i != FD_820 - && i != FD_1200 && i != FD_1440 - && i != FD_1480 && i != FD_1720) - continue; - break; - } - typesize = fd_types[i - 1].size / 2; - /* - * XXX all these conversions give bloated code and - * confusing names. - */ - if (typesize == 1476) - typesize = 1480; - if (typesize == 1722) - typesize = 1720; - typemynor = mynor | i; - fd->bdevs[i] = - devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK, - UID_ROOT, GID_OPERATOR, 0640, - "fd%d.%d", fd->fdu, typesize); - fd->cdevs[i] = - devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR, - UID_ROOT, GID_OPERATOR, 0640, - "rfd%d.%d", fd->fdu, typesize); - } - - for (i = 0; i < MAXPARTITIONS; i++) { - fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], - "fd%d%c", fd->fdu, 'a' + i); - fd->cdevs[1 + NUMDENS + i] = - devfs_makelink(fd->cdevs[0], - "rfd%d%c", fd->fdu, 'a' + i); - } -#endif /* DEVFS */ - /* - * Export the drive to the devstat interface. - */ - devstat_add_entry(&fd->device_stats, device_get_name(dev), - device_get_unit(dev), 512, DEVSTAT_NO_ORDERED_TAGS, - DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER, - DEVSTAT_PRIORITY_FD); - return (0); -} - -#ifdef FDC_YE -/* - * this is a subset of fdattach() optimized for the Y-E Data - * PCMCIA floppy drive. - */ -static int yeattach(struct isa_device *dev) -{ - fdcu_t fdcu = dev->id_unit; - fdc_p fdc = fdc_data + fdcu; - fdsu_t fdsu = 0; /* assume 1 drive per YE controller */ - fdu_t fdu; - fd_p fd; - int st0, st3, i; -#ifdef DEVFS - int mynor; - int typemynor; - int typesize; -#endif - fdc->fdcu = fdcu; - /* - * the FDC_PCMCIA flag is used to to indicate special PIO is used - * instead of DMA - */ - fdc->flags = FDC_ATTACHED|FDC_PCMCIA; - fdc->state = DEVIDLE; - /* reset controller, turn motor off, clear fdout mirror reg */ - outb(fdc->baseport + FDOUT, ((fdc->fdout = 0))); - bufq_init(&fdc->head); - /* - * assume 2 drives/ "normal" controller - */ - fdu = fdcu * 2; - if (fdu >= NFD) { - printf("fdu %d >= NFD\n",fdu); - return(0); - }; - fd = &fd_data[fdu]; - - set_motor(fdcu, fdsu, TURNON); - DELAY(1000000); /* 1 sec */ - fdc->fdct = FDC_NE765; - - if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) && - (st3 & NE7_ST3_T0)) { - /* if at track 0, first seek inwards */ - /* seek some steps: */ - (void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0); - DELAY(300000); /* ...wait a moment... */ - (void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */ - } - - /* If we're at track 0 first seek inwards. */ - if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) { - /* Seek some steps... */ - if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) { - /* ...wait a moment... */ - DELAY(300000); - /* make ctrlr happy: */ - (void)fd_sense_int(fdc, 0, 0); - } - } - - for(i = 0; i < 2; i++) { - /* - * we must recalibrate twice, just in case the - * heads have been beyond cylinder 76, since most - * FDCs still barf when attempting to recalibrate - * more than 77 steps - */ - /* go back to 0: */ - if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) { - /* a second being enough for full stroke seek*/ - DELAY(i == 0? 1000000: 300000); - - /* anything responding? */ - if (fd_sense_int(fdc, &st0, 0) == 0 && - (st0 & NE7_ST0_EC) == 0) - break; /* already probed succesfully */ - } - } - - set_motor(fdcu, fdsu, TURNOFF); - - if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */ - return(0); - - fd->track = FD_NO_TRACK; - fd->fdc = fdc; - fd->fdsu = fdsu; - fd->options = 0; - printf("fdc%d: 1.44MB 3.5in PCMCIA\n", fdcu); - fd->type = FD_1440; - -#ifdef DEVFS - mynor = fdcu << 6; - fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK, - UID_ROOT, GID_OPERATOR, 0640, - "fd%d", fdu); - fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR, - UID_ROOT, GID_OPERATOR, 0640, - "rfd%d", fdu); - /* - * XXX this and the lookup in Fdopen() should be - * data driven. - */ - typemynor = mynor | FD_1440; - typesize = fd_types[FD_1440 - 1].size / 2; - /* - * XXX all these conversions give bloated code and - * confusing names. - */ - if (typesize == 1476) - typesize = 1480; - if (typesize == 1722) - typesize = 1720; - fd->bdevs[FD_1440] = devfs_add_devswf(&fd_cdevsw, typemynor, - DV_BLK, UID_ROOT, GID_OPERATOR, - 0640, "fd%d.%d", fdu, typesize); - fd->cdevs[FD_1440] = devfs_add_devswf(&fd_cdevsw, typemynor, - DV_CHR, UID_ROOT, GID_OPERATOR, - 0640,"rfd%d.%d", fdu, typesize); - for (i = 0; i < MAXPARTITIONS; i++) { - fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0], - "fd%d%c", fdu, 'a' + i); - fd->cdevs[1 + NUMDENS + i] = devfs_makelink(fd->cdevs[0], - "rfd%d%c", fdu, 'a' + i); - } -#endif /* DEVFS */ - return (1); -} -#endif - -/****************************************************************************/ -/* motor control stuff */ -/* remember to not deselect the drive we're working on */ -/****************************************************************************/ -static void -set_motor(struct fdc_data *fdc, int fdsu, int turnon) -{ - int fdout = fdc->fdout; - int needspecify = 0; - - if(turnon) { - fdout &= ~FDO_FDSEL; - fdout |= (FDO_MOEN0 << fdsu) + fdsu; - } else - fdout &= ~(FDO_MOEN0 << fdsu); - - if(!turnon - && (fdout & (FDO_MOEN0+FDO_MOEN1+FDO_MOEN2+FDO_MOEN3)) == 0) - /* gonna turn off the last drive, put FDC to bed */ - fdout &= ~ (FDO_FRST|FDO_FDMAEN); - else { - /* make sure controller is selected and specified */ - if((fdout & (FDO_FRST|FDO_FDMAEN)) == 0) - needspecify = 1; - fdout |= (FDO_FRST|FDO_FDMAEN); - } - - outb(fdc->baseport+FDOUT, fdout); - fdc->fdout = fdout; - TRACE1("[0x%x->FDOUT]", fdout); - - if (needspecify) { - /* - * XXX - * special case: since we have just woken up the FDC - * from its sleep, we silently assume the command will - * be accepted, and do not test for a timeout - */ - (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, - NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), - 0); - if (fdc->flags & FDC_HAS_FIFO) - (void) enable_fifo(fdc); - } -} - -static void -fd_turnoff(void *xfd) -{ - int s; - fd_p fd = xfd; - - TRACE1("[fd%d: turnoff]", fd->fdu); - - /* - * Don't turn off the motor yet if the drive is active. - * XXX shouldn't even schedule turnoff until drive is inactive - * and nothing is queued on it. - */ - if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) { - fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); - return; - } - - s = splbio(); - fd->flags &= ~FD_MOTOR; - set_motor(fd->fdc, fd->fdsu, TURNOFF); - splx(s); -} - -static void -fd_motor_on(void *xfd) -{ - int s; - fd_p fd = xfd; - - s = splbio(); - fd->flags &= ~FD_MOTOR_WAIT; - if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT)) - { - fdc_intr(fd->fdc); - } - splx(s); -} - -static void -fd_turnon(fd_p fd) -{ - if(!(fd->flags & FD_MOTOR)) - { - fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT); - set_motor(fd->fdc, fd->fdsu, TURNON); - timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */ - } -} - -static void -fdc_reset(fdc_p fdc) -{ - /* Try a reset, keep motor on */ - outb(fdc->baseport + FDOUT, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); - TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN)); - DELAY(100); - /* enable FDC, but defer interrupts a moment */ - outb(fdc->baseport + FDOUT, fdc->fdout & ~FDO_FDMAEN); - TRACE1("[0x%x->FDOUT]", fdc->fdout & ~FDO_FDMAEN); - DELAY(100); - outb(fdc->baseport + FDOUT, fdc->fdout); - TRACE1("[0x%x->FDOUT]", fdc->fdout); - - /* XXX after a reset, silently believe the FDC will accept commands */ - (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY, - NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0), - 0); - if (fdc->flags & FDC_HAS_FIFO) - (void) enable_fifo(fdc); -} - -/****************************************************************************/ -/* fdc in/out */ -/****************************************************************************/ -int -in_fdc(struct fdc_data *fdc) -{ - int baseport = fdc->baseport; - int i, j = 100000; - while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) - != (NE7_DIO|NE7_RQM) && j-- > 0) - if (i == NE7_RQM) - return fdc_err(fdc, "ready for output in input\n"); - if (j <= 0) - return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); -#ifdef FDC_DEBUG - i = inb(baseport+FDDATA); - TRACE1("[FDDATA->0x%x]", (unsigned char)i); - return(i); -#else /* !FDC_DEBUG */ - return inb(baseport+FDDATA); -#endif /* FDC_DEBUG */ -} - -/* - * fd_in: Like in_fdc, but allows you to see if it worked. - */ -static int -fd_in(struct fdc_data *fdc, int *ptr) -{ - int baseport = fdc->baseport; - int i, j = 100000; - while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM)) - != (NE7_DIO|NE7_RQM) && j-- > 0) - if (i == NE7_RQM) - return fdc_err(fdc, "ready for output in input\n"); - if (j <= 0) - return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); -#ifdef FDC_DEBUG - i = inb(baseport+FDDATA); - TRACE1("[FDDATA->0x%x]", (unsigned char)i); - *ptr = i; - return 0; -#else /* !FDC_DEBUG */ - i = inb(baseport+FDDATA); - if (ptr) - *ptr = i; - return 0; -#endif /* FDC_DEBUG */ -} - -int -out_fdc(struct fdc_data *fdc, int x) -{ - int baseport = fdc->baseport; - int i; - - /* Check that the direction bit is set */ - i = 100000; - while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0); - if (i <= 0) return fdc_err(fdc, "direction bit not set\n"); - - /* Check that the floppy controller is ready for a command */ - i = 100000; - while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0); - if (i <= 0) - return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); - - /* Send the command and return */ - outb(baseport+FDDATA, x); - TRACE1("[0x%x->FDDATA]", x); - return (0); -} - -/****************************************************************************/ -/* fdopen/fdclose */ -/****************************************************************************/ -int -Fdopen(dev_t dev, int flags, int mode, struct proc *p) -{ - fdu_t fdu = FDUNIT(minor(dev)); - int type = FDTYPE(minor(dev)); - fd_p fd; - fdc_p fdc; - - /* check bounds */ - if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0) - return (ENXIO); - fdc = fd->fdc; - if ((fdc == NULL) || (fd->type == NO_TYPE)) - return (ENXIO); - if (type > NUMDENS) - return (ENXIO); - if (type == 0) - type = fd->type; - else { - /* - * For each type of basic drive, make sure we are trying - * to open a type it can do, - */ - if (type != fd->type) { - switch (fd->type) { - case FD_360: - return (ENXIO); - case FD_720: - if ( type != FD_820 - && type != FD_800 - ) - return (ENXIO); - break; - case FD_1200: - switch (type) { - case FD_1480: - type = FD_1480in5_25; - break; - case FD_1440: - type = FD_1440in5_25; - break; - case FD_820: - type = FD_820in5_25; - break; - case FD_800: - type = FD_800in5_25; - break; - case FD_720: - type = FD_720in5_25; - break; - case FD_360: - type = FD_360in5_25; - break; - default: - return(ENXIO); - } - break; - case FD_1440: - if ( type != FD_1720 - && type != FD_1480 - && type != FD_1200 - && type != FD_820 - && type != FD_800 - && type != FD_720 - ) - return(ENXIO); - break; - } - } - } - fd->ft = fd_types + type - 1; - fd->flags |= FD_OPEN; - device_busy(fd->dev); - device_busy(fd->fdc->fdc_dev); - return 0; -} - -int -fdclose(dev_t dev, int flags, int mode, struct proc *p) -{ - fdu_t fdu = FDUNIT(minor(dev)); - struct fd_data *fd; - - fd = devclass_get_softc(fd_devclass, fdu); - fd->flags &= ~FD_OPEN; - fd->options &= ~FDOPT_NORETRY; - - return (0); -} - -/****************************************************************************/ -/* fdstrategy */ -/****************************************************************************/ -void -fdstrategy(struct buf *bp) -{ - unsigned nblocks, blknum, cando; - int s; - fdu_t fdu; - fdc_p fdc; - fd_p fd; - size_t fdblk; - - fdu = FDUNIT(minor(bp->b_dev)); - fd = devclass_get_softc(fd_devclass, fdu); - if (fd == 0) - panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)", - (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev)); - fdc = fd->fdc; -#ifdef FDC_YE - if (fd->type == NO_TYPE) { - bp->b_error = ENXIO; - bp->b_flags |= B_ERROR; - /* - * I _refuse_ to use a goto - */ - biodone(bp); - return; - }; -#endif - - fdblk = 128 << (fd->ft->secsize); - if (!(bp->b_flags & B_FORMAT)) { - if (bp->b_blkno < 0) { - printf( - "fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n", - fdu, (u_long)bp->b_blkno, bp->b_bcount); - bp->b_error = EINVAL; - bp->b_flags |= B_ERROR; - goto bad; - } - if ((bp->b_bcount % fdblk) != 0) { - bp->b_error = EINVAL; - bp->b_flags |= B_ERROR; - goto bad; - } - } - - /* - * Set up block calculations. - */ - if (bp->b_blkno > 20000000) { - /* - * Reject unreasonably high block number, prevent the - * multiplication below from overflowing. - */ - bp->b_error = EINVAL; - bp->b_flags |= B_ERROR; - goto bad; - } - blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk; - nblocks = fd->ft->size; - bp->b_resid = 0; - if (blknum + (bp->b_bcount / fdblk) > nblocks) { - if (blknum <= nblocks) { - cando = (nblocks - blknum) * fdblk; - bp->b_resid = bp->b_bcount - cando; - if (cando == 0) - goto bad; /* not actually bad but EOF */ - } else { - bp->b_error = EINVAL; - bp->b_flags |= B_ERROR; - goto bad; - } - } - bp->b_pblkno = bp->b_blkno; - s = splbio(); - bufqdisksort(&fdc->head, bp); - untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */ - - /* Tell devstat we are starting on the transaction */ - devstat_start_transaction(&fd->device_stats); - - fdstart(fdc); - splx(s); - return; - -bad: - biodone(bp); -} - -/***************************************************************\ -* fdstart * -* We have just queued something.. if the controller is not busy * -* then simulate the case where it has just finished a command * -* So that it (the interrupt routine) looks on the queue for more* -* work to do and picks up what we just added. * -* If the controller is already busy, we need do nothing, as it * -* will pick up our work when the present work completes * -\***************************************************************/ -static void -fdstart(struct fdc_data *fdc) -{ - int s; - - s = splbio(); - if(fdc->state == DEVIDLE) - { - fdc_intr(fdc); - } - splx(s); -} - -static void -fd_iotimeout(void *xfdc) -{ - fdc_p fdc; - int s; - - fdc = xfdc; - TRACE1("fd%d[fd_iotimeout()]", fdc->fdu); - - /* - * Due to IBM's brain-dead design, the FDC has a faked ready - * signal, hardwired to ready == true. Thus, any command - * issued if there's no diskette in the drive will _never_ - * complete, and must be aborted by resetting the FDC. - * Many thanks, Big Blue! - * The FDC must not be reset directly, since that would - * interfere with the state machine. Instead, pretend that - * the command completed but was invalid. The state machine - * will reset the FDC and retry once. - */ - s = splbio(); - fdc->status[0] = NE7_ST0_IC_IV; - fdc->flags &= ~FDC_STAT_VALID; - fdc->state = IOTIMEDOUT; - fdc_intr(fdc); - splx(s); -} - -/* just ensure it has the right spl */ -static void -fd_pseudointr(void *xfdc) -{ - int s; - - s = splbio(); - fdc_intr(xfdc); - splx(s); -} - -/***********************************************************************\ -* fdintr * -* keep calling the state machine until it returns a 0 * -* ALWAYS called at SPLBIO * -\***********************************************************************/ -static void -fdc_intr(void *xfdc) -{ - fdc_p fdc = xfdc; - while(fdstate(fdc)) - ; -} - -#ifdef FDC_YE -/* - * magic pseudo-DMA initialization for YE FDC. Sets count and - * direction - */ -#define SET_BCDR(wr,cnt,port) outb(port,(((cnt)-1) & 0xff)); \ - outb(port+1,((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f))) - -/* - * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy - */ -static int fdcpio(fdcu_t fdcu, long flags, caddr_t addr, u_int count) -{ - u_char *cptr = (u_char *)addr; - fdc_p fdc = &fdc_data[fdcu]; - int io = fdc->baseport; - - if (flags & B_READ) { - if (fdc->state != PIOREAD) { - fdc->state = PIOREAD; - return(0); - }; - SET_BCDR(0,count,io); - insb(io+FDC_YE_DATAPORT,cptr,count); - } else { - outsb(io+FDC_YE_DATAPORT,cptr,count); - SET_BCDR(0,count,io); - }; - return(1); -} -#endif /* FDC_YE */ - -/***********************************************************************\ -* The controller state machine. * -* if it returns a non zero value, it should be called again immediatly * -\***********************************************************************/ -static int -fdstate(fdc_p fdc) -{ - int read, format, head, i, sec = 0, sectrac, st0, cyl, st3; - unsigned blknum = 0, b_cylinder = 0; - fdu_t fdu = fdc->fdu; - fd_p fd; - register struct buf *bp; - struct fd_formb *finfo = NULL; - size_t fdblk; - - bp = fdc->bp; - if (bp == NULL) { - bp = bufq_first(&fdc->head); - if (bp != NULL) { - bufq_remove(&fdc->head, bp); - fdc->bp = bp; - } - } - if (bp == NULL) { - /***********************************************\ - * nothing left for this controller to do * - * Force into the IDLE state, * - \***********************************************/ - fdc->state = DEVIDLE; - if (fdc->fd) { - device_print_prettyname(fdc->fdc_dev); - printf("unexpected valid fd pointer\n"); - fdc->fd = (fd_p) 0; - fdc->fdu = -1; - } - TRACE1("[fdc%d IDLE]", fdc->fdcu); - return (0); - } - fdu = FDUNIT(minor(bp->b_dev)); - fd = devclass_get_softc(fd_devclass, fdu); - fdblk = 128 << fd->ft->secsize; - if (fdc->fd && (fd != fdc->fd)) { - device_print_prettyname(fd->dev); - printf("confused fd pointers\n"); - } - read = bp->b_flags & B_READ; - format = bp->b_flags & B_FORMAT; - if (format) { - finfo = (struct fd_formb *)bp->b_data; - fd->skip = (char *)&(finfo->fd_formb_cylno(0)) - - (char *)finfo; - } - if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) { - blknum = (unsigned) bp->b_pblkno * DEV_BSIZE/fdblk + - fd->skip/fdblk; - b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads); - } - TRACE1("fd%d", fdu); - TRACE1("[%s]", fdstates[fdc->state]); - TRACE1("(0x%x)", fd->flags); - untimeout(fd_turnoff, fd, fd->toffhandle); - fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz); - switch (fdc->state) - { - case DEVIDLE: - case FINDWORK: /* we have found new work */ - fdc->retry = 0; - fd->skip = 0; - fdc->fd = fd; - fdc->fdu = fdu; - outb(fdc->baseport+FDCTL, fd->ft->trans); - TRACE1("[0x%x->FDCTL]", fd->ft->trans); - /*******************************************************\ - * If the next drive has a motor startup pending, then * - * it will start up in its own good time * - \*******************************************************/ - if(fd->flags & FD_MOTOR_WAIT) { - fdc->state = MOTORWAIT; - return (0); /* come back later */ - } - /*******************************************************\ - * Maybe if it's not starting, it SHOULD be starting * - \*******************************************************/ - if (!(fd->flags & FD_MOTOR)) - { - fdc->state = MOTORWAIT; - fd_turnon(fd); - return (0); - } - else /* at least make sure we are selected */ - { - set_motor(fdc, fd->fdsu, TURNON); - } - if (fdc->flags & FDC_NEEDS_RESET) { - fdc->state = RESETCTLR; - fdc->flags &= ~FDC_NEEDS_RESET; - } else - fdc->state = DOSEEK; - break; - case DOSEEK: - if (b_cylinder == (unsigned)fd->track) - { - fdc->state = SEEKCOMPLETE; - break; - } - if (fd_cmd(fdc, 3, NE7CMD_SEEK, - fd->fdsu, b_cylinder * fd->ft->steptrac, - 0)) - { - /* - * seek command not accepted, looks like - * the FDC went off to the Saints... - */ - fdc->retry = 6; /* try a reset */ - return(retrier(fdc)); - } - fd->track = FD_NO_TRACK; - fdc->state = SEEKWAIT; - return(0); /* will return later */ - case SEEKWAIT: - /* allow heads to settle */ - timeout(fd_pseudointr, fdc, hz / 16); - fdc->state = SEEKCOMPLETE; - return(0); /* will return later */ - case SEEKCOMPLETE : /* SEEK DONE, START DMA */ - /* Make sure seek really happened*/ - if(fd->track == FD_NO_TRACK) { - int descyl = b_cylinder * fd->ft->steptrac; - do { - /* - * This might be a "ready changed" interrupt, - * which cannot really happen since the - * RDY pin is hardwired to + 5 volts. This - * generally indicates a "bouncing" intr - * line, so do one of the following: - * - * When running on an enhanced FDC that is - * known to not go stuck after responding - * with INVALID, fetch all interrupt states - * until seeing either an INVALID or a - * real interrupt condition. - * - * When running on a dumb old NE765, give - * up immediately. The controller will - * provide up to four dummy RC interrupt - * conditions right after reset (for the - * corresponding four drives), so this is - * our only chance to get notice that it - * was not the FDC that caused the interrupt. - */ - if (fd_sense_int(fdc, &st0, &cyl) - == FD_NOT_VALID) - return 0; - if(fdc->fdct == FDC_NE765 - && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) - return 0; /* hope for a real intr */ - } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); - - if (0 == descyl) { - int failed = 0; - /* - * seek to cyl 0 requested; make sure we are - * really there - */ - if (fd_sense_drive_status(fdc, &st3)) - failed = 1; - if ((st3 & NE7_ST3_T0) == 0) { - printf( - "fd%d: Seek to cyl 0, but not really there (ST3 = %b)\n", - fdu, st3, NE7_ST3BITS); - failed = 1; - } - - if (failed) { - if(fdc->retry < 3) - fdc->retry = 3; - return (retrier(fdc)); - } - } - - if (cyl != descyl) { - printf( - "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n", - fdu, descyl, cyl, st0); - if (fdc->retry < 3) - fdc->retry = 3; - return (retrier(fdc)); - } - } - - fd->track = b_cylinder; -#ifdef FDC_YE - if (!(fdc->flags & FDC_PCMCIA)) -#endif - isa_dmastart(bp->b_flags, bp->b_data+fd->skip, - format ? bp->b_bcount : fdblk, fdc->dmachan); - sectrac = fd->ft->sectrac; - sec = blknum % (sectrac * fd->ft->heads); - head = sec / sectrac; - sec = sec % sectrac + 1; - fd->hddrv = ((head&1)<<2)+fdu; - - if(format || !read) - { - /* make sure the drive is writable */ - if(fd_sense_drive_status(fdc, &st3) != 0) - { - /* stuck controller? */ - isa_dmadone(bp->b_flags, bp->b_data + fd->skip, - format ? bp->b_bcount : fdblk, - fdc->dmachan); - fdc->retry = 6; /* reset the beast */ - return (retrier(fdc)); - } - if(st3 & NE7_ST3_WP) - { - /* - * XXX YES! this is ugly. - * in order to force the current operation - * to fail, we will have to fake an FDC - * error - all error handling is done - * by the retrier() - */ - fdc->status[0] = NE7_ST0_IC_AT; - fdc->status[1] = NE7_ST1_NW; - fdc->status[2] = 0; - fdc->status[3] = fd->track; - fdc->status[4] = head; - fdc->status[5] = sec; - fdc->retry = 8; /* break out immediately */ - fdc->state = IOTIMEDOUT; /* not really... */ - return (1); - } - } - - if (format) { -#ifdef FDC_YE - if (fdc->flags & FDC_PCMCIA) - (void)fdcpio(fdcu,bp->b_flags, - bp->b_data+fd->skip, - bp->b_bcount); -#endif - /* formatting */ - if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu, - finfo->fd_formb_secshift, - finfo->fd_formb_nsecs, - finfo->fd_formb_gaplen, - finfo->fd_formb_fillbyte, 0)) { - /* controller fell over */ - isa_dmadone(bp->b_flags, bp->b_data + fd->skip, - format ? bp->b_bcount : fdblk, - fdc->dmachan); - fdc->retry = 6; - return (retrier(fdc)); - } - } else { -#ifdef FDC_YE - if (fdc->flags & FDC_PCMCIA) { - /* - * this seems to be necessary even when - * reading data - */ - SET_BCDR(1,fdblk,fdc->baseport); - - /* - * perform the write pseudo-DMA before - * the WRITE command is sent - */ - if (!read) - (void)fdcpio(fdcu,bp->b_flags, - bp->b_data+fd->skip, - fdblk); - } -#endif - if (fd_cmd(fdc, 9, - (read ? NE7CMD_READ : NE7CMD_WRITE), - head << 2 | fdu, /* head & unit */ - fd->track, /* track */ - head, - sec, /* sector + 1 */ - fd->ft->secsize, /* sector size */ - sectrac, /* sectors/track */ - fd->ft->gap, /* gap size */ - fd->ft->datalen, /* data length */ - 0)) { - /* the beast is sleeping again */ - isa_dmadone(bp->b_flags, bp->b_data + fd->skip, - format ? bp->b_bcount : fdblk, - fdc->dmachan); - fdc->retry = 6; - return (retrier(fdc)); - } - } -#ifdef FDC_YE - if (fdc->flags & FDC_PCMCIA) - /* - * if this is a read, then simply await interrupt - * before performing PIO - */ - if (read && !fdcpio(fdcu,bp->b_flags, - bp->b_data+fd->skip,fdblk)) { - fd->tohandle = timeout(fd_iotimeout, - (caddr_t)fdcu, hz); - return(0); /* will return later */ - }; - - /* - * write (or format) operation will fall through and - * await completion interrupt - */ -#endif - fdc->state = IOCOMPLETE; - fd->tohandle = timeout(fd_iotimeout, fdc, hz); - return (0); /* will return later */ -#ifdef FDC_YE - case PIOREAD: - /* - * actually perform the PIO read. The IOCOMPLETE case - * removes the timeout for us. - */ - (void)fdcpio(fdcu,bp->b_flags,bp->b_data+fd->skip,fdblk); - fdc->state = IOCOMPLETE; - /* FALLTHROUGH */ -#endif - case IOCOMPLETE: /* IO DONE, post-analyze */ - untimeout(fd_iotimeout, fdc, fd->tohandle); - - if (fd_read_status(fdc, fd->fdsu)) { - isa_dmadone(bp->b_flags, bp->b_data + fd->skip, - format ? bp->b_bcount : fdblk, - fdc->dmachan); - if (fdc->retry < 6) - fdc->retry = 6; /* force a reset */ - return (retrier(fdc)); - } - - fdc->state = IOTIMEDOUT; - - /* FALLTHROUGH */ - - case IOTIMEDOUT: -#ifdef FDC_YE - if (!(fdc->flags & FDC_PCMCIA)) -#endif - isa_dmadone(bp->b_flags, bp->b_data + fd->skip, - format ? bp->b_bcount : fdblk, fdc->dmachan); - if (fdc->status[0] & NE7_ST0_IC) { - if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT - && fdc->status[1] & NE7_ST1_OR) { - /* - * DMA overrun. Someone hogged the bus - * and didn't release it in time for the - * next FDC transfer. - * Just restart it, don't increment retry - * count. (vak) - */ - fdc->state = SEEKCOMPLETE; - return (1); - } - else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_IV - && fdc->retry < 6) - fdc->retry = 6; /* force a reset */ - else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT - && fdc->status[2] & NE7_ST2_WC - && fdc->retry < 3) - fdc->retry = 3; /* force recalibrate */ - return (retrier(fdc)); - } - /* All OK */ - fd->skip += fdblk; - if (!format && fd->skip < bp->b_bcount - bp->b_resid) { - /* set up next transfer */ - fdc->state = DOSEEK; - } else { - /* ALL DONE */ - fd->skip = 0; - fdc->bp = NULL; - /* Tell devstat we have finished with the transaction */ - devstat_end_transaction(&fd->device_stats, - bp->b_bcount - bp->b_resid, - DEVSTAT_TAG_NONE, - (bp->b_flags & B_READ) ? - DEVSTAT_READ : DEVSTAT_WRITE); - biodone(bp); - fdc->fd = (fd_p) 0; - fdc->fdu = -1; - fdc->state = FINDWORK; - } - return (1); - case RESETCTLR: - fdc_reset(fdc); - fdc->retry++; - fdc->state = RESETCOMPLETE; - return (0); - case RESETCOMPLETE: - /* - * Discard all the results from the reset so that they - * can't cause an unexpected interrupt later. - */ - for (i = 0; i < 4; i++) - (void)fd_sense_int(fdc, &st0, &cyl); - fdc->state = STARTRECAL; - /* Fall through. */ - case STARTRECAL: - if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) { - /* arrgl */ - fdc->retry = 6; - return (retrier(fdc)); - } - fdc->state = RECALWAIT; - return (0); /* will return later */ - case RECALWAIT: - /* allow heads to settle */ - timeout(fd_pseudointr, fdc, hz / 8); - fdc->state = RECALCOMPLETE; - return (0); /* will return later */ - case RECALCOMPLETE: - do { - /* - * See SEEKCOMPLETE for a comment on this: - */ - if (fd_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) - return 0; - if(fdc->fdct == FDC_NE765 - && (st0 & NE7_ST0_IC) == NE7_ST0_IC_RC) - return 0; /* hope for a real intr */ - } while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC); - if ((st0 & NE7_ST0_IC) != NE7_ST0_IC_NT || cyl != 0) - { - if(fdc->retry > 3) - /* - * a recalibrate from beyond cylinder 77 - * will "fail" due to the FDC limitations; - * since people used to complain much about - * the failure message, try not logging - * this one if it seems to be the first - * time in a line - */ - printf("fd%d: recal failed ST0 %b cyl %d\n", - fdu, st0, NE7_ST0BITS, cyl); - if(fdc->retry < 3) fdc->retry = 3; - return (retrier(fdc)); - } - fd->track = 0; - /* Seek (probably) necessary */ - fdc->state = DOSEEK; - return (1); /* will return immediatly */ - case MOTORWAIT: - if(fd->flags & FD_MOTOR_WAIT) - { - return (0); /* time's not up yet */ - } - if (fdc->flags & FDC_NEEDS_RESET) { - fdc->state = RESETCTLR; - fdc->flags &= ~FDC_NEEDS_RESET; - } else { - /* - * If all motors were off, then the controller was - * reset, so it has lost track of the current - * cylinder. Recalibrate to handle this case. - * But first, discard the results of the reset. - */ - fdc->state = RESETCOMPLETE; - } - return (1); /* will return immediatly */ - default: - device_print_prettyname(fdc->fdc_dev); - printf("unexpected FD int->"); - if (fd_read_status(fdc, fd->fdsu) == 0) - printf("FDC status :%x %x %x %x %x %x %x ", - fdc->status[0], - fdc->status[1], - fdc->status[2], - fdc->status[3], - fdc->status[4], - fdc->status[5], - fdc->status[6] ); - else - printf("No status available "); - if (fd_sense_int(fdc, &st0, &cyl) != 0) - { - printf("[controller is dead now]\n"); - return (0); - } - printf("ST0 = %x, PCN = %x\n", st0, cyl); - return (0); - } - /*XXX confusing: some branches return immediately, others end up here*/ - return (1); /* Come back immediatly to new state */ -} - -static int -retrier(struct fdc_data *fdc) -{ - register struct buf *bp; - struct fd_data *fd; - int fdu; - - bp = fdc->bp; - - /* XXX shouldn't this be cached somewhere? */ - fdu = FDUNIT(minor(bp->b_dev)); - fd = devclass_get_softc(fd_devclass, fdu); - if (fd->options & FDOPT_NORETRY) - goto fail; - - switch (fdc->retry) { - case 0: case 1: case 2: - fdc->state = SEEKCOMPLETE; - break; - case 3: case 4: case 5: - fdc->state = STARTRECAL; - break; - case 6: - fdc->state = RESETCTLR; - break; - case 7: - break; - default: - fail: - { - dev_t sav_b_dev = bp->b_dev; - /* Trick diskerr */ - bp->b_dev = makedev(major(bp->b_dev), - (FDUNIT(minor(bp->b_dev))<<3)|RAW_PART); - diskerr(bp, "fd", "hard error", LOG_PRINTF, - fdc->fd->skip / DEV_BSIZE, - (struct disklabel *)NULL); - bp->b_dev = sav_b_dev; - if (fdc->flags & FDC_STAT_VALID) - { - printf( - " (ST0 %b ST1 %b ST2 %b cyl %u hd %u sec %u)\n", - fdc->status[0], NE7_ST0BITS, - fdc->status[1], NE7_ST1BITS, - fdc->status[2], NE7_ST2BITS, - fdc->status[3], fdc->status[4], - fdc->status[5]); - } - else - printf(" (No status)\n"); - } - bp->b_flags |= B_ERROR; - bp->b_error = EIO; - bp->b_resid += bp->b_bcount - fdc->fd->skip; - fdc->bp = NULL; - - /* Tell devstat we have finished with the transaction */ - devstat_end_transaction(&fdc->fd->device_stats, - bp->b_bcount - bp->b_resid, - DEVSTAT_TAG_NONE, - (bp->b_flags & B_READ) ? DEVSTAT_READ : - DEVSTAT_WRITE); - fdc->fd->skip = 0; - biodone(bp); - fdc->state = FINDWORK; - fdc->flags |= FDC_NEEDS_RESET; - fdc->fd = (fd_p) 0; - fdc->fdu = -1; - return (1); - } - fdc->retry++; - return (1); -} - -static int -fdformat(dev, finfo, p) - dev_t dev; - struct fd_formb *finfo; - struct proc *p; -{ - fdu_t fdu; - fd_p fd; - - struct buf *bp; - int rv = 0, s; - size_t fdblk; - - fdu = FDUNIT(minor(dev)); - fd = devclass_get_softc(fd_devclass, fdu); - fdblk = 128 << fd->ft->secsize; - - /* set up a buffer header for fdstrategy() */ - bp = (struct buf *)malloc(sizeof(struct buf), M_TEMP, M_NOWAIT); - if(bp == 0) - return ENOBUFS; - /* - * keep the process from being swapped - */ - PHOLD(p); - bzero((void *)bp, sizeof(struct buf)); - bp->b_flags = B_BUSY | B_PHYS | B_FORMAT; - - /* - * calculate a fake blkno, so fdstrategy() would initiate a - * seek to the requested cylinder - */ - bp->b_blkno = (finfo->cyl * (fd->ft->sectrac * fd->ft->heads) - + finfo->head * fd->ft->sectrac) * fdblk / DEV_BSIZE; - - bp->b_bcount = sizeof(struct fd_idfield_data) * finfo->fd_formb_nsecs; - bp->b_data = (caddr_t)finfo; - - /* now do the format */ - bp->b_dev = dev; - fdstrategy(bp); - - /* ...and wait for it to complete */ - s = splbio(); - while(!(bp->b_flags & B_DONE)) { - rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz); - if (rv == EWOULDBLOCK) - break; - } - splx(s); - - if (rv == EWOULDBLOCK) { - /* timed out */ - rv = EIO; - biodone(bp); - } - if (bp->b_flags & B_ERROR) - rv = bp->b_error; - /* - * allow the process to be swapped - */ - PRELE(p); - free(bp, M_TEMP); - return rv; -} - -/* - * TODO: don't allocate buffer on stack. - */ - -static int -fdioctl(dev, cmd, addr, flag, p) - dev_t dev; - u_long cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - fdu_t fdu = FDUNIT(minor(dev)); - fd_p fd = devclass_get_softc(fd_devclass, fdu); - size_t fdblk; - - struct fd_type *fdt; - struct disklabel *dl; - char buffer[DEV_BSIZE]; - int error = 0; - - fdblk = 128 << fd->ft->secsize; - - switch (cmd) { - case DIOCGDINFO: - bzero(buffer, sizeof (buffer)); - dl = (struct disklabel *)buffer; - dl->d_secsize = fdblk; - fdt = fd->ft; - dl->d_secpercyl = fdt->size / fdt->tracks; - dl->d_type = DTYPE_FLOPPY; - - if (readdisklabel(dkmodpart(dev, RAW_PART), fdstrategy, dl) - == NULL) - error = 0; - else - error = EINVAL; - - *(struct disklabel *)addr = *dl; - break; - - case DIOCSDINFO: - if ((flag & FWRITE) == 0) - error = EBADF; - break; - - case DIOCWLABEL: - if ((flag & FWRITE) == 0) - error = EBADF; - break; - - case DIOCWDINFO: - if ((flag & FWRITE) == 0) { - error = EBADF; - break; - } - - dl = (struct disklabel *)addr; - - if ((error = setdisklabel((struct disklabel *)buffer, dl, - (u_long)0)) != 0) - break; - - error = writedisklabel(dev, fdstrategy, - (struct disklabel *)buffer); - break; - case FD_FORM: - if ((flag & FWRITE) == 0) - error = EBADF; /* must be opened for writing */ - else if (((struct fd_formb *)addr)->format_version != - FD_FORMAT_VERSION) - error = EINVAL; /* wrong version of formatting prog */ - else - error = fdformat(dev, (struct fd_formb *)addr, p); - break; - - case FD_GTYPE: /* get drive type */ - *(struct fd_type *)addr = *fd->ft; - break; - - case FD_STYPE: /* set drive type */ - /* this is considered harmful; only allow for superuser */ - if (suser(p) != 0) - return EPERM; - *fd->ft = *(struct fd_type *)addr; - break; - - case FD_GOPTS: /* get drive options */ - *(int *)addr = fd->options; - break; - - case FD_SOPTS: /* set drive options */ - fd->options = *(int *)addr; - break; - - default: - error = ENOTTY; - break; - } - return (error); -} - -static device_method_t fdc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, fdc_probe), - DEVMETHOD(device_attach, fdc_attach), - DEVMETHOD(device_detach, bus_generic_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), - /* 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); - -static device_method_t fd_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, fd_probe), - DEVMETHOD(device_attach, fd_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX */ - DEVMETHOD(device_resume, bus_generic_resume), /* XXX */ - - { 0, 0 } -}; - -static driver_t fd_driver = { - "fd", - fd_methods, - sizeof(struct fd_data) -}; - -DEV_DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, CDEV_MAJOR, BDEV_MAJOR, - fd_cdevsw, 0, 0); - -#endif /* NFDC > 0 */ - -/* - * Hello emacs, these are the - * Local Variables: - * c-indent-level: 8 - * c-continued-statement-offset: 8 - * c-continued-brace-offset: 0 - * c-brace-offset: -8 - * c-brace-imaginary-offset: 0 - * c-argdecl-indent: 8 - * c-label-offset: -8 - * c++-hanging-braces: 1 - * c++-access-specifier-offset: -8 - * c++-empty-arglist-indent: 8 - * c++-friend-offset: 0 - * End: - */ diff --git a/sys/i386/isa/fdc.h b/sys/i386/isa/fdc.h deleted file mode 100644 index 83e291f98131e..0000000000000 --- a/sys/i386/isa/fdc.h +++ /dev/null @@ -1,95 +0,0 @@ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * 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. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id: fdc.h,v 1.13 1999/01/15 09:15:27 bde Exp $ - * - */ - -enum fdc_type -{ - FDC_NE765, FDC_I82077, FDC_NE72065, FDC_UNKNOWN = -1 -}; - - -/***********************************************************************\ -* Per controller structure. * -\***********************************************************************/ -struct fdc_data -{ - int fdcu; /* our unit number */ - int baseport; - int dmachan; - int flags; -#define FDC_ATTACHED 0x01 -#define FDC_HASFTAPE 0x02 -#define FDC_TAPE_BUSY 0x04 -#define FDC_STAT_VALID 0x08 -#define FDC_HAS_FIFO 0x10 -#define FDC_NEEDS_RESET 0x20 -#ifdef FDC_YE -#define FDC_PCMCIA 0x40 -#define FDC_UNLOADED 0x80 -#endif - struct fd_data *fd; - int fdu; /* the active drive */ - int 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 */ - struct buf_queue_head head; - struct buf *bp; /* active buffer */ - struct resource *res_ioport, *res_irq, *res_drq; - int rid_ioport, rid_irq, rid_drq; - void *fdc_intr; - struct device *fdc_dev; -}; - -/***********************************************************************\ -* Throughout this file the following conventions will be used: * -* fd is a pointer to the fd_data struct for the drive in question * -* fdc is a pointer to the fdc_data struct for the controller * -* fdu is the floppy drive unit number * -* fdcu is the floppy controller unit number * -* fdsu is the floppy drive unit number on that controller. (sub-unit) * -\***********************************************************************/ -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; - -#define FDUNIT(s) (((s)>>6)&03) -#define FDTYPE(s) ((s)&077) diff --git a/sys/i386/isa/fdreg.h b/sys/i386/isa/fdreg.h deleted file mode 100644 index 5ceb73f433014..0000000000000 --- a/sys/i386/isa/fdreg.h +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * Copyright (c) 1991 The Regents of the University of California. - * 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. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * from: @(#)fdreg.h 7.1 (Berkeley) 5/9/91 - * $Id$ - */ - -/* - * AT floppy controller registers and bitfields - */ - -/* uses NEC765 controller */ -#include <i386/isa/ic/nec765.h> - -/* registers */ -#define FDOUT 2 /* Digital Output Register (W) */ -#define FDO_FDSEL 0x03 /* floppy device select */ -#define FDO_FRST 0x04 /* floppy controller reset */ -#define FDO_FDMAEN 0x08 /* enable floppy DMA and Interrupt */ -#define FDO_MOEN0 0x10 /* motor enable drive 0 */ -#define FDO_MOEN1 0x20 /* motor enable drive 1 */ -#define FDO_MOEN2 0x40 /* motor enable drive 2 */ -#define FDO_MOEN3 0x80 /* motor enable drive 3 */ - -#define FDSTS 4 /* NEC 765 Main Status Register (R) */ -#define FDDATA 5 /* NEC 765 Data Register (R/W) */ -#define FDCTL 7 /* Control Register (W) */ - -#ifndef FDC_500KBPS -# define FDC_500KBPS 0x00 /* 500KBPS MFM drive transfer rate */ -# define FDC_300KBPS 0x01 /* 300KBPS MFM drive transfer rate */ -# define FDC_250KBPS 0x02 /* 250KBPS MFM drive transfer rate */ -# define FDC_125KBPS 0x03 /* 125KBPS FM drive transfer rate */ - /* for some controllers 1MPBS instead */ -#endif /* FDC_500KBPS */ - -#define FDIN 7 /* Digital Input Register (R) */ -#define FDI_DCHG 0x80 /* diskette has been changed */ - /* requires drive and motor being selected */ - /* is cleared by any step pulse to drive */ diff --git a/sys/i386/isa/ic/nec765.h b/sys/i386/isa/ic/nec765.h deleted file mode 100644 index 3a5561888e874..0000000000000 --- a/sys/i386/isa/ic/nec765.h +++ /dev/null @@ -1,142 +0,0 @@ -/*- - * Copyright (c) 1991 The Regents of the University of California. - * 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. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * from: @(#)nec765.h 7.1 (Berkeley) 5/9/91 - * $Id: nec765.h,v 1.6 1997/02/22 09:38:04 peter Exp $ - */ - -/* - * Nec 765 floppy disc controller definitions - */ - -/* Main status register */ -#define NE7_DAB 0x01 /* Diskette drive A is seeking, thus busy */ -#define NE7_DBB 0x02 /* Diskette drive B is seeking, thus busy */ -#define NE7_CB 0x10 /* Diskette Controller Busy */ -#define NE7_NDM 0x20 /* Diskette Controller in Non Dma Mode */ -#define NE7_DIO 0x40 /* Diskette Controller Data register I/O */ -#define NE7_RQM 0x80 /* Diskette Controller ReQuest for Master */ - -/* Status register ST0 */ -#define NE7_ST0BITS "\020\010invld\007abnrml\006seek_cmplt\005equ_chck\004drive_notrdy\003top_head" - -#define NE7_ST0_IC 0xc0 /* interrupt completion code */ - -#define NE7_ST0_IC_RC 0xc0 /* terminated due to ready changed, n/a */ -#define NE7_ST0_IC_IV 0x80 /* invalid command; must reset FDC */ -#define NE7_ST0_IC_AT 0x40 /* abnormal termination, check error stat */ -#define NE7_ST0_IC_NT 0x00 /* normal termination */ - -#define NE7_ST0_SE 0x20 /* seek end */ -#define NE7_ST0_EC 0x10 /* equipment check, recalibrated but no trk0 */ -#define NE7_ST0_NR 0x08 /* not ready (n/a) */ -#define NE7_ST0_HD 0x04 /* upper head selected */ -#define NE7_ST0_DR 0x03 /* drive code */ - -/* Status register ST1 */ -#define NE7_ST1BITS "\020\010end_of_cyl\006bad_crc\005data_overrun\003sec_not_fnd\002write_protect\001no_am" - -#define NE7_ST1_EN 0x80 /* end of cylinder, access past last record */ -#define NE7_ST1_DE 0x20 /* data error, CRC fail in ID or data */ -#define NE7_ST1_OR 0x10 /* DMA overrun, DMA failed to do i/o quickly */ -#define NE7_ST1_ND 0x04 /* no data, sector not found or CRC in ID f. */ -#define NE7_ST1_NW 0x02 /* not writeable, attempt to violate WP */ -#define NE7_ST1_MA 0x01 /* missing address mark (in ID or data field)*/ - -/* Status register ST2 */ -#define NE7_ST2BITS "\020\007ctrl_mrk\006bad_crc\005wrong_cyl\004scn_eq\003scn_not_fnd\002bad_cyl\001no_dam" - -#define NE7_ST2_CM 0x40 /* control mark; found deleted data */ -#define NE7_ST2_DD 0x20 /* data error in data field, CRC fail */ -#define NE7_ST2_WC 0x10 /* wrong cylinder, ID field mismatches cmd */ -#define NE7_ST2_SH 0x08 /* scan equal hit */ -#define NE7_ST2_SN 0x04 /* scan not satisfied */ -#define NE7_ST2_BC 0x02 /* bad cylinder, cylinder marked 0xff */ -#define NE7_ST2_MD 0x01 /* missing address mark in data field */ - -/* Status register ST3 */ -#define NE7_ST3BITS "\020\010fault\007write_protect\006drdy\005tk0\004two_side\003side_sel\002" - -#define NE7_ST3_FT 0x80 /* fault; PC: n/a */ -#define NE7_ST3_WP 0x40 /* write protected */ -#define NE7_ST3_RD 0x20 /* ready; PC: always true */ -#define NE7_ST3_T0 0x10 /* track 0 */ -#define NE7_ST3_TS 0x08 /* two-sided; PC: n/a */ -#define NE7_ST3_HD 0x04 /* upper head select */ -#define NE7_ST3_US 0x03 /* unit select */ - -/* Commands */ -/* - * the top three bits -- where appropriate -- are set as follows: - * - * 0x80 - MT multi-track; allow both sides to be handled in single cmd - * 0x40 - MFM modified frequency modulation; use MFM encoding - * 0x20 - SK skip; skip sectors marked as "deleted" - */ -#define NE7CMD_READTRK 0x42 /* read whole track */ -#define NE7CMD_SPECIFY 3 /* specify drive parameters - requires unit - parameters byte */ -#define NE7CMD_SENSED 4 /* sense drive - requires unit select byte */ -#define NE7CMD_WRITE 0xc5 /* write - requires eight additional bytes */ -#define NE7CMD_READ 0xe6 /* read - requires eight additional bytes */ -#define NE7CMD_RECAL 7 /* recalibrate drive - requires - unit select byte */ -#define NE7CMD_SENSEI 8 /* sense controller interrupt status */ -#define NE7CMD_WRITEDEL 0xc9 /* write deleted data */ -#define NE7CMD_READID 0x4a /* read ID field */ -#define NE7CMD_READDEL 0xec /* read deleted data */ -#define NE7CMD_FORMAT 0x4d /* format - requires five additional bytes */ -#define NE7CMD_SEEK 0x0f /* seek drive - requires unit select byte - and new cyl byte */ -#define NE7CMD_SCNEQU 0xf1 /* scan equal */ -#define NE7CMD_SCNLE 0xf9 /* scan less or equal */ -#define NE7CMD_SCNGE 0xfd /* scan greater or equal */ - -/* - * Enhanced controller commands: - */ -#define NE7CMD_VERSION 0x10 /* version (ok for all controllers) */ - -#define I8207X_CONFIGURE 0x13 /* configure enhanced features */ - -/* - * "specify" definitions - * - * acronyms (times are relative to a FDC clock of 8 MHz): - * srt - step rate; PC usually 3 ms - * hut - head unload time; PC usually maximum of 240 ms - * hlt - head load time; PC usually minimum of 2 ms - * nd - no DMA flag; PC usually not set (0) - */ - -#define NE7_SPEC_1(srt, hut) (((16 - (srt)) << 4) | (((hut) / 16))) -#define NE7_SPEC_2(hlt, nd) (((hlt) & 0xFE) | ((nd) & 1)) diff --git a/sys/i386/isa/rtc.h b/sys/i386/isa/rtc.h deleted file mode 100644 index ea187d9e186ea..0000000000000 --- a/sys/i386/isa/rtc.h +++ /dev/null @@ -1,117 +0,0 @@ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * William Jolitz. - * - * 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. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - * - * from: @(#)rtc.h 7.1 (Berkeley) 5/12/91 - * $Id: rtc.h,v 1.10 1997/02/22 09:37:03 peter Exp $ - */ - -#ifndef _I386_ISA_RTC_H_ -#define _I386_ISA_RTC_H_ 1 - -/* - * MC146818 RTC Register locations - */ - -#define RTC_SEC 0x00 /* seconds */ -#define RTC_SECALRM 0x01 /* seconds alarm */ -#define RTC_MIN 0x02 /* minutes */ -#define RTC_MINALRM 0x03 /* minutes alarm */ -#define RTC_HRS 0x04 /* hours */ -#define RTC_HRSALRM 0x05 /* hours alarm */ -#define RTC_WDAY 0x06 /* week day */ -#define RTC_DAY 0x07 /* day of month */ -#define RTC_MONTH 0x08 /* month of year */ -#define RTC_YEAR 0x09 /* month of year */ - -#define RTC_STATUSA 0x0a /* status register A */ -#define RTCSA_TUP 0x80 /* time update, don't look now */ -#define RTCSA_RESET 0x70 /* reset divider */ -#define RTCSA_DIVIDER 0x20 /* divider correct for 32768 Hz */ -#define RTCSA_8192 0x03 /* 8192 Hz interrupt */ -#define RTCSA_4096 0x04 -#define RTCSA_2048 0x05 -#define RTCSA_1024 0x06 /* default for profiling */ -#define RTCSA_PROF RTCSA_1024 -#define RTC_PROFRATE 1024 -#define RTCSA_512 0x07 -#define RTCSA_256 0x08 -#define RTCSA_128 0x09 -#define RTCSA_NOPROF RTCSA_128 -#define RTC_NOPROFRATE 128 -#define RTCSA_64 0x0a -#define RTCSA_32 0x0b /* 32 Hz interrupt */ - -#define RTC_STATUSB 0x0b /* status register B */ -#define RTCSB_DST 0x01 /* USA Daylight Savings Time enable */ -#define RTCSB_24HR 0x02 /* 0 = 12 hours, 1 = 24 hours */ -#define RTCSB_BCD 0x04 /* 0 = BCD, 1 = Binary coded time */ -#define RTCSB_SQWE 0x08 /* 1 = output sqare wave at SQW pin */ -#define RTCSB_UINTR 0x10 /* 1 = enable update-ended interrupt */ -#define RTCSB_AINTR 0x20 /* 1 = enable alarm interrupt */ -#define RTCSB_PINTR 0x40 /* 1 = enable periodic clock interrupt */ -#define RTCSB_HALT 0x80 /* stop clock updates */ - -#define RTC_INTR 0x0c /* status register C (R) interrupt source */ -#define RTCIR_UPDATE 0x10 /* update intr */ -#define RTCIR_ALARM 0x20 /* alarm intr */ -#define RTCIR_PERIOD 0x40 /* periodic intr */ -#define RTCIR_INT 0x80 /* interrupt output signal */ - -#define RTC_STATUSD 0x0d /* status register D (R) Lost Power */ -#define RTCSD_PWR 0x80 /* clock power OK */ - -#define RTC_DIAG 0x0e /* status register E - bios diagnostic */ -#define RTCDG_BITS "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time" - -#define RTC_RESET 0x0f /* status register F - reset code byte */ -#define RTCRS_RST 0x00 /* normal reset */ -#define RTCRS_LOAD 0x04 /* load system */ - -#define RTC_FDISKETTE 0x10 /* diskette drive type in upper/lower nibble */ -#define RTCFDT_NONE 0 /* none present */ -#define RTCFDT_360K 0x10 /* 360K */ -#define RTCFDT_12M 0x20 /* 1.2M */ -#define RTCFDT_720K 0x30 /* 720K */ -#define RTCFDT_144M 0x40 /* 1.44M */ -#define RTCFDT_288M_1 0x50 /* 2.88M, some BIOSes */ -#define RTCFDT_288M 0x60 /* 2.88M */ - -#define RTC_BASELO 0x15 /* low byte of basemem size */ -#define RTC_BASEHI 0x16 /* high byte of basemem size */ -#define RTC_EXTLO 0x17 /* low byte of extended mem size */ -#define RTC_EXTHI 0x18 /* low byte of extended mem size */ - -#define RTC_CENTURY 0x32 /* current century */ -#endif /* _I386_ISA_RTC_H_ */ diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index 64ef3b21c17ac..6b787b80b80b7 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.134 1999/05/28 14:08:59 bde Exp $ + * $Id: clock.c,v 1.135 1999/05/29 06:57:55 phk Exp $ */ /* @@ -84,7 +84,7 @@ #include <i386/isa/icu.h> #include <i386/isa/isa.h> -#include <i386/isa/rtc.h> +#include <isa/rtc.h> #include <i386/isa/timerreg.h> #include <i386/isa/intr_machdep.h> |
