aboutsummaryrefslogtreecommitdiff
path: root/sys/isa
diff options
context:
space:
mode:
Diffstat (limited to 'sys/isa')
-rw-r--r--sys/isa/atrtc.c1182
-rw-r--r--sys/isa/bt_isa.c311
-rw-r--r--sys/isa/fd.c2296
-rw-r--r--sys/isa/fdc.h91
-rw-r--r--sys/isa/fdreg.h69
-rw-r--r--sys/isa/ic/nec765.h142
-rw-r--r--sys/isa/joy.c300
-rw-r--r--sys/isa/ppc.c1794
-rw-r--r--sys/isa/ppcreg.h222
-rw-r--r--sys/isa/rtc.h117
10 files changed, 0 insertions, 6524 deletions
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c
deleted file mode 100644
index d9bca71ad7c1..000000000000
--- a/sys/isa/atrtc.c
+++ /dev/null
@@ -1,1182 +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 and Don Ahn.
- *
- * 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: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.128 1998/10/23 10:46:20 phk Exp $
- */
-
-/*
- * Routines to handle clock hardware.
- */
-
-/*
- * inittodr, settodr and support routines written
- * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>
- *
- * reintroduced and updated by Chris Stenton <chris@gnome.co.uk> 8/10/94
- */
-
-#include "opt_clock.h"
-#include "apm.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#ifndef SMP
-#include <sys/lock.h>
-#endif
-#include <sys/sysctl.h>
-
-#include <machine/clock.h>
-#ifdef CLK_CALIBRATION_LOOP
-#include <machine/cons.h>
-#endif
-#include <machine/cputypes.h>
-#include <machine/frame.h>
-#include <machine/ipl.h>
-#include <machine/limits.h>
-#include <machine/md_var.h>
-#if NAPM > 0
-#include <machine/apm_bios.h>
-#include <i386/apm/apm_setup.h>
-#endif
-#ifdef APIC_IO
-#include <machine/segments.h>
-#endif
-#if defined(SMP) || defined(APIC_IO)
-#include <machine/smp.h>
-#endif /* SMP || APIC_IO */
-#include <machine/specialreg.h>
-
-#include <i386/isa/icu.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/rtc.h>
-#include <i386/isa/timerreg.h>
-
-#include <sys/interrupt.h>
-
-#ifdef SMP
-#define disable_intr() CLOCK_DISABLE_INTR()
-#define enable_intr() CLOCK_ENABLE_INTR()
-
-#ifdef APIC_IO
-#include <i386/isa/intr_machdep.h>
-/* The interrupt triggered by the 8254 (timer) chip */
-int apic_8254_intr;
-static u_long read_intr_count __P((int vec));
-static void setup_8254_mixed_mode __P((void));
-#endif
-#endif /* SMP */
-
-/*
- * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
- * can use a simple formula for leap years.
- */
-#define LEAPYEAR(y) ((u_int)(y) % 4 == 0)
-#define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31)
-
-#define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
-
-/*
- * Time in timer cycles that it takes for microtime() to disable interrupts
- * and latch the count. microtime() currently uses "cli; outb ..." so it
- * normally takes less than 2 timer cycles. Add a few for cache misses.
- * Add a few more to allow for latency in bogus calls to microtime() with
- * interrupts already disabled.
- */
-#define TIMER0_LATCH_COUNT 20
-
-/*
- * Maximum frequency that we are willing to allow for timer0. Must be
- * low enough to guarantee that the timer interrupt handler returns
- * before the next timer interrupt.
- */
-#define TIMER0_MAX_FREQ 20000
-
-int adjkerntz; /* local offset from GMT in seconds */
-int disable_rtc_set; /* disable resettodr() if != 0 */
-u_int idelayed;
-int statclock_disable;
-u_int stat_imask = SWI_CLOCK_MASK;
-#ifndef TIMER_FREQ
-#define TIMER_FREQ 1193182
-#endif
-u_int timer_freq = TIMER_FREQ;
-int timer0_max_count;
-u_int tsc_freq;
-int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
-
-static int beeping = 0;
-static u_int clk_imask = HWI_MASK | SWI_MASK;
-static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
-static u_int hardclock_max_count;
-static u_int32_t i8254_lastcount;
-static u_int32_t i8254_offset;
-static int i8254_ticked;
-/*
- * XXX new_function and timer_func should not handle clockframes, but
- * timer_func currently needs to hold hardclock to handle the
- * timer0_state == 0 case. We should use register_intr()/unregister_intr()
- * to switch between clkintr() and a slightly different timerintr().
- */
-static void (*new_function) __P((struct clockframe *frame));
-static u_int new_rate;
-static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
-static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
-static u_int timer0_prescaler_count;
-
-/* Values for timerX_state: */
-#define RELEASED 0
-#define RELEASE_PENDING 1
-#define ACQUIRED 2
-#define ACQUIRE_PENDING 3
-
-static u_char timer0_state;
-static u_char timer2_state;
-static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
-static u_int tsc_present;
-
-static unsigned i8254_get_timecount __P((struct timecounter *tc));
-static unsigned tsc_get_timecount __P((struct timecounter *tc));
-static void set_timer_freq(u_int freq, int intr_freq);
-
-static struct timecounter tsc_timecounter = {
- tsc_get_timecount, /* get_timecount */
- 0, /* no poll_pps */
- ~0u, /* counter_mask */
- 0, /* frequency */
- "TSC" /* name */
-};
-
-SYSCTL_OPAQUE(_debug, OID_AUTO, tsc_timecounter, CTLFLAG_RD,
- &tsc_timecounter, sizeof(tsc_timecounter), "S,timecounter", "");
-
-static struct timecounter i8254_timecounter = {
- i8254_get_timecount, /* get_timecount */
- 0, /* no poll_pps */
- ~0u, /* counter_mask */
- 0, /* frequency */
- "i8254" /* name */
-};
-
-SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD,
- &i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", "");
-
-static void
-clkintr(struct clockframe frame)
-{
- if (timecounter->tc_get_timecount == i8254_get_timecount) {
- /*
- * Maintain i8254_offset and related variables. Optimize
- * the usual case where i8254 counter rollover has not been
- * detected in i8254_get_timecount() by pretending that we
- * read the counter when it rolled over. Otherwise, call
- * i8254_get_timecount() to do most of the work. The
- * hardware counter must be read to ensure monotonicity
- * despite multiple rollovers and misbehaving hardware.
- */
- (disable_intr)(); /* XXX avoid clock locking */
- if (i8254_ticked) {
- i8254_get_timecount(NULL);
- i8254_ticked = 0;
- } else {
- i8254_offset += timer0_max_count;
- i8254_lastcount = 0;
- }
- (enable_intr)(); /* XXX avoid clock locking */
- }
- timer_func(&frame);
- switch (timer0_state) {
-
- case RELEASED:
- setdelayed();
- break;
-
- case ACQUIRED:
- if ((timer0_prescaler_count += timer0_max_count)
- >= hardclock_max_count) {
- timer0_prescaler_count -= hardclock_max_count;
- hardclock(&frame);
- setdelayed();
- }
- break;
-
- case ACQUIRE_PENDING:
- setdelayed();
- timer0_max_count = TIMER_DIV(new_rate);
- disable_intr();
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, timer0_max_count & 0xff);
- outb(TIMER_CNTR0, timer0_max_count >> 8);
- enable_intr();
- timer0_prescaler_count = 0;
- timer_func = new_function;
- timer0_state = ACQUIRED;
- break;
-
- case RELEASE_PENDING:
- if ((timer0_prescaler_count += timer0_max_count)
- >= hardclock_max_count) {
- timer0_prescaler_count -= hardclock_max_count;
-#ifdef FIXME
- /*
- * XXX: This magic doesn't work, but It shouldn't be
- * needed now anyway since we will not be able to
- * aquire the i8254 if it is used for timecounting.
- */
- /*
- * See microtime.s for this magic.
- */
- time.tv_usec += (27465 * timer0_prescaler_count) >> 15;
- if (time.tv_usec >= 1000000)
- time.tv_usec -= 1000000;
-#endif
- hardclock(&frame);
- setdelayed();
- timer0_max_count = hardclock_max_count;
- disable_intr();
- outb(TIMER_MODE,
- TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, timer0_max_count & 0xff);
- outb(TIMER_CNTR0, timer0_max_count >> 8);
- enable_intr();
- timer0_prescaler_count = 0;
- timer_func = hardclock;
- timer0_state = RELEASED;
- }
- break;
- }
-}
-
-/*
- * The acquire and release functions must be called at ipl >= splclock().
- */
-int
-acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
-{
- static int old_rate;
-
- if (rate <= 0 || rate > TIMER0_MAX_FREQ)
- return (-1);
- if (strcmp(timecounter->tc_name, "i8254") == 0)
- return (-1);
- switch (timer0_state) {
-
- case RELEASED:
- timer0_state = ACQUIRE_PENDING;
- break;
-
- case RELEASE_PENDING:
- if (rate != old_rate)
- return (-1);
- /*
- * The timer has been released recently, but is being
- * re-acquired before the release completed. In this
- * case, we simply reclaim it as if it had not been
- * released at all.
- */
- timer0_state = ACQUIRED;
- break;
-
- default:
- return (-1); /* busy */
- }
- new_function = function;
- old_rate = new_rate = rate;
- return (0);
-}
-
-int
-acquire_timer2(int mode)
-{
-
- if (timer2_state != RELEASED)
- return (-1);
- timer2_state = ACQUIRED;
-
- /*
- * This access to the timer registers is as atomic as possible
- * because it is a single instruction. We could do better if we
- * knew the rate. Use of splclock() limits glitches to 10-100us,
- * and this is probably good enough for timer2, so we aren't as
- * careful with it as with timer0.
- */
- outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
-
- return (0);
-}
-
-int
-release_timer0()
-{
- switch (timer0_state) {
-
- case ACQUIRED:
- timer0_state = RELEASE_PENDING;
- break;
-
- case ACQUIRE_PENDING:
- /* Nothing happened yet, release quickly. */
- timer0_state = RELEASED;
- break;
-
- default:
- return (-1);
- }
- return (0);
-}
-
-int
-release_timer2()
-{
-
- if (timer2_state != ACQUIRED)
- return (-1);
- timer2_state = RELEASED;
- outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
- return (0);
-}
-
-/*
- * This routine receives statistical clock interrupts from the RTC.
- * As explained above, these occur at 128 interrupts per second.
- * When profiling, we receive interrupts at a rate of 1024 Hz.
- *
- * This does not actually add as much overhead as it sounds, because
- * when the statistical clock is active, the hardclock driver no longer
- * needs to keep (inaccurate) statistics on its own. This decouples
- * statistics gathering from scheduling interrupts.
- *
- * The RTC chip requires that we read status register C (RTC_INTR)
- * to acknowledge an interrupt, before it will generate the next one.
- * Under high interrupt load, rtcintr() can be indefinitely delayed and
- * the clock can tick immediately after the read from RTC_INTR. In this
- * case, the mc146818A interrupt signal will not drop for long enough
- * to register with the 8259 PIC. If an interrupt is missed, the stat
- * clock will halt, considerably degrading system performance. This is
- * why we use 'while' rather than a more straightforward 'if' below.
- * Stat clock ticks can still be lost, causing minor loss of accuracy
- * in the statistics, but the stat clock will no longer stop.
- */
-static void
-rtcintr(struct clockframe frame)
-{
- while (rtcin(RTC_INTR) & RTCIR_PERIOD)
- statclock(&frame);
-}
-
-#include "opt_ddb.h"
-#ifdef DDB
-#include <ddb/ddb.h>
-
-DB_SHOW_COMMAND(rtc, rtc)
-{
- printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n",
- rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY),
- rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC),
- rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR));
-}
-#endif /* DDB */
-
-static int
-getit(void)
-{
- u_long ef;
- int high, low;
-
- ef = read_eflags();
- disable_intr();
-
- /* Select timer0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
-
- low = inb(TIMER_CNTR0);
- high = inb(TIMER_CNTR0);
-
- CLOCK_UNLOCK();
- write_eflags(ef);
- return ((high << 8) | low);
-}
-
-/*
- * Wait "n" microseconds.
- * Relies on timer 1 counting down from (timer_freq / hz)
- * Note: timer had better have been programmed before this is first used!
- */
-void
-DELAY(int n)
-{
- int delta, prev_tick, tick, ticks_left;
-
-#ifdef DELAYDEBUG
- int getit_calls = 1;
- int n1;
- static int state = 0;
-
- if (state == 0) {
- state = 1;
- for (n1 = 1; n1 <= 10000000; n1 *= 10)
- DELAY(n1);
- state = 2;
- }
- if (state == 1)
- printf("DELAY(%d)...", n);
-#endif
- /*
- * Guard against the timer being uninitialized if we are called
- * early for console i/o.
- */
- if (timer0_max_count == 0)
- set_timer_freq(timer_freq, hz);
-
- /*
- * Read the counter first, so that the rest of the setup overhead is
- * counted. Guess the initial overhead is 20 usec (on most systems it
- * takes about 1.5 usec for each of the i/o's in getit(). The loop
- * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The
- * multiplications and divisions to scale the count take a while).
- */
- prev_tick = getit();
- n -= 0; /* XXX actually guess no initial overhead */
- /*
- * Calculate (n * (timer_freq / 1e6)) without using floating point
- * and without any avoidable overflows.
- */
- if (n <= 0)
- ticks_left = 0;
- else if (n < 256)
- /*
- * Use fixed point to avoid a slow division by 1000000.
- * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
- * 2^15 is the first power of 2 that gives exact results
- * for n between 0 and 256.
- */
- ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
- else
- /*
- * Don't bother using fixed point, although gcc-2.7.2
- * generates particularly poor code for the long long
- * division, since even the slow way will complete long
- * before the delay is up (unless we're interrupted).
- */
- ticks_left = ((u_int)n * (long long)timer_freq + 999999)
- / 1000000;
-
- while (ticks_left > 0) {
- tick = getit();
-#ifdef DELAYDEBUG
- ++getit_calls;
-#endif
- delta = prev_tick - tick;
- prev_tick = tick;
- if (delta < 0) {
- delta += timer0_max_count;
- /*
- * Guard against timer0_max_count being wrong.
- * This shouldn't happen in normal operation,
- * but it may happen if set_timer_freq() is
- * traced.
- */
- if (delta < 0)
- delta = 0;
- }
- ticks_left -= delta;
- }
-#ifdef DELAYDEBUG
- if (state == 1)
- printf(" %d calls to getit() at %d usec each\n",
- getit_calls, (n + 5) / getit_calls);
-#endif
-}
-
-static void
-sysbeepstop(void *chan)
-{
- outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */
- release_timer2();
- beeping = 0;
-}
-
-int
-sysbeep(int pitch, int period)
-{
- int x = splclock();
-
- if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
- if (!beeping) {
- /* Something else owns it. */
- splx(x);
- return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
- }
- disable_intr();
- outb(TIMER_CNTR2, pitch);
- outb(TIMER_CNTR2, (pitch>>8));
- enable_intr();
- if (!beeping) {
- /* enable counter2 output to speaker */
- outb(IO_PPI, inb(IO_PPI) | 3);
- beeping = period;
- timeout(sysbeepstop, (void *)NULL, period);
- }
- splx(x);
- return (0);
-}
-
-/*
- * RTC support routines
- */
-
-int
-rtcin(reg)
- int reg;
-{
- u_char val;
-
- outb(IO_RTC, reg);
- inb(0x84);
- val = inb(IO_RTC + 1);
- inb(0x84);
- return (val);
-}
-
-static __inline void
-writertc(u_char reg, u_char val)
-{
- inb(0x84);
- outb(IO_RTC, reg);
- inb(0x84);
- outb(IO_RTC + 1, val);
- inb(0x84); /* XXX work around wrong order in rtcin() */
-}
-
-static __inline int
-readrtc(int port)
-{
- return(bcd2bin(rtcin(port)));
-}
-
-static u_int
-calibrate_clocks(void)
-{
- u_int count, prev_count, tot_count;
- int sec, start_sec, timeout;
-
- if (bootverbose)
- printf("Calibrating clock(s) ... ");
- if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
- goto fail;
- timeout = 100000000;
-
- /* Read the mc146818A seconds counter. */
- for (;;) {
- if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
- sec = rtcin(RTC_SEC);
- break;
- }
- if (--timeout == 0)
- goto fail;
- }
-
- /* Wait for the mC146818A seconds counter to change. */
- start_sec = sec;
- for (;;) {
- if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
- sec = rtcin(RTC_SEC);
- if (sec != start_sec)
- break;
- }
- if (--timeout == 0)
- goto fail;
- }
-
- /* Start keeping track of the i8254 counter. */
- prev_count = getit();
- if (prev_count == 0 || prev_count > timer0_max_count)
- goto fail;
- tot_count = 0;
-
- if (tsc_present)
- wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */
-
- /*
- * Wait for the mc146818A seconds counter to change. Read the i8254
- * counter for each iteration since this is convenient and only
- * costs a few usec of inaccuracy. The timing of the final reads
- * of the counters almost matches the timing of the initial reads,
- * so the main cause of inaccuracy is the varying latency from
- * inside getit() or rtcin(RTC_STATUSA) to the beginning of the
- * rtcin(RTC_SEC) that returns a changed seconds count. The
- * maximum inaccuracy from this cause is < 10 usec on 486's.
- */
- start_sec = sec;
- for (;;) {
- if (!(rtcin(RTC_STATUSA) & RTCSA_TUP))
- sec = rtcin(RTC_SEC);
- count = getit();
- if (count == 0 || count > timer0_max_count)
- goto fail;
- if (count > prev_count)
- tot_count += prev_count - (count - timer0_max_count);
- else
- tot_count += prev_count - count;
- prev_count = count;
- if (sec != start_sec)
- break;
- if (--timeout == 0)
- goto fail;
- }
-
- /*
- * Read the cpu cycle counter. The timing considerations are
- * similar to those for the i8254 clock.
- */
- if (tsc_present)
- tsc_freq = rdtsc();
-
- if (bootverbose) {
- if (tsc_present)
- printf("TSC clock: %u Hz, ", tsc_freq);
- printf("i8254 clock: %u Hz\n", tot_count);
- }
- return (tot_count);
-
-fail:
- if (bootverbose)
- printf("failed, using default i8254 clock of %u Hz\n",
- timer_freq);
- return (timer_freq);
-}
-
-static void
-set_timer_freq(u_int freq, int intr_freq)
-{
- u_long ef;
- int new_timer0_max_count;
-
- ef = read_eflags();
- disable_intr();
- timer_freq = freq;
- new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
- if (new_timer0_max_count != timer0_max_count) {
- timer0_max_count = new_timer0_max_count;
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
- outb(TIMER_CNTR0, timer0_max_count & 0xff);
- outb(TIMER_CNTR0, timer0_max_count >> 8);
- }
- CLOCK_UNLOCK();
- write_eflags(ef);
-}
-
-/*
- * Initialize 8254 timer 0 early so that it can be used in DELAY().
- * XXX initialization of other timers is unintentionally left blank.
- */
-void
-startrtclock()
-{
- u_int delta, freq;
-
- if (cpu_feature & CPUID_TSC)
- tsc_present = 1;
- else
- tsc_present = 0;
-
- writertc(RTC_STATUSA, rtc_statusa);
- writertc(RTC_STATUSB, RTCSB_24HR);
-
- set_timer_freq(timer_freq, hz);
- freq = calibrate_clocks();
-#ifdef CLK_CALIBRATION_LOOP
- if (bootverbose) {
- printf(
- "Press a key on the console to abort clock calibration\n");
- while (cncheckc() == -1)
- calibrate_clocks();
- }
-#endif
-
- /*
- * Use the calibrated i8254 frequency if it seems reasonable.
- * Otherwise use the default, and don't use the calibrated i586
- * frequency.
- */
- delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
- if (delta < timer_freq / 100) {
-#ifndef CLK_USE_I8254_CALIBRATION
- if (bootverbose)
- printf(
-"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
- freq = timer_freq;
-#endif
- timer_freq = freq;
- } else {
- if (bootverbose)
- printf(
- "%d Hz differs from default of %d Hz by more than 1%%\n",
- freq, timer_freq);
- tsc_freq = 0;
- }
-
- set_timer_freq(timer_freq, hz);
- i8254_timecounter.tc_frequency = timer_freq;
- init_timecounter(&i8254_timecounter);
-
-#ifndef CLK_USE_TSC_CALIBRATION
- if (tsc_freq != 0) {
- if (bootverbose)
- printf(
-"CLK_USE_TSC_CALIBRATION not specified - using old calibration method\n");
- tsc_freq = 0;
- }
-#endif
- if (tsc_present && tsc_freq == 0) {
- /*
- * Calibration of the i586 clock relative to the mc146818A
- * clock failed. Do a less accurate calibration relative
- * to the i8254 clock.
- */
- wrmsr(0x10, 0LL); /* XXX */
- DELAY(1000000);
- tsc_freq = rdtsc();
-#ifdef CLK_USE_TSC_CALIBRATION
- if (bootverbose)
- printf("TSC clock: %u Hz (Method B)\n", tsc_freq);
-#endif
- }
-
-#if !defined(SMP)
- /*
- * We can not use the TSC in SMP mode, until we figure out a
- * cheap (impossible), reliable and precise (yeah right!) way
- * to synchronize the TSCs of all the CPUs.
- * Curse Intel for leaving the counter out of the I/O APIC.
- */
-
-#if NAPM > 0
- /*
- * We can not use the TSC if we found an APM bios. Too many
- * of them lie about their ability&intention to fiddle the CPU
- * clock for us to rely on this. Precise timekeeping on an
- * APM'ed machine is at best a fools pursuit anyway, since
- * any and all of the time spent in various SMM code can't
- * be reliably accounted for. Reading the RTC is your only
- * source of reliable time info. The i8254 looses too of course
- * but we need to have some kind of time...
- */
- if (apm_version != APMINI_CANTFIND)
- return;
-#endif /* NAPM > 0 */
-
- if (tsc_present && tsc_freq != 0) {
- tsc_timecounter.tc_frequency = tsc_freq;
- init_timecounter(&tsc_timecounter);
- }
-
-#endif /* !defined(SMP) */
-}
-
-/*
- * Initialize the time of day register, based on the time base which is, e.g.
- * from a filesystem.
- */
-void
-inittodr(time_t base)
-{
- unsigned long sec, days;
- int yd;
- int year, month;
- int y, m, s;
- struct timespec ts;
-
- if (base) {
- s = splclock();
- ts.tv_sec = base;
- ts.tv_nsec = 0;
- set_timecounter(&ts);
- splx(s);
- }
-
- /* Look if we have a RTC present and the time is valid */
- if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
- goto wrong_time;
-
- /* wait for time update to complete */
- /* If RTCSA_TUP is zero, we have at least 244us before next update */
- while (rtcin(RTC_STATUSA) & RTCSA_TUP);
-
- days = 0;
-#ifdef USE_RTC_CENTURY
- year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100;
-#else
- year = readrtc(RTC_YEAR) + 1900;
- if (year < 1970)
- year += 100;
-#endif
- if (year < 1970)
- goto wrong_time;
- month = readrtc(RTC_MONTH);
- for (m = 1; m < month; m++)
- days += daysinmonth[m-1];
- if ((month > 2) && LEAPYEAR(year))
- days ++;
- days += readrtc(RTC_DAY) - 1;
- yd = days;
- for (y = 1970; y < year; y++)
- days += DAYSPERYEAR + LEAPYEAR(y);
- sec = ((( days * 24 +
- readrtc(RTC_HRS)) * 60 +
- readrtc(RTC_MIN)) * 60 +
- readrtc(RTC_SEC));
- /* sec now contains the number of seconds, since Jan 1 1970,
- in the local time zone */
-
- sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
-
- y = time_second - sec;
- if (y <= -2 || y >= 2) {
- /* badly off, adjust it */
- s = splclock();
- ts.tv_sec = sec;
- ts.tv_nsec = 0;
- set_timecounter(&ts);
- splx(s);
- }
- return;
-
-wrong_time:
- printf("Invalid time in real time clock.\n");
- printf("Check and reset the date immediately!\n");
-}
-
-/*
- * Write system time back to RTC
- */
-void
-resettodr()
-{
- unsigned long tm;
- int y, m, s;
-
- if (disable_rtc_set)
- return;
-
- s = splclock();
- tm = time_second;
- splx(s);
-
- /* Disable RTC updates and interrupts. */
- writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
-
- /* Calculate local time to put in RTC */
-
- tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
-
- writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */
- writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */
- writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24; /* Write back Hours */
-
- /* We have now the days since 01-01-1970 in tm */
- writertc(RTC_WDAY, (tm+4)%7); /* Write back Weekday */
- for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
- tm >= m;
- y++, m = DAYSPERYEAR + LEAPYEAR(y))
- tm -= m;
-
- /* Now we have the years in y and the day-of-the-year in tm */
- writertc(RTC_YEAR, bin2bcd(y%100)); /* Write back Year */
-#ifdef USE_RTC_CENTURY
- writertc(RTC_CENTURY, bin2bcd(y/100)); /* ... and Century */
-#endif
- for (m = 0; ; m++) {
- int ml;
-
- ml = daysinmonth[m];
- if (m == 1 && LEAPYEAR(y))
- ml++;
- if (tm < ml)
- break;
- tm -= ml;
- }
-
- writertc(RTC_MONTH, bin2bcd(m + 1)); /* Write back Month */
- writertc(RTC_DAY, bin2bcd(tm + 1)); /* Write back Month Day */
-
- /* Reenable RTC updates and interrupts. */
- writertc(RTC_STATUSB, rtc_statusb);
-}
-
-
-/*
- * Start both clocks running.
- */
-void
-cpu_initclocks()
-{
- int diag;
-#ifdef APIC_IO
- int apic_8254_trial;
-#endif /* APIC_IO */
-
- if (statclock_disable) {
- /*
- * The stat interrupt mask is different without the
- * statistics clock. Also, don't set the interrupt
- * flag which would normally cause the RTC to generate
- * interrupts.
- */
- stat_imask = HWI_MASK | SWI_MASK;
- rtc_statusb = RTCSB_24HR;
- } else {
- /* Setting stathz to nonzero early helps avoid races. */
- stathz = RTC_NOPROFRATE;
- profhz = RTC_PROFRATE;
- }
-
- /* Finish initializing 8253 timer 0. */
-#ifdef APIC_IO
-
- apic_8254_intr = isa_apic_irq(0);
- apic_8254_trial = 0;
- if (apic_8254_intr >= 0 ) {
- if (apic_int_type(0, 0) == 3)
- apic_8254_trial = 1;
- } else {
- /* look for ExtInt on pin 0 */
- if (apic_int_type(0, 0) == 3) {
- apic_8254_intr = 0;
- setup_8254_mixed_mode();
- } else
- panic("APIC_IO: Cannot route 8254 interrupt to CPU");
- }
-
- register_intr(/* irq */ apic_8254_intr, /* XXX id */ 0, /* flags */ 0,
- /* XXX */ (inthand2_t *)clkintr, &clk_imask,
- /* unit */ 0);
- INTREN(1 << apic_8254_intr);
-
-#else /* APIC_IO */
-
- register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0,
- /* XXX */ (inthand2_t *)clkintr, &clk_imask,
- /* unit */ 0);
- INTREN(IRQ0);
-
-#endif /* APIC_IO */
-
- /* Initialize RTC. */
- writertc(RTC_STATUSA, rtc_statusa);
- writertc(RTC_STATUSB, RTCSB_24HR);
-
- /* Don't bother enabling the statistics clock. */
- if (statclock_disable)
- return;
- diag = rtcin(RTC_DIAG);
- if (diag != 0)
- printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
-
-#ifdef APIC_IO
- if (isa_apic_irq(8) != 8)
- panic("APIC RTC != 8");
-#endif /* APIC_IO */
-
- register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
- /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
- /* unit */ 0);
-
-#ifdef APIC_IO
- INTREN(APIC_IRQ8);
-#else
- INTREN(IRQ8);
-#endif /* APIC_IO */
-
- writertc(RTC_STATUSB, rtc_statusb);
-
-#ifdef APIC_IO
- if (apic_8254_trial) {
-
- printf("APIC_IO: Testing 8254 interrupt delivery\n");
- while (read_intr_count(8) < 6)
- ; /* nothing */
- if (read_intr_count(apic_8254_intr) < 3) {
- /*
- * The MP table is broken.
- * The 8254 was not connected to the specified pin
- * on the IO APIC.
- * Workaround: Limited variant of mixed mode.
- */
- INTRDIS(1 << apic_8254_intr);
- unregister_intr(apic_8254_intr,
- /* XXX */ (inthand2_t *) clkintr);
- printf("APIC_IO: Broken MP table detected: "
- "8254 is not connected to IO APIC int pin %d\n",
- apic_8254_intr);
-
- apic_8254_intr = 0;
- setup_8254_mixed_mode();
- register_intr(/* irq */ apic_8254_intr, /* XXX id */ 0, /* flags */ 0,
- /* XXX */ (inthand2_t *)clkintr, &clk_imask,
- /* unit */ 0);
- INTREN(1 << apic_8254_intr);
- }
-
- }
- if (apic_8254_intr)
- printf("APIC_IO: routing 8254 via pin %d\n",apic_8254_intr);
- else
- printf("APIC_IO: routing 8254 via 8259 on pin 0\n");
-#endif
-
-}
-
-#ifdef APIC_IO
-static u_long
-read_intr_count(int vec)
-{
- u_long *up;
- up = intr_countp[vec];
- if (up)
- return *up;
- return 0UL;
-}
-
-static void
-setup_8254_mixed_mode()
-{
- /*
- * Allow 8254 timer to INTerrupt 8259:
- * re-initialize master 8259:
- * reset; prog 4 bytes, single ICU, edge triggered
- */
- outb(IO_ICU1, 0x13);
- outb(IO_ICU1 + 1, NRSVIDT); /* start vector (unused) */
- outb(IO_ICU1 + 1, 0x00); /* ignore slave */
- outb(IO_ICU1 + 1, 0x03); /* auto EOI, 8086 */
- outb(IO_ICU1 + 1, 0xfe); /* unmask INT0 */
-
- /* program IO APIC for type 3 INT on INT0 */
- if (ext_int_setup(0, 0) < 0)
- panic("8254 redirect via APIC pin0 impossible!");
-}
-#endif
-
-void
-setstatclockrate(int newhz)
-{
- if (newhz == RTC_PROFRATE)
- rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
- else
- rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
- writertc(RTC_STATUSA, rtc_statusa);
-}
-
-static int
-sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
-{
- int error;
- u_int freq;
-
- /*
- * Use `i8254' instead of `timer' in external names because `timer'
- * is is too generic. Should use it everywhere.
- */
- freq = timer_freq;
- error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
- if (error == 0 && req->newptr != NULL) {
- if (timer0_state != RELEASED)
- return (EBUSY); /* too much trouble to handle */
- set_timer_freq(freq, hz);
- i8254_timecounter.tc_frequency = freq;
- }
- return (error);
-}
-
-SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
- 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
-
-static int
-sysctl_machdep_tsc_freq SYSCTL_HANDLER_ARGS
-{
- int error;
- u_int freq;
-
- if (!tsc_present)
- return (EOPNOTSUPP);
- freq = tsc_freq;
- error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
- if (error == 0 && req->newptr != NULL) {
- tsc_freq = freq;
- tsc_timecounter.tc_frequency = tsc_freq;
- }
- return (error);
-}
-
-SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_INT | CTLFLAG_RW,
- 0, sizeof(u_int), sysctl_machdep_tsc_freq, "I", "");
-
-static unsigned
-i8254_get_timecount(struct timecounter *tc)
-{
- u_int count;
- u_long ef;
- u_int high, low;
-
- ef = read_eflags();
- disable_intr();
-
- /* Select timer0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
-
- low = inb(TIMER_CNTR0);
- high = inb(TIMER_CNTR0);
-
- count = hardclock_max_count - ((high << 8) | low);
- if (count < i8254_lastcount) {
- i8254_ticked = 1;
- i8254_offset += hardclock_max_count;
- }
-
- i8254_lastcount = count;
- count += i8254_offset;
- CLOCK_UNLOCK();
- write_eflags(ef);
- return (count);
-}
-
-static unsigned
-tsc_get_timecount(struct timecounter *tc)
-{
- return (rdtsc());
-}
diff --git a/sys/isa/bt_isa.c b/sys/isa/bt_isa.c
deleted file mode 100644
index f646f85bf158..000000000000
--- a/sys/isa/bt_isa.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Product specific probe and attach routines for:
- * Buslogic BT-54X and BT-445 cards
- *
- * Copyright (c) 1998 Justin T. Gibbs
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * 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.
- *
- * $Id: bt_isa.c,v 1.4 1998/10/12 18:53:33 imp Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <machine/bus_pio.h>
-#include <machine/bus.h>
-
-#include <i386/isa/isa_device.h>
-#include <dev/buslogic/btreg.h>
-
-#include <cam/scsi/scsi_all.h>
-
-static int bt_isa_probe __P((struct isa_device *dev));
-static int bt_isa_attach __P((struct isa_device *dev));
-static void bt_isa_intr __P((void *unit));
-
-static bus_dma_filter_t btvlbouncefilter;
-static bus_dmamap_callback_t btmapsensebuffers;
-
-struct isa_driver btdriver =
-{
- bt_isa_probe,
- bt_isa_attach,
- "bt"
-};
-
-/*
- * Check if the device can be found at the port given
- * and if so, set it up ready for further work
- * as an argument, takes the isa_device structure from
- * autoconf.c
- */
-static int
-bt_isa_probe(dev)
- struct isa_device *dev;
-{
- /*
- * find unit and check we have that many defined
- */
- struct bt_softc *bt;
- int port_index;
- int max_port_index;
-
- /*
- * We ignore the unit number assigned by config to allow
- * consistant numbering between PCI/EISA/ISA devices.
- * This is a total kludge until we have a configuration
- * manager.
- */
- dev->id_unit = bt_unit;
-
- bt = NULL;
- port_index = 0;
- max_port_index = BT_NUM_ISAPORTS - 1;
- /*
- * Bound our board search if the user has
- * specified an exact port.
- */
- bt_find_probe_range(dev->id_iobase, &port_index, &max_port_index);
-
- if (port_index < 0)
- return 0;
-
- /* Attempt to find an adapter */
- for (;port_index <= max_port_index; port_index++) {
- config_data_t config_data;
- u_int ioport;
- int error;
-
- ioport = bt_iop_from_bio(port_index);
-
- /*
- * Ensure this port has not already been claimed already
- * by a PCI, EISA or ISA adapter.
- */
- if (bt_check_probed_iop(ioport) != 0)
- continue;
- dev->id_iobase = ioport;
- if (haveseen_isadev(dev, CC_IOADDR | CC_QUIET))
- continue;
-
- /* Allocate a softc for use during probing */
- bt = bt_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport);
-
- if (bt == NULL)
- break;
-
- /* We're going to attempt to probe it now, so mark it probed */
- bt_mark_probed_bio(port_index);
-
- /* See if there is really a card present */
- if (bt_probe(bt) || bt_fetch_adapter_info(bt)) {
- bt_free(bt);
- continue;
- }
-
- /*
- * Determine our IRQ, and DMA settings and
- * export them to the configuration system.
- */
- error = bt_cmd(bt, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
- (u_int8_t*)&config_data, sizeof(config_data),
- DEFAULT_CMD_TIMEOUT);
- if (error != 0) {
- printf("bt_isa_probe: Could not determine IRQ or DMA "
- "settings for adapter at 0x%x. Failing probe\n",
- ioport);
- bt_free(bt);
- continue;
- }
-
- if (bt->model[0] == '5') {
- /* DMA settings only make sense for ISA cards */
- switch (config_data.dma_chan) {
- case DMA_CHAN_5:
- dev->id_drq = 5;
- break;
- case DMA_CHAN_6:
- dev->id_drq = 6;
- break;
- case DMA_CHAN_7:
- dev->id_drq = 7;
- break;
- default:
- printf("bt_isa_probe: Invalid DMA setting "
- "detected for adapter at 0x%x. "
- "Failing probe\n", ioport);
- return (0);
- }
- } else {
- /* VL DMA */
- dev->id_drq = -1;
- }
- dev->id_irq = (config_data.irq << 9);
- dev->id_intr = bt_isa_intr;
-
- bt_unit++;
- return (BT_NREGS);
- }
-
- return (0);
-}
-
-/*
- * Attach all the sub-devices we can find
- */
-static int
-bt_isa_attach(dev)
- struct isa_device *dev;
-{
- struct bt_softc *bt;
- bus_dma_filter_t *filter;
- void *filter_arg;
- bus_addr_t lowaddr;
-
- bt = bt_softcs[dev->id_unit];
- if (dev->id_drq != -1)
- isa_dmacascade(dev->id_drq);
-
- /* Allocate our parent dmatag */
- filter = NULL;
- filter_arg = NULL;
- lowaddr = BUS_SPACE_MAXADDR_24BIT;
- if (bt->model[0] == '4') {
- /*
- * This is a VL adapter. Typically, VL devices have access
- * to the full 32bit address space. On BT-445S adapters
- * prior to revision E, there is a hardware bug that causes
- * corruption of transfers to/from addresses in the range of
- * the BIOS modulo 16MB. The only properly functioning
- * BT-445S Host Adapters have firmware version 3.37.
- * If we encounter one of these adapters and the BIOS is
- * installed, install a filter function for our bus_dma_map
- * that will catch these accesses and bounce them to a safe
- * region of memory.
- */
- if (bt->bios_addr != 0
- && strcmp(bt->model, "445S") == 0
- && strcmp(bt->firmware_ver, "3.37") < 0) {
- filter = btvlbouncefilter;
- filter_arg = bt;
- } else {
- lowaddr = BUS_SPACE_MAXADDR_32BIT;
- }
- }
-
- /* XXX Should be a child of the ISA or VL bus dma tag */
- if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/0, /*boundary*/0,
- lowaddr, /*highaddr*/BUS_SPACE_MAXADDR,
- filter, filter_arg,
- /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
- /*nsegments*/BUS_SPACE_UNRESTRICTED,
- /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/0, &bt->parent_dmat) != 0) {
- bt_free(bt);
- return (-1);
- }
-
- if (bt_init(bt)) {
- bt_free(bt);
- return (-1);
- }
-
- if (lowaddr != BUS_SPACE_MAXADDR_32BIT) {
- /* DMA tag for our sense buffers */
- if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0,
- /*boundary*/0,
- /*lowaddr*/BUS_SPACE_MAXADDR,
- /*highaddr*/BUS_SPACE_MAXADDR,
- /*filter*/NULL, /*filterarg*/NULL,
- bt->max_ccbs
- * sizeof(struct scsi_sense_data),
- /*nsegments*/1,
- /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/0, &bt->sense_dmat) != 0) {
- bt_free(bt);
- return (-1);
- }
-
- bt->init_level++;
-
- /* Allocation of sense buffers */
- if (bus_dmamem_alloc(bt->sense_dmat,
- (void **)&bt->sense_buffers,
- BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) {
- bt_free(bt);
- return (-1);
- }
-
- bt->init_level++;
-
- /* And permanently map them */
- bus_dmamap_load(bt->sense_dmat, bt->sense_dmamap,
- bt->sense_buffers,
- bt->max_ccbs * sizeof(*bt->sense_buffers),
- btmapsensebuffers, bt, /*flags*/0);
-
- bt->init_level++;
- }
-
- return (bt_attach(bt));
-}
-
-/*
- * Handle an ISA interrupt.
- * XXX should go away as soon as ISA interrupt handlers
- * take a (void *) arg.
- */
-static void
-bt_isa_intr(void *unit)
-{
- struct bt_softc* arg = bt_softcs[(int)unit];
- bt_intr((void *)arg);
-}
-
-#define BIOS_MAP_SIZE (16 * 1024)
-
-static int
-btvlbouncefilter(void *arg, bus_addr_t addr)
-{
- struct bt_softc *bt;
-
- bt = (struct bt_softc *)arg;
-
- addr &= BUS_SPACE_MAXADDR_24BIT;
-
- if (addr == 0
- || (addr >= bt->bios_addr
- && addr < (bt->bios_addr + BIOS_MAP_SIZE)))
- return (1);
- return (0);
-}
-
-static void
-btmapsensebuffers(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- struct bt_softc* bt;
-
- bt = (struct bt_softc*)arg;
- bt->sense_buffers_physbase = segs->ds_addr;
-}
diff --git a/sys/isa/fd.c b/sys/isa/fd.c
deleted file mode 100644
index 9972a38f5c35..000000000000
--- a/sys/isa/fd.c
+++ /dev/null
@@ -1,2296 +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.131 1999/01/15 09:15:27 bde 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/conf.h>
-#include <sys/fcntl.h>
-#include <machine/clock.h>
-#include <machine/ioctl_fd.h>
-#include <sys/disklabel.h>
-#include <sys/buf.h>
-#include <sys/devicestat.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-#include <sys/syslog.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/fdreg.h>
-#include <i386/isa/fdc.h>
-#include <i386/isa/rtc.h>
-#include <machine/stdarg.h>
-#ifdef DEVFS
-#include <sys/devfsext.h>
-#endif /* DEVFS */
-
-/* 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
-
-/*
- * this biotab field doubles as a field for the physical unit number
- * on the controller
- */
-#define id_physid id_scsiid
-
-/* 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. *
-\***********************************************************************/
-struct fdc_data fdc_data[NFDC];
-
-/***********************************************************************\
-* Per drive structure. *
-* N per controller (DRVS_PER_CTLR) *
-\***********************************************************************/
-static 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
-} fd_data[NFD];
-
-/***********************************************************************\
-* 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
-
-/* autoconfig functions */
-static int fdprobe(struct isa_device *);
-static int fdattach(struct isa_device *);
-
-/* needed for ft driver, thus exported */
-int in_fdc(fdcu_t);
-int out_fdc(fdcu_t, int);
-
-/* internal functions */
-static void set_motor(fdcu_t, int, int);
-# define TURNON 1
-# define TURNOFF 0
-static timeout_t fd_turnoff;
-static timeout_t fd_motor_on;
-static void fd_turnon(fdu_t);
-static void fdc_reset(fdc_p);
-static int fd_in(fdcu_t, int *);
-static void fdstart(fdcu_t);
-static timeout_t fd_iotimeout;
-static timeout_t fd_pseudointr;
-static ointhand2_t fdintr;
-static int fdstate(fdcu_t, fdc_p);
-static int retrier(fdcu_t);
-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 */
-
-
-/* autoconfig structure */
-
-struct isa_driver fdcdriver = {
- fdprobe, fdattach, "fdc",
-};
-
-static d_open_t Fdopen; /* NOTE, not fdopen */
-static d_read_t fdread;
-static d_write_t fdwrite;
-static d_close_t fdclose;
-static d_ioctl_t fdioctl;
-static d_strategy_t fdstrategy;
-
-/* even if SLICE defined, these are needed for the ft support. */
-#define CDEV_MAJOR 9
-#define BDEV_MAJOR 2
-
-
-static struct cdevsw fd_cdevsw = {
- Fdopen, fdclose, fdread, fdwrite,
- fdioctl, nostop, nullreset, nodevtotty,
- seltrue, nommap, fdstrategy, "fd",
- NULL, -1, nodump, nopsize,
- D_DISK, 0, -1 };
-
-
-static struct isa_device *fdcdevs[NFDC];
-
-
-static int
-fdc_err(fdcu_t fdcu, const char *s)
-{
- fdc_data[fdcu].fdc_errs++;
- if(s) {
- if(fdc_data[fdcu].fdc_errs < FDC_ERRMAX)
- printf("fdc%d: %s", fdcu, s);
- else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX)
- printf("fdc%d: too many errors, not logging any more\n",
- fdcu);
- }
-
- 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(fdcu_t fdcu, 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(fdcu, 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(fdcu, msg);
- }
- }
- n_in = va_arg(ap, int);
- for (n = 0; n < n_in; n++)
- {
- int *ptr = va_arg(ap, int *);
- if (fd_in(fdcu, 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(fdcu, 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->fdcu, I8207X_CONFIGURE) < 0)
- return fdc_err(fdc->fdcu, "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->fdcu, 3,
- 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
- fdc_reset(fdc);
- return fdc_err(fdc->fdcu, "Enable FIFO failed\n");
- }
- fdc->flags |= FDC_HAS_FIFO;
- return 0;
- }
- if (fd_cmd(fdc->fdcu, 4,
- I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0)
- return fdc_err(fdc->fdcu, "Re-enable FIFO failed\n");
- return 0;
-}
-
-static int
-fd_sense_drive_status(fdc_p fdc, int *st3p)
-{
- int st3;
-
- if (fd_cmd(fdc->fdcu, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3))
- {
- return fdc_err(fdc->fdcu, "Sense Drive Status failed\n");
- }
- if (st3p)
- *st3p = st3;
-
- return 0;
-}
-
-static int
-fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
-{
- int st0, cyl;
-
- int ret = fd_cmd(fdc->fdcu, 1, NE7CMD_SENSEI, 1, &st0);
-
- if (ret)
- {
- (void)fdc_err(fdc->fdcu,
- "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->fdcu, &cyl) < 0)
- {
- return fdc_err(fdc->fdcu, "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->fdcu, &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 */
-/****************************************************************************/
-
-/*
- * probe for existance of controller
- */
-static int
-fdprobe(struct isa_device *dev)
-{
- fdcu_t fdcu = dev->id_unit;
- if(fdc_data[fdcu].flags & FDC_ATTACHED)
- {
- printf("fdc%d: unit used multiple times\n", fdcu);
- return 0;
- }
-
- fdcdevs[fdcu] = dev;
- fdc_data[fdcu].baseport = dev->id_iobase;
-
- /* First - lets reset the floppy controller */
- outb(dev->id_iobase+FDOUT, 0);
- DELAY(100);
- outb(dev->id_iobase+FDOUT, FDO_FRST);
-
- /* see if it can handle a command */
- if (fd_cmd(fdcu,
- 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
- 0))
- {
- return(0);
- }
-#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 (IO_FDCSIZE);
-}
-
-/*
- * wire controller into system, look for floppy units
- */
-static int
-fdattach(struct isa_device *dev)
-{
- unsigned fdt;
- fdu_t fdu;
- fdcu_t fdcu = dev->id_unit;
- fdc_p fdc = fdc_data + fdcu;
- fd_p fd;
- int fdsu, st0, st3, i;
- struct isa_device *fdup;
- int ic_type = 0;
-#ifdef DEVFS
- int mynor;
- int typemynor;
- int typesize;
-#endif
-
- dev->id_ointr = fdintr;
- fdc->fdcu = fdcu;
- fdc->flags |= FDC_ATTACHED;
- fdc->dmachan = dev->id_drq;
- /* Acquire the DMA channel forever, The driver will do the rest */
- 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);
-
- /* check for each floppy drive */
- for (fdup = isa_biotab_fdc; fdup->id_driver != 0; fdup++) {
- if (fdup->id_iobase != dev->id_iobase)
- continue;
- fdu = fdup->id_unit;
- fd = &fd_data[fdu];
- if (fdu >= (NFD))
- continue;
- fdsu = fdup->id_physid;
- /* look up what bios thinks we have */
- switch (fdu) {
- case 0: if (dev->id_flags & 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)
- ) {
- fd->type = NO_TYPE;
- continue;
- }
-
- /* select it */
- set_motor(fdcu, fdsu, TURNON);
- DELAY(1000000); /* 1 sec */
-
- if (ic_type == 0 &&
- fd_cmd(fdcu, 1, NE7CMD_VERSION, 1, &ic_type) == 0)
- {
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("fdc%d: ", fdcu);
-#endif
- ic_type = (u_char)ic_type;
- switch( ic_type ) {
- case 0x80:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("NEC 765\n");
-#endif
- fdc->fdct = FDC_NE765;
- break;
- case 0x81:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("Intel 82077\n");
-#endif
- fdc->fdct = FDC_I82077;
- break;
- case 0x90:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("NEC 72065B\n");
-#endif
- fdc->fdct = FDC_NE72065;
- break;
- default:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("unknown IC type %02x\n", ic_type);
-#endif
- fdc->fdct = FDC_UNKNOWN;
- break;
- }
- if (fdc->fdct != FDC_NE765 &&
- fdc->fdct != FDC_UNKNOWN &&
- enable_fifo(fdc) == 0) {
- printf("fdc%d: FIFO enabled", fdcu);
- printf(", %d bytes threshold\n",
- fifo_threshold);
- }
- }
- 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 */
- continue;
-
- fd->track = FD_NO_TRACK;
- fd->fdc = fdc;
- fd->fdsu = fdsu;
- fd->options = 0;
- callout_handle_init(&fd->toffhandle);
- callout_handle_init(&fd->tohandle);
- printf("fd%d: ", fdu);
-
- switch (fdt) {
- case RTCFDT_12M:
- printf("1.2MB 5.25in\n");
- fd->type = FD_1200;
- break;
- case RTCFDT_144M | RTCFDT_144M_PRETENDED:
- printf("config-pretended ");
- fdt = RTCFDT_144M;
- /* fallthrough */
- case RTCFDT_144M:
- printf("1.44MB 3.5in\n");
- fd->type = FD_1440;
- break;
- case RTCFDT_288M:
- case RTCFDT_288M_1:
- printf("2.88MB 3.5in - 1.44MB mode\n");
- fd->type = FD_1440;
- break;
- case RTCFDT_360K:
- printf("360KB 5.25in\n");
- fd->type = FD_360;
- break;
- case RTCFDT_720K:
- printf("720KB 3.5in\n");
- fd->type = FD_720;
- break;
- default:
- printf("unknown\n");
- fd->type = NO_TYPE;
- continue;
- }
-#ifdef DEVFS
- mynor = fdu << 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);
- 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", fdu, typesize);
- fd->cdevs[i] =
- 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 */
- /*
- * Export the drive to the devstat interface.
- */
- devstat_add_entry(&fd->device_stats, "fd",
- fdu, 512,
- DEVSTAT_NO_ORDERED_TAGS,
- DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER);
-
- }
-
- return (1);
-}
-
-
-
-#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(fdcu_t fdcu, int fdsu, int turnon)
-{
- int fdout = fdc_data[fdcu].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_data[fdcu].baseport+FDOUT, fdout);
- fdc_data[fdcu].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(fdcu, 3, NE7CMD_SPECIFY,
- NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
- 0);
- if (fdc_data[fdcu].flags & FDC_HAS_FIFO)
- (void) enable_fifo(&fdc_data[fdcu]);
- }
-}
-
-static void
-fd_turnoff(void *arg1)
-{
- fdu_t fdu = (fdu_t)arg1;
- int s;
- fd_p fd = fd_data + fdu;
-
- TRACE1("[fd%d: turnoff]", 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 == fdu) {
- fd->toffhandle = timeout(fd_turnoff, arg1, 4 * hz);
- return;
- }
-
- s = splbio();
- fd->flags &= ~FD_MOTOR;
- set_motor(fd->fdc->fdcu, fd->fdsu, TURNOFF);
- splx(s);
-}
-
-static void
-fd_motor_on(void *arg1)
-{
- fdu_t fdu = (fdu_t)arg1;
- int s;
-
- fd_p fd = fd_data + fdu;
- s = splbio();
- fd->flags &= ~FD_MOTOR_WAIT;
- if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT))
- {
- fdintr(fd->fdc->fdcu);
- }
- splx(s);
-}
-
-static void
-fd_turnon(fdu_t fdu)
-{
- fd_p fd = fd_data + fdu;
- if(!(fd->flags & FD_MOTOR))
- {
- fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT);
- set_motor(fd->fdc->fdcu, fd->fdsu, TURNON);
- timeout(fd_motor_on, (caddr_t)fdu, hz); /* in 1 sec its ok */
- }
-}
-
-static void
-fdc_reset(fdc_p fdc)
-{
- fdcu_t fdcu = fdc->fdcu;
-
- /* 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(fdcu, 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(fdcu_t fdcu)
-{
- int baseport = fdc_data[fdcu].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(fdcu, "ready for output in input\n");
- if (j <= 0)
- return fdc_err(fdcu, 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(fdcu_t fdcu, int *ptr)
-{
- int baseport = fdc_data[fdcu].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(fdcu, "ready for output in input\n");
- if (j <= 0)
- return fdc_err(fdcu, 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(fdcu_t fdcu, int x)
-{
- int baseport = fdc_data[fdcu].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(fdcu, "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(fdcu, 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));
- fdc_p fdc;
-
- /* check bounds */
- if (fdu >= NFD)
- return(ENXIO);
- fdc = fd_data[fdu].fdc;
- if ((fdc == NULL) || (fd_data[fdu].type == NO_TYPE))
- return(ENXIO);
- if (type > NUMDENS)
- return(ENXIO);
- if (type == 0)
- type = fd_data[fdu].type;
- else {
- /*
- * For each type of basic drive, make sure we are trying
- * to open a type it can do,
- */
- if (type != fd_data[fdu].type) {
- switch (fd_data[fdu].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_data[fdu].ft = fd_types + type - 1;
- fd_data[fdu].flags |= FD_OPEN;
-
- return 0;
-}
-
-int
-fdclose(dev_t dev, int flags, int mode, struct proc *p)
-{
- fdu_t fdu = FDUNIT(minor(dev));
-
- fd_data[fdu].flags &= ~FD_OPEN;
- fd_data[fdu].options &= ~FDOPT_NORETRY;
-
- return(0);
-}
-
-static int
-fdread(dev_t dev, struct uio *uio, int ioflag)
-{
- return (physio(fdstrategy, NULL, dev, 1, minphys, uio));
-}
-
-static int
-fdwrite(dev_t dev, struct uio *uio, int ioflag)
-{
- return (physio(fdstrategy, NULL, dev, 0, minphys, uio));
-}
-
-
-/****************************************************************************/
-/* fdstrategy */
-/****************************************************************************/
-void
-fdstrategy(struct buf *bp)
-{
- unsigned nblocks, blknum, cando;
- int s;
- fdcu_t fdcu;
- fdu_t fdu;
- fdc_p fdc;
- fd_p fd;
- size_t fdblk;
-
- fdu = FDUNIT(minor(bp->b_dev));
- fd = &fd_data[fdu];
- fdc = fd->fdc;
- fdcu = fdc->fdcu;
-#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 ((fdu >= NFD) || (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, (caddr_t)fdu, fd->toffhandle); /* a good idea */
-
- /* Tell devstat we are starting on the transaction */
- devstat_start_transaction(&fd->device_stats);
-
- fdstart(fdcu);
- 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(fdcu_t fdcu)
-{
- int s;
-
- s = splbio();
- if(fdc_data[fdcu].state == DEVIDLE)
- {
- fdintr(fdcu);
- }
- splx(s);
-}
-
-static void
-fd_iotimeout(void *arg1)
-{
- fdc_p fdc;
- fdcu_t fdcu;
- int s;
-
- fdcu = (fdcu_t)arg1;
- fdc = fdc_data + fdcu;
- 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;
- fdintr(fdcu);
- splx(s);
-}
-
-/* just ensure it has the right spl */
-static void
-fd_pseudointr(void *arg1)
-{
- fdcu_t fdcu = (fdcu_t)arg1;
- int s;
-
- s = splbio();
- fdintr(fdcu);
- splx(s);
-}
-
-/***********************************************************************\
-* fdintr *
-* keep calling the state machine until it returns a 0 *
-* ALWAYS called at SPLBIO *
-\***********************************************************************/
-static void
-fdintr(fdcu_t fdcu)
-{
- fdc_p fdc = fdc_data + fdcu;
- while(fdstate(fdcu, 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(fdcu_t fdcu, 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)
- {
- printf("fd%d: unexpected valid fd pointer\n",
- fdc->fdu);
- fdc->fd = (fd_p) 0;
- fdc->fdu = -1;
- }
- TRACE1("[fdc%d IDLE]", fdcu);
- return(0);
- }
- fdu = FDUNIT(minor(bp->b_dev));
- fd = fd_data + fdu;
- fdblk = 128 << fd->ft->secsize;
- if (fdc->fd && (fd != fdc->fd))
- {
- printf("fd%d: confused fd pointers\n", fdu);
- }
- 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, (caddr_t)fdu, fd->toffhandle);
- fd->toffhandle = timeout(fd_turnoff, (caddr_t)fdu, 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(fdu);
- return(0);
- }
- else /* at least make sure we are selected */
- {
- set_motor(fdcu, 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(fdcu, 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(fdcu));
- }
- fd->track = FD_NO_TRACK;
- fdc->state = SEEKWAIT;
- return(0); /* will return later */
- case SEEKWAIT:
- /* allow heads to settle */
- timeout(fd_pseudointr, (caddr_t)fdcu, 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(fdcu));
- }
- }
-
- 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(fdcu));
- }
- }
-
- 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(fdcu));
- }
- 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(fdcu, 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(fdcu));
- }
- }
- 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(fdcu, 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(fdcu));
- }
- }
-#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, (caddr_t)fdcu, 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, (caddr_t)fdcu, 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(fdcu);
- }
-
- 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(fdcu));
- }
- /* 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(fdcu,
- 2, NE7CMD_RECAL, fdu,
- 0)) /* Recalibrate Function */
- {
- /* arrgl */
- fdc->retry = 6;
- return(retrier(fdcu));
- }
- fdc->state = RECALWAIT;
- return(0); /* will return later */
- case RECALWAIT:
- /* allow heads to settle */
- timeout(fd_pseudointr, (caddr_t)fdcu, 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(fdcu));
- }
- 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.
- */
- fdc->state = STARTRECAL;
- }
- return(1); /* will return immediatly */
- default:
- printf("fdc%d: Unexpected FD int->", fdcu);
- 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(fdcu)
- fdcu_t fdcu;
-{
- fdc_p fdc = fdc_data + fdcu;
- register struct buf *bp;
-
- bp = fdc->bp;
-
- if(fd_data[FDUNIT(minor(bp->b_dev))].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 = &fd_data[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
- */
- p->p_flag |= P_PHYSIO;
- bzero((void *)bp, sizeof(struct buf));
- bp->b_flags = B_BUSY | B_PHYS | B_FORMAT;
- bp->b_proc = p;
-
- /*
- * 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
- */
- p->p_flag &= ~P_PHYSIO;
- 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 = &fd_data[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_data[FDUNIT(minor(dev))].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->p_ucred, &p->p_acflag) != 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 fd_devsw_installed = 0;
-
-static void fd_drvinit(void *notused )
-{
-
- if( ! fd_devsw_installed ) {
- cdevsw_add_generic(BDEV_MAJOR,CDEV_MAJOR, &fd_cdevsw);
- fd_devsw_installed = 1;
- }
-}
-
-SYSINIT(fddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,fd_drvinit,NULL)
-
-
-#endif
-
-/*
- * 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/isa/fdc.h b/sys/isa/fdc.h
deleted file mode 100644
index 43bf9f8f5f4c..000000000000
--- a/sys/isa/fdc.h
+++ /dev/null
@@ -1,91 +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.12 1998/12/12 08:16:01 imp 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 */
-};
-
-/***********************************************************************\
-* 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/isa/fdreg.h b/sys/isa/fdreg.h
deleted file mode 100644
index 5ceb73f43301..000000000000
--- a/sys/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/isa/ic/nec765.h b/sys/isa/ic/nec765.h
deleted file mode 100644
index 3a5561888e87..000000000000
--- a/sys/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/isa/joy.c b/sys/isa/joy.c
deleted file mode 100644
index f64d99e501f9..000000000000
--- a/sys/isa/joy.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*-
- * Copyright (c) 1995 Jean-Marc Zucconi
- * 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
- * in this position and unchanged.
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "joy.h"
-
-#if NJOY > 0
-
-#include "opt_devfs.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#ifdef DEVFS
-#include <sys/devfsext.h>
-#endif /*DEVFS*/
-#include <sys/uio.h>
-
-#include <machine/clock.h>
-#include <machine/joystick.h>
-
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/timerreg.h>
-
-/* The game port can manage 4 buttons and 4 variable resistors (usually 2
- * joysticks, each with 2 buttons and 2 pots.) via the port at address 0x201.
- * Getting the state of the buttons is done by reading the game port:
- * buttons 1-4 correspond to bits 4-7 and resistors 1-4 (X1, Y1, X2, Y2)
- * to bits 0-3.
- * if button 1 (resp 2, 3, 4) is pressed, the bit 4 (resp 5, 6, 7) is set to 0
- * to get the value of a resistor, write the value 0xff at port and
- * wait until the corresponding bit returns to 0.
- */
-
-
-/* the formulae below only work if u is ``not too large''. See also
- * the discussion in microtime.s */
-#define usec2ticks(u) (((u) * 19549)>>14)
-#define ticks2usec(u) (((u) * 3433)>>12)
-
-
-#define joypart(d) minor(d)&1
-#define UNIT(d) minor(d)>>1&3
-#ifndef JOY_TIMEOUT
-#define JOY_TIMEOUT 2000 /* 2 milliseconds */
-#endif
-
-static struct {
- int port;
- int x_off[2], y_off[2];
- int timeout[2];
-#ifdef DEVFS
- void *devfs_token;
-#endif
-} joy[NJOY];
-
-
-static int joyprobe (struct isa_device *);
-static int joyattach (struct isa_device *);
-
-struct isa_driver joydriver = {joyprobe, joyattach, "joy"};
-
-#define CDEV_MAJOR 51
-static d_open_t joyopen;
-static d_close_t joyclose;
-static d_read_t joyread;
-static d_ioctl_t joyioctl;
-
-static struct cdevsw joy_cdevsw =
- { joyopen, joyclose, joyread, nowrite, /*51*/
- joyioctl, nostop, nullreset, nodevtotty,/*joystick */
- seltrue, nommap, NULL, "joy", NULL, -1 };
-
-static int get_tick __P((void));
-
-
-static int
-joyprobe (struct isa_device *dev)
-{
-#ifdef WANT_JOYSTICK_CONNECTED
- outb (dev->id_iobase, 0xff);
- DELAY (10000); /* 10 ms delay */
- return (inb (dev->id_iobase) & 0x0f) != 0x0f;
-#else
- return 1;
-#endif
-}
-
-static int
-joyattach (struct isa_device *dev)
-{
- int unit = dev->id_unit;
-
- joy[unit].port = dev->id_iobase;
- joy[unit].timeout[0] = joy[unit].timeout[1] = 0;
- printf("joy%d: joystick\n", unit);
-#ifdef DEVFS
- joy[dev->id_unit].devfs_token =
- devfs_add_devswf(&joy_cdevsw, 0, DV_CHR, 0, 0,
- 0600, "joy%d", unit);
-#endif
- return 1;
-}
-
-static int
-joyopen (dev_t dev, int flags, int fmt, struct proc *p)
-{
- int unit = UNIT (dev);
- int i = joypart (dev);
-
- if (joy[unit].timeout[i])
- return EBUSY;
- joy[unit].x_off[i] = joy[unit].y_off[i] = 0;
- joy[unit].timeout[i] = JOY_TIMEOUT;
- return 0;
-}
-static int
-joyclose (dev_t dev, int flags, int fmt, struct proc *p)
-{
- int unit = UNIT (dev);
- int i = joypart (dev);
-
- joy[unit].timeout[i] = 0;
- return 0;
-}
-
-static int
-joyread (dev_t dev, struct uio *uio, int flag)
-{
- int unit = UNIT(dev);
- int port = joy[unit].port;
- int i, t0, t1;
- int state = 0, x = 0, y = 0;
- struct joystick c;
-
- disable_intr ();
- outb (port, 0xff);
- t0 = get_tick ();
- t1 = t0;
- i = usec2ticks(joy[unit].timeout[joypart(dev)]);
- while (t0-t1 < i) {
- state = inb (port);
- if (joypart(dev) == 1)
- state >>= 2;
- t1 = get_tick ();
- if (t1 > t0)
- t1 -= timer0_max_count;
- if (!x && !(state & 0x01))
- x = t1;
- if (!y && !(state & 0x02))
- y = t1;
- if (x && y)
- break;
- }
- enable_intr ();
- c.x = x ? joy[unit].x_off[joypart(dev)] + ticks2usec(t0-x) : 0x80000000;
- c.y = y ? joy[unit].y_off[joypart(dev)] + ticks2usec(t0-y) : 0x80000000;
- state >>= 4;
- c.b1 = ~state & 1;
- c.b2 = ~(state >> 1) & 1;
- return uiomove ((caddr_t)&c, sizeof(struct joystick), uio);
-}
-
-static int
-joyioctl (dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
-{
- int unit = UNIT (dev);
- int i = joypart (dev);
- int x;
-
- switch (cmd) {
- case JOY_SETTIMEOUT:
- x = *(int *) data;
- if (x < 1 || x > 10000) /* 10ms maximum! */
- return EINVAL;
- joy[unit].timeout[i] = x;
- break;
- case JOY_GETTIMEOUT:
- *(int *) data = joy[unit].timeout[i];
- break;
- case JOY_SET_X_OFFSET:
- joy[unit].x_off[i] = *(int *) data;
- break;
- case JOY_SET_Y_OFFSET:
- joy[unit].y_off[i] = *(int *) data;
- break;
- case JOY_GET_X_OFFSET:
- *(int *) data = joy[unit].x_off[i];
- break;
- case JOY_GET_Y_OFFSET:
- *(int *) data = joy[unit].y_off[i];
- break;
- default:
- return ENXIO;
- }
- return 0;
-}
-
-static int
-get_tick ()
-{
- int low, high;
-
- outb (TIMER_MODE, TIMER_SEL0);
- low = inb (TIMER_CNTR0);
- high = inb (TIMER_CNTR0);
-
- return (high << 8) | low;
-}
-
-
-static joy_devsw_installed = 0;
-
-static void joy_drvinit(void *unused)
-{
- dev_t dev;
-
- if( ! joy_devsw_installed ) {
- dev = makedev(CDEV_MAJOR,0);
- cdevsw_add(&dev,&joy_cdevsw,NULL);
- joy_devsw_installed = 1;
- }
-}
-
-SYSINIT(joydev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,joy_drvinit,NULL)
-
-#ifdef JOY_MODULE
-
-#include <sys/exec.h>
-#include <sys/sysent.h>
-#include <sys/lkm.h>
-
-MOD_DEV (joy, LM_DT_CHAR, CDEV_MAJOR, &joy_cdevsw);
-
-static struct isa_device dev = {0, &joydriver, IO_GAME, 0, -1, (caddr_t) 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0};
-
-static int
-joy_load (struct lkm_table *lkmtp, int cmd)
-{
- if (joyprobe (&dev)) {
- joyattach (&dev);
-/* joy_drvinit (0);*/
- uprintf ("Joystick driver loaded\n");
- return 0;
- } else {
- uprintf ("Joystick driver: probe failed\n");
- return 1;
- }
-}
-
-static int
-joy_unload (struct lkm_table *lkmtp, int cmd)
-{
- uprintf ("Joystick driver unloaded\n");
- return 0;
-}
-
-static int
-joy_stat (struct lkm_table *lkmtp, int cmd)
-{
- return 0;
-}
-
-int
-joy_mod (struct lkm_table *lkmtp, int cmd, int ver)
-{
- MOD_DISPATCH(joy, lkmtp, cmd, ver,
- joy_load, joy_unload, joy_stat);
-}
-
-#endif /* JOY_MODULE */
-
-
-#endif /* NJOY > 0 */
diff --git a/sys/isa/ppc.c b/sys/isa/ppc.c
deleted file mode 100644
index bd6249b33a71..000000000000
--- a/sys/isa/ppc.c
+++ /dev/null
@@ -1,1794 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998 Nicolas Souchu
- * 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.
- *
- * 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.
- *
- * $Id: ppc.c,v 1.14 1999/01/10 12:04:53 nsouch Exp $
- *
- */
-#include "ppc.h"
-
-#if NPPC > 0
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-
-#include <machine/clock.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-
-#include <i386/isa/isa_device.h>
-
-#include <dev/ppbus/ppbconf.h>
-#include <dev/ppbus/ppb_msq.h>
-
-#include <i386/isa/ppcreg.h>
-
-#include "opt_ppc.h"
-
-#define LOG_PPC(function, ppc, string) \
- if (bootverbose) printf("%s: %s\n", function, string)
-
-static int ppcprobe(struct isa_device *);
-static int ppcattach(struct isa_device *);
-
-struct isa_driver ppcdriver = {
- ppcprobe, ppcattach, "ppc"
-};
-
-static struct ppc_data *ppcdata[NPPC];
-static int nppc = 0;
-
-static char *ppc_types[] = {
- "SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306",
- "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334", 0
-};
-
-/* list of available modes */
-static char *ppc_avms[] = {
- "COMPATIBLE", "NIBBLE-only", "PS2-only", "PS2/NIBBLE", "EPP-only",
- "EPP/NIBBLE", "EPP/PS2", "EPP/PS2/NIBBLE", "ECP-only",
- "ECP/NIBBLE", "ECP/PS2", "ECP/PS2/NIBBLE", "ECP/EPP",
- "ECP/EPP/NIBBLE", "ECP/EPP/PS2", "ECP/EPP/PS2/NIBBLE", 0
-};
-
-/* list of current executing modes
- * Note that few modes do not actually exist.
- */
-static char *ppc_modes[] = {
- "COMPATIBLE", "NIBBLE", "PS/2", "PS/2", "EPP",
- "EPP", "EPP", "EPP", "ECP",
- "ECP", "ECP+PS2", "ECP+PS2", "ECP+EPP",
- "ECP+EPP", "ECP+EPP", "ECP+EPP", 0
-};
-
-static char *ppc_epp_protocol[] = { " (EPP 1.9)", " (EPP 1.7)", 0 };
-
-/*
- * BIOS printer list - used by BIOS probe.
- */
-#define BIOS_PPC_PORTS 0x408
-#define BIOS_PORTS (short *)(KERNBASE+BIOS_PPC_PORTS)
-#define BIOS_MAX_PPC 4
-
-/*
- * All these functions are default actions for IN/OUT operations.
- * They may be redefined if needed.
- */
-static void ppc_outsb_epp(int unit, char *addr, int cnt) {
- outsb(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
-static void ppc_outsw_epp(int unit, char *addr, int cnt) {
- outsw(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
-static void ppc_outsl_epp(int unit, char *addr, int cnt) {
- outsl(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
-static void ppc_insb_epp(int unit, char *addr, int cnt) {
- insb(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
-static void ppc_insw_epp(int unit, char *addr, int cnt) {
- insw(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
-static void ppc_insl_epp(int unit, char *addr, int cnt) {
- insl(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
-
-static u_char ppc_rdtr(int unit) { return r_dtr(ppcdata[unit]); }
-static u_char ppc_rstr(int unit) { return r_str(ppcdata[unit]); }
-static u_char ppc_rctr(int unit) { return r_ctr(ppcdata[unit]); }
-static u_char ppc_repp(int unit) { return r_epp(ppcdata[unit]); }
-static u_char ppc_recr(int unit) { return r_ecr(ppcdata[unit]); }
-static u_char ppc_rfifo(int unit) { return r_fifo(ppcdata[unit]); }
-
-static void ppc_wdtr(int unit, char byte) { w_dtr(ppcdata[unit], byte); }
-static void ppc_wstr(int unit, char byte) { w_str(ppcdata[unit], byte); }
-static void ppc_wctr(int unit, char byte) { w_ctr(ppcdata[unit], byte); }
-static void ppc_wepp(int unit, char byte) { w_epp(ppcdata[unit], byte); }
-static void ppc_wecr(int unit, char byte) { w_ecr(ppcdata[unit], byte); }
-static void ppc_wfifo(int unit, char byte) { w_fifo(ppcdata[unit], byte); }
-
-static void ppc_reset_epp_timeout(int);
-static void ppc_ecp_sync(int);
-static ointhand2_t ppcintr;
-
-static int ppc_exec_microseq(int, struct ppb_microseq **);
-static int ppc_generic_setmode(int, int);
-static int ppc_smclike_setmode(int, int);
-
-static int ppc_read(int, char *, int, int);
-static int ppc_write(int, char *, int, int);
-
-static struct ppb_adapter ppc_smclike_adapter = {
-
- 0, /* no intr handler, filled by chipset dependent code */
-
- ppc_reset_epp_timeout, ppc_ecp_sync,
-
- ppc_exec_microseq,
-
- ppc_smclike_setmode, ppc_read, ppc_write,
-
- ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
- ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
-
- ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo,
- ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo
-};
-
-static struct ppb_adapter ppc_generic_adapter = {
-
- 0, /* no intr handler, filled by chipset dependent code */
-
- ppc_reset_epp_timeout, ppc_ecp_sync,
-
- ppc_exec_microseq,
-
- ppc_generic_setmode, ppc_read, ppc_write,
-
- ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
- ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
-
- ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp, ppc_recr, ppc_rfifo,
- ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp, ppc_wecr, ppc_wfifo
-};
-
-/*
- * ppc_ecp_sync() XXX
- */
-static void
-ppc_ecp_sync(int unit) {
-
- struct ppc_data *ppc = ppcdata[unit];
- int i, r;
-
- if (!(ppc->ppc_avm & PPB_ECP))
- return;
-
- r = r_ecr(ppc);
- if ((r & 0xe0) != PPC_ECR_EPP)
- return;
-
- for (i = 0; i < 100; i++) {
- r = r_ecr(ppc);
- if (r & 0x1)
- return;
- DELAY(100);
- }
-
- printf("ppc%d: ECP sync failed as data still " \
- "present in FIFO.\n", unit);
-
- return;
-}
-
-/*
- * ppc_detect_fifo()
- *
- * Detect parallel port FIFO
- */
-static int
-ppc_detect_fifo(struct ppc_data *ppc)
-{
- char ecr_sav;
- char ctr_sav, ctr, cc;
- short i;
-
- /* save registers */
- ecr_sav = r_ecr(ppc);
- ctr_sav = r_ctr(ppc);
-
- /* enter ECP configuration mode, no interrupt, no DMA */
- w_ecr(ppc, 0xf4);
-
- /* read PWord size - transfers in FIFO mode must be PWord aligned */
- ppc->ppc_pword = (r_cnfgA(ppc) & PPC_PWORD_MASK);
-
- /* XXX 16 and 32 bits implementations not supported */
- if (ppc->ppc_pword != PPC_PWORD_8) {
- LOG_PPC(__FUNCTION__, ppc, "PWord not supported");
- goto error;
- }
-
- w_ecr(ppc, 0x34); /* byte mode, no interrupt, no DMA */
- ctr = r_ctr(ppc);
- w_ctr(ppc, ctr | PCD); /* set direction to 1 */
-
- /* enter ECP test mode, no interrupt, no DMA */
- w_ecr(ppc, 0xd4);
-
- /* flush the FIFO */
- for (i=0; i<1024; i++) {
- if (r_ecr(ppc) & PPC_FIFO_EMPTY)
- break;
- cc = r_fifo(ppc);
- }
-
- if (i >= 1024) {
- LOG_PPC(__FUNCTION__, ppc, "can't flush FIFO");
- goto error;
- }
-
- /* enable interrupts, no DMA */
- w_ecr(ppc, 0xd0);
-
- /* determine readIntrThreshold
- * fill the FIFO until serviceIntr is set
- */
- for (i=0; i<1024; i++) {
- w_fifo(ppc, (char)i);
- if (!ppc->ppc_rthr && (r_ecr(ppc) & PPC_SERVICE_INTR)) {
- /* readThreshold reached */
- ppc->ppc_rthr = i+1;
- }
- if (r_ecr(ppc) & PPC_FIFO_FULL) {
- ppc->ppc_fifo = i+1;
- break;
- }
- }
-
- if (i >= 1024) {
- LOG_PPC(__FUNCTION__, ppc, "can't fill FIFO");
- goto error;
- }
-
- w_ecr(ppc, 0xd4); /* test mode, no interrupt, no DMA */
- w_ctr(ppc, ctr & ~PCD); /* set direction to 0 */
- w_ecr(ppc, 0xd0); /* enable interrupts */
-
- /* determine writeIntrThreshold
- * empty the FIFO until serviceIntr is set
- */
- for (i=ppc->ppc_fifo; i>0; i--) {
- if (r_fifo(ppc) != (char)(ppc->ppc_fifo-i)) {
- LOG_PPC(__FUNCTION__, ppc, "invalid data in FIFO");
- goto error;
- }
- if (r_ecr(ppc) & PPC_SERVICE_INTR) {
- /* writeIntrThreshold reached */
- ppc->ppc_wthr = ppc->ppc_fifo - i+1;
- }
- /* if FIFO empty before the last byte, error */
- if (i>1 && (r_ecr(ppc) & PPC_FIFO_EMPTY)) {
- LOG_PPC(__FUNCTION__, ppc, "data lost in FIFO");
- goto error;
- }
- }
-
- /* FIFO must be empty after the last byte */
- if (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
- LOG_PPC(__FUNCTION__, ppc, "can't empty the FIFO");
- goto error;
- }
-
- w_ctr(ppc, ctr_sav);
- w_ecr(ppc, ecr_sav);
-
- return (0);
-
-error:
- w_ctr(ppc, ctr_sav);
- w_ecr(ppc, ecr_sav);
-
- return (EINVAL);
-}
-
-static int
-ppc_detect_port(struct ppc_data *ppc)
-{
-
- w_ctr(ppc, 0x0c); /* To avoid missing PS2 ports */
- w_dtr(ppc, 0xaa);
- if (r_dtr(ppc) != 0xaa)
- return (0);
-
- return (1);
-}
-
-/*
- * ppc_pc873xx_detect
- *
- * Probe for a Natsemi PC873xx-family part.
- *
- * References in this function are to the National Semiconductor
- * PC87332 datasheet TL/C/11930, May 1995 revision.
- */
-static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0};
-static int pc873xx_porttab[] = {0x0378, 0x03bc, 0x0278, 0};
-static int pc873xx_irqtab[] = {5, 7, 5, 0};
-
-static int pc873xx_regstab[] = {
- PC873_FER, PC873_FAR, PC873_PTR,
- PC873_FCR, PC873_PCR, PC873_PMC,
- PC873_TUP, PC873_SID, PC873_PNP0,
- PC873_PNP1, PC873_LPTBA, -1
-};
-
-static char *pc873xx_rnametab[] = {
- "FER", "FAR", "PTR", "FCR", "PCR",
- "PMC", "TUP", "SID", "PNP0", "PNP1",
- "LPTBA", NULL
-};
-
-static int
-ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode) /* XXX mode never forced */
-{
- static int index = 0;
- int idport, irq;
- int ptr, pcr, val, i;
-
- while ((idport = pc873xx_basetab[index++])) {
-
- /* XXX should check first to see if this location is already claimed */
-
- /*
- * Pull the 873xx through the power-on ID cycle (2.2,1.).
- * We can't use this to locate the chip as it may already have
- * been used by the BIOS.
- */
- (void)inb(idport); (void)inb(idport);
- (void)inb(idport); (void)inb(idport);
-
- /*
- * Read the SID byte. Possible values are :
- *
- * 01010xxx PC87334
- * 0001xxxx PC87332
- * 01110xxx PC87306
- */
- outb(idport, PC873_SID);
- val = inb(idport + 1);
- if ((val & 0xf0) == 0x10) {
- ppc->ppc_type = NS_PC87332;
- } else if ((val & 0xf8) == 0x70) {
- ppc->ppc_type = NS_PC87306;
- } else if ((val & 0xf8) == 0x50) {
- ppc->ppc_type = NS_PC87334;
- } else {
- if (bootverbose && (val != 0xff))
- printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val);
- continue ; /* not recognised */
- }
-
- /* print registers */
- if (bootverbose) {
- printf("PC873xx");
- for (i=0; pc873xx_regstab[i] != -1; i++) {
- outb(idport, pc873xx_regstab[i]);
- printf(" %s=0x%x", pc873xx_rnametab[i],
- inb(idport + 1) & 0xff);
- }
- printf("\n");
- }
-
- /*
- * We think we have one. Is it enabled and where we want it to be?
- */
- outb(idport, PC873_FER);
- val = inb(idport + 1);
- if (!(val & PC873_PPENABLE)) {
- if (bootverbose)
- printf("PC873xx parallel port disabled\n");
- continue;
- }
- outb(idport, PC873_FAR);
- val = inb(idport + 1) & 0x3;
- /* XXX we should create a driver instance for every port found */
- if (pc873xx_porttab[val] != ppc->ppc_base) {
- if (bootverbose)
- printf("PC873xx at 0x%x not for driver at port 0x%x\n",
- pc873xx_porttab[val], ppc->ppc_base);
- continue;
- }
-
- outb(idport, PC873_PTR);
- ptr = inb(idport + 1);
-
- /* get irq settings */
- if (ppc->ppc_base == 0x378)
- irq = (ptr & PC873_LPTBIRQ7) ? 7 : 5;
- else
- irq = pc873xx_irqtab[val];
-
- if (bootverbose)
- printf("PC873xx irq %d at 0x%x\n", irq, ppc->ppc_base);
-
- /*
- * Check if irq settings are correct
- */
- if (irq != ppc->ppc_irq) {
- /*
- * If the chipset is not locked and base address is 0x378,
- * we have another chance
- */
- if (ppc->ppc_base == 0x378 && !(ptr & PC873_CFGLOCK)) {
- if (ppc->ppc_irq == 7) {
- outb(idport + 1, (ptr | PC873_LPTBIRQ7));
- outb(idport + 1, (ptr | PC873_LPTBIRQ7));
- } else {
- outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
- outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
- }
- if (bootverbose)
- printf("PC873xx irq set to %d\n", ppc->ppc_irq);
- } else {
- if (bootverbose)
- printf("PC873xx sorry, can't change irq setting\n");
- }
- } else {
- if (bootverbose)
- printf("PC873xx irq settings are correct\n");
- }
-
- outb(idport, PC873_PCR);
- pcr = inb(idport + 1);
-
- if ((ptr & PC873_CFGLOCK) || !chipset_mode) {
- if (bootverbose)
- printf("PC873xx %s", (ptr & PC873_CFGLOCK)?"locked":"unlocked");
-
- ppc->ppc_avm |= PPB_NIBBLE;
- if (bootverbose)
- printf(", NIBBLE");
-
- if (pcr & PC873_EPPEN) {
- ppc->ppc_avm |= PPB_EPP;
-
- if (bootverbose)
- printf(", EPP");
-
- if (pcr & PC873_EPP19)
- ppc->ppc_epp = EPP_1_9;
- else
- ppc->ppc_epp = EPP_1_7;
-
- if ((ppc->ppc_type == NS_PC87332) && bootverbose) {
- outb(idport, PC873_PTR);
- ptr = inb(idport + 1);
- if (ptr & PC873_EPPRDIR)
- printf(", Regular mode");
- else
- printf(", Automatic mode");
- }
- } else if (pcr & PC873_ECPEN) {
- ppc->ppc_avm |= PPB_ECP;
- if (bootverbose)
- printf(", ECP");
-
- if (pcr & PC873_ECPCLK) { /* XXX */
- ppc->ppc_avm |= PPB_PS2;
- if (bootverbose)
- printf(", PS/2");
- }
- } else {
- outb(idport, PC873_PTR);
- ptr = inb(idport + 1);
- if (ptr & PC873_EXTENDED) {
- ppc->ppc_avm |= PPB_SPP;
- if (bootverbose)
- printf(", SPP");
- }
- }
- } else {
- if (bootverbose)
- printf("PC873xx unlocked");
-
- if (chipset_mode & PPB_ECP) {
- if ((chipset_mode & PPB_EPP) && bootverbose)
- printf(", ECP+EPP not supported");
-
- pcr &= ~PC873_EPPEN;
- pcr |= (PC873_ECPEN | PC873_ECPCLK); /* XXX */
- outb(idport + 1, pcr);
- outb(idport + 1, pcr);
-
- if (bootverbose)
- printf(", ECP");
-
- } else if (chipset_mode & PPB_EPP) {
- pcr &= ~(PC873_ECPEN | PC873_ECPCLK);
- pcr |= (PC873_EPPEN | PC873_EPP19);
- outb(idport + 1, pcr);
- outb(idport + 1, pcr);
-
- ppc->ppc_epp = EPP_1_9; /* XXX */
-
- if (bootverbose)
- printf(", EPP1.9");
-
- /* enable automatic direction turnover */
- if (ppc->ppc_type == NS_PC87332) {
- outb(idport, PC873_PTR);
- ptr = inb(idport + 1);
- ptr &= ~PC873_EPPRDIR;
- outb(idport + 1, ptr);
- outb(idport + 1, ptr);
-
- if (bootverbose)
- printf(", Automatic mode");
- }
- } else {
- pcr &= ~(PC873_ECPEN | PC873_ECPCLK | PC873_EPPEN);
- outb(idport + 1, pcr);
- outb(idport + 1, pcr);
-
- /* configure extended bit in PTR */
- outb(idport, PC873_PTR);
- ptr = inb(idport + 1);
-
- if (chipset_mode & PPB_PS2) {
- ptr |= PC873_EXTENDED;
-
- if (bootverbose)
- printf(", PS/2");
-
- } else {
- /* default to NIBBLE mode */
- ptr &= ~PC873_EXTENDED;
-
- if (bootverbose)
- printf(", NIBBLE");
- }
- outb(idport + 1, ptr);
- outb(idport + 1, ptr);
- }
-
- ppc->ppc_avm = chipset_mode;
- }
-
- if (bootverbose)
- printf("\n");
-
- ppc->ppc_link.adapter = &ppc_generic_adapter;
- ppc_generic_setmode(ppc->ppc_unit, chipset_mode);
-
- return(chipset_mode);
- }
- return(-1);
-}
-
-static int
-ppc_check_epp_timeout(struct ppc_data *ppc)
-{
- ppc_reset_epp_timeout(ppc->ppc_unit);
-
- return (!(r_str(ppc) & TIMEOUT));
-}
-
-/*
- * ppc_smc37c66xgt_detect
- *
- * SMC FDC37C66xGT configuration.
- */
-static int
-ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode)
-{
- int s, i;
- char r;
- int type = -1;
- int csr = SMC66x_CSR; /* initial value is 0x3F0 */
-
- int port_address[] = { -1 /* disabled */ , 0x3bc, 0x378, 0x278 };
-
-
-#define cio csr+1 /* config IO port is either 0x3F1 or 0x371 */
-
- /*
- * Detection: enter configuration mode and read CRD register.
- */
-
- s = splhigh();
- outb(csr, SMC665_iCODE);
- outb(csr, SMC665_iCODE);
- splx(s);
-
- outb(csr, 0xd);
- if (inb(cio) == 0x65) {
- type = SMC_37C665GT;
- goto config;
- }
-
- for (i = 0; i < 2; i++) {
- s = splhigh();
- outb(csr, SMC666_iCODE);
- outb(csr, SMC666_iCODE);
- splx(s);
-
- outb(csr, 0xd);
- if (inb(cio) == 0x66) {
- type = SMC_37C666GT;
- break;
- }
-
- /* Another chance, CSR may be hard-configured to be at 0x370 */
- csr = SMC666_CSR;
- }
-
-config:
- /*
- * If chipset not found, do not continue.
- */
- if (type == -1)
- return (-1);
-
- /* select CR1 */
- outb(csr, 0x1);
-
- /* read the port's address: bits 0 and 1 of CR1 */
- r = inb(cio) & SMC_CR1_ADDR;
- if (port_address[r] != ppc->ppc_base)
- return (-1);
-
- ppc->ppc_type = type;
-
- /*
- * CR1 and CR4 registers bits 3 and 0/1 for mode configuration
- * If SPP mode is detected, try to set ECP+EPP mode
- */
-
- if (bootverbose) {
- outb(csr, 0x1);
- printf("ppc%d: SMC registers CR1=0x%x", ppc->ppc_unit,
- inb(cio) & 0xff);
-
- outb(csr, 0x4);
- printf(" CR4=0x%x", inb(cio) & 0xff);
- }
-
- /* select CR1 */
- outb(csr, 0x1);
-
- if (!chipset_mode) {
- /* autodetect mode */
-
- /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
- if (type == SMC_37C666GT) {
- ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
- if (bootverbose)
- printf(" configuration hardwired, supposing " \
- "ECP+EPP SPP");
-
- } else
- if ((inb(cio) & SMC_CR1_MODE) == 0) {
- /* already in extended parallel port mode, read CR4 */
- outb(csr, 0x4);
- r = (inb(cio) & SMC_CR4_EMODE);
-
- switch (r) {
- case SMC_SPP:
- ppc->ppc_avm |= PPB_SPP;
- if (bootverbose)
- printf(" SPP");
- break;
-
- case SMC_EPPSPP:
- ppc->ppc_avm |= PPB_EPP | PPB_SPP;
- if (bootverbose)
- printf(" EPP SPP");
- break;
-
- case SMC_ECP:
- ppc->ppc_avm |= PPB_ECP | PPB_SPP;
- if (bootverbose)
- printf(" ECP SPP");
- break;
-
- case SMC_ECPEPP:
- ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
- if (bootverbose)
- printf(" ECP+EPP SPP");
- break;
- }
- } else {
- /* not an extended port mode */
- ppc->ppc_avm |= PPB_SPP;
- if (bootverbose)
- printf(" SPP");
- }
-
- } else {
- /* mode forced */
- ppc->ppc_avm = chipset_mode;
-
- /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
- if (type == SMC_37C666GT)
- goto end_detect;
-
- r = inb(cio);
- if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) {
- /* do not use ECP when the mode is not forced to */
- outb(cio, r | SMC_CR1_MODE);
- if (bootverbose)
- printf(" SPP");
- } else {
- /* an extended mode is selected */
- outb(cio, r & ~SMC_CR1_MODE);
-
- /* read CR4 register and reset mode field */
- outb(csr, 0x4);
- r = inb(cio) & ~SMC_CR4_EMODE;
-
- if (chipset_mode & PPB_ECP) {
- if (chipset_mode & PPB_EPP) {
- outb(cio, r | SMC_ECPEPP);
- if (bootverbose)
- printf(" ECP+EPP");
- } else {
- outb(cio, r | SMC_ECP);
- if (bootverbose)
- printf(" ECP");
- }
- } else {
- /* PPB_EPP is set */
- outb(cio, r | SMC_EPPSPP);
- if (bootverbose)
- printf(" EPP SPP");
- }
- }
- ppc->ppc_avm = chipset_mode;
- }
-
- /* set FIFO threshold to 16 */
- if (ppc->ppc_avm & PPB_ECP) {
- /* select CRA */
- outb(csr, 0xa);
- outb(cio, 16);
- }
-
-end_detect:
-
- if (bootverbose)
- printf ("\n");
-
- if (ppc->ppc_avm & PPB_EPP) {
- /* select CR4 */
- outb(csr, 0x4);
- r = inb(cio);
-
- /*
- * Set the EPP protocol...
- * Low=EPP 1.9 (1284 standard) and High=EPP 1.7
- */
- if (ppc->ppc_epp == EPP_1_9)
- outb(cio, (r & ~SMC_CR4_EPPTYPE));
- else
- outb(cio, (r | SMC_CR4_EPPTYPE));
- }
-
- /* end config mode */
- outb(csr, 0xaa);
-
- ppc->ppc_link.adapter = &ppc_smclike_adapter;
- ppc_smclike_setmode(ppc->ppc_unit, chipset_mode);
-
- return (chipset_mode);
-}
-
-/*
- * Winbond W83877F stuff
- *
- * EFER: extended function enable register
- * EFIR: extended function index register
- * EFDR: extended function data register
- */
-#define efir ((efer == 0x250) ? 0x251 : 0x3f0)
-#define efdr ((efer == 0x250) ? 0x252 : 0x3f1)
-
-static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 };
-static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 };
-static int w83877f_keyiter[] = { 1, 2, 2, 1 };
-static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 };
-
-static int
-ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode)
-{
- int i, j, efer;
- unsigned char r, hefere, hefras;
-
- for (i = 0; i < 4; i ++) {
- /* first try to enable configuration registers */
- efer = w83877f_efers[i];
-
- /* write the key to the EFER */
- for (j = 0; j < w83877f_keyiter[i]; j ++)
- outb (efer, w83877f_keys[i]);
-
- /* then check HEFERE and HEFRAS bits */
- outb (efir, 0x0c);
- hefere = inb(efdr) & WINB_HEFERE;
-
- outb (efir, 0x16);
- hefras = inb(efdr) & WINB_HEFRAS;
-
- /*
- * HEFRAS HEFERE
- * 0 1 write 89h to 250h (power-on default)
- * 1 0 write 86h twice to 3f0h
- * 1 1 write 87h twice to 3f0h
- * 0 0 write 88h to 250h
- */
- if ((hefere | hefras) == w83877f_hefs[i])
- goto found;
- }
-
- return (-1); /* failed */
-
-found:
- /* check base port address - read from CR23 */
- outb(efir, 0x23);
- if (ppc->ppc_base != inb(efdr) * 4) /* 4 bytes boundaries */
- return (-1);
-
- /* read CHIP ID from CR9/bits0-3 */
- outb(efir, 0x9);
-
- switch (inb(efdr) & WINB_CHIPID) {
- case WINB_W83877F_ID:
- ppc->ppc_type = WINB_W83877F;
- break;
-
- case WINB_W83877AF_ID:
- ppc->ppc_type = WINB_W83877AF;
- break;
-
- default:
- ppc->ppc_type = WINB_UNKNOWN;
- }
-
- if (bootverbose) {
- /* dump of registers */
- printf("ppc%d: 0x%x - ", ppc->ppc_unit, w83877f_keys[i]);
- for (i = 0; i <= 0xd; i ++) {
- outb(efir, i);
- printf("0x%x ", inb(efdr));
- }
- for (i = 0x10; i <= 0x17; i ++) {
- outb(efir, i);
- printf("0x%x ", inb(efdr));
- }
- outb(efir, 0x1e);
- printf("0x%x ", inb(efdr));
- for (i = 0x20; i <= 0x29; i ++) {
- outb(efir, i);
- printf("0x%x ", inb(efdr));
- }
- printf("\n");
- printf("ppc%d:", ppc->ppc_unit);
- }
-
- ppc->ppc_link.adapter = &ppc_generic_adapter;
-
- if (!chipset_mode) {
- /* autodetect mode */
-
- /* select CR0 */
- outb(efir, 0x0);
- r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1);
-
- /* select CR9 */
- outb(efir, 0x9);
- r |= (inb(efdr) & WINB_PRTMODS2);
-
- switch (r) {
- case WINB_W83757:
- if (bootverbose)
- printf("ppc%d: W83757 compatible mode\n",
- ppc->ppc_unit);
- return (-1); /* generic or SMC-like */
-
- case WINB_EXTFDC:
- case WINB_EXTADP:
- case WINB_EXT2FDD:
- case WINB_JOYSTICK:
- if (bootverbose)
- printf(" not in parallel port mode\n");
- return (-1);
-
- case (WINB_PARALLEL | WINB_EPP_SPP):
- ppc->ppc_avm |= PPB_EPP | PPB_SPP;
- if (bootverbose)
- printf(" EPP SPP");
- break;
-
- case (WINB_PARALLEL | WINB_ECP):
- ppc->ppc_avm |= PPB_ECP | PPB_SPP;
- if (bootverbose)
- printf(" ECP SPP");
- break;
-
- case (WINB_PARALLEL | WINB_ECP_EPP):
- ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
- ppc->ppc_link.adapter = &ppc_smclike_adapter;
-
- if (bootverbose)
- printf(" ECP+EPP SPP");
- break;
- default:
- printf("%s: unknown case (0x%x)!\n", __FUNCTION__, r);
- }
-
- } else {
- /* mode forced */
-
- /* select CR9 and set PRTMODS2 bit */
- outb(efir, 0x9);
- outb(efdr, inb(efdr) & ~WINB_PRTMODS2);
-
- /* select CR0 and reset PRTMODSx bits */
- outb(efir, 0x0);
- outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1));
-
- if (chipset_mode & PPB_ECP) {
- if (chipset_mode & PPB_EPP) {
- outb(efdr, inb(efdr) | WINB_ECP_EPP);
- if (bootverbose)
- printf(" ECP+EPP");
-
- ppc->ppc_link.adapter = &ppc_smclike_adapter;
-
- } else {
- outb(efdr, inb(efdr) | WINB_ECP);
- if (bootverbose)
- printf(" ECP");
- }
- } else {
- /* select EPP_SPP otherwise */
- outb(efdr, inb(efdr) | WINB_EPP_SPP);
- if (bootverbose)
- printf(" EPP SPP");
- }
- ppc->ppc_avm = chipset_mode;
- }
-
- if (bootverbose)
- printf("\n");
-
- /* exit configuration mode */
- outb(efer, 0xaa);
-
- ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode);
-
- return (chipset_mode);
-}
-
-/*
- * ppc_generic_detect
- */
-static int
-ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
-{
- /* default to generic */
- ppc->ppc_link.adapter = &ppc_generic_adapter;
-
- if (bootverbose)
- printf("ppc%d:", ppc->ppc_unit);
-
- if (!chipset_mode) {
- /* first, check for ECP */
- w_ecr(ppc, PPC_ECR_PS2);
- if ((r_ecr(ppc) & 0xe0) == PPC_ECR_PS2) {
- ppc->ppc_avm |= PPB_ECP | PPB_SPP;
- if (bootverbose)
- printf(" ECP SPP");
-
- /* search for SMC style ECP+EPP mode */
- w_ecr(ppc, PPC_ECR_EPP);
- }
-
- /* try to reset EPP timeout bit */
- if (ppc_check_epp_timeout(ppc)) {
- ppc->ppc_avm |= PPB_EPP;
-
- if (ppc->ppc_avm & PPB_ECP) {
- /* SMC like chipset found */
- ppc->ppc_type = SMC_LIKE;
- ppc->ppc_link.adapter = &ppc_smclike_adapter;
-
- if (bootverbose)
- printf(" ECP+EPP");
- } else {
- if (bootverbose)
- printf(" EPP");
- }
- } else {
- /* restore to standard mode */
- w_ecr(ppc, PPC_ECR_STD);
- }
-
- /* XXX try to detect NIBBLE and PS2 modes */
- ppc->ppc_avm |= PPB_NIBBLE;
-
- if (bootverbose)
- printf(" SPP");
-
- } else {
- ppc->ppc_avm = chipset_mode;
- }
-
- if (bootverbose)
- printf("\n");
-
- ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode);
-
- return (chipset_mode);
-}
-
-/*
- * ppc_detect()
- *
- * mode is the mode suggested at boot
- */
-static int
-ppc_detect(struct ppc_data *ppc, int chipset_mode) {
-
- int i, mode;
-
- /* list of supported chipsets */
- int (*chipset_detect[])(struct ppc_data *, int) = {
- ppc_pc873xx_detect,
- ppc_smc37c66xgt_detect,
- ppc_w83877f_detect,
- ppc_generic_detect,
- NULL
- };
-
- /* if can't find the port and mode not forced return error */
- if (!ppc_detect_port(ppc) && chipset_mode == 0)
- return (EIO); /* failed, port not present */
-
- /* assume centronics compatible mode is supported */
- ppc->ppc_avm = PPB_COMPATIBLE;
-
- /* we have to differenciate available chipset modes,
- * chipset running modes and IEEE-1284 operating modes
- *
- * after detection, the port must support running in compatible mode
- */
- if (ppc->ppc_flags & 0x40) {
- if (bootverbose)
- printf("ppc: chipset forced to generic\n");
-
- ppc->ppc_mode = ppc_generic_detect(ppc, chipset_mode);
-
- } else {
- for (i=0; chipset_detect[i] != NULL; i++) {
- if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
- ppc->ppc_mode = mode;
- break;
- }
- }
- }
-
- /* configure/detect ECP FIFO */
- if ((ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_flags & 0x80))
- ppc_detect_fifo(ppc);
-
- return (0);
-}
-
-/*
- * ppc_exec_microseq()
- *
- * Execute a microsequence.
- * Microsequence mechanism is supposed to handle fast I/O operations.
- */
-static int
-ppc_exec_microseq(int unit, struct ppb_microseq **p_msq)
-{
- struct ppc_data *ppc = ppcdata[unit];
- struct ppb_microseq *mi;
- char cc, *p;
- int i, iter, len;
- int error;
-
- register int reg;
- register char mask;
- register int accum = 0;
- register char *ptr = 0;
-
- struct ppb_microseq *stack = 0;
-
-/* microsequence registers are equivalent to PC-like port registers */
-#define r_reg(register,ppc) (inb((ppc)->ppc_base + register))
-#define w_reg(register,ppc,byte) outb((ppc)->ppc_base + register, byte)
-
-#define INCR_PC (mi ++) /* increment program counter */
-
- mi = *p_msq;
- for (;;) {
- switch (mi->opcode) {
- case MS_OP_RSET:
- cc = r_reg(mi->arg[0].i, ppc);
- cc &= (char)mi->arg[2].i; /* clear mask */
- cc |= (char)mi->arg[1].i; /* assert mask */
- w_reg(mi->arg[0].i, ppc, cc);
- INCR_PC;
- break;
-
- case MS_OP_RASSERT_P:
- reg = mi->arg[1].i;
- ptr = ppc->ppc_ptr;
-
- if ((len = mi->arg[0].i) == MS_ACCUM) {
- accum = ppc->ppc_accum;
- for (; accum; accum--)
- w_reg(reg, ppc, *ptr++);
- ppc->ppc_accum = accum;
- } else
- for (i=0; i<len; i++)
- w_reg(reg, ppc, *ptr++);
- ppc->ppc_ptr = ptr;
-
- INCR_PC;
- break;
-
- case MS_OP_RFETCH_P:
- reg = mi->arg[1].i;
- mask = (char)mi->arg[2].i;
- ptr = ppc->ppc_ptr;
-
- if ((len = mi->arg[0].i) == MS_ACCUM) {
- accum = ppc->ppc_accum;
- for (; accum; accum--)
- *ptr++ = r_reg(reg, ppc) & mask;
- ppc->ppc_accum = accum;
- } else
- for (i=0; i<len; i++)
- *ptr++ = r_reg(reg, ppc) & mask;
- ppc->ppc_ptr = ptr;
-
- INCR_PC;
- break;
-
- case MS_OP_RFETCH:
- *((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) &
- (char)mi->arg[1].i;
- INCR_PC;
- break;
-
- case MS_OP_RASSERT:
- case MS_OP_DELAY:
-
- /* let's suppose the next instr. is the same */
- prefetch:
- for (;mi->opcode == MS_OP_RASSERT; INCR_PC)
- w_reg(mi->arg[0].i, ppc, (char)mi->arg[1].i);
-
- if (mi->opcode == MS_OP_DELAY) {
- DELAY(mi->arg[0].i);
- INCR_PC;
- goto prefetch;
- }
- break;
-
- case MS_OP_ADELAY:
- if (mi->arg[0].i)
- tsleep(NULL, PPBPRI, "ppbdelay",
- mi->arg[0].i * (hz/1000));
- INCR_PC;
- break;
-
- case MS_OP_TRIG:
- reg = mi->arg[0].i;
- iter = mi->arg[1].i;
- p = (char *)mi->arg[2].p;
-
- /* XXX delay limited to 255 us */
- for (i=0; i<iter; i++) {
- w_reg(reg, ppc, *p++);
- DELAY((unsigned char)*p++);
- }
- INCR_PC;
- break;
-
- case MS_OP_SET:
- ppc->ppc_accum = mi->arg[0].i;
- INCR_PC;
- break;
-
- case MS_OP_DBRA:
- if (--ppc->ppc_accum > 0)
- mi += mi->arg[0].i;
- else
- INCR_PC;
- break;
-
- case MS_OP_BRSET:
- cc = r_str(ppc);
- if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i)
- mi += mi->arg[1].i;
- else
- INCR_PC;
- break;
-
- case MS_OP_BRCLEAR:
- cc = r_str(ppc);
- if ((cc & (char)mi->arg[0].i) == 0)
- mi += mi->arg[1].i;
- else
- INCR_PC;
- break;
-
- case MS_OP_BRSTAT:
- cc = r_str(ppc);
- if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
- (char)mi->arg[0].i)
- mi += mi->arg[2].i;
- else
- INCR_PC;
- break;
-
- case MS_OP_C_CALL:
- /*
- * If the C call returns !0 then end the microseq.
- * The current state of ptr is passed to the C function
- */
- if ((error = mi->arg[0].f(mi->arg[1].p, ppc->ppc_ptr)))
- return (error);
-
- INCR_PC;
- break;
-
- case MS_OP_PTR:
- ppc->ppc_ptr = (char *)mi->arg[0].p;
- INCR_PC;
- break;
-
- case MS_OP_CALL:
- if (stack)
- panic("%s: too much calls", __FUNCTION__);
-
- if (mi->arg[0].p) {
- /* store the state of the actual
- * microsequence
- */
- stack = mi;
-
- /* jump to the new microsequence */
- mi = (struct ppb_microseq *)mi->arg[0].p;
- } else
- INCR_PC;
-
- break;
-
- case MS_OP_SUBRET:
- /* retrieve microseq and pc state before the call */
- mi = stack;
-
- /* reset the stack */
- stack = 0;
-
- /* XXX return code */
-
- INCR_PC;
- break;
-
- case MS_OP_PUT:
- case MS_OP_GET:
- case MS_OP_RET:
- /* can't return to ppb level during the execution
- * of a submicrosequence */
- if (stack)
- panic("%s: can't return to ppb level",
- __FUNCTION__);
-
- /* update pc for ppb level of execution */
- *p_msq = mi;
-
- /* return to ppb level of execution */
- return (0);
-
- default:
- panic("%s: unknown microsequence opcode 0x%x",
- __FUNCTION__, mi->opcode);
- }
- }
-
- /* unreached */
-}
-
-static void
-ppcintr(int unit)
-{
- struct ppc_data *ppc = ppcdata[unit];
- char ctr, ecr;
-
- ctr = r_ctr(ppc);
- ecr = r_ecr(ppc);
-
-#ifdef PPC_DEBUG
- printf("!");
-#endif
-
- /* don't use ecp mode with IRQENABLE set */
- if (ctr & IRQENABLE) {
- /* call upper code */
- ppb_intr(&ppc->ppc_link);
- return;
- }
-
- if (ctr & nFAULT) {
- if (ppc->ppc_irqstat & PPC_IRQ_nFAULT) {
-
- w_ecr(ppc, ecr | PPC_nFAULT_INTR);
- ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
- } else {
- /* call upper code */
- ppb_intr(&ppc->ppc_link);
- return;
- }
- }
-
- if (ppc->ppc_irqstat & PPC_IRQ_DMA) {
- /* disable interrupts (should be done by hardware though) */
- w_ecr(ppc, ecr | PPC_SERVICE_INTR);
- ppc->ppc_irqstat &= ~PPC_IRQ_DMA;
- ecr = r_ecr(ppc);
-
- /* check if DMA completed */
- if ((ppc->ppc_avm & PPB_ECP) && (ecr & PPC_ENABLE_DMA)) {
-#ifdef PPC_DEBUG
- printf("a");
-#endif
- /* stop DMA */
- w_ecr(ppc, ecr & ~PPC_ENABLE_DMA);
- ecr = r_ecr(ppc);
-
- if (ppc->ppc_dmastat == PPC_DMA_STARTED) {
-#ifdef PPC_DEBUG
- printf("d");
-#endif
- isa_dmadone(
- ppc->ppc_dmaflags,
- ppc->ppc_dmaddr,
- ppc->ppc_dmacnt,
- ppc->ppc_dmachan);
-
- ppc->ppc_dmastat = PPC_DMA_COMPLETE;
-
- /* wakeup the waiting process */
- wakeup((caddr_t)ppc);
- }
- }
- } else if (ppc->ppc_irqstat & PPC_IRQ_FIFO) {
-
- /* classic interrupt I/O */
- ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
-
- }
-
- return;
-}
-
-static int
-ppc_read(int unit, char *buf, int len, int mode)
-{
- return (EINVAL);
-}
-
-/*
- * Call this function if you want to send data in any advanced mode
- * of your parallel port: FIFO, DMA
- *
- * If what you want is not possible (no ECP, no DMA...),
- * EINVAL is returned
- */
-static int
-ppc_write(int unit, char *buf, int len, int how)
-{
- struct ppc_data *ppc = ppcdata[unit];
- char ecr, ecr_sav, ctr, ctr_sav;
- int s, error = 0;
- int spin;
-
-#ifdef PPC_DEBUG
- printf("w");
-#endif
-
- ecr_sav = r_ecr(ppc);
- ctr_sav = r_ctr(ppc);
-
- /*
- * Send buffer with DMA, FIFO and interrupts
- */
- if (ppc->ppc_avm & PPB_ECP) {
-
- if (ppc->ppc_dmachan >= 0) {
-
- /* byte mode, no intr, no DMA, dir=0, flush fifo
- */
- ecr = PPC_ECR_STD | PPC_DISABLE_INTR;
- w_ecr(ppc, ecr);
-
- /* disable nAck interrupts */
- ctr = r_ctr(ppc);
- ctr &= ~IRQENABLE;
- w_ctr(ppc, ctr);
-
- ppc->ppc_dmaflags = 0;
- ppc->ppc_dmaddr = (caddr_t)buf;
- ppc->ppc_dmacnt = (u_int)len;
-
- switch (ppc->ppc_mode) {
- case PPB_COMPATIBLE:
- /* compatible mode with FIFO, no intr, DMA, dir=0 */
- ecr = PPC_ECR_FIFO | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
- break;
- case PPB_ECP:
- ecr = PPC_ECR_ECP | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
- break;
- default:
- error = EINVAL;
- goto error;
- }
-
- w_ecr(ppc, ecr);
- ecr = r_ecr(ppc);
-
- /* enter splhigh() not to be preempted
- * by the dma interrupt, we may miss
- * the wakeup otherwise
- */
- s = splhigh();
-
- ppc->ppc_dmastat = PPC_DMA_INIT;
-
- /* enable interrupts */
- ecr &= ~PPC_SERVICE_INTR;
- ppc->ppc_irqstat = PPC_IRQ_DMA;
- w_ecr(ppc, ecr);
-
- isa_dmastart(
- ppc->ppc_dmaflags,
- ppc->ppc_dmaddr,
- ppc->ppc_dmacnt,
- ppc->ppc_dmachan);
-#ifdef PPC_DEBUG
- printf("s%d", ppc->ppc_dmacnt);
-#endif
- ppc->ppc_dmastat = PPC_DMA_STARTED;
-
- /* Wait for the DMA completed interrupt. We hope we won't
- * miss it, otherwise a signal will be necessary to unlock the
- * process.
- */
- do {
- /* release CPU */
- error = tsleep((caddr_t)ppc,
- PPBPRI | PCATCH, "ppcdma", 0);
-
- } while (error == EWOULDBLOCK);
-
- splx(s);
-
- if (error) {
-#ifdef PPC_DEBUG
- printf("i");
-#endif
- /* stop DMA */
- isa_dmadone(
- ppc->ppc_dmaflags, ppc->ppc_dmaddr,
- ppc->ppc_dmacnt, ppc->ppc_dmachan);
-
- /* no dma, no interrupt, flush the fifo */
- w_ecr(ppc, PPC_ECR_RESET);
-
- ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
- goto error;
- }
-
- /* wait for an empty fifo */
- while (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
-
- for (spin=100; spin; spin--)
- if (r_ecr(ppc) & PPC_FIFO_EMPTY)
- goto fifo_empty;
-#ifdef PPC_DEBUG
- printf("Z");
-#endif
- error = tsleep((caddr_t)ppc, PPBPRI | PCATCH, "ppcfifo", hz/100);
- if (error != EWOULDBLOCK) {
-#ifdef PPC_DEBUG
- printf("I");
-#endif
- /* no dma, no interrupt, flush the fifo */
- w_ecr(ppc, PPC_ECR_RESET);
-
- ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
- error = EINTR;
- goto error;
- }
- }
-
-fifo_empty:
- /* no dma, no interrupt, flush the fifo */
- w_ecr(ppc, PPC_ECR_RESET);
-
- } else
- error = EINVAL; /* XXX we should FIFO and
- * interrupts */
- } else
- error = EINVAL;
-
-error:
-
- /* PDRQ must be kept unasserted until nPDACK is
- * deasserted for a minimum of 350ns (SMC datasheet)
- *
- * Consequence may be a FIFO that never empty
- */
- DELAY(1);
-
- w_ecr(ppc, ecr_sav);
- w_ctr(ppc, ctr_sav);
-
- return (error);
-}
-
-/*
- * Configure current operating mode
- */
-static int
-ppc_generic_setmode(int unit, int mode)
-{
- struct ppc_data *ppc = ppcdata[unit];
- u_char ecr = 0;
-
- /* check if mode is available */
- if (mode && !(ppc->ppc_avm & mode))
- return (EINVAL);
-
- /* if ECP mode, configure ecr register */
- if (ppc->ppc_avm & PPB_ECP) {
- /* return to byte mode (keeping direction bit),
- * no interrupt, no DMA to be able to change to
- * ECP
- */
- w_ecr(ppc, PPC_ECR_RESET);
- ecr = PPC_DISABLE_INTR;
-
- if (mode & PPB_EPP)
- return (EINVAL);
- else if (mode & PPB_ECP)
- /* select ECP mode */
- ecr |= PPC_ECR_ECP;
- else if (mode & PPB_PS2)
- /* select PS2 mode with ECP */
- ecr |= PPC_ECR_PS2;
- else
- /* select COMPATIBLE/NIBBLE mode */
- ecr |= PPC_ECR_STD;
-
- w_ecr(ppc, ecr);
- }
-
- ppc->ppc_mode = mode;
-
- return (0);
-}
-
-/*
- * The ppc driver is free to choose options like FIFO or DMA
- * if ECP mode is available.
- *
- * The 'RAW' option allows the upper drivers to force the ppc mode
- * even with FIFO, DMA available.
- */
-int
-ppc_smclike_setmode(int unit, int mode)
-{
- struct ppc_data *ppc = ppcdata[unit];
- u_char ecr = 0;
-
- /* check if mode is available */
- if (mode && !(ppc->ppc_avm & mode))
- return (EINVAL);
-
- /* if ECP mode, configure ecr register */
- if (ppc->ppc_avm & PPB_ECP) {
- /* return to byte mode (keeping direction bit),
- * no interrupt, no DMA to be able to change to
- * ECP or EPP mode
- */
- w_ecr(ppc, PPC_ECR_RESET);
- ecr = PPC_DISABLE_INTR;
-
- if (mode & PPB_EPP)
- /* select EPP mode */
- ecr |= PPC_ECR_EPP;
- else if (mode & PPB_ECP)
- /* select ECP mode */
- ecr |= PPC_ECR_ECP;
- else if (mode & PPB_PS2)
- /* select PS2 mode with ECP */
- ecr |= PPC_ECR_PS2;
- else
- /* select COMPATIBLE/NIBBLE mode */
- ecr |= PPC_ECR_STD;
-
- w_ecr(ppc, ecr);
- }
-
- ppc->ppc_mode = mode;
-
- return (0);
-}
-
-/*
- * EPP timeout, according to the PC87332 manual
- * Semantics of clearing EPP timeout bit.
- * PC87332 - reading SPP_STR does it...
- * SMC - write 1 to EPP timeout bit XXX
- * Others - (?) write 0 to EPP timeout bit
- */
-static void
-ppc_reset_epp_timeout(int unit)
-{
- struct ppc_data *ppc = ppcdata[unit];
- register char r;
-
- r = r_str(ppc);
- w_str(ppc, r | 0x1);
- w_str(ppc, r & 0xfe);
-
- return;
-}
-
-static int
-ppcprobe(struct isa_device *dvp)
-{
- static short next_bios_ppc = 0;
- struct ppc_data *ppc;
-
- /*
- * If port not specified, use bios list.
- */
- if(dvp->id_iobase < 0) {
- if((next_bios_ppc < BIOS_MAX_PPC) &&
- (*(BIOS_PORTS+next_bios_ppc) != 0) ) {
- dvp->id_iobase = *(BIOS_PORTS+next_bios_ppc++);
- if (bootverbose)
- printf("ppc: parallel port found at 0x%x\n",
- dvp->id_iobase);
- } else
- return (0);
- }
-
- /*
- * Port was explicitly specified.
- * This allows probing of ports unknown to the BIOS.
- */
-
- /*
- * Allocate the ppc_data structure.
- */
- ppc = malloc(sizeof(struct ppc_data), M_DEVBUF, M_NOWAIT);
- if (!ppc) {
- printf("ppc: cannot malloc!\n");
- goto error;
- }
- bzero(ppc, sizeof(struct ppc_data));
-
- ppc->ppc_base = dvp->id_iobase;
- ppc->ppc_unit = dvp->id_unit;
- ppc->ppc_type = GENERIC;
-
- /* store boot flags */
- ppc->ppc_flags = dvp->id_flags;
-
- ppc->ppc_mode = PPB_COMPATIBLE;
- ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4;
-
- /*
- * XXX Try and detect if interrupts are working
- */
- if (!(dvp->id_flags & 0x20))
- ppc->ppc_irq = ffs(dvp->id_irq) - 1;
-
- ppc->ppc_dmachan = dvp->id_drq;
-
- ppcdata[ppc->ppc_unit] = ppc;
- nppc ++;
-
- /*
- * Link the Parallel Port Chipset (adapter) to
- * the future ppbus. Default to a generic chipset
- */
- ppc->ppc_link.adapter_unit = ppc->ppc_unit;
- ppc->ppc_link.adapter = &ppc_generic_adapter;
-
- /*
- * Try to detect the chipset and its mode.
- */
- if (ppc_detect(ppc, dvp->id_flags & 0xf))
- goto error;
-
- return (1);
-
-error:
- return (0);
-}
-
-static int
-ppcattach(struct isa_device *isdp)
-{
- struct ppc_data *ppc = ppcdata[isdp->id_unit];
- struct ppb_data *ppbus;
-
- printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit,
- ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm],
- ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
- ppc_epp_protocol[ppc->ppc_epp] : "");
-
- if (ppc->ppc_fifo)
- printf("ppc%d: FIFO with %d/%d/%d bytes threshold\n",
- ppc->ppc_unit, ppc->ppc_fifo, ppc->ppc_wthr,
- ppc->ppc_rthr);
-
- isdp->id_ointr = ppcintr;
-
- /*
- * Prepare ppbus data area for upper level code.
- */
- ppbus = ppb_alloc_bus();
-
- if (!ppbus)
- return (0);
-
- ppc->ppc_link.ppbus = ppbus;
- ppbus->ppb_link = &ppc->ppc_link;
-
- if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_dmachan > 0)) {
-
- /* acquire the DMA channel forever */
- isa_dma_acquire(ppc->ppc_dmachan);
- isa_dmainit(ppc->ppc_dmachan, 1024); /* nlpt.BUFSIZE */
- }
-
- /*
- * Probe the ppbus and attach devices found.
- */
- ppb_attachdevs(ppbus);
-
- return (1);
-}
-#endif
diff --git a/sys/isa/ppcreg.h b/sys/isa/ppcreg.h
deleted file mode 100644
index c847e6ccd218..000000000000
--- a/sys/isa/ppcreg.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*-
- * Copyright (c) 1997 Nicolas Souchu
- * 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.
- *
- * 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.
- *
- * $Id: ppcreg.h,v 1.6 1999/01/10 12:04:53 nsouch Exp $
- *
- */
-#ifndef __PPCREG_H
-#define __PPCREG_H
-
-/*
- * Parallel Port Chipset type.
- */
-#define SMC_LIKE 0
-#define SMC_37C665GT 1
-#define SMC_37C666GT 2
-#define NS_PC87332 3
-#define NS_PC87306 4
-#define INTEL_820191AA 5 /* XXX not implemented */
-#define GENERIC 6
-#define WINB_W83877F 7
-#define WINB_W83877AF 8
-#define WINB_UNKNOWN 9
-#define NS_PC87334 10
-
-/*
- * Generic structure to hold parallel port chipset info.
- */
-struct ppc_data {
-
- int ppc_unit;
- int ppc_type;
-
- int ppc_mode; /* chipset current mode */
- int ppc_avm; /* chipset available modes */
-
-#define PPC_IRQ_NONE 0x0
-#define PPC_IRQ_nACK 0x1
-#define PPC_IRQ_DMA 0x2
-#define PPC_IRQ_FIFO 0x4
-#define PPC_IRQ_nFAULT 0x8
- int ppc_irqstat; /* remind irq settings */
-
-#define PPC_DMA_INIT 0x01
-#define PPC_DMA_STARTED 0x02
-#define PPC_DMA_COMPLETE 0x03
-#define PPC_DMA_INTERRUPTED 0x04
-#define PPC_DMA_ERROR 0x05
- int ppc_dmastat; /* dma state */
- int ppc_dmachan; /* dma channel */
- int ppc_dmaflags; /* dma transfer flags */
- caddr_t ppc_dmaddr; /* buffer address */
- u_int ppc_dmacnt; /* count of bytes sent with dma */
-
-#define PPC_PWORD_MASK 0x30
-#define PPC_PWORD_16 0x00
-#define PPC_PWORD_8 0x10
-#define PPC_PWORD_32 0x20
- char ppc_pword; /* PWord size */
- short ppc_fifo; /* FIFO threshold */
-
- short ppc_wthr; /* writeIntrThresold */
- short ppc_rthr; /* readIntrThresold */
-
-#define ppc_base ppc_link.base
-#define ppc_epp ppc_link.epp_protocol
-#define ppc_irq ppc_link.id_irq
-#define ppc_subm ppc_link.submicroseq
-#define ppc_ptr ppc_link.ptr
-#define ppc_accum ppc_link.accum
-
- unsigned char ppc_flags;
-
- struct ppb_link ppc_link;
-};
-
-/*
- * Parallel Port Chipset registers.
- */
-#define PPC_SPP_DTR 0 /* SPP data register */
-#define PPC_ECP_A_FIFO 0 /* ECP Address fifo register */
-#define PPC_SPP_STR 1 /* SPP status register */
-#define PPC_SPP_CTR 2 /* SPP control register */
-#define PPC_EPP_DATA 4 /* EPP data register (8, 16 or 32 bit) */
-#define PPC_ECP_D_FIFO 0x400 /* ECP Data fifo register */
-#define PPC_ECP_CNFGA 0x400 /* Configuration register A */
-#define PPC_ECP_CNFGB 0x401 /* Configuration register B */
-#define PPC_ECP_ECR 0x402 /* ECP extended control register */
-
-#define PPC_FIFO_EMPTY 0x1 /* ecr register - bit 0 */
-#define PPC_FIFO_FULL 0x2 /* ecr register - bit 1 */
-#define PPC_SERVICE_INTR 0x4 /* ecr register - bit 2 */
-#define PPC_ENABLE_DMA 0x8 /* ecr register - bit 3 */
-#define PPC_nFAULT_INTR 0x10 /* ecr register - bit 4 */
-#define PPC_ECR_STD 0x0
-#define PPC_ECR_PS2 0x20
-#define PPC_ECR_FIFO 0x40
-#define PPC_ECR_ECP 0x60
-#define PPC_ECR_EPP 0x80
-
-#define PPC_DISABLE_INTR (PPC_SERVICE_INTR | PPC_nFAULT_INTR)
-#define PPC_ECR_RESET (PPC_ECR_PS2 | PPC_DISABLE_INTR)
-
-#define r_dtr(ppc) (inb((ppc)->ppc_base + PPC_SPP_DTR))
-#define r_str(ppc) (inb((ppc)->ppc_base + PPC_SPP_STR))
-#define r_ctr(ppc) (inb((ppc)->ppc_base + PPC_SPP_CTR))
-#define r_epp(ppc) (inb((ppc)->ppc_base + PPC_EPP_DATA))
-#define r_cnfgA(ppc) (inb((ppc)->ppc_base + PPC_ECP_CNFGA))
-#define r_cnfgB(ppc) (inb((ppc)->ppc_base + PPC_ECP_CNFGB))
-#define r_ecr(ppc) (inb((ppc)->ppc_base + PPC_ECP_ECR))
-#define r_fifo(ppc) (inb((ppc)->ppc_base + PPC_ECP_D_FIFO))
-
-#define w_dtr(ppc,byte) outb((ppc)->ppc_base + PPC_SPP_DTR, byte)
-#define w_str(ppc,byte) outb((ppc)->ppc_base + PPC_SPP_STR, byte)
-#define w_ctr(ppc,byte) outb((ppc)->ppc_base + PPC_SPP_CTR, byte)
-#define w_epp(ppc,byte) outb((ppc)->ppc_base + PPC_EPP_DATA, byte)
-#define w_ecr(ppc,byte) outb((ppc)->ppc_base + PPC_ECP_ECR, byte)
-#define w_fifo(ppc,byte) outb((ppc)->ppc_base + PPC_ECP_D_FIFO, byte)
-
-/*
- * Register defines for the PC873xx parts
- */
-
-#define PC873_FER 0x00
-#define PC873_PPENABLE (1<<0)
-#define PC873_FAR 0x01
-#define PC873_PTR 0x02
-#define PC873_CFGLOCK (1<<6)
-#define PC873_EPPRDIR (1<<7)
-#define PC873_EXTENDED (1<<7)
-#define PC873_LPTBIRQ7 (1<<3)
-#define PC873_FCR 0x03
-#define PC873_ZWS (1<<5)
-#define PC873_ZWSPWDN (1<<6)
-#define PC873_PCR 0x04
-#define PC873_EPPEN (1<<0)
-#define PC873_EPP19 (1<<1)
-#define PC873_ECPEN (1<<2)
-#define PC873_ECPCLK (1<<3)
-#define PC873_PMC 0x06
-#define PC873_TUP 0x07
-#define PC873_SID 0x08
-#define PC873_PNP0 0x1b
-#define PC873_PNP1 0x1c
-#define PC873_LPTBA 0x19
-
-/*
- * Register defines for the SMC FDC37C66xGT parts
- */
-
-/* Init codes */
-#define SMC665_iCODE 0x55
-#define SMC666_iCODE 0x44
-
-/* Base configuration ports */
-#define SMC66x_CSR 0x3F0
-#define SMC666_CSR 0x370 /* hard-configured value for 666 */
-
-/* Bits */
-#define SMC_CR1_ADDR 0x3 /* bit 0 and 1 */
-#define SMC_CR1_MODE (1<<3) /* bit 3 */
-#define SMC_CR4_EMODE 0x3 /* bits 0 and 1 */
-#define SMC_CR4_EPPTYPE (1<<6) /* bit 6 */
-
-/* Extended modes */
-#define SMC_SPP 0x0 /* SPP */
-#define SMC_EPPSPP 0x1 /* EPP and SPP */
-#define SMC_ECP 0x2 /* ECP */
-#define SMC_ECPEPP 0x3 /* ECP and EPP */
-
-/*
- * Register defines for the Winbond W83877F parts
- */
-
-#define WINB_W83877F_ID 0xa
-#define WINB_W83877AF_ID 0xb
-
-/* Configuration bits */
-#define WINB_HEFERE (1<<5) /* CROC bit 5 */
-#define WINB_HEFRAS (1<<0) /* CR16 bit 0 */
-
-#define WINB_PNPCVS (1<<2) /* CR16 bit 2 */
-#define WINB_CHIPID 0xf /* CR9 bits 0-3 */
-
-#define WINB_PRTMODS0 (1<<2) /* CR0 bit 2 */
-#define WINB_PRTMODS1 (1<<3) /* CR0 bit 3 */
-#define WINB_PRTMODS2 (1<<7) /* CR9 bit 7 */
-
-/* W83877F modes: CR9/bit7 | CR0/bit3 | CR0/bit2 */
-#define WINB_W83757 0x0
-#define WINB_EXTFDC 0x4
-#define WINB_EXTADP 0x8
-#define WINB_EXT2FDD 0xc
-#define WINB_JOYSTICK 0x80
-
-#define WINB_PARALLEL 0x80
-#define WINB_EPP_SPP 0x4
-#define WINB_ECP 0x8
-#define WINB_ECP_EPP 0xc
-
-#endif
diff --git a/sys/isa/rtc.h b/sys/isa/rtc.h
deleted file mode 100644
index ea187d9e186e..000000000000
--- a/sys/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_ */